[protobuf] cmd/protoc-gen-go: generate message fields

562 views
Skip to first unread message

Damien Neil (Gerrit)

unread,
Sep 12, 2018, 12:33:28 PM9/12/18
to Ian Lance Taylor, goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

Damien Neil has uploaded this change for review.

View Change

cmd/protoc-gen-go: generate message fields

This produces exactly the same output as github.com/golang/protobuf.

Change-Id: I01aacc9277c5cb5b4cc295f5ee8af12b4a524781
---
M cmd/protoc-gen-go/main.go
M cmd/protoc-gen-go/testdata/comments/comments.pb.go
A cmd/protoc-gen-go/testdata/fieldnames/fieldnames.pb.go
A cmd/protoc-gen-go/testdata/fieldnames/fieldnames.proto
M cmd/protoc-gen-go/testdata/proto2/enum.pb.go
A cmd/protoc-gen-go/testdata/proto2/fields.pb.go
A cmd/protoc-gen-go/testdata/proto2/fields.proto
M cmd/protoc-gen-go/testdata/proto2/nested_messages.pb.go
M cmd/protoc-gen-go/testdata/proto2/proto2.pb.go
M cmd/protoc-gen-go/testdata/proto2/proto2.proto
A cmd/protoc-gen-go/testdata/proto3/fields.pb.go
A cmd/protoc-gen-go/testdata/proto3/fields.proto
M protogen/protogen.go
13 files changed, 853 insertions(+), 37 deletions(-)

diff --git a/cmd/protoc-gen-go/main.go b/cmd/protoc-gen-go/main.go
index c243e00..ce864e8 100644
--- a/cmd/protoc-gen-go/main.go
+++ b/cmd/protoc-gen-go/main.go
@@ -200,26 +200,69 @@

genWellKnownType(g, enum.GoIdent, enum.Desc)

- // The name registered is, confusingly, <proto_package>.<go_ident>.
- // This probably should have been the full name of the proto enum
- // type instead, but changing it at this point would require thought.
- regName := string(f.Desc.Package()) + "." + enum.GoIdent.GoName
f.init = append(f.init, fmt.Sprintf("%s(%q, %s, %s)",
g.QualifiedGoIdent(protogen.GoIdent{
GoImportPath: protoPackage,
GoName: "RegisterEnum",
}),
- regName, nameMap, valueMap,
+ enumRegistryName(enum), nameMap, valueMap,
))
}

+// enumRegistryName returns the name used to register an enum with the proto
+// package registry.
+//
+// Confusingly, this is <proto_package>.<go_ident>. This probably should have
+// been the full name of the proto enum type instead, but changing it at this
+// point would require thought.
+func enumRegistryName(enum *protogen.Enum) string {
+ // Find the FileDescriptor for this enum.
+ var desc protoreflect.Descriptor = enum.Desc
+ for {
+ p, ok := desc.Parent()
+ if !ok {
+ break
+ }
+ desc = p
+ }
+ fdesc := desc.(protoreflect.FileDescriptor)
+ return string(fdesc.Package()) + "." + enum.GoIdent.GoName
+}
+
+// Method names that may be generated. Fields with these names get an
+// underscore appended. Any change to this set is a potential incompatible
+// API change because it changes generated field names.
+var methodNames = [...]string{
+ "Reset",
+ "String",
+ "ProtoMessage",
+ "Marshal",
+ "Unmarshal",
+ "ExtensionRangeArray",
+ "ExtensionMap",
+ "Descriptor",
+}
+
func genMessage(gen *protogen.Plugin, g *protogen.GeneratedFile, f *File, message *protogen.Message) {
- for _, enum := range message.Enums {
- genEnum(gen, g, f, enum)
+ for _, e := range message.Enums {
+ genEnum(gen, g, f, e)
}

genComment(g, f, message.Path)
+ // TODO: deprecation
g.P("type ", message.GoIdent, " struct {")
+ for _, field := range message.Fields {
+ if field.Desc.OneofType() != nil {
+ // TODO oneofs
+ continue
+ }
+ genComment(g, f, field.Path)
+ g.P(field.GoIdent, " ", fieldGoType(g, field), fmt.Sprintf(" `protobuf:%q json:%q`", fieldProtobufTag(field), fieldJSONTag(field)))
+ }
+ g.P("XXX_NoUnkeyedLiteral struct{} `json:\"-\"`")
+ // TODO XXX_InternalExtensions
+ g.P("XXX_unrecognized []byte `json:\"-\"`")
+ g.P("XXX_sizecache int32 `json:\"-\"`")
g.P("}")
g.P()

@@ -228,6 +271,123 @@
}
}

