diff --git a/encoding/protojson/encode.go b/encoding/protojson/encode.go index d55786e1..1662e405 100644 --- a/encoding/protojson/encode.go +++ b/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 } diff --git a/encoding/protojson/encode_test.go b/encoding/protojson/encode_test.go index 4ee275a5..9a1c86e2 100644 --- a/encoding/protojson/encode_test.go +++ b/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" + ] + } + ] }`, }}