adwinsky / goprotobuf

Automatically exported from code.google.com/p/goprotobuf
Other
0 stars 0 forks source link

Empty (but not nil) "bytes" fields omitted from json.Marshal output #22

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Define a Protocol Buffers message with a "bytes" field, e.g.

message m {
    optional bytes b = 1;
}

2. In Go, set the field to an empty slice:

m := &M{}
m.B  = []byte{}

3. Call json.Marshal to generate JSON:

json_bytes, _ := json.Marshal(m)

What is the expected output? What do you see instead?

Expected JSON output is {"b":""}, however the generated one is {}

Note that json.Marshal behavior for strings is correct, that is an empty string 
will be represented in JSON output as "" and will not be omitted.

What version of the product are you using? On what operating system?

tip

Please provide any additional information below.

An immediate workaround for this problem would be to not generate 
"json:omitempty" field tag for byte slices. It would solve the problem at a 
cost of enabling generation of JSON "null" values for nil byte slice fields.

A permanent solution may require a change in the json package. For example, a 
new "json:omitnil" field tag could be introduced that would omit fields in JSON 
output only if their value is nil.

Original issue reported on code.google.com by alav...@piqi.org on 5 Nov 2011 at 11:46

GoogleCodeExporter commented 9 years ago
The ability to distinguish between fields not set and fields set to their 
default value is a historic oddity of protocol buffers, and is supported by the 
binary (wire) format out of necessity for interoperation with other languages. 
There's no need for such support in the JSON format; there's no support in the 
protocol buffer text format either.

As you said, a proper solution would require modifications to the json package; 
I doubt that would fly.

If you require the full feature set of protocol buffers, you need to use the 
binary format, not JSON.

Original comment by dsymo...@golang.org on 6 Nov 2011 at 11:33

GoogleCodeExporter commented 9 years ago
I realize that JSON serialization is a side feature of this library. But I find 
it useful and I think it is important to have consistent serialization behavior 
when unmarshal is the inverse of marshal. In the current implementation, this 
holds true for all primitive Protobuf types except for bytes.

Another reason would be fixing inconsistency in JSON serialization behavior 
between empty strings and empty byte slices.

Speaking of modifying the json package. I had a chance to talk briefly over the 
issue with rsc a couple of weeks ago. He was not opposed to the idea of 
introducing another json tag option as soon as it is useful. Besides solving 
this problem "json:omitnil" could be used in other contexts as well. 
Personally, I would prefer to use omitnil instead of omitempty in most cases.

I can submit a feature request for "json:omitnil"  and, if it is accepted, 
implement it in the json package.

Original comment by alav...@piqi.org on 7 Nov 2011 at 4:56