[ 
https://issues.apache.org/jira/browse/THRIFT-5801?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18112671#comment-18112671
 ] 

Sylwester Lachiewicz commented on THRIFT-5801:
----------------------------------------------

We investigated this across 6 language implementations (Go, Rust, Java, C++, 
Python, Node.js) to compare wire representation and runtime behavior.

h3. Cross-Language Comparison for optional list<string> f_1 = ["a", "b"]

|| Language || Field Representation || Default State on Init || Serialized Wire 
Output || Read / Accessor Value ||
| Go | *[]string | nil (unset) | 00 (Empty struct, 0 bytes) | GetF_1() returns 
["a", "b"] |
| Rust | Option<Vec<String>> | None (unset) | 00 (Empty struct, 0 bytes) | None 
(default accessor returns ["a", "b"]) |
| C++ | std::vector<std::string> | ["a", "b"] (__isset = true) | 
0f00010b00000002... (19 bytes) | ["a", "b"] |
| Java | List<String> | ["a", "b"] | 0f00010b00000002... (19 bytes) | ["a", 
"b"] |
| Python | list | ['a', 'b'] | 0f00010b00000002... (19 bytes) | ['a', 'b'] |
| Node.js | Array | ['a', 'b'] | 0f00010b00000002... (19 bytes) | ['a', 'b'] |

h3. Findings

1. *Bandwidth Efficiency & IDL Spec Conformance*:
According to the Thrift IDL specification (doc/specs/idl.md):
{quote}
*optional*
- Write: Optional fields are only written when they are set
- Read: Optional fields may, or may not be part of the input stream.
- Default values: are written when the isset flag is set
{quote}
Both Go and Rust distinguish between an unset optional field and an explicitly 
set field. Leaving the optional pointer / Option unset prevents serializing and 
transmitting default collections over the network on every RPC call when the 
caller never modified the field.

2. *Interoperability*:
When Go or Rust serializes an empty struct (00), receiving endpoints in C++, 
Java, Python, and Node.js still populate the default value ["a", "b"] during 
deserialization. The logical data seen by the receiver application is identical 
across all languages.

3. *Accessor Method*:
In Go, callers access the default value through the generated getter 
`GetF_1()`, which returns `[]string{"a", "b"}` when the pointer is nil.

This behavior is compliant with Thrift IDL write semantics and is working as 
designed.

> Go does not handle the default value of list type correctly
> -----------------------------------------------------------
>
>                 Key: THRIFT-5801
>                 URL: https://issues.apache.org/jira/browse/THRIFT-5801
>             Project: Thrift
>          Issue Type: Bug
>          Components: Go - Compiler
>    Affects Versions: 0.19.0, 0.20.0
>            Reporter: Team_RPCtester
>            Priority: Major
>
> Hi,
> We discover an inconsistent behavior illustrated by the following example.
> {code:java}
> namespace go commonResourcestruct 
> StructClass_0 {
>   1: optional list<string, string> f_1 = ["a", "b"],
> }
> service DataService {
>     StructClass_0 Method_1(1: StructClass_0 agr_method_1)
> } {code}
> When default values are set for optional container type fields (e.g., lists, 
> sets), these fields are not automatically initialized in Go if not explicitly 
> set, whereas in other languages, these container type fields are 
> automatically initialized according to the default values. For example, in 
> the Go client side, our code are as follows:
> {code:java}
> agr_method_1_0 := commonResource.NewStructClass_0() 
> fmt.Println(agr_method_1_0) 
> // method_1_re_agr_method_1_0: StructClass_0({F_1:<nil>}) {code}
> In the Python client side:
> {code:java}
> agr_method_1 = StructClass_0()   
> print(agr_method_1)  
> # agr_method_1: StructClass_0(f_1-[’a’,’b’]) {code}
> In Go, the field f_1 is nil, while in Python, the field f_1 is automatically 
> set to its default value ['a', 'b'].
> Can you help check the issue?
> Thank you.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to