cmd/protoc-gen-go: factor out oneof field naming
A oneof is represented by a single struct field of interface type.
Pull out the decision of what to name that field into a separate
function.
The function is trivial (return oneof.GoName), but factoring out the
field name like this makes it a bit easier to experiment with changes to
the oneof implementation in the future.
Change-Id: I1114b68c85cb6608852fa1c6bf4103ff58fd5de6
Reviewed-on: https://go-review.googlesource.com/c/146397
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
diff --git a/cmd/protoc-gen-go/internal_gengo/oneof.go b/cmd/protoc-gen-go/internal_gengo/oneof.go
index 26ad1c5..eb22a2f 100644
--- a/cmd/protoc-gen-go/internal_gengo/oneof.go
+++ b/cmd/protoc-gen-go/internal_gengo/oneof.go
@@ -18,13 +18,13 @@
if g.PrintLeadingComments(oneof.Location) {
g.P("//")
}
- g.P("// Types that are valid to be assigned to ", oneof.GoName, ":")
+ g.P("// Types that are valid to be assigned to ", oneofFieldName(oneof), ":")
for _, field := range oneof.Fields {
g.PrintLeadingComments(field.Location)
g.P("//\t*", fieldOneofType(field))
}
- g.Annotate(message.GoIdent.GoName+"."+oneof.GoName, oneof.Location)
- g.P(oneof.GoName, " ", oneofInterfaceName(message, oneof), " `protobuf_oneof:\"", oneof.Desc.Name(), "\"`")
+ g.Annotate(message.GoIdent.GoName+"."+oneofFieldName(oneof), oneof.Location)
+ g.P(oneofFieldName(oneof), " ", oneofInterfaceName(oneof), " `protobuf_oneof:\"", oneof.Desc.Name(), "\"`")
}
// genOneofTypes generates the interface type used for a oneof field,
@@ -33,7 +33,7 @@
// It also generates the getter method for the parent oneof field
// (but not the member fields).
func genOneofTypes(gen *protogen.Plugin, g *protogen.GeneratedFile, f *fileInfo, message *protogen.Message, oneof *protogen.Oneof) {
- ifName := oneofInterfaceName(message, oneof)
+ ifName := oneofInterfaceName(oneof)
g.P("type ", ifName, " interface {")
g.P(ifName, "()")
g.P("}")
@@ -58,15 +58,25 @@
g.Annotate(message.GoIdent.GoName+".Get"+oneof.GoName, oneof.Location)
g.P("func (m *", message.GoIdent.GoName, ") Get", oneof.GoName, "() ", ifName, " {")
g.P("if m != nil {")
- g.P("return m.", oneof.GoName)
+ g.P("return m.", oneofFieldName(oneof))
g.P("}")
g.P("return nil")
g.P("}")
g.P()
}
-func oneofInterfaceName(message *protogen.Message, oneof *protogen.Oneof) string {
- return fmt.Sprintf("is%s_%s", message.GoIdent.GoName, oneof.GoName)
+// oneofFieldName returns the name of the struct field holding the oneof value.
+//
+// This function is trivial, but pulling out the name like this makes it easier
+// to experiment with alternative oneof implementations.
+func oneofFieldName(oneof *protogen.Oneof) string {
+ return oneof.GoName
+}
+
+// oneofInterfaceName returns the name of the interface type implemented by
+// the oneof field value types.
+func oneofInterfaceName(oneof *protogen.Oneof) string {
+ return fmt.Sprintf("is%s_%s", oneof.ParentMessage.GoIdent.GoName, oneof.GoName)
}
// genOneofFuncs generates the XXX_OneofFuncs method for a message.
@@ -104,7 +114,7 @@
g.P("m := msg.(*", message.GoIdent, ")")
for _, oneof := range message.Oneofs {
g.P("// ", oneof.Desc.Name())
- g.P("switch x := m.", oneof.GoName, ".(type) {")
+ g.P("switch x := m.", oneofFieldName(oneof), ".(type) {")
for _, field := range oneof.Fields {
genOneofFieldMarshal(g, field)
}
@@ -113,7 +123,7 @@
g.P("return ", protogen.GoIdent{
GoImportPath: "fmt",
GoName: "Errorf",
- }, `("`, message.GoIdent.GoName, ".", oneof.GoName, ` has unexpected type %T", x)`)
+ }, `("`, message.GoIdent.GoName, ".", oneofFieldName(oneof), ` has unexpected type %T", x)`)
g.P("}")
}
g.P("return nil")
@@ -140,7 +150,7 @@
g.P("m := msg.(*", message.GoIdent, ")")
for _, oneof := range message.Oneofs {
g.P("// ", oneof.Desc.Name())
- g.P("switch x := m.", oneof.GoName, ".(type) {")
+ g.P("switch x := m.", oneofFieldName(oneof), ".(type) {")
for _, field := range oneof.Fields {
genOneofFieldSizer(g, field)
}
@@ -238,11 +248,11 @@
case protoreflect.BoolKind:
checkTag("WireVarint")
g.P("x, err := b.DecodeVarint()")
- g.P("m.", oneof.GoName, " = &", fieldOneofType(field), "{x != 0}")
+ g.P("m.", oneofFieldName(oneof), " = &", fieldOneofType(field), "{x != 0}")
case protoreflect.EnumKind:
checkTag("WireVarint")
g.P("x, err := b.DecodeVarint()")
- g.P("m.", oneof.GoName, " = &", fieldOneofType(field), "{", field.EnumType.GoIdent, "(x)}")
+ g.P("m.", oneofFieldName(oneof), " = &", fieldOneofType(field), "{", field.EnumType.GoIdent, "(x)}")
case protoreflect.Int32Kind, protoreflect.Uint32Kind, protoreflect.Int64Kind, protoreflect.Uint64Kind:
checkTag("WireVarint")
g.P("x, err := b.DecodeVarint()")
@@ -250,63 +260,63 @@
if goType, _ := fieldGoType(g, field); goType != "uint64" {
x = goType + "(x)"
}
- g.P("m.", oneof.GoName, " = &", fieldOneofType(field), "{", x, "}")
+ g.P("m.", oneofFieldName(oneof), " = &", fieldOneofType(field), "{", x, "}")
case protoreflect.Sint32Kind:
checkTag("WireVarint")
g.P("x, err := b.DecodeZigzag32()")
- g.P("m.", oneof.GoName, " = &", fieldOneofType(field), "{int32(x)}")
+ g.P("m.", oneofFieldName(oneof), " = &", fieldOneofType(field), "{int32(x)}")
case protoreflect.Sint64Kind:
checkTag("WireVarint")
g.P("x, err := b.DecodeZigzag64()")
- g.P("m.", oneof.GoName, " = &", fieldOneofType(field), "{int64(x)}")
+ g.P("m.", oneofFieldName(oneof), " = &", fieldOneofType(field), "{int64(x)}")
case protoreflect.Sfixed32Kind:
checkTag("WireFixed32")
g.P("x, err := b.DecodeFixed32()")
- g.P("m.", oneof.GoName, " = &", fieldOneofType(field), "{int32(x)}")
+ g.P("m.", oneofFieldName(oneof), " = &", fieldOneofType(field), "{int32(x)}")
case protoreflect.Fixed32Kind:
checkTag("WireFixed32")
g.P("x, err := b.DecodeFixed32()")
- g.P("m.", oneof.GoName, " = &", fieldOneofType(field), "{uint32(x)}")
+ g.P("m.", oneofFieldName(oneof), " = &", fieldOneofType(field), "{uint32(x)}")
case protoreflect.FloatKind:
checkTag("WireFixed32")
g.P("x, err := b.DecodeFixed32()")
- g.P("m.", oneof.GoName, " = &", fieldOneofType(field), "{", protogen.GoIdent{
+ g.P("m.", oneofFieldName(oneof), " = &", fieldOneofType(field), "{", protogen.GoIdent{
GoImportPath: "math",
GoName: "Float32frombits",
}, "(uint32(x))}")
case protoreflect.Sfixed64Kind:
checkTag("WireFixed64")
g.P("x, err := b.DecodeFixed64()")
- g.P("m.", oneof.GoName, " = &", fieldOneofType(field), "{int64(x)}")
+ g.P("m.", oneofFieldName(oneof), " = &", fieldOneofType(field), "{int64(x)}")
case protoreflect.Fixed64Kind:
checkTag("WireFixed64")
g.P("x, err := b.DecodeFixed64()")
- g.P("m.", oneof.GoName, " = &", fieldOneofType(field), "{x}")
+ g.P("m.", oneofFieldName(oneof), " = &", fieldOneofType(field), "{x}")
case protoreflect.DoubleKind:
checkTag("WireFixed64")
g.P("x, err := b.DecodeFixed64()")
- g.P("m.", oneof.GoName, " = &", fieldOneofType(field), "{", protogen.GoIdent{
+ g.P("m.", oneofFieldName(oneof), " = &", fieldOneofType(field), "{", protogen.GoIdent{
GoImportPath: "math",
GoName: "Float64frombits",
}, "(x)}")
case protoreflect.StringKind:
checkTag("WireBytes")
g.P("x, err := b.DecodeStringBytes()")
- g.P("m.", oneof.GoName, " = &", fieldOneofType(field), "{x}")
+ g.P("m.", oneofFieldName(oneof), " = &", fieldOneofType(field), "{x}")
case protoreflect.BytesKind:
checkTag("WireBytes")
g.P("x, err := b.DecodeRawBytes(true)")
- g.P("m.", oneof.GoName, " = &", fieldOneofType(field), "{x}")
+ g.P("m.", oneofFieldName(oneof), " = &", fieldOneofType(field), "{x}")
case protoreflect.MessageKind:
checkTag("WireBytes")
g.P("msg := new(", field.MessageType.GoIdent, ")")
g.P("err := b.DecodeMessage(msg)")
- g.P("m.", oneof.GoName, " = &", fieldOneofType(field), "{msg}")
+ g.P("m.", oneofFieldName(oneof), " = &", fieldOneofType(field), "{msg}")
case protoreflect.GroupKind:
checkTag("WireStartGroup")
g.P("msg := new(", field.MessageType.GoIdent, ")")
g.P("err := b.DecodeGroup(msg)")
- g.P("m.", oneof.GoName, " = &", fieldOneofType(field), "{msg}")
+ g.P("m.", oneofFieldName(oneof), " = &", fieldOneofType(field), "{msg}")
}
g.P("return true, err")
}