+func fieldGoType(g *protogen.GeneratedFile, field *protogen.Field) string {
+ var typ string
+ switch field.Desc.Kind() {
+ case protoreflect.BoolKind:
+ typ = "bool"
+ case protoreflect.EnumKind:
+ typ = g.QualifiedGoIdent(field.EnumType.GoIdent)
+ case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
+ typ = "int32"
+ case protoreflect.Uint32Kind, protoreflect.Fixed32Kind:
+ typ = "uint32"
+ case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
+ typ = "int64"
+ case protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
+ typ = "uint64"
+ case protoreflect.FloatKind:
+ typ = "float32"
+ case protoreflect.DoubleKind:
+ typ = "float64"
+ case protoreflect.StringKind:
+ typ = "string"
+ case protoreflect.BytesKind:
+ typ = "[]byte"
+ case protoreflect.MessageKind, protoreflect.GroupKind:
+ typ = "*" + g.QualifiedGoIdent(field.MessageType.GoIdent)
+ }
+ if field.Desc.Cardinality() == protoreflect.Repeated {
+ return "[]" + typ
+ }
+ if field.Desc.Syntax() == protoreflect.Proto3 {
+ return typ
+ }
+ if field.Desc.OneofType() != nil {
+ return typ
+ }
+ nonPointerKinds := map[protoreflect.Kind]bool{
+ protoreflect.GroupKind: true,
+ protoreflect.MessageKind: true,
+ protoreflect.BytesKind: true,
+ }
+ if !nonPointerKinds[field.Desc.Kind()] {
+ return "*" + typ
+ }
+ return typ
+}
+
+func fieldProtobufTag(field *protogen.Field) string {
+ var tag []string
+ // wire type
+ tag = append(tag, wireTypes[field.Desc.Kind()])
+ // field number
+ tag = append(tag, strconv.Itoa(int(field.Desc.Number())))
+ // cardinality
+ switch field.Desc.Cardinality() {
+ case protoreflect.Optional:
+ tag = append(tag, "opt")
+ case protoreflect.Required:
+ tag = append(tag, "req")
+ case protoreflect.Repeated:
+ tag = append(tag, "rep")
+ default:
+ tag = append(tag, "")
+ }
+ // TODO: packed
+ // name
+ name := string(field.Desc.Name())
+ if field.Desc.Kind() == protoreflect.GroupKind {
+ // We must use the type name for groups instead of the field
+ // name to preserve capitalization???
+ // TODO: understand this
+ name = string(field.MessageType.Desc.Name())
+ }
+ tag = append(tag, "name="+name)
+ // JSON name
+ if jsonName := field.Desc.JSONName(); jsonName != "" && jsonName != name {
+ tag = append(tag, "json="+jsonName)
+ }
+ // proto3
+ if field.Desc.Syntax() == protoreflect.Proto3 {
+ tag = append(tag, "proto3")
+ }
+ // enum
+ if field.Desc.Kind() == protoreflect.EnumKind {
+ tag = append(tag, "enum="+enumRegistryName(field.EnumType))
+ }
+ // oneof
+ if field.Desc.OneofType() != nil {
+ tag = append(tag, "oneof")
+ }
+ return strings.Join(tag, ",")
+}
+
+var wireTypes = map[protoreflect.Kind]string{
+ protoreflect.BoolKind: "varint",
+ protoreflect.EnumKind: "varint",
+ protoreflect.Int32Kind: "varint",
+ protoreflect.Sint32Kind: "zigzag32",
+ protoreflect.Uint32Kind: "varint",
+ protoreflect.Int64Kind: "varint",
+ protoreflect.Sint64Kind: "zigzag64",
+ protoreflect.Uint64Kind: "varint",
+ protoreflect.Sfixed32Kind: "fixed32",
+ protoreflect.Fixed32Kind: "fixed32",
+ protoreflect.FloatKind: "fixed32",
+ protoreflect.Sfixed64Kind: "fixed64",
+ protoreflect.Fixed64Kind: "fixed64",
+ protoreflect.DoubleKind: "fixed64",
+ protoreflect.StringKind: "bytes",
+ protoreflect.BytesKind: "bytes",
+ protoreflect.MessageKind: "bytes",
+ protoreflect.GroupKind: "group",
+}
+
+func fieldJSONTag(field *protogen.Field) string {
+ return string(field.Desc.Name()) + ",omitempty"
+}
+
func genComment(g *protogen.GeneratedFile, f *File, path []int32) {
for _, loc := range f.locationMap[pathKey(path)] {
if loc.LeadingComments == nil {
diff --git a/cmd/protoc-gen-go/testdata/comments/comments.pb.go b/cmd/protoc-gen-go/testdata/comments/comments.pb.go
index 2b870cd..c222dfd 100644
--- a/cmd/protoc-gen-go/testdata/comments/comments.pb.go
+++ b/cmd/protoc-gen-go/testdata/comments/comments.pb.go
@@ -7,26 +7,44 @@

// COMMENT: Message1
type Message1 struct {
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
}

// COMMENT: Message1A
type Message1_Message1A struct {
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
}

// COMMENT: Message1B
type Message1_Message1B struct {
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
}

// COMMENT: Message2
type Message2 struct {
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
}

// COMMENT: Message2A
type Message2_Message2A struct {
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
}

// COMMENT: Message2B
type Message2_Message2B struct {
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
}

func init() { proto.RegisterFile("comments/comments.proto", fileDescriptor_885e8293f1fab554) }
diff --git a/cmd/protoc-gen-go/testdata/fieldnames/fieldnames.pb.go b/cmd/protoc-gen-go/testdata/fieldnames/fieldnames.pb.go
new file mode 100644
index 0000000..9596379
--- /dev/null
+++ b/cmd/protoc-gen-go/testdata/fieldnames/fieldnames.pb.go
@@ -0,0 +1,63 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: fieldnames/fieldnames.proto
+
+package fieldnames
+
+// Assorted edge cases in field name conflict resolution.
+//
+// Not all (or possibly any) of these behave in an easily-understood fashion.
+// This exists to demonstrate the current behavior and catch unintended
+// changes in it.
+type Message struct {
+ // Various CamelCase conversions.
+ FieldOne *string `protobuf:"bytes,1,opt,name=field_one,json=fieldOne" json:"field_one,omitempty"`
+ FieldTwo *string `protobuf:"bytes,2,opt,name=FieldTwo" json:"FieldTwo,omitempty"`
+ FieldThree *string `protobuf:"bytes,3,opt,name=fieldThree" json:"fieldThree,omitempty"`
+ Field_Four *string `protobuf:"bytes,4,opt,name=field__four,json=fieldFour" json:"field__four,omitempty"`
+ // Field names that conflict with standard methods on the message struct.
+ Descriptor_ *string `protobuf:"bytes,10,opt,name=descriptor" json:"descriptor,omitempty"`
+ Marshal_ *string `protobuf:"bytes,11,opt,name=marshal" json:"marshal,omitempty"`
+ Unmarshal_ *string `protobuf:"bytes,12,opt,name=unmarshal" json:"unmarshal,omitempty"`
+ ProtoMessage_ *string `protobuf:"bytes,13,opt,name=proto_message,json=protoMessage" json:"proto_message,omitempty"`
+ // Field names that conflict with each other after CamelCasing.
+ CamelCase *string `protobuf:"bytes,20,opt,name=CamelCase" json:"CamelCase,omitempty"`
+ CamelCase_ *string `protobuf:"bytes,21,opt,name=CamelCase_,json=CamelCase" json:"CamelCase_,omitempty"`
+ CamelCase__ *string `protobuf:"bytes,22,opt,name=camel_case,json=camelCase" json:"camel_case,omitempty"`
+ CamelCase___ *string `protobuf:"bytes,23,opt,name=CamelCase__,json=CamelCase" json:"CamelCase__,omitempty"`
+ // Field with a getter that conflicts with another field.
+ GetName *string `protobuf:"bytes,30,opt,name=get_name,json=getName" json:"get_name,omitempty"`
+ Name_ *string `protobuf:"bytes,31,opt,name=name" json:"name,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func init() { proto.RegisterFile("fieldnames/fieldnames.proto", fileDescriptor_6bbe3f70febb9403) }
+
+var fileDescriptor_6bbe3f70febb9403 = []byte{
+ // 382 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x92, 0x4b, 0x6f, 0xd3, 0x40,
+ 0x10, 0xc7, 0x09, 0x44, 0x6a, 0x3c, 0x69, 0x79, 0xac, 0x78, 0x6c, 0x69, 0x31, 0x08, 0x2e, 0x39,
+ 0x50, 0x5b, 0x82, 0x33, 0x42, 0x24, 0x52, 0xc5, 0x85, 0x56, 0x8a, 0x72, 0xe2, 0xb2, 0x5a, 0xd6,
+ 0xe3, 0x4d, 0x24, 0x7b, 0x27, 0x5a, 0x6f, 0xc4, 0x17, 0xe5, 0x03, 0x21, 0xcf, 0xc6, 0x76, 0x94,
+ 0xe6, 0x36, 0xf3, 0xfb, 0x3f, 0xac, 0xb1, 0x0d, 0x57, 0xe5, 0x06, 0xab, 0xc2, 0xe9, 0x1a, 0x9b,
+ 0x7c, 0x18, 0xb3, 0xad, 0xa7, 0x40, 0xe2, 0xd2, 0x12, 0x0f, 0x71, 0x35, 0xd9, 0x60, 0xf8, 0xf8,
+ 0x6f, 0x0c, 0x67, 0xbf, 0xb0, 0x69, 0xb4, 0x45, 0x71, 0x05, 0x09, 0x2b, 0x8a, 0x1c, 0xca, 0xd1,
+ 0x87, 0xd1, 0x2c, 0x59, 0x4e, 0x18, 0xdc, 0x3b, 0x14, 0x6f, 0x61, 0x72, 0xdb, 0xce, 0xab, 0xbf,
+ 0x24, 0x1f, 0x47, 0xad, 0xdb, 0x45, 0x0a, 0xc0, 0xbe, 0xd5, 0xda, 0x23, 0xca, 0x27, 0xac, 0x1e,
+ 0x10, 0x91, 0xc2, 0x34, 0x16, 0xab, 0x92, 0x76, 0x5e, 0x8e, 0xd9, 0x10, 0x9f, 0x75, 0x4b, 0x3b,
+ 0xdf, 0xe6, 0x0b, 0x6c, 0x8c, 0xdf, 0x6c, 0x03, 0x79, 0x09, 0x31, 0x3f, 0x10, 0x21, 0xe1, 0xac,
+ 0xd6, 0xbe, 0x59, 0xeb, 0x4a, 0x4e, 0x59, 0xec, 0x56, 0x71, 0x0d, 0xc9, 0xce, 0x75, 0xda, 0x79,
+ 0xec, 0xed, 0x81, 0xf8, 0x04, 0x17, 0x7c, 0xb1, 0xaa, 0xe3, 0x85, 0xf2, 0x82, 0x1d, 0xe7, 0x0c,
+ 0xbb, 0xab, 0xaf, 0x21, 0x59, 0xe8, 0x1a, 0xab, 0x85, 0x6e, 0x50, 0xbe, 0x8c, 0x15, 0x3d, 0x10,
+ 0xef, 0x00, 0xfa, 0x45, 0xc9, 0x57, 0x27, 0x64, 0xd3, 0x2e, 0xca, 0xb4, 0xe9, 0xd7, 0x51, 0x36,
+ 0xbd, 0x9c, 0xc2, 0x74, 0x48, 0x2b, 0xf9, 0xe6, 0x38, 0x7e, 0x09, 0x13, 0x8b, 0x41, 0xb5, 0x9f,
+ 0x42, 0xa6, 0xf1, 0x32, 0x8b, 0xe1, 0x4e, 0xd7, 0x28, 0x04, 0x8c, 0x19, 0xbf, 0x67, 0xcc, 0xb3,
+ 0x98, 0xc1, 0xd3, 0x7b, 0x87, 0x54, 0x2e, 0xc8, 0x95, 0xd5, 0xc6, 0x84, 0x1f, 0x72, 0xd6, 0xaa,
+ 0x3f, 0x1f, 0x2d, 0x8f, 0xb8, 0xf8, 0x0c, 0x2f, 0xa8, 0x25, 0xca, 0x91, 0x32, 0x7b, 0x2a, 0xbf,
+ 0xb0, 0x79, 0xb4, 0x7c, 0xc6, 0xd2, 0x1d, 0x75, 0xf6, 0x07, 0xbd, 0x73, 0xf9, 0x75, 0x6f, 0x3d,
+ 0xe2, 0x73, 0x01, 0xcf, 0x63, 0x6f, 0x57, 0xaa, 0xf4, 0x09, 0xf6, 0x67, 0xfe, 0xfd, 0xf7, 0x37,
+ 0x4b, 0x64, 0x2b, 0xcc, 0x2c, 0x55, 0xda, 0xd9, 0x8c, 0xbc, 0xcd, 0xf9, 0xb5, 0xe7, 0xa6, 0x2e,
+ 0xe2, 0x64, 0x6e, 0x2c, 0xba, 0x1b, 0x4b, 0x79, 0xc0, 0x26, 0x14, 0x3a, 0xe8, 0x83, 0x1f, 0xf7,
+ 0x7f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x92, 0xbf, 0xac, 0x4e, 0xd0, 0x02, 0x00, 0x00,
+}
diff --git a/cmd/protoc-gen-go/testdata/fieldnames/fieldnames.proto b/cmd/protoc-gen-go/testdata/fieldnames/fieldnames.proto
new file mode 100644
index 0000000..9b4b917
--- /dev/null
+++ b/cmd/protoc-gen-go/testdata/fieldnames/fieldnames.proto
@@ -0,0 +1,49 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+syntax = "proto2";
+
+package goproto.protoc.fieldnames;
+
+option go_package = "google.golang.org/proto/cmd/protoc-gen-go/testdata/fieldnames";
+
+// Assorted edge cases in field name conflict resolution.
+//
+// Not all (or possibly any) of these behave in an easily-understood fashion.
+// This exists to demonstrate the current behavior and catch unintended
+// changes in it.
+message Message {
+ // Various CamelCase conversions.
+ optional string field_one = 1;
+ optional string FieldTwo = 2;
+ optional string fieldThree = 3;
+ optional string field__four = 4;
+
+ // Field names that conflict with standard methods on the message struct.
+ optional string descriptor = 10;
+ optional string marshal = 11;
+ optional string unmarshal = 12;
+ optional string proto_message = 13;
+
+ // Field names that conflict with each other after CamelCasing.
+ optional string CamelCase = 20;
+ optional string CamelCase_ = 21;
+ optional string camel_case = 22; // conflicts with 20, 21
+ optional string CamelCase__ = 23; // conflicts with 21, 21, renamed 22
+
+ // Field with a getter that conflicts with another field.
+ optional string get_name = 30;
+ optional string name = 31;
+
+ // Oneof that conflicts with its first field: The oneof is renamed.
+ oneof oneof_conflict_a {
+ string OneofConflictA = 40;
+ }
+
+ // Oneof that conflicts with its second field: The field is renamed.
+ oneof oneof_conflict_b {
+ string oneof_no_conflict = 50;
+ string OneofConflictB = 51;
+ }
+}
diff --git a/cmd/protoc-gen-go/testdata/proto2/enum.pb.go b/cmd/protoc-gen-go/testdata/proto2/enum.pb.go
index 85b2fad..e8e053c 100644
--- a/cmd/protoc-gen-go/testdata/proto2/enum.pb.go
+++ b/cmd/protoc-gen-go/testdata/proto2/enum.pb.go
@@ -165,6 +165,9 @@
}

type EnumContainerMessage1 struct {
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
}

// NestedEnumType2A comment.
@@ -244,6 +247,9 @@
}

type EnumContainerMessage1_EnumContainerMessage2 struct {
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
}

func init() {
diff --git a/cmd/protoc-gen-go/testdata/proto2/fields.pb.go b/cmd/protoc-gen-go/testdata/proto2/fields.pb.go
new file mode 100644
index 0000000..dee8e9f
--- /dev/null
+++ b/cmd/protoc-gen-go/testdata/proto2/fields.pb.go
@@ -0,0 +1,201 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: proto2/fields.proto
+
+package proto2
+
+import proto "github.com/golang/protobuf/proto"
+
+type FieldTestMessage_Enum int32
+
+const (
+ FieldTestMessage_ZERO FieldTestMessage_Enum = 0
+)
+
+var FieldTestMessage_Enum_name = map[int32]string{
+ 0: "ZERO",
+}
+
+var FieldTestMessage_Enum_value = map[string]int32{
+ "ZERO": 0,
+}
+
+func (x FieldTestMessage_Enum) Enum() *FieldTestMessage_Enum {
+ p := new(FieldTestMessage_Enum)
+ *p = x
+ return p
+}
+
+func (x FieldTestMessage_Enum) String() string {
+ return proto.EnumName(FieldTestMessage_Enum_name, int32(x))
+}
+
+func (x *FieldTestMessage_Enum) UnmarshalJSON(data []byte) error {
+ value, err := proto.UnmarshalJSONEnum(FieldTestMessage_Enum_value, data, "FieldTestMessage_Enum")
+ if err != nil {
+ return err
+ }
+ *x = FieldTestMessage_Enum(value)
+ return nil
+}
+
+func (FieldTestMessage_Enum) EnumDescriptor() ([]byte, []int) {
+ return fileDescriptor_fd8a9d72b841fd68, []int{0, 0}
+}
+
+type FieldTestMessage struct {
+ OptionalBool *string `protobuf:"bytes,1,opt,name=optional_bool,json=optionalBool" json:"optional_bool,omitempty"`
+ OptionalEnum *FieldTestMessage_Enum `protobuf:"varint,2,opt,name=optional_enum,json=optionalEnum,enum=goproto.protoc.proto2.FieldTestMessage_Enum" json:"optional_enum,omitempty"`
+ OptionalInt32 *int32 `protobuf:"varint,3,opt,name=optional_int32,json=optionalInt32" json:"optional_int32,omitempty"`
+ OptionalSint32 *int32 `protobuf:"zigzag32,4,opt,name=optional_sint32,json=optionalSint32" json:"optional_sint32,omitempty"`
+ OptionalUint32 *uint32 `protobuf:"varint,5,opt,name=optional_uint32,json=optionalUint32" json:"optional_uint32,omitempty"`
+ OptionalInt64 *int64 `protobuf:"varint,6,opt,name=optional_int64,json=optionalInt64" json:"optional_int64,omitempty"`
+ OptionalSint64 *int64 `protobuf:"zigzag64,7,opt,name=optional_sint64,json=optionalSint64" json:"optional_sint64,omitempty"`
+ OptionalUint64 *uint64 `protobuf:"varint,8,opt,name=optional_uint64,json=optionalUint64" json:"optional_uint64,omitempty"`
+ OptionalSfixed32 *int32 `protobuf:"fixed32,9,opt,name=optional_sfixed32,json=optionalSfixed32" json:"optional_sfixed32,omitempty"`
+ OptionalFixed32 *uint32 `protobuf:"fixed32,10,opt,name=optional_fixed32,json=optionalFixed32" json:"optional_fixed32,omitempty"`
+ OptionalFloat *float32 `protobuf:"fixed32,11,opt,name=optional_float,json=optionalFloat" json:"optional_float,omitempty"`
+ OptionalSfixed64 *int64 `protobuf:"fixed64,12,opt,name=optional_sfixed64,json=optionalSfixed64" json:"optional_sfixed64,omitempty"`
+ OptionalFixed64 *uint64 `protobuf:"fixed64,13,opt,name=optional_fixed64,json=optionalFixed64" json:"optional_fixed64,omitempty"`
+ OptionalDouble *float64 `protobuf:"fixed64,14,opt,name=optional_double,json=optionalDouble" json:"optional_double,omitempty"`
+ OptionalString *string `protobuf:"bytes,15,opt,name=optional_string,json=optionalString" json:"optional_string,omitempty"`
+ OptionalBytes []byte `protobuf:"bytes,16,opt,name=optional_bytes,json=optionalBytes" json:"optional_bytes,omitempty"`
+ Optional_Message *FieldTestMessage_Message `protobuf:"bytes,17,opt,name=optional_Message,json=optionalMessage" json:"optional_Message,omitempty"`
+ Optionalgroup *FieldTestMessage_OptionalGroup `protobuf:"group,18,opt,name=OptionalGroup,json=optionalgroup" json:"optionalgroup,omitempty"`
+ RequiredBool *string `protobuf:"bytes,101,req,name=required_bool,json=requiredBool" json:"required_bool,omitempty"`
+ RequiredEnum *FieldTestMessage_Enum `protobuf:"varint,102,req,name=required_enum,json=requiredEnum,enum=goproto.protoc.proto2.FieldTestMessage_Enum" json:"required_enum,omitempty"`
+ RequiredInt32 *int32 `protobuf:"varint,103,req,name=required_int32,json=requiredInt32" json:"required_int32,omitempty"`
+ RequiredSint32 *int32 `protobuf:"zigzag32,104,req,name=required_sint32,json=requiredSint32" json:"required_sint32,omitempty"`
+ RequiredUint32 *uint32 `protobuf:"varint,105,req,name=required_uint32,json=requiredUint32" json:"required_uint32,omitempty"`
+ RequiredInt64 *int64 `protobuf:"varint,106,req,name=required_int64,json=requiredInt64" json:"required_int64,omitempty"`
+ RequiredSint64 *int64 `protobuf:"zigzag64,107,req,name=required_sint64,json=requiredSint64" json:"required_sint64,omitempty"`
+ RequiredUint64 *uint64 `protobuf:"varint,108,req,name=required_uint64,json=requiredUint64" json:"required_uint64,omitempty"`
+ RequiredSfixed32 *int32 `protobuf:"fixed32,109,req,name=required_sfixed32,json=requiredSfixed32" json:"required_sfixed32,omitempty"`
+ RequiredFixed32 *uint32 `protobuf:"fixed32,110,req,name=required_fixed32,json=requiredFixed32" json:"required_fixed32,omitempty"`
+ RequiredFloat *float32 `protobuf:"fixed32,111,req,name=required_float,json=requiredFloat" json:"required_float,omitempty"`
+ RequiredSfixed64 *int64 `protobuf:"fixed64,112,req,name=required_sfixed64,json=requiredSfixed64" json:"required_sfixed64,omitempty"`
+ RequiredFixed64 *uint64 `protobuf:"fixed64,113,req,name=required_fixed64,json=requiredFixed64" json:"required_fixed64,omitempty"`
+ RequiredDouble *float64 `protobuf:"fixed64,114,req,name=required_double,json=requiredDouble" json:"required_double,omitempty"`
+ RequiredString *string `protobuf:"bytes,115,req,name=required_string,json=requiredString" json:"required_string,omitempty"`
+ RequiredBytes []byte `protobuf:"bytes,116,req,name=required_bytes,json=requiredBytes" json:"required_bytes,omitempty"`
+ Required_Message *FieldTestMessage_Message `protobuf:"bytes,117,req,name=required_Message,json=requiredMessage" json:"required_Message,omitempty"`
+ Requiredgroup *FieldTestMessage_RequiredGroup `protobuf:"group,118,req,name=RequiredGroup,json=requiredgroup" json:"requiredgroup,omitempty"`
+ RepeatedBool []string `protobuf:"bytes,201,rep,name=repeated_bool,json=repeatedBool" json:"repeated_bool,omitempty"`
+ RepeatedEnum []FieldTestMessage_Enum `protobuf:"varint,202,rep,name=repeated_enum,json=repeatedEnum,enum=goproto.protoc.proto2.FieldTestMessage_Enum" json:"repeated_enum,omitempty"`
+ RepeatedInt32 []int32 `protobuf:"varint,203,rep,name=repeated_int32,json=repeatedInt32" json:"repeated_int32,omitempty"`
+ RepeatedSint32 []int32 `protobuf:"zigzag32,204,rep,name=repeated_sint32,json=repeatedSint32" json:"repeated_sint32,omitempty"`
+ RepeatedUint32 []uint32 `protobuf:"varint,205,rep,name=repeated_uint32,json=repeatedUint32" json:"repeated_uint32,omitempty"`
+ RepeatedInt64 []int64 `protobuf:"varint,206,rep,name=repeated_int64,json=repeatedInt64" json:"repeated_int64,omitempty"`
+ RepeatedSint64 []int64 `protobuf:"zigzag64,207,rep,name=repeated_sint64,json=repeatedSint64" json:"repeated_sint64,omitempty"`
+ RepeatedUint64 []uint64 `protobuf:"varint,208,rep,name=repeated_uint64,json=repeatedUint64" json:"repeated_uint64,omitempty"`
+ RepeatedSfixed32 []int32 `protobuf:"fixed32,209,rep,name=repeated_sfixed32,json=repeatedSfixed32" json:"repeated_sfixed32,omitempty"`
+ RepeatedFixed32 []uint32 `protobuf:"fixed32,210,rep,name=repeated_fixed32,json=repeatedFixed32" json:"repeated_fixed32,omitempty"`
+ RepeatedFloat []float32 `protobuf:"fixed32,211,rep,name=repeated_float,json=repeatedFloat" json:"repeated_float,omitempty"`
+ RepeatedSfixed64 []int64 `protobuf:"fixed64,212,rep,name=repeated_sfixed64,json=repeatedSfixed64" json:"repeated_sfixed64,omitempty"`
+ RepeatedFixed64 []uint64 `protobuf:"fixed64,213,rep,name=repeated_fixed64,json=repeatedFixed64" json:"repeated_fixed64,omitempty"`
+ RepeatedDouble []float64 `protobuf:"fixed64,214,rep,name=repeated_double,json=repeatedDouble" json:"repeated_double,omitempty"`
+ RepeatedString []string `protobuf:"bytes,215,rep,name=repeated_string,json=repeatedString" json:"repeated_string,omitempty"`
+ RepeatedBytes [][]byte `protobuf:"bytes,216,rep,name=repeated_bytes,json=repeatedBytes" json:"repeated_bytes,omitempty"`
+ Repeated_Message []*FieldTestMessage_Message `protobuf:"bytes,217,rep,name=repeated_Message,json=repeatedMessage" json:"repeated_Message,omitempty"`
+ Repeatedgroup []*FieldTestMessage_RepeatedGroup `protobuf:"group,218,rep,name=RepeatedGroup,json=repeatedgroup" json:"repeatedgroup,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+type FieldTestMessage_OptionalGroup struct {
+ OptionalGroup *string `protobuf:"bytes,19,opt,name=optional_group,json=optionalGroup" json:"optional_group,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+type FieldTestMessage_RequiredGroup struct {
+ RequiredGroup *string `protobuf:"bytes,119,req,name=required_group,json=requiredGroup" json:"required_group,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+type FieldTestMessage_RepeatedGroup struct {
+ RepeatedGroup []string `protobuf:"bytes,219,rep,name=repeated_group,json=repeatedGroup" json:"repeated_group,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+type FieldTestMessage_Message struct {
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func init() {
+ proto.RegisterEnum("goproto.protoc.proto2.FieldTestMessage_Enum", FieldTestMessage_Enum_name, FieldTestMessage_Enum_value)
+}
+
+func init() { proto.RegisterFile("proto2/fields.proto", fileDescriptor_fd8a9d72b841fd68) }
+
+var fileDescriptor_fd8a9d72b841fd68 = []byte{
+ // 969 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x96, 0xdb, 0x6f, 0x1b, 0x45,
+ 0x14, 0xc6, 0x99, 0x89, 0x9b, 0x34, 0xdb, 0x38, 0x71, 0xb6, 0x02, 0x8d, 0x78, 0x3a, 0x2a, 0xb7,
+ 0x01, 0x5a, 0x5b, 0x72, 0x87, 0x41, 0x88, 0xb7, 0x88, 0xa6, 0xe2, 0x01, 0x55, 0x2c, 0xf0, 0x92,
+ 0x22, 0x55, 0x4e, 0xbc, 0x59, 0x0c, 0x1b, 0x8f, 0x6b, 0xaf, 0xb9, 0xfc, 0x7d, 0x3c, 0x71, 0xbf,
+ 0xdf, 0xff, 0x19, 0x74, 0xe6, 0xcc, 0x65, 0x67, 0xdd, 0x87, 0x26, 0x4f, 0xb6, 0x4f, 0xbe, 0xf3,
+ 0x7d, 0x73, 0xc6, 0xe7, 0xe7, 0x4d, 0x76, 0x73, 0xb1, 0x34, 0x8d, 0x19, 0x8f, 0xce, 0x67, 0x65,
+ 0x3d, 0x5d, 0x0d, 0xed, 0xa7, 0xfc, 0xd9, 0xca, 0xd8, 0x37, 0xf4, 0xf1, 0x8c, 0x5e, 0xc6, 0xb7,
+ 0xbe, 0x7e, 0x2e, 0x1b, 0x1c, 0xa3, 0xee, 0xc3, 0x72, 0xd5, 0xbc, 0x57, 0xae, 0x56, 0x93, 0xaa,
+ 0xcc, 0x5f, 0xc8, 0xfa, 0x66, 0xd1, 0xcc, 0xcc, 0x7c, 0x52, 0x3f, 0x3a, 0x35, 0xa6, 0x16, 0x0c,
+ 0x98, 0xdc, 0x2d, 0xf6, 0x7c, 0xf1, 0xc8, 0x98, 0x3a, 0x7f, 0xbf, 0x25, 0x2a, 0xe7, 0xeb, 0x0b,
+ 0xc1, 0x81, 0xc9, 0xfd, 0xf1, 0xed, 0xe1, 0x13, 0x83, 0x86, 0xdd, 0x90, 0xe1, 0xbd, 0xf9, 0xfa,
+ 0x22, 0x5a, 0xe2, 0xa7, 0xfc, 0xa5, 0x6c, 0x3f, 0x58, 0xce, 0xe6, 0xcd, 0xdd, 0xb1, 0xd8, 0x02,
+ 0x26, 0xaf, 0x15, 0x21, 0xe8, 0x5d, 0x2c, 0xe6, 0xaf, 0x64, 0x07, 0x41, 0xb6, 0x22, 0x5d, 0x0f,
+ 0x98, 0x3c, 0x2c, 0x42, 0xf7, 0x07, 0xb3, 0x0d, 0xe1, 0x9a, 0x84, 0xd7, 0x80, 0xc9, 0x7e, 0x14,
+ 0x7e, 0x44, 0xc2, 0x4e, 0xb0, 0x56, 0x62, 0x1b, 0x98, 0xdc, 0x4a, 0x82, 0xb5, 0xda, 0x08, 0xd6,
+ 0x4a, 0xec, 0x00, 0x93, 0x79, 0x1a, 0xdc, 0x11, 0xae, 0x49, 0x78, 0x1d, 0x98, 0xec, 0xa5, 0xc1,
+ 0x5a, 0xe5, 0xaf, 0x67, 0x87, 0xd1, 0xf1, 0x7c, 0xf6, 0x65, 0x39, 0xbd, 0x3b, 0x16, 0xbb, 0xc0,
+ 0xe4, 0x41, 0x31, 0x08, 0x9e, 0xae, 0x9e, 0xbf, 0x9a, 0x85, 0xda, 0x23, 0xaf, 0xcd, 0x80, 0xc9,
+ 0x9d, 0x22, 0xa4, 0x1d, 0x3b, 0x69, 0x7b, 0xa0, 0xf3, 0xda, 0x4c, 0x1a, 0x71, 0x03, 0x98, 0xe4,
+ 0x71, 0xa0, 0x63, 0x2c, 0x3e, 0x21, 0x5e, 0x2b, 0xb1, 0x07, 0x4c, 0x0e, 0xba, 0xf1, 0x5a, 0x6d,
+ 0xc6, 0x6b, 0x25, 0xfa, 0xc0, 0xe4, 0x76, 0x27, 0xbe, 0x33, 0xff, 0xd4, 0xac, 0x4f, 0xeb, 0x52,
+ 0xec, 0x03, 0x93, 0x2c, 0xce, 0xff, 0x8e, 0xad, 0xa6, 0x37, 0xda, 0x2c, 0x67, 0xf3, 0x4a, 0x1c,
+ 0xd8, 0x5d, 0x8b, 0x37, 0x6a, 0xab, 0xc9, 0x40, 0xa7, 0x5f, 0x35, 0xe5, 0x4a, 0x0c, 0x80, 0xc9,
+ 0xbd, 0x38, 0xd0, 0x11, 0x16, 0xf3, 0x93, 0xd6, 0x19, 0xdd, 0xa2, 0x89, 0x43, 0x60, 0xf2, 0xc6,
+ 0x78, 0xf4, 0xb4, 0x7b, 0xe9, 0x5e, 0xe3, 0x50, 0x9e, 0x8a, 0x87, 0x71, 0xe1, 0xab, 0xa5, 0x59,
+ 0x2f, 0x44, 0x0e, 0x4c, 0x66, 0xe3, 0x37, 0x9e, 0xd6, 0xf8, 0x81, 0x6b, 0xbe, 0x8f, 0xcd, 0x45,
+ 0xea, 0x85, 0xc8, 0x2d, 0xcb, 0xc7, 0xeb, 0xd9, 0xb2, 0x9c, 0x12, 0x72, 0x25, 0x70, 0x44, 0xce,
+ 0x17, 0x3d, 0x72, 0x41, 0x64, 0x91, 0x3b, 0x07, 0x7e, 0x79, 0xe4, 0xbc, 0x85, 0x47, 0x2e, 0x58,
+ 0x12, 0x21, 0x15, 0x70, 0x44, 0xce, 0x57, 0x03, 0x72, 0x41, 0xe6, 0x90, 0xfb, 0x04, 0x38, 0x22,
+ 0xe7, 0xcb, 0x11, 0xb9, 0x20, 0x74, 0xc8, 0xcd, 0x80, 0x23, 0x72, 0xbe, 0x1c, 0x91, 0x6b, 0x07,
+ 0x6b, 0x25, 0x3e, 0x05, 0x8e, 0xc8, 0xb5, 0x82, 0x69, 0x93, 0x92, 0x60, 0xad, 0xc4, 0x67, 0xc0,
+ 0x11, 0xb9, 0x76, 0x70, 0x47, 0xe8, 0x90, 0xab, 0x81, 0x23, 0x72, 0xed, 0x60, 0x42, 0x2e, 0x3a,
+ 0x7a, 0x8c, 0x2e, 0x80, 0x23, 0x72, 0xc1, 0xb3, 0x85, 0x5c, 0x10, 0x7b, 0xed, 0x1c, 0x38, 0x22,
+ 0xe7, 0xeb, 0x2d, 0xe4, 0xa2, 0xd4, 0x22, 0x67, 0x80, 0x23, 0x72, 0x41, 0xe8, 0x91, 0xeb, 0xc4,
+ 0x6b, 0x25, 0x16, 0xc0, 0x11, 0xb9, 0x34, 0x9e, 0x90, 0x4b, 0xe3, 0xb5, 0x12, 0x8f, 0x81, 0x23,
+ 0x72, 0x49, 0x7c, 0x67, 0x7e, 0x87, 0xdc, 0x12, 0x38, 0x22, 0xe7, 0xcb, 0x11, 0xb9, 0x78, 0x00,
+ 0x42, 0x6e, 0x65, 0x77, 0x2d, 0xde, 0x68, 0x40, 0x2e, 0xae, 0xa4, 0x45, 0xae, 0x01, 0x8e, 0xc8,
+ 0x85, 0x9d, 0xf4, 0xc8, 0x05, 0x99, 0x47, 0x6e, 0x0d, 0xfc, 0x4a, 0xc8, 0x79, 0xa3, 0x16, 0x72,
+ 0xbe, 0x44, 0xc8, 0x7d, 0x0e, 0xfc, 0x32, 0xc8, 0x15, 0xae, 0xd9, 0x21, 0x97, 0x78, 0xe5, 0x2f,
+ 0xa2, 0xf9, 0xa2, 0x9c, 0x34, 0x1e, 0xb9, 0x6f, 0x18, 0x6c, 0x11, 0x73, 0x54, 0xb5, 0xcc, 0x15,
+ 0x2d, 0x95, 0x65, 0xee, 0x5b, 0x54, 0x5d, 0x01, 0x3a, 0xf2, 0xb0, 0xd0, 0xbd, 0x8c, 0x37, 0xeb,
+ 0x3c, 0x89, 0x91, 0xef, 0xd0, 0xd4, 0x52, 0x47, 0x65, 0xa2, 0x4e, 0xe2, 0x57, 0xe5, 0x74, 0x8e,
+ 0xba, 0xef, 0x51, 0x68, 0xb1, 0xa3, 0xba, 0xc3, 0xae, 0xad, 0x74, 0xd8, 0xfd, 0x80, 0xca, 0x7e,
+ 0x54, 0x3a, 0xee, 0x3a, 0xd9, 0x5a, 0x89, 0x1f, 0x51, 0xb8, 0x95, 0x64, 0x6b, 0xb5, 0x91, 0xad,
+ 0x95, 0xf8, 0x09, 0x85, 0x79, 0x9a, 0xdd, 0x51, 0x3a, 0xf2, 0x7e, 0x46, 0x65, 0x2f, 0xcd, 0xd6,
+ 0x2a, 0xbf, 0x8d, 0xbb, 0xef, 0x3d, 0x3d, 0x4e, 0xbf, 0xa0, 0xd6, 0xb2, 0xe7, 0x5c, 0x3d, 0x7b,
+ 0xaf, 0x65, 0xa1, 0x16, 0xd8, 0xfb, 0x15, 0xc5, 0x16, 0x3e, 0xfa, 0x83, 0x87, 0xaf, 0x3d, 0x15,
+ 0xc1, 0xf7, 0x1b, 0x2a, 0x79, 0x9c, 0x8a, 0xe8, 0xdb, 0x3c, 0x81, 0x56, 0xe2, 0x77, 0x94, 0x0e,
+ 0xba, 0x27, 0xd0, 0x6a, 0xf3, 0x04, 0x5a, 0x89, 0x3f, 0x50, 0xbc, 0xdd, 0x39, 0x41, 0xe7, 0x16,
+ 0x1c, 0x7f, 0x7f, 0xa2, 0x94, 0xc5, 0x5b, 0x70, 0x00, 0x26, 0x37, 0x4b, 0x00, 0xfe, 0x45, 0x9b,
+ 0x17, 0x6f, 0x96, 0x08, 0x6c, 0x4f, 0x45, 0x04, 0xfe, 0x8d, 0xc2, 0xbd, 0x38, 0x15, 0x21, 0xf8,
+ 0xb0, 0x75, 0x4e, 0x8f, 0xe0, 0x3f, 0xa8, 0xbc, 0x1a, 0x83, 0xe4, 0xe4, 0x19, 0xfc, 0x38, 0x02,
+ 0x40, 0x0c, 0xfe, 0x8b, 0xce, 0x97, 0x82, 0x90, 0xba, 0x03, 0x84, 0x2d, 0xb3, 0xe7, 0x75, 0xd6,
+ 0x4f, 0x9e, 0x8b, 0xc9, 0x83, 0x9e, 0xf2, 0x6e, 0xda, 0x7f, 0x08, 0xc2, 0xf3, 0xf2, 0xbe, 0xef,
+ 0x4b, 0xe0, 0x4e, 0x7e, 0xad, 0xa8, 0xef, 0x0b, 0xfb, 0xab, 0x16, 0xa0, 0xa7, 0xbe, 0x37, 0xb1,
+ 0xaf, 0x75, 0x9e, 0xe4, 0x8e, 0xa9, 0xef, 0x3f, 0xfa, 0x32, 0xc2, 0x41, 0xa9, 0x71, 0x37, 0xdb,
+ 0x71, 0x03, 0xdd, 0x1a, 0x64, 0x3d, 0x8b, 0xf1, 0xf5, 0xac, 0x77, 0x72, 0xaf, 0x78, 0x30, 0x78,
+ 0xe6, 0xe8, 0xed, 0x93, 0xb7, 0x2a, 0x63, 0xaa, 0xba, 0x1c, 0x56, 0xa6, 0x9e, 0xcc, 0xab, 0xa1,
+ 0x59, 0x56, 0x23, 0x7b, 0x1f, 0xa3, 0xb3, 0x8b, 0x29, 0xbd, 0x3b, 0xbb, 0x53, 0x95, 0xf3, 0x3b,
+ 0x95, 0x19, 0x35, 0xe5, 0xaa, 0x99, 0x4e, 0x9a, 0x09, 0x95, 0xc7, 0xff, 0x07, 0x00, 0x00, 0xff,
+ 0xff, 0xc9, 0x6e, 0x69, 0xe6, 0xaf, 0x0b, 0x00, 0x00,
+}
diff --git a/cmd/protoc-gen-go/testdata/proto2/fields.proto b/cmd/protoc-gen-go/testdata/proto2/fields.proto
new file mode 100644
index 0000000..1e65c6d
--- /dev/null
+++ b/cmd/protoc-gen-go/testdata/proto2/fields.proto
@@ -0,0 +1,77 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+syntax = "proto2";
+
+package goproto.protoc.proto2;
+
+option go_package = "google.golang.org/proto/cmd/protoc-gen-go/testdata/proto2";
+
+message FieldTestMessage {
+ optional string optional_bool = 1;
+ optional Enum optional_enum = 2;
+ optional int32 optional_int32 = 3;
+ optional sint32 optional_sint32 = 4;
+ optional uint32 optional_uint32 = 5;
+ optional int64 optional_int64 = 6;
+ optional sint64 optional_sint64 = 7;
+ optional uint64 optional_uint64 = 8;
+ optional sfixed32 optional_sfixed32 = 9;
+ optional fixed32 optional_fixed32 = 10;
+ optional float optional_float = 11;
+ optional sfixed64 optional_sfixed64 = 12;
+ optional fixed64 optional_fixed64 = 13;
+ optional double optional_double = 14;
+ optional string optional_string = 15;
+ optional bytes optional_bytes = 16;
+ optional Message optional_Message = 17;
+ optional group OptionalGroup = 18 {
+ optional string optional_group = 19;
+ }
+
+ required string required_bool = 101;
+ required Enum required_enum = 102;
+ required int32 required_int32 = 103;
+ required sint32 required_sint32 = 104;
+ required uint32 required_uint32 = 105;
+ required int64 required_int64 = 106;
+ required sint64 required_sint64 = 107;
+ required uint64 required_uint64 = 108;
+ required sfixed32 required_sfixed32 = 109;
+ required fixed32 required_fixed32 = 110;
+ required float required_float = 111;
+ required sfixed64 required_sfixed64 = 112;
+ required fixed64 required_fixed64 = 113;
+ required double required_double = 114;
+ required string required_string = 115;
+ required bytes required_bytes = 116;
+ required Message required_Message = 117;
+ required group RequiredGroup = 118 {
+ required string required_group = 119;
+ }
+
+ repeated string repeated_bool = 201;
+ repeated Enum repeated_enum = 202;
+ repeated int32 repeated_int32 = 203;
+ repeated sint32 repeated_sint32 = 204;
+ repeated uint32 repeated_uint32 = 205;
+ repeated int64 repeated_int64 = 206;
+ repeated sint64 repeated_sint64 = 207;
+ repeated uint64 repeated_uint64 = 208;
+ repeated sfixed32 repeated_sfixed32 = 209;
+ repeated fixed32 repeated_fixed32 = 210;
+ repeated float repeated_float = 211;
+ repeated sfixed64 repeated_sfixed64 = 212;
+ repeated fixed64 repeated_fixed64 = 213;
+ repeated double repeated_double = 214;
+ repeated string repeated_string = 215;
+ repeated bytes repeated_bytes = 216;
+ repeated Message repeated_Message = 217;
+ repeated group RepeatedGroup = 218 {
+ repeated string repeated_group = 219;
+ }
+
+ enum Enum { ZERO = 0; }
+ message Message {}
+}
diff --git a/cmd/protoc-gen-go/testdata/proto2/nested_messages.pb.go b/cmd/protoc-gen-go/testdata/proto2/nested_messages.pb.go
index ba78d1b..f86082d 100644
--- a/cmd/protoc-gen-go/testdata/proto2/nested_messages.pb.go
+++ b/cmd/protoc-gen-go/testdata/proto2/nested_messages.pb.go
@@ -4,12 +4,24 @@
package proto2

type Layer1 struct {
+ L2 *Layer1_Layer2 `protobuf:"bytes,1,opt,name=l2" json:"l2,omitempty"`
+ L3 *Layer1_Layer2_Layer3 `protobuf:"bytes,2,opt,name=l3" json:"l3,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
}

type Layer1_Layer2 struct {
+ L3 *Layer1_Layer2_Layer3 `protobuf:"bytes,1,opt,name=l3" json:"l3,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
}

type Layer1_Layer2_Layer3 struct {
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
}

func init() { proto.RegisterFile("proto2/nested_messages.proto", fileDescriptor_7417ee157699d191) }
diff --git a/cmd/protoc-gen-go/testdata/proto2/proto2.pb.go b/cmd/protoc-gen-go/testdata/proto2/proto2.pb.go
index 72dcb71..9dc8ff2 100644
--- a/cmd/protoc-gen-go/testdata/proto2/proto2.pb.go
+++ b/cmd/protoc-gen-go/testdata/proto2/proto2.pb.go
@@ -4,17 +4,25 @@
package proto2

type Message struct {
+ I32 *int32 `protobuf:"varint,1,opt,name=i32" json:"i32,omitempty"`
+ M *Message `protobuf:"bytes,2,opt,name=m" json:"m,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
}

func init() { proto.RegisterFile("proto2/proto2.proto", fileDescriptor_d756bbe8817c03c1) }

var fileDescriptor_d756bbe8817c03c1 = []byte{
- // 107 bytes of a gzipped FileDescriptorProto
+ // 146 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x2e, 0x28, 0xca, 0x2f,
0xc9, 0x37, 0xd2, 0x87, 0x50, 0x7a, 0x60, 0x4a, 0x48, 0x34, 0x3d, 0x1f, 0xcc, 0x80, 0x70, 0x93,
- 0x21, 0x94, 0x91, 0x12, 0x27, 0x17, 0xbb, 0x6f, 0x6a, 0x71, 0x71, 0x62, 0x7a, 0xaa, 0x93, 0x75,
- 0x94, 0x65, 0x7a, 0x7e, 0x7e, 0x7a, 0x4e, 0xaa, 0x5e, 0x7a, 0x7e, 0x4e, 0x62, 0x5e, 0xba, 0x5e,
- 0x7e, 0x51, 0x3a, 0xc4, 0x0c, 0xfd, 0xe4, 0xdc, 0x14, 0x08, 0x2b, 0x59, 0x37, 0x3d, 0x35, 0x4f,
- 0x37, 0x3d, 0x5f, 0xbf, 0x24, 0xb5, 0xb8, 0x24, 0x25, 0xb1, 0x24, 0x11, 0x6a, 0x09, 0x20, 0x00,
- 0x00, 0xff, 0xff, 0xd7, 0x76, 0x0d, 0x22, 0x74, 0x00, 0x00, 0x00,
+ 0x21, 0x94, 0x91, 0x92, 0x27, 0x17, 0xbb, 0x6f, 0x6a, 0x71, 0x71, 0x62, 0x7a, 0xaa, 0x90, 0x00,
+ 0x17, 0x73, 0xa6, 0xb1, 0x91, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0x6b, 0x10, 0x88, 0x29, 0xa4, 0xc3,
+ 0xc5, 0x98, 0x2b, 0xc1, 0xa4, 0xc0, 0xa8, 0xc1, 0x6d, 0x24, 0xa7, 0x87, 0x55, 0xbf, 0x1e, 0x54,
+ 0x73, 0x10, 0x63, 0xae, 0x93, 0x75, 0x94, 0x65, 0x7a, 0x7e, 0x7e, 0x7a, 0x4e, 0xaa, 0x5e, 0x7a,
+ 0x7e, 0x4e, 0x62, 0x5e, 0xba, 0x5e, 0x7e, 0x51, 0x3a, 0xc4, 0x0d, 0xfa, 0xc9, 0xb9, 0x29, 0x10,
+ 0x56, 0xb2, 0x6e, 0x7a, 0x6a, 0x9e, 0x6e, 0x7a, 0xbe, 0x7e, 0x49, 0x6a, 0x71, 0x49, 0x4a, 0x62,
+ 0x49, 0x22, 0xd4, 0x91, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x8c, 0x68, 0x66, 0x37, 0xb4, 0x00,
+ 0x00, 0x00,
}
diff --git a/cmd/protoc-gen-go/testdata/proto2/proto2.proto b/cmd/protoc-gen-go/testdata/proto2/proto2.proto
index 055bc71..9e7e29d 100644
--- a/cmd/protoc-gen-go/testdata/proto2/proto2.proto
+++ b/cmd/protoc-gen-go/testdata/proto2/proto2.proto
@@ -9,4 +9,7 @@
option go_package = "google.golang.org/proto/cmd/protoc-gen-go/testdata/proto2";

message Message {
+ optional int32 i32 = 1;
+
+ optional Message m = 2;
}
diff --git a/cmd/protoc-gen-go/testdata/proto3/fields.pb.go b/cmd/protoc-gen-go/testdata/proto3/fields.pb.go
new file mode 100644
index 0000000..2cc5e06
--- /dev/null
+++ b/cmd/protoc-gen-go/testdata/proto3/fields.pb.go
@@ -0,0 +1,95 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: proto3/fields.proto
+
+package proto3
+
+import proto "github.com/golang/protobuf/proto"
+
+type FieldTestMessage_Enum int32
+
+const (
+ FieldTestMessage_ZERO FieldTestMessage_Enum = 0
+)
+
+var FieldTestMessage_Enum_name = map[int32]string{
+ 0: "ZERO",
+}
+
+var FieldTestMessage_Enum_value = map[string]int32{
+ "ZERO": 0,
+}
+
+func (x FieldTestMessage_Enum) String() string {
+ return proto.EnumName(FieldTestMessage_Enum_name, int32(x))
+}
+
+func (FieldTestMessage_Enum) EnumDescriptor() ([]byte, []int) {
+ return fileDescriptor_f1e3ea068187307c, []int{0, 0}
+}
+
+type FieldTestMessage struct {
+ OptionalBool string `protobuf:"bytes,1,opt,name=optional_bool,json=optionalBool,proto3" json:"optional_bool,omitempty"`
+ OptionalEnum FieldTestMessage_Enum `protobuf:"varint,2,opt,name=optional_enum,json=optionalEnum,proto3,enum=goproto.protoc.proto3.FieldTestMessage_Enum" json:"optional_enum,omitempty"`
+ OptionalInt32 int32 `protobuf:"varint,3,opt,name=optional_int32,json=optionalInt32,proto3" json:"optional_int32,omitempty"`
+ OptionalSint32 int32 `protobuf:"zigzag32,4,opt,name=optional_sint32,json=optionalSint32,proto3" json:"optional_sint32,omitempty"`
+ OptionalUint32 uint32 `protobuf:"varint,5,opt,name=optional_uint32,json=optionalUint32,proto3" json:"optional_uint32,omitempty"`
+ OptionalInt64 int64 `protobuf:"varint,6,opt,name=optional_int64,json=optionalInt64,proto3" json:"optional_int64,omitempty"`
+ OptionalSint64 int64 `protobuf:"zigzag64,7,opt,name=optional_sint64,json=optionalSint64,proto3" json:"optional_sint64,omitempty"`
+ OptionalUint64 uint64 `protobuf:"varint,8,opt,name=optional_uint64,json=optionalUint64,proto3" json:"optional_uint64,omitempty"`
+ OptionalSfixed32 int32 `protobuf:"fixed32,9,opt,name=optional_sfixed32,json=optionalSfixed32,proto3" json:"optional_sfixed32,omitempty"`
+ OptionalFixed32 uint32 `protobuf:"fixed32,10,opt,name=optional_fixed32,json=optionalFixed32,proto3" json:"optional_fixed32,omitempty"`
+ OptionalFloat float32 `protobuf:"fixed32,11,opt,name=optional_float,json=optionalFloat,proto3" json:"optional_float,omitempty"`
+ OptionalSfixed64 int64 `protobuf:"fixed64,12,opt,name=optional_sfixed64,json=optionalSfixed64,proto3" json:"optional_sfixed64,omitempty"`
+ OptionalFixed64 uint64 `protobuf:"fixed64,13,opt,name=optional_fixed64,json=optionalFixed64,proto3" json:"optional_fixed64,omitempty"`
+ OptionalDouble float64 `protobuf:"fixed64,14,opt,name=optional_double,json=optionalDouble,proto3" json:"optional_double,omitempty"`
+ OptionalString string `protobuf:"bytes,15,opt,name=optional_string,json=optionalString,proto3" json:"optional_string,omitempty"`
+ OptionalBytes []byte `protobuf:"bytes,16,opt,name=optional_bytes,json=optionalBytes,proto3" json:"optional_bytes,omitempty"`
+ Optional_Message *FieldTestMessage_Message `protobuf:"bytes,17,opt,name=optional_Message,json=optionalMessage,proto3" json:"optional_Message,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+type FieldTestMessage_Message struct {
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func init() {
+ proto.RegisterEnum("goproto.protoc.proto3.FieldTestMessage_Enum", FieldTestMessage_Enum_name, FieldTestMessage_Enum_value)
+}
+
+func init() { proto.RegisterFile("proto3/fields.proto", fileDescriptor_f1e3ea068187307c) }
+
+var fileDescriptor_f1e3ea068187307c = []byte{
+ // 440 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0x4f, 0x6b, 0xdb, 0x40,
+ 0x10, 0xc5, 0x3b, 0x89, 0x63, 0xc7, 0x1b, 0xff, 0x91, 0xb7, 0x14, 0x96, 0x9e, 0x96, 0x94, 0xd2,
+ 0x2d, 0x6d, 0x24, 0xb0, 0x84, 0xa0, 0xf4, 0x66, 0x1a, 0x43, 0x0f, 0xa5, 0x54, 0x6d, 0x2f, 0xbe,
+ 0x04, 0xc9, 0x5a, 0x2f, 0x02, 0x59, 0x13, 0xac, 0x15, 0xb4, 0x1f, 0xb0, 0xdf, 0xab, 0x48, 0xab,
+ 0x48, 0x96, 0xec, 0x43, 0x4e, 0x33, 0xf3, 0x78, 0x9a, 0x9f, 0xde, 0x32, 0xe4, 0xe5, 0xe3, 0x01,
+ 0x35, 0xba, 0xce, 0x2e, 0x91, 0x69, 0x9c, 0xdb, 0xd5, 0x44, 0x5f, 0x29, 0xac, 0x1a, 0x33, 0x6e,
+ 0x4d, 0x71, 0x6f, 0xff, 0x0d, 0x89, 0xb5, 0x2e, 0x7d, 0xbf, 0x64, 0xae, 0xbf, 0xc9, 0x3c, 0x0f,
+ 0x95, 0xa4, 0x6f, 0xc8, 0x14, 0x1f, 0x75, 0x82, 0x59, 0x98, 0x3e, 0x44, 0x88, 0x29, 0x03, 0x0e,
+ 0x62, 0x1c, 0x4c, 0x9e, 0xc4, 0x15, 0x62, 0x4a, 0x7f, 0x1c, 0x99, 0x64, 0x56, 0xec, 0xd9, 0x05,
+ 0x07, 0x31, 0x5b, 0x7e, 0xb4, 0xcf, 0x82, 0xec, 0x3e, 0xc4, 0xbe, 0xcf, 0x8a, 0x7d, 0xbb, 0xb2,
+ 0x9c, 0xe8, 0x5b, 0x32, 0x6b, 0x56, 0x26, 0x99, 0x76, 0x97, 0xec, 0x92, 0x83, 0xb8, 0x0a, 0x1a,
+ 0xd0, 0xd7, 0x52, 0xa4, 0xef, 0xc8, 0xbc, 0xb1, 0xe5, 0xc6, 0x37, 0xe0, 0x20, 0x16, 0x41, 0xf3,
+ 0xf5, 0xcf, 0xe4, 0xc4, 0x58, 0x18, 0xe3, 0x15, 0x07, 0x31, 0x6d, 0x8d, 0xbf, 0x8d, 0xb1, 0x07,
+ 0xf6, 0x3d, 0x36, 0xe4, 0x20, 0x2e, 0x3b, 0x60, 0xdf, 0x3b, 0x01, 0xfb, 0x1e, 0x1b, 0x71, 0x10,
+ 0xb4, 0x0b, 0xee, 0x19, 0x0b, 0x63, 0xbc, 0xe6, 0x20, 0x06, 0x5d, 0xb0, 0xef, 0xd1, 0x0f, 0x64,
+ 0xd1, 0x6e, 0xdc, 0x25, 0x7f, 0x64, 0xec, 0x2e, 0xd9, 0x98, 0x83, 0x98, 0x07, 0x56, 0xb3, 0xb3,
+ 0xd6, 0xe9, 0x7b, 0xd2, 0x68, 0x0f, 0x4f, 0x5e, 0xc2, 0x41, 0x8c, 0x82, 0x86, 0xb6, 0xae, 0xad,
+ 0xc7, 0x81, 0x76, 0x29, 0x86, 0x9a, 0xdd, 0x70, 0x10, 0x17, 0x6d, 0xa0, 0x75, 0x29, 0x9e, 0xc1,
+ 0xfb, 0x1e, 0x9b, 0x70, 0x10, 0x56, 0x1f, 0xef, 0x7b, 0xa7, 0x78, 0xdf, 0x63, 0x53, 0x0e, 0x62,
+ 0xd8, 0xc3, 0xf7, 0xf2, 0xc7, 0x58, 0x44, 0xa9, 0x64, 0x33, 0x0e, 0x02, 0xda, 0xfc, 0x5f, 0x2a,
+ 0xb5, 0xfb, 0xa2, 0xfa, 0x90, 0x64, 0x8a, 0xcd, 0xab, 0x5b, 0x6b, 0x5f, 0xb4, 0x52, 0x3b, 0x81,
+ 0xa2, 0xbf, 0x5a, 0xe6, 0xcc, 0xe2, 0x20, 0x26, 0x6d, 0xa0, 0x55, 0x29, 0xd2, 0xcd, 0xd1, 0x3f,
+ 0xd6, 0x87, 0xc6, 0x16, 0x1c, 0xc4, 0xcd, 0xd2, 0x79, 0xee, 0x5d, 0xd6, 0xb5, 0x0d, 0x55, 0x0b,
+ 0xaf, 0xc7, 0x64, 0x54, 0xb7, 0xb7, 0x16, 0x19, 0x54, 0x07, 0x7b, 0x4d, 0x06, 0x9b, 0xfb, 0xe0,
+ 0xbb, 0xf5, 0x62, 0xf5, 0x79, 0xf3, 0x49, 0x21, 0xaa, 0x54, 0xda, 0x0a, 0xd3, 0x30, 0x53, 0x36,
+ 0x1e, 0x94, 0x53, 0x21, 0x9c, 0xed, 0x3e, 0x36, 0xdd, 0xf6, 0x4e, 0xc9, 0xec, 0x4e, 0xa1, 0xa3,
+ 0x65, 0xae, 0xe3, 0x50, 0x87, 0x46, 0x76, 0xa3, 0xa1, 0xa9, 0xff, 0x03, 0x00, 0x00, 0xff, 0xff,
+ 0xa9, 0x42, 0xe7, 0xab, 0xb9, 0x03, 0x00, 0x00,
+}
diff --git a/cmd/protoc-gen-go/testdata/proto3/fields.proto b/cmd/protoc-gen-go/testdata/proto3/fields.proto
new file mode 100644
index 0000000..9c46a76
--- /dev/null
+++ b/cmd/protoc-gen-go/testdata/proto3/fields.proto
@@ -0,0 +1,33 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+syntax = "proto3";
+
+package goproto.protoc.proto3;
+
+option go_package = "google.golang.org/proto/cmd/protoc-gen-go/testdata/proto3";
+
+message FieldTestMessage {
+ string optional_bool = 1;
+ Enum optional_enum = 2;
+ int32 optional_int32 = 3;
+ sint32 optional_sint32 = 4;
+ uint32 optional_uint32 = 5;
+ int64 optional_int64 = 6;
+ sint64 optional_sint64 = 7;
+ uint64 optional_uint64 = 8;
+ sfixed32 optional_sfixed32 = 9;
+ fixed32 optional_fixed32 = 10;
+ float optional_float = 11;
+ sfixed64 optional_sfixed64 = 12;
+ fixed64 optional_fixed64 = 13;
+ double optional_double = 14;
+ string optional_string = 15;
+ bytes optional_bytes = 16;
+ Message optional_Message = 17;
+
+ enum Enum { ZERO = 0; }
+ message Message {}
+}
+
diff --git a/protogen/protogen.go b/protogen/protogen.go
index ee4c735..2a991ac 100644
--- a/protogen/protogen.go
+++ b/protogen/protogen.go
@@ -94,10 +94,12 @@
Files []*File
filesByName map[string]*File

- fileReg *protoregistry.Files
- pathType pathType
- genFiles []*GeneratedFile
- err error
+ fileReg *protoregistry.Files
+ messagesByName map[protoreflect.FullName]*Message
+ enumsByName map[protoreflect.FullName]*Enum
+ pathType pathType
+ genFiles []*GeneratedFile
+ err error
}

// Options are optional parameters to New.
@@ -136,9 +138,11 @@
opts = &Options{}
}
gen := &Plugin{
- Request: req,
- filesByName: make(map[string]*File),
- fileReg: protoregistry.NewFiles(),
+ Request: req,
+ filesByName: make(map[string]*File),
+ fileReg: protoregistry.NewFiles(),
+ messagesByName: make(map[protoreflect.FullName]*Message),
+ enumsByName: make(map[protoreflect.FullName]*Enum),
}

packageNames := make(map[string]GoPackageName) // filename -> package name
@@ -387,7 +391,11 @@
f.GeneratedFilenamePrefix = prefix

for i, mdescs := 0, desc.Messages(); i < mdescs.Len(); i++ {
- f.Messages = append(f.Messages, newMessage(gen, f, nil, mdescs.Get(i)))
+ message, err := newMessage(gen, f, nil, mdescs.Get(i))
+ if err != nil {
+ return nil, err
+ }
+ f.Messages = append(f.Messages, message)
}
for i, edescs := 0, desc.Enums(); i < edescs.Len(); i++ {
f.Enums = append(f.Enums, newEnum(gen, f, nil, edescs.Get(i)))
@@ -420,12 +428,13 @@
Desc protoreflect.MessageDescriptor

GoIdent GoIdent // name of the generated Go type
+ Fields []*Field // message field declarations
Messages []*Message // nested message declarations
Enums []*Enum // nested enum declarations
Path []int32 // location path of this message
}

-func newMessage(gen *Plugin, f *File, parent *Message, desc protoreflect.MessageDescriptor) *Message {
+func newMessage(gen *Plugin, f *File, parent *Message, desc protoreflect.MessageDescriptor) (*Message, error) {
var path []int32
if parent != nil {
path = pathAppend(parent.Path, messageMessageField, int32(desc.Index()))
@@ -437,13 +446,107 @@
GoIdent: newGoIdent(f, desc),
Path: path,
}
+ gen.messagesByName[desc.FullName()] = message
for i, mdescs := 0, desc.Messages(); i < mdescs.Len(); i++ {
- message.Messages = append(message.Messages, newMessage(gen, f, message, mdescs.Get(i)))
+ m, err := newMessage(gen, f, message, mdescs.Get(i))
+ if err != nil {
+ return nil, err
+ }
+ message.Messages = append(message.Messages, m)
}
for i, edescs := 0, desc.Enums(); i < edescs.Len(); i++ {
message.Enums = append(message.Enums, newEnum(gen, f, message, edescs.Get(i)))
}
- return message
+ for i, fdescs := 0, desc.Fields(); i < fdescs.Len(); i++ {
+ field, err := newField(gen, f, message, fdescs.Get(i))
+ if err != nil {
+ return nil, err
+ }
+ message.Fields = append(message.Fields, field)
+ }
+
+ // Field name conflict resolution.
+ //
+ // TODO: If we ever support a 'go_name' option to set the Go name of a
+ // field, we should consider dropping this entirely. The conflict
+ // resolution algorithm is subtle and surprising (changing the order
+ // in which fields appear in the .proto source file can change the
+ // names of fields in generated code), and does not adapt well to
+ // adding new per-field methods such as setters.
+ //
+ // We assume well-known method names that may be attached to a generated
+ // message type, as well as a 'Get*' method for each field. For each
+ // field in turn, we add _s to its name until there are no conflicts.
+ //
+ // Any change to the following set of method names is a potential
+ // incompatible API change because it may change generated field names.
+ usedNames := map[string]bool{
+ "Reset": true,
+ "String": true,
+ "ProtoMessage": true,
+ "Marshal": true,
+ "Unmarshal": true,
+ "ExtensionRangeArray": true,
+ "ExtensionMap": true,
+ "Descriptor": true,
+ }
+ makeNameUnique := func(name string) string {
+ for usedNames[name] || usedNames["Get"+name] {
+ name += "_"
+ }
+ usedNames[name] = true
+ usedNames["Get"+name] = true
+ return name
+ }
+ for _, field := range message.Fields {
+ field.GoIdent.GoName = makeNameUnique(field.GoIdent.GoName)
+ // TODO: If this is the first field of a oneof that we haven't seen
+ // before, generate the name for the oneof.
+ }
+
+ return message, nil
+}
+
+// A Field describes a message field.
+type Field struct {
+ Desc protoreflect.FieldDescriptor
+
+ // GoIdent is the base name of this field's Go fields and methods.
+ // For code generated by protoc-gen-go, this means a field named
+ // '{{GoIdent}}' and a getter method named 'Get{{GoIdent}}'.
+ GoIdent GoIdent
+
+ MessageType *Message // message type, for fields with kind Message or Group
+ EnumType *Enum // enum type, for fields with kind Enum
+ Path []int32 // location path of this message field
+}
+
+func newField(gen *Plugin, f *File, message *Message, desc protoreflect.FieldDescriptor) (*Field, error) {
+ field := &Field{
+ Desc: desc,
+ GoIdent: GoIdent{
+ GoName: camelCase(string(desc.Name())),
+ GoImportPath: f.GoImportPath,
+ },
+ Path: pathAppend(message.Path, messageFieldField, int32(desc.Index())),
+ }
+ switch desc.Kind() {
+ case protoreflect.MessageKind, protoreflect.GroupKind:
+ mname := desc.MessageType().FullName()
+ message, ok := gen.messagesByName[mname]
+ if !ok {
+ return nil, fmt.Errorf("field %v: no descriptor for type %v", desc.FullName(), mname)
+ }
+ field.MessageType = message
+ case protoreflect.EnumKind:
+ ename := desc.EnumType().FullName()
+ enum, ok := gen.enumsByName[ename]
+ if !ok {
+ return nil, fmt.Errorf("field %v: no descriptor for enum %v", desc.FullName(), ename)
+ }
+ field.EnumType = enum
+ }
+ return field, nil
}

// An Enum describes an enum.
@@ -467,6 +570,7 @@
GoIdent: newGoIdent(f, desc),
Path: path,
}
+ gen.enumsByName[desc.FullName()] = enum
for i, evdescs := 0, enum.Desc.Values(); i < evdescs.Len(); i++ {
enum.Values = append(enum.Values, newEnumValue(gen, f, parent, enum, evdescs.Get(i)))
}
@@ -561,19 +665,6 @@
return string(packageName) + "." + ident.GoName
}

-func (g *GeneratedFile) goPackageName(importPath GoImportPath) GoPackageName {
- if name, ok := g.packageNames[importPath]; ok {
- return name
- }
- name := cleanPackageName(baseName(string(importPath)))
- for i, orig := 1, name; g.usedPackageNames[name]; i++ {
- name = orig + GoPackageName(strconv.Itoa(i))
- }
- g.packageNames[importPath] = name
- g.usedPackageNames[name] = true
- return name
-}
-
// Write implements io.Writer.
func (g *GeneratedFile) Write(p []byte) (n int, err error) {
return g.buf.Write(p)

To view, visit change 134955. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: protobuf
Gerrit-Branch: master
Gerrit-Change-Id: I01aacc9277c5cb5b4cc295f5ee8af12b4a524781
Gerrit-Change-Number: 134955
Gerrit-PatchSet: 1
Gerrit-Owner: Damien Neil <dn...@google.com>
Gerrit-MessageType: newchange

Damien Neil (Gerrit)

unread,
Sep 12, 2018, 12:38:20 PM9/12/18
to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

Damien Neil uploaded patch set #2 to this change.

View Change

cmd/protoc-gen-go: generate message fields

This produces exactly the same output as github.com/golang/protobuf.

Change-Id: I01aacc9277c5cb5b4cc295f5ee8af12b4a524781
---
M cmd/protoc-gen-go/main.go
M cmd/protoc-gen-go/testdata/comments/comments.pb.go
A cmd/protoc-gen-go/testdata/fieldnames/fieldnames.pb.go
A cmd/protoc-gen-go/testdata/fieldnames/fieldnames.proto
M cmd/protoc-gen-go/testdata/proto2/enum.pb.go
A cmd/protoc-gen-go/testdata/proto2/fields.pb.go
A cmd/protoc-gen-go/testdata/proto2/fields.proto
M cmd/protoc-gen-go/testdata/proto2/nested_messages.pb.go
M cmd/protoc-gen-go/testdata/proto2/proto2.pb.go
M cmd/protoc-gen-go/testdata/proto2/proto2.proto
A cmd/protoc-gen-go/testdata/proto3/fields.pb.go
A cmd/protoc-gen-go/testdata/proto3/fields.proto
M protogen/protogen.go
13 files changed, 839 insertions(+), 37 deletions(-)

To view, visit change 134955. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: protobuf
Gerrit-Branch: master
Gerrit-Change-Id: I01aacc9277c5cb5b4cc295f5ee8af12b4a524781
Gerrit-Change-Number: 134955
Gerrit-PatchSet: 2
Gerrit-Owner: Damien Neil <dn...@google.com>
Gerrit-MessageType: newpatchset

Damien Neil (Gerrit)

unread,
Sep 12, 2018, 12:47:02 PM9/12/18
to Joe Tsai, goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

Damien Neil uploaded patch set #3 to this change.

View Change

cmd/protoc-gen-go: generate message fields

This produces exactly the same output as github.com/golang/protobuf.

Change-Id: I01aacc9277c5cb5b4cc295f5ee8af12b4a524781
---
M cmd/protoc-gen-go/main.go
M cmd/protoc-gen-go/testdata/comments/comments.pb.go
A cmd/protoc-gen-go/testdata/fieldnames/fieldnames.pb.go
A cmd/protoc-gen-go/testdata/fieldnames/fieldnames.proto
M cmd/protoc-gen-go/testdata/proto2/enum.pb.go
A cmd/protoc-gen-go/testdata/proto2/fields.pb.go
A cmd/protoc-gen-go/testdata/proto2/fields.proto
M cmd/protoc-gen-go/testdata/proto2/nested_messages.pb.go
M cmd/protoc-gen-go/testdata/proto2/proto2.pb.go
M cmd/protoc-gen-go/testdata/proto2/proto2.proto
A cmd/protoc-gen-go/testdata/proto3/fields.pb.go
A cmd/protoc-gen-go/testdata/proto3/fields.proto
M protogen/protogen.go
13 files changed, 839 insertions(+), 37 deletions(-)

To view, visit change 134955. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: protobuf
Gerrit-Branch: master
Gerrit-Change-Id: I01aacc9277c5cb5b4cc295f5ee8af12b4a524781
Gerrit-Change-Number: 134955
Gerrit-PatchSet: 3
Gerrit-Owner: Damien Neil <dn...@google.com>
Gerrit-Reviewer: Damien Neil <dn...@google.com>
Gerrit-Reviewer: Joe Tsai <thebroke...@gmail.com>
Gerrit-MessageType: newpatchset

Damien Neil (Gerrit)

unread,
Sep 12, 2018, 12:53:28 PM9/12/18
to Joe Tsai, goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

Damien Neil uploaded patch set #4 to this change.

View Change

cmd/protoc-gen-go: generate message fields

This produces exactly the same output as github.com/golang/protobuf.

Change-Id: I01aacc9277c5cb5b4cc295f5ee8af12b4a524781
---
M cmd/protoc-gen-go/main.go
M cmd/protoc-gen-go/testdata/comments/comments.pb.go
A cmd/protoc-gen-go/testdata/fieldnames/fieldnames.pb.go
A cmd/protoc-gen-go/testdata/fieldnames/fieldnames.proto
M cmd/protoc-gen-go/testdata/proto2/enum.pb.go
A cmd/protoc-gen-go/testdata/proto2/fields.pb.go
A cmd/protoc-gen-go/testdata/proto2/fields.proto
M cmd/protoc-gen-go/testdata/proto2/nested_messages.pb.go
M cmd/protoc-gen-go/testdata/proto2/proto2.pb.go
M cmd/protoc-gen-go/testdata/proto2/proto2.proto
A cmd/protoc-gen-go/testdata/proto3/fields.pb.go
A cmd/protoc-gen-go/testdata/proto3/fields.proto
M protogen/protogen.go
13 files changed, 840 insertions(+), 37 deletions(-)

To view, visit change 134955. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: protobuf
Gerrit-Branch: master
Gerrit-Change-Id: I01aacc9277c5cb5b4cc295f5ee8af12b4a524781
Gerrit-Change-Number: 134955
Gerrit-PatchSet: 4

Joe Tsai (Gerrit)

unread,
Sep 12, 2018, 1:08:16 PM9/12/18
to Damien Neil, goph...@pubsubhelper.golang.org, Joe Tsai, golang-co...@googlegroups.com

Patch set 4:Code-Review +1

View Change

7 comments:


    • var wireTypes = map[protoreflect.Kind]string{

    • 	protoreflect.BoolKind:     "varint",
      protoreflect.EnumKind: "varint",
      protoreflect.Int32Kind: "varint",
      protoreflect.Sint32Kind: "zigzag32",
      protoreflect.Uint32Kind: "varint",
      protoreflect.Int64Kind: "varint",
      protoreflect.Sint64Kind: "zigzag64",
      protoreflect.Uint64Kind: "varint",
      protoreflect.Sfixed32Kind: "fixed32",
      protoreflect.Fixed32Kind: "fixed32",
      protoreflect.FloatKind: "fixed32",
      protoreflect.Sfixed64Kind: "fixed64",
      protoreflect.Fixed64Kind: "fixed64",
      protoreflect.DoubleKind: "fixed64",
      protoreflect.StringKind: "bytes",
      protoreflect.BytesKind: "bytes",
      protoreflect.MessageKind: "bytes",

      I wonder if wire type should be a method on protoreflect.Kind?

  • File protogen/protogen.go:

    • Patch Set #3, Line 564:

      Is this deletion intentional? It is dead code.

    • Patch Set #3, Line 519: message type, for fields with kind Message or Group

      If I ever get around to merging hotlinks into godoc, this will be a false positive, since Message is a type in this package.

      Either:

       // type for message or group kinds

      or:

       // type for protoreflect.MessageKind or protoreflect.GroupKind
    • Patch Set #3, Line 537:

      		if !ok {


    • return nil, fmt.Errorf("field %v: no descriptor for type %v", desc.FullName(), mname)
      }

    • FYI, the prototype package should eventually verify that a set of created file descriptors are internally consistent. Not that it hurts to have your own consistency check.

To view, visit change 134955. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: protobuf
Gerrit-Branch: master
Gerrit-Change-Id: I01aacc9277c5cb5b4cc295f5ee8af12b4a524781
Gerrit-Change-Number: 134955
Gerrit-PatchSet: 4
Gerrit-Owner: Damien Neil <dn...@google.com>
Gerrit-Reviewer: Damien Neil <dn...@google.com>
Gerrit-Reviewer: Joe Tsai <thebroke...@gmail.com>
Gerrit-Comment-Date: Wed, 12 Sep 2018 17:08:14 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: Yes
Gerrit-MessageType: comment

Joe Tsai (Gerrit)

unread,
Sep 12, 2018, 1:08:37 PM9/12/18
to Damien Neil, goph...@pubsubhelper.golang.org, Joe Tsai, golang-co...@googlegroups.com

Patch set 4:Code-Review +2

View Change

    To view, visit change 134955. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: protobuf
    Gerrit-Branch: master
    Gerrit-Change-Id: I01aacc9277c5cb5b4cc295f5ee8af12b4a524781
    Gerrit-Change-Number: 134955
    Gerrit-PatchSet: 4
    Gerrit-Owner: Damien Neil <dn...@google.com>
    Gerrit-Reviewer: Damien Neil <dn...@google.com>
    Gerrit-Reviewer: Joe Tsai <thebroke...@gmail.com>
    Gerrit-Comment-Date: Wed, 12 Sep 2018 17:08:35 +0000
    Gerrit-HasComments: No
    Gerrit-Has-Labels: Yes
    Gerrit-MessageType: comment

    Damien Neil (Gerrit)

    unread,
    Sep 12, 2018, 2:07:21 PM9/12/18
    to Joe Tsai, goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

    Damien Neil uploaded patch set #5 to this change.

    View Change

    cmd/protoc-gen-go: generate message fields

    This produces exactly the same output as github.com/golang/protobuf.

    Change-Id: I01aacc9277c5cb5b4cc295f5ee8af12b4a524781
    ---
    M cmd/protoc-gen-go/main.go
    M cmd/protoc-gen-go/testdata/comments/comments.pb.go
    A cmd/protoc-gen-go/testdata/fieldnames/fieldnames.pb.go
    A cmd/protoc-gen-go/testdata/fieldnames/fieldnames.proto
    M cmd/protoc-gen-go/testdata/proto2/enum.pb.go
    A cmd/protoc-gen-go/testdata/proto2/fields.pb.go
    A cmd/protoc-gen-go/testdata/proto2/fields.proto
    M cmd/protoc-gen-go/testdata/proto2/nested_messages.pb.go
    M cmd/protoc-gen-go/testdata/proto2/proto2.pb.go
    M cmd/protoc-gen-go/testdata/proto2/proto2.proto
    A cmd/protoc-gen-go/testdata/proto3/fields.pb.go
    A cmd/protoc-gen-go/testdata/proto3/fields.proto
    M protogen/protogen.go
    13 files changed, 839 insertions(+), 37 deletions(-)

    To view, visit change 134955. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: protobuf
    Gerrit-Branch: master
    Gerrit-Change-Id: I01aacc9277c5cb5b4cc295f5ee8af12b4a524781
    Gerrit-Change-Number: 134955
    Gerrit-PatchSet: 5
    Gerrit-Owner: Damien Neil <dn...@google.com>
    Gerrit-Reviewer: Damien Neil <dn...@google.com>
    Gerrit-Reviewer: Joe Tsai <thebroke...@gmail.com>
    Gerrit-MessageType: newpatchset

    Damien Neil (Gerrit)

    unread,
    Sep 12, 2018, 2:07:26 PM9/12/18
    to goph...@pubsubhelper.golang.org, Joe Tsai, golang-co...@googlegroups.com

    View Change

    5 comments:

      • Patch Set #3, Line 286:

        	if field.Desc.Cardinality() == protoreflect.Repeated {
        return "[]" + typ
        }

        Add TODO for map types?

      • Done

      • Perhaps return reflect. […]

        Eh, I don't need any of the methods from StructTag and this just gets printed. I think it's fine to leave it as a string.

      • It should have been deleted in the cl that added QualifiedGoIdent. I could split it out into a separate commit, but it's probably fine to just delete it here.

      • If I ever get around to merging hotlinks into godoc, this will be a false positive, since Message is […]

        reworded

    To view, visit change 134955. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: protobuf
    Gerrit-Branch: master
    Gerrit-Change-Id: I01aacc9277c5cb5b4cc295f5ee8af12b4a524781
    Gerrit-Change-Number: 134955
    Gerrit-PatchSet: 4
    Gerrit-Owner: Damien Neil <dn...@google.com>
    Gerrit-Reviewer: Damien Neil <dn...@google.com>
    Gerrit-Reviewer: Joe Tsai <thebroke...@gmail.com>
    Gerrit-Comment-Date: Wed, 12 Sep 2018 18:07:24 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Joe Tsai <thebroke...@gmail.com>
    Gerrit-MessageType: comment

    Damien Neil (Gerrit)

    unread,
    Sep 12, 2018, 2:08:42 PM9/12/18
    to goph...@pubsubhelper.golang.org, golang-...@googlegroups.com, Joe Tsai, golang-co...@googlegroups.com

    Damien Neil merged this change.

    View Change

    Approvals: Joe Tsai: Looks good to me, approved
    cmd/protoc-gen-go: generate message fields

    This produces exactly the same output as github.com/golang/protobuf.

    Change-Id: I01aacc9277c5cb5b4cc295f5ee8af12b4a524781
    Reviewed-on: https://go-review.googlesource.com/134955
    Reviewed-by: Joe Tsai <thebroke...@gmail.com>

    ---
    M cmd/protoc-gen-go/main.go
    M cmd/protoc-gen-go/testdata/comments/comments.pb.go
    A cmd/protoc-gen-go/testdata/fieldnames/fieldnames.pb.go
    A cmd/protoc-gen-go/testdata/fieldnames/fieldnames.proto
    M cmd/protoc-gen-go/testdata/proto2/enum.pb.go
    A cmd/protoc-gen-go/testdata/proto2/fields.pb.go
    A cmd/protoc-gen-go/testdata/proto2/fields.proto
    M cmd/protoc-gen-go/testdata/proto2/nested_messages.pb.go
    M cmd/protoc-gen-go/testdata/proto2/proto2.pb.go
    M cmd/protoc-gen-go/testdata/proto2/proto2.proto
    A cmd/protoc-gen-go/testdata/proto3/fields.pb.go
    A cmd/protoc-gen-go/testdata/proto3/fields.proto
    M protogen/protogen.go
    13 files changed, 839 insertions(+), 37 deletions(-)

    diff --git a/cmd/protoc-gen-go/main.go b/cmd/protoc-gen-go/main.go
    index c243e00..1f24a1a 100644
    --- a/cmd/protoc-gen-go/main.go
    +++ b/cmd/protoc-gen-go/main.go
    @@ -200,26 +200,55 @@
     func genMessage(gen *protogen.Plugin, g *protogen.GeneratedFile, f *File, message *protogen.Message) {
    - for _, enum := range message.Enums {
    - genEnum(gen, g, f, enum)
    + for _, e := range message.Enums {
    + genEnum(gen, g, f, e)
    }

    genComment(g, f, message.Path)
    + // TODO: deprecation
    g.P("type ", message.GoIdent, " struct {")
    + for _, field := range message.Fields {
    + if field.Desc.OneofType() != nil {
    + // TODO oneofs
    + continue
    + }
    + genComment(g, f, field.Path)
    + g.P(field.GoIdent, " ", fieldGoType(g, field), fmt.Sprintf(" `protobuf:%q json:%q`", fieldProtobufTag(field), fieldJSONTag(field)))
    + }
    + g.P("XXX_NoUnkeyedLiteral struct{} `json:\"-\"`")
    + // TODO XXX_InternalExtensions
    + g.P("XXX_unrecognized []byte `json:\"-\"`")
    + g.P("XXX_sizecache int32 `json:\"-\"`")
    g.P("}")
    g.P()

    @@ -228,6 +257,123 @@

    }
    }

    +func fieldGoType(g *protogen.GeneratedFile, field *protogen.Field) string {
    +	// TODO: map types
    +	// TODO: default values

    + // TODO: packed
    + // name
    + name := string(field.Desc.Name())
    + if field.Desc.Kind() == protoreflect.GroupKind {
    +		// The name of the FieldDescriptor for a group field is
    + // lowercased. To find the original capitalization, we
    + // look in the field's MessageType.
    index ee4c735..5e1cd83 100644
    +	// We assume well-known method names that may be attached to a generated
    + // message type, as well as a 'Get*' method for each field. For each
    + // field in turn, we add _s to its name until there are no conflicts.
    + //
    + // Any change to the following set of method names is a potential
    + // incompatible API change because it may change generated field names.
    +	//
    + // TODO: If we ever support a 'go_name' option to set the Go name of a
    + // field, we should consider dropping this entirely. The conflict
    + // resolution algorithm is subtle and surprising (changing the order
    + // in which fields appear in the .proto source file can change the
    + // names of fields in generated code), and does not adapt well to
    + // adding new per-field methods such as setters.
    +	MessageType *Message // type for message or group fields; nil otherwise
    + EnumType *Enum // type for enum fields; nil otherwise
    + Path []int32 // location path of this field
    Gerrit-PatchSet: 6
    Gerrit-Owner: Damien Neil <dn...@google.com>
    Gerrit-Reviewer: Damien Neil <dn...@google.com>
    Gerrit-Reviewer: Joe Tsai <thebroke...@gmail.com>
    Gerrit-MessageType: merged
    Reply all
    Reply to author
    Forward
    0 new messages