protobuf icon indicating copy to clipboard operation
protobuf copied to clipboard

Feature Request: Need an option to control the json tag name use camel-case or origin filed name!

Open zj8487 opened this issue 5 years ago • 4 comments

Hi, All I am very sorry to disturb.

What is the Question? If we use the following message to generate the golang code, the protobuf json tag and the json tag is different.

message Station {
  string alignment_id = 1;
};
type Station struct {
	AlignmentId          string   `protobuf:"bytes,1,opt,name=alignment_id,json=alignmentId,proto3" json:"alignment_id,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

As we see, the protobuf json tag name is alignmentId with camel-case. but the json tag name is alignment_id.

protobuf:"bytes,1,opt,name=alignment_id,json=alignmentId,proto3" json:"alignment_id,omitempty"

What is my expectation? in this case, i wish the json tag name and the protobuf tag name is same like as follow:

protobuf:"bytes,1,opt,name=alignment_id,json=alignmentId,proto3" json:"alignmentId,omitempty"

Why dose it happen? I checked the code and notice that the json tag name uses the field name directly, see the code here. The snapshot as follow:

base := CamelCase(*field.Name)
ns := allocNames(base, "Get"+base)
fieldName, fieldGetterName := ns[0], ns[1]
typename, wiretype := g.GoType(message, field)
jsonName := *field.Name
tag := fmt.Sprintf("protobuf:%s json:%q", g.goTag(message, field, wiretype), jsonName+",omitempty")

I know everyone may have different expectation. so i want to know if it is possible to add an option to control whether the json tag name use camel-case or origin field name?

Why not use the goog tag? The another way to do is as follow:

message Status {
  int32 code = 1 [(gogoproto.jsontag) = "code"];
  string message = 2 [(gogoproto.jsontag) = "message"];
}

In this case, we have to set it on every field.

zj8487 avatar Jan 16 '19 09:01 zj8487

What command did you use to generate your golang files from the proto definitions?

RyanBeatty avatar Jan 17 '19 23:01 RyanBeatty

@RyanBeatty Thank you very much. The command i use to generate golang files from the proto definitions as follow:

grpc-tools/bin/protoc --gogoslick_out=Mgoogle/protobuf/any.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/duration.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/empty.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/struct.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/timestamp.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/wrappers.proto=github.com/gogo/protobuf/types,plugins=grpc:pb/golang --proto_path=message message/recruit/*.proto

zj8487 avatar Jan 18 '19 01:01 zj8487

Hey. I don't think I am going to add this extension as an option as the current tag options allows one to do what you are asking for with the help of a vanity binary. Here is an example:

https://github.com/jmarais/protobuf/blob/jsoncasevanity/protoc-gen-gojsoncase/main.go

As you can see it is just a little bit of extra code and then you can set the "gogoproto.jsontag" extension on all the fields with the desired tag formatting.

I see you are using gogoslick so you might have to look and add the options from the gogoslick vanity:

https://github.com/gogo/protobuf/blob/master/protoc-gen-gogoslick/main.go

With my example you would use: --gojsoncase_out to generate your *.pb.go files.

jmarais avatar Feb 25 '19 06:02 jmarais

I, too, would like the generated json tag to be lower-camel-case so as to be consistent with protojson.Marshal().

Leaving it as a per-field option increases boilerplate programming (which can and should be automated) and leaves lots of room for error (eg typos).

noel-yap avatar Oct 25 '23 22:10 noel-yap