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>
diff --git a/encoding/protojson/decode.go b/encoding/protojson/decode.go
index ec32c48..faa56b0 100644
--- a/encoding/protojson/decode.go
+++ b/encoding/protojson/decode.go
@@ -190,6 +190,16 @@
 			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
diff --git a/encoding/protojson/decode_test.go b/encoding/protojson/decode_test.go
index 65ec37a..e5385f4 100644
--- a/encoding/protojson/decode_test.go
+++ b/encoding/protojson/decode_test.go
@@ -470,6 +470,17 @@
 			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{},
 		inputText: `{