mirror of
https://github.com/protocolbuffers/protobuf-go.git
synced 2025-01-29 09:32:38 +00:00
encoding/jsonpb: fix encoding of empty google.protobuf.Value
Description of message Value states: `Value` represents a dynamically typed value which can be either null, a number, a string, a boolean, a recursive struct value, or a list of values. A producer of value is expected to set one of that variants, absence of any variant indicates an error. https://github.com/protocolbuffers/protobuf/blob/3.7.x/src/google/protobuf/struct.proto#L57-L60 Previous implementation was following C++ lib behavior. Change-Id: Id51792e2fc8cc465a05a978e63410d3b6802b522 Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/168901 Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
This commit is contained in:
parent
a3421952ac
commit
1c7462c1ba
@ -111,14 +111,8 @@ func (e encoder) marshalFields(m pref.Message) error {
|
||||
continue
|
||||
}
|
||||
|
||||
// An empty google.protobuf.Value should NOT be marshaled out.
|
||||
// Hence need to check ahead for this.
|
||||
val := knownFields.Get(num)
|
||||
if isEmptyKnownValue(val, fd.MessageType()) {
|
||||
continue
|
||||
}
|
||||
|
||||
name := fd.JSONName()
|
||||
val := knownFields.Get(num)
|
||||
if err := e.WriteName(name); !nerr.Merge(err) {
|
||||
return err
|
||||
}
|
||||
|
@ -1008,15 +1008,15 @@ func TestMarshal(t *testing.T) {
|
||||
input: &knownpb.Empty{},
|
||||
want: `{}`,
|
||||
}, {
|
||||
desc: "Value empty",
|
||||
input: &knownpb.Value{},
|
||||
want: ``,
|
||||
desc: "Value empty",
|
||||
input: &knownpb.Value{},
|
||||
wantErr: true,
|
||||
}, {
|
||||
desc: "Value empty field",
|
||||
input: &pb2.KnownTypes{
|
||||
OptValue: &knownpb.Value{},
|
||||
},
|
||||
want: `{}`,
|
||||
wantErr: true,
|
||||
}, {
|
||||
desc: "Value contains NullValue",
|
||||
input: &knownpb.Value{Kind: &knownpb.Value_NullValue{}},
|
||||
@ -1531,7 +1531,7 @@ func TestMarshal(t *testing.T) {
|
||||
},
|
||||
input: func() proto.Message {
|
||||
m := &knownpb.Value{}
|
||||
b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
|
||||
b, err := proto.Marshal(m)
|
||||
if err != nil {
|
||||
t.Fatalf("error in binary marshaling message for Any.value: %v", err)
|
||||
}
|
||||
@ -1540,9 +1540,7 @@ func TestMarshal(t *testing.T) {
|
||||
Value: b,
|
||||
}
|
||||
}(),
|
||||
want: `{
|
||||
"@type": "type.googleapis.com/google.protobuf.Value"
|
||||
}`,
|
||||
wantErr: true,
|
||||
}, {
|
||||
desc: "Any with Duration",
|
||||
mo: jsonpb.MarshalOptions{
|
||||
@ -1641,7 +1639,9 @@ func TestMarshal(t *testing.T) {
|
||||
{Kind: &knownpb.Value_ListValue{}},
|
||||
},
|
||||
},
|
||||
OptValue: &knownpb.Value{},
|
||||
OptValue: &knownpb.Value{
|
||||
Kind: &knownpb.Value_StringValue{"world"},
|
||||
},
|
||||
OptEmpty: &knownpb.Empty{},
|
||||
OptAny: &knownpb.Any{
|
||||
TypeUrl: "google.protobuf.Empty",
|
||||
@ -1671,6 +1671,7 @@ func TestMarshal(t *testing.T) {
|
||||
{},
|
||||
[]
|
||||
],
|
||||
"optValue": "world",
|
||||
"optEmpty": {},
|
||||
"optAny": {
|
||||
"@type": "google.protobuf.Empty"
|
||||
|
@ -128,10 +128,6 @@ func (e encoder) marshalAny(m pref.Message) error {
|
||||
// with corresponding custom JSON encoding of the embedded message as a
|
||||
// field.
|
||||
if isCustomType(emt.FullName()) {
|
||||
// An empty google.protobuf.Value should NOT be marshaled out.
|
||||
if isEmptyKnownValue(pref.ValueOf(em), emt) {
|
||||
return nil
|
||||
}
|
||||
e.WriteName("value")
|
||||
return e.marshalCustomType(em)
|
||||
}
|
||||
@ -176,14 +172,6 @@ func (e encoder) marshalListValue(m pref.Message) error {
|
||||
return e.marshalList(val.List(), fd)
|
||||
}
|
||||
|
||||
// isEmptyKnownValue returns true if given val is of type google.protobuf.Value
|
||||
// and does not have any of its oneof fields set.
|
||||
func isEmptyKnownValue(val pref.Value, md pref.MessageDescriptor) bool {
|
||||
return md != nil &&
|
||||
md.FullName() == "google.protobuf.Value" &&
|
||||
val.Message().KnownFields().Len() == 0
|
||||
}
|
||||
|
||||
func (e encoder) marshalKnownValue(m pref.Message) error {
|
||||
msgType := m.Type()
|
||||
fieldDescs := msgType.Oneofs().Get(0).Fields()
|
||||
@ -200,8 +188,8 @@ func (e encoder) marshalKnownValue(m pref.Message) error {
|
||||
return e.marshalSingular(val, fd)
|
||||
}
|
||||
|
||||
// None of the fields are set.
|
||||
return nil
|
||||
// Return error if none of the fields are set.
|
||||
return errors.New("%s: none of the variants is set", msgType.FullName())
|
||||
}
|
||||
|
||||
const (
|
||||
|
Loading…
x
Reference in New Issue
Block a user