encoding/protojson: parse groups according to their real proto name

Ironically, the "real" protobuf name of a group is not the name
of the field descriptor, but the message descriptor.

Change-Id: I26ab546a94e934766fa6af6252cacd294442a221
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/195780
Reviewed-by: Herbie Ong <herbie@google.com>
This commit is contained in:
Joe Tsai 2019-09-15 00:32:55 -07:00 committed by Joe Tsai
parent 84177c9bf3
commit 7fa1ee5937
2 changed files with 21 additions and 0 deletions

View File

@ -190,6 +190,16 @@ func (o UnmarshalOptions) unmarshalFields(m pref.Message, skipTypeURL bool) erro
fd = fieldDescs.ByJSONName(name)
if fd == nil {
fd = fieldDescs.ByName(pref.Name(name))
if fd == nil {
// The proto name of a group field is in all lowercase,
// while the textual field name is the group message name.
gd := fieldDescs.ByName(pref.Name(strings.ToLower(name)))
if gd != nil && gd.Kind() == pref.GroupKind && gd.Message().Name() == pref.Name(name) {
fd = gd
}
} else if fd.Kind() == pref.GroupKind && fd.Message().Name() != pref.Name(name) {
fd = nil // reset since field name is actually the message name
}
}
if fd != nil && fd.IsWeak() && fd.Message().IsPlaceholder() {
fd = nil // reset since the weak reference is not linked in

View File

@ -469,6 +469,17 @@ func TestUnmarshal(t *testing.T) {
wantMessage: &pb3.JSONNames{
SString: "proto name used",
},
}, {
desc: "proto group name",
inputMessage: &pb2.Nests{},
inputText: `{
"OptGroup": {"optString": "hello"},
"RptGroup": [{"rptString": ["goodbye"]}]
}`,
wantMessage: &pb2.Nests{
Optgroup: &pb2.Nests_OptGroup{OptString: proto.String("hello")},
Rptgroup: []*pb2.Nests_RptGroup{{RptString: []string{"goodbye"}}},
},
}, {
desc: "json_name",
inputMessage: &pb3.JSONNames{},