Просмотр исходного кода

encoding/protojson: add MarshalOptions.UseProtoNames

UseProtoNames=true uses proto field name in JSON field names.

Change-Id: I23249dc1787d9735bef780b1ef8d294a9c55c043
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/193998
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
Herbie Ong 6 лет назад
Родитель
Сommit
956cd6ddcd
2 измененных файлов с 62 добавлено и 11 удалено
  1. 22 11
      encoding/protojson/encode.go
  2. 40 0
      encoding/protojson/encode_test.go

+ 22 - 11
encoding/protojson/encode.go

@@ -34,23 +34,27 @@ type MarshalOptions struct {
 	// Marshal will return error if there are any missing required fields.
 	AllowPartial bool
 
+	// UseProtoNames uses proto field name instead of lowerCamelCase name in JSON
+	// field names.
+	UseProtoNames bool
+
 	// UseEnumNumbers emits enum values as numbers.
 	UseEnumNumbers bool
 
 	// EmitUnpopulated specifies whether to emit unpopulated fields. It does not
 	// emit unpopulated oneof fields or unpopulated extension fields.
 	// The JSON value emitted for unpopulated fields are as follows:
-	// ╔═══════╤════════════════════════════╗
-	// ║ JSON  │ Protobuf field             ║
-	// ╠═══════╪════════════════════════════╣
-	// ║ false │ proto3 boolean fields      ║
-	// ║ 0     │ proto3 numeric fields      ║
-	// ║ ""    │ proto3 string/bytes fields ║
-	// ║ null  │ proto2 scalar fields       ║
-	// ║ null  │ message fields             ║
-	// ║ []    │ list fields                ║
-	// ║ {}    │ map fields                 ║
-	// ╚═══════╧════════════════════════════╝
+	//  ╔═══════╤════════════════════════════╗
+	//  ║ JSON  │ Protobuf field             ║
+	//  ╠═══════╪════════════════════════════╣
+	//  ║ false │ proto3 boolean fields      ║
+	//  ║ 0     │ proto3 numeric fields      ║
+	//  ║ ""    │ proto3 string/bytes fields ║
+	//  ║ null  │ proto2 scalar fields       ║
+	//  ║ null  │ message fields             ║
+	//  ║ []    │ list fields                ║
+	//  ║ {}    │ map fields                 ║
+	//  ╚═══════╧════════════════════════════╝
 	EmitUnpopulated bool
 
 	// If Indent is a non-empty string, it causes entries for an Array or Object
@@ -128,6 +132,13 @@ func (o MarshalOptions) marshalFields(m pref.Message) error {
 		}
 
 		name := fd.JSONName()
+		if o.UseProtoNames {
+			name = string(fd.Name())
+			// Use type name for group field name.
+			if fd.Kind() == pref.GroupKind {
+				name = string(fd.Message().Name())
+			}
+		}
 		if err := o.encoder.WriteName(name); err != nil {
 			return err
 		}

+ 40 - 0
encoding/protojson/encode_test.go

@@ -2174,6 +2174,46 @@ func TestMarshal(t *testing.T) {
     "10": 10,
     "47": 47
   }
+}`,
+	}, {
+		desc: "UseProtoNames",
+		mo:   protojson.MarshalOptions{UseProtoNames: true},
+		input: &pb2.Nests{
+			OptNested: &pb2.Nested{},
+			Optgroup: &pb2.Nests_OptGroup{
+				OptString: proto.String("inside a group"),
+				OptNested: &pb2.Nested{
+					OptString: proto.String("nested message inside a group"),
+				},
+				Optnestedgroup: &pb2.Nests_OptGroup_OptNestedGroup{
+					OptFixed32: proto.Uint32(47),
+				},
+			},
+			Rptgroup: []*pb2.Nests_RptGroup{
+				{
+					RptString: []string{"hello", "world"},
+				},
+			},
+		},
+		want: `{
+  "opt_nested": {},
+  "OptGroup": {
+    "opt_string": "inside a group",
+    "opt_nested": {
+      "opt_string": "nested message inside a group"
+    },
+    "OptNestedGroup": {
+      "opt_fixed32": 47
+    }
+  },
+  "RptGroup": [
+    {
+      "rpt_string": [
+        "hello",
+        "world"
+      ]
+    }
+  ]
 }`,
 	}}