mirror of
https://github.com/protocolbuffers/protobuf-go.git
synced 2025-03-09 22:13:27 +00:00
cmd/protoc-gen-go: generate enums
This produces exactly the same output (to the best of my ability to determine) as github.com/golang/protobuf. Change-Id: Ib60e7a836efb1eb0e5167b30458049ec239e7903 Reviewed-on: https://go-review.googlesource.com/134695 Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
This commit is contained in:
parent
cab8dfee90
commit
46abb57549
@ -18,8 +18,11 @@ import (
|
||||
"github.com/golang/protobuf/proto"
|
||||
descpb "github.com/golang/protobuf/protoc-gen-go/descriptor"
|
||||
"google.golang.org/proto/protogen"
|
||||
"google.golang.org/proto/reflect/protoreflect"
|
||||
)
|
||||
|
||||
const protoPackage = "github.com/golang/protobuf/proto"
|
||||
|
||||
func main() {
|
||||
protogen.Run(func(gen *protogen.Plugin) error {
|
||||
for _, f := range gen.Files {
|
||||
@ -34,7 +37,9 @@ func main() {
|
||||
|
||||
type File struct {
|
||||
*protogen.File
|
||||
locationMap map[string][]*descpb.SourceCodeInfo_Location
|
||||
locationMap map[string][]*descpb.SourceCodeInfo_Location
|
||||
descriptorVar string // var containing the gzipped FileDescriptorProto
|
||||
init []string
|
||||
}
|
||||
|
||||
func genFile(gen *protogen.Plugin, file *protogen.File) {
|
||||
@ -47,6 +52,12 @@ func genFile(gen *protogen.Plugin, file *protogen.File) {
|
||||
f.locationMap[key] = append(f.locationMap[key], loc)
|
||||
}
|
||||
|
||||
// Determine the name of the var holding the file descriptor:
|
||||
//
|
||||
// fileDescriptor_<hash of filename>
|
||||
filenameHash := sha256.Sum256([]byte(f.Desc.Path()))
|
||||
f.descriptorVar = fmt.Sprintf("fileDescriptor_%s", hex.EncodeToString(filenameHash[:8]))
|
||||
|
||||
g := gen.NewGeneratedFile(f.GeneratedFilenamePrefix+".pb.go", f.GoImportPath)
|
||||
g.P("// Code generated by protoc-gen-go. DO NOT EDIT.")
|
||||
g.P("// source: ", f.Desc.Path())
|
||||
@ -57,20 +68,26 @@ func genFile(gen *protogen.Plugin, file *protogen.File) {
|
||||
g.P("package ", f.GoPackageName)
|
||||
g.P()
|
||||
|
||||
for _, enum := range f.Enums {
|
||||
genEnum(gen, g, f, enum)
|
||||
}
|
||||
for _, message := range f.Messages {
|
||||
genMessage(gen, g, f, message)
|
||||
}
|
||||
|
||||
if len(f.init) != 0 {
|
||||
g.P("func init() {")
|
||||
for _, s := range f.init {
|
||||
g.P(s)
|
||||
}
|
||||
g.P("}")
|
||||
g.P()
|
||||
}
|
||||
|
||||
genFileDescriptor(gen, g, f)
|
||||
}
|
||||
|
||||
func genFileDescriptor(gen *protogen.Plugin, g *protogen.GeneratedFile, f *File) {
|
||||
// Determine the name of the var holding the file descriptor:
|
||||
//
|
||||
// fileDescriptor_<hash of filename>
|
||||
filenameHash := sha256.Sum256([]byte(f.Desc.Path()))
|
||||
varName := fmt.Sprintf("fileDescriptor_%s", hex.EncodeToString(filenameHash[:8]))
|
||||
|
||||
// Trim the source_code_info from the descriptor.
|
||||
// Marshal and gzip it.
|
||||
descProto := proto.Clone(f.Proto).(*descpb.FileDescriptorProto)
|
||||
@ -86,9 +103,9 @@ func genFileDescriptor(gen *protogen.Plugin, g *protogen.GeneratedFile, f *File)
|
||||
w.Close()
|
||||
b = buf.Bytes()
|
||||
|
||||
g.P("func init() { proto.RegisterFile(", strconv.Quote(f.Desc.Path()), ", ", varName, ") }")
|
||||
g.P("func init() { proto.RegisterFile(", strconv.Quote(f.Desc.Path()), ", ", f.descriptorVar, ") }")
|
||||
g.P()
|
||||
g.P("var ", varName, " = []byte{")
|
||||
g.P("var ", f.descriptorVar, " = []byte{")
|
||||
g.P("// ", len(b), " bytes of a gzipped FileDescriptorProto")
|
||||
for len(b) > 0 {
|
||||
n := 16
|
||||
@ -108,7 +125,92 @@ func genFileDescriptor(gen *protogen.Plugin, g *protogen.GeneratedFile, f *File)
|
||||
g.P()
|
||||
}
|
||||
|
||||
func genEnum(gen *protogen.Plugin, g *protogen.GeneratedFile, f *File, enum *protogen.Enum) {
|
||||
genComment(g, f, enum.Path)
|
||||
// TODO: deprecation
|
||||
g.P("type ", enum.GoIdent, " int32")
|
||||
g.P("const (")
|
||||
for _, value := range enum.Values {
|
||||
genComment(g, f, value.Path)
|
||||
// TODO: deprecation
|
||||
g.P(value.GoIdent, " ", enum.GoIdent, " = ", value.Desc.Number())
|
||||
}
|
||||
g.P(")")
|
||||
g.P()
|
||||
nameMap := enum.GoIdent.GoName + "_name"
|
||||
g.P("var ", nameMap, " = map[int32]string{")
|
||||
generated := make(map[protoreflect.EnumNumber]bool)
|
||||
for _, value := range enum.Values {
|
||||
duplicate := ""
|
||||
if _, present := generated[value.Desc.Number()]; present {
|
||||
duplicate = "// Duplicate value: "
|
||||
}
|
||||
g.P(duplicate, value.Desc.Number(), ": ", strconv.Quote(string(value.Desc.Name())), ",")
|
||||
generated[value.Desc.Number()] = true
|
||||
}
|
||||
g.P("}")
|
||||
g.P()
|
||||
valueMap := enum.GoIdent.GoName + "_value"
|
||||
g.P("var ", valueMap, " = map[string]int32{")
|
||||
for _, value := range enum.Values {
|
||||
g.P(strconv.Quote(string(value.Desc.Name())), ": ", value.Desc.Number(), ",")
|
||||
}
|
||||
g.P("}")
|
||||
g.P()
|
||||
if enum.Desc.Syntax() != protoreflect.Proto3 {
|
||||
g.P("func (x ", enum.GoIdent, ") Enum() *", enum.GoIdent, " {")
|
||||
g.P("p := new(", enum.GoIdent, ")")
|
||||
g.P("*p = x")
|
||||
g.P("return p")
|
||||
g.P("}")
|
||||
g.P()
|
||||
}
|
||||
g.P("func (x ", enum.GoIdent, ") String() string {")
|
||||
g.P("return ", protogen.GoIdent{GoImportPath: protoPackage, GoName: "EnumName"}, "(", enum.GoIdent, "_name, int32(x))")
|
||||
g.P("}")
|
||||
g.P()
|
||||
|
||||
if enum.Desc.Syntax() != protoreflect.Proto3 {
|
||||
g.P("func (x *", enum.GoIdent, ") UnmarshalJSON(data []byte) error {")
|
||||
g.P("value, err := ", protogen.GoIdent{GoImportPath: protoPackage, GoName: "UnmarshalJSONEnum"}, "(", enum.GoIdent, `_value, data, "`, enum.GoIdent, `")`)
|
||||
g.P("if err != nil {")
|
||||
g.P("return err")
|
||||
g.P("}")
|
||||
g.P("*x = ", enum.GoIdent, "(value)")
|
||||
g.P("return nil")
|
||||
g.P("}")
|
||||
g.P()
|
||||
}
|
||||
|
||||
var indexes []string
|
||||
for i := 1; i < len(enum.Path); i += 2 {
|
||||
indexes = append(indexes, strconv.Itoa(int(enum.Path[i])))
|
||||
}
|
||||
g.P("func (", enum.GoIdent, ") EnumDescriptor() ([]byte, []int) {")
|
||||
g.P("return ", f.descriptorVar, ", []int{", strings.Join(indexes, ","), "}")
|
||||
g.P("}")
|
||||
g.P()
|
||||
|
||||
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,
|
||||
))
|
||||
}
|
||||
|
||||
func genMessage(gen *protogen.Plugin, g *protogen.GeneratedFile, f *File, message *protogen.Message) {
|
||||
for _, enum := range message.Enums {
|
||||
genEnum(gen, g, f, enum)
|
||||
}
|
||||
|
||||
genComment(g, f, message.Path)
|
||||
g.P("type ", message.GoIdent, " struct {")
|
||||
g.P("}")
|
||||
@ -142,3 +244,15 @@ func pathKey(path []int32) string {
|
||||
}
|
||||
return string(buf)
|
||||
}
|
||||
|
||||
func genWellKnownType(g *protogen.GeneratedFile, ident protogen.GoIdent, desc protoreflect.Descriptor) {
|
||||
if wellKnownTypes[desc.FullName()] {
|
||||
g.P("func (", ident, `) XXX_WellKnownType() string { return "`, desc.Name(), `" }`)
|
||||
g.P()
|
||||
}
|
||||
}
|
||||
|
||||
// Names of messages and enums for which we will generate XXX_WellKnownType methods.
|
||||
var wellKnownTypes = map[protoreflect.FullName]bool{
|
||||
"google.protobuf.NullValue": true,
|
||||
}
|
||||
|
278
cmd/protoc-gen-go/testdata/proto2/enum.pb.go
vendored
Normal file
278
cmd/protoc-gen-go/testdata/proto2/enum.pb.go
vendored
Normal file
@ -0,0 +1,278 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: proto2/enum.proto
|
||||
|
||||
package proto2
|
||||
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
|
||||
// EnumType1 comment.
|
||||
type EnumType1 int32
|
||||
|
||||
const (
|
||||
// EnumType1_ONE comment.
|
||||
EnumType1_ONE EnumType1 = 1
|
||||
// EnumType1_TWO comment.
|
||||
EnumType1_TWO EnumType1 = 2
|
||||
)
|
||||
|
||||
var EnumType1_name = map[int32]string{
|
||||
1: "ONE",
|
||||
2: "TWO",
|
||||
}
|
||||
|
||||
var EnumType1_value = map[string]int32{
|
||||
"ONE": 1,
|
||||
"TWO": 2,
|
||||
}
|
||||
|
||||
func (x EnumType1) Enum() *EnumType1 {
|
||||
p := new(EnumType1)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x EnumType1) String() string {
|
||||
return proto.EnumName(EnumType1_name, int32(x))
|
||||
}
|
||||
|
||||
func (x *EnumType1) UnmarshalJSON(data []byte) error {
|
||||
value, err := proto.UnmarshalJSONEnum(EnumType1_value, data, "EnumType1")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*x = EnumType1(value)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (EnumType1) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_de9f68860d540858, []int{0}
|
||||
}
|
||||
|
||||
type EnumType2 int32
|
||||
|
||||
const (
|
||||
EnumType2_duplicate1 EnumType2 = 1
|
||||
EnumType2_duplicate2 EnumType2 = 1
|
||||
)
|
||||
|
||||
var EnumType2_name = map[int32]string{
|
||||
1: "duplicate1",
|
||||
// Duplicate value: 1: "duplicate2",
|
||||
}
|
||||
|
||||
var EnumType2_value = map[string]int32{
|
||||
"duplicate1": 1,
|
||||
"duplicate2": 1,
|
||||
}
|
||||
|
||||
func (x EnumType2) Enum() *EnumType2 {
|
||||
p := new(EnumType2)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x EnumType2) String() string {
|
||||
return proto.EnumName(EnumType2_name, int32(x))
|
||||
}
|
||||
|
||||
func (x *EnumType2) UnmarshalJSON(data []byte) error {
|
||||
value, err := proto.UnmarshalJSONEnum(EnumType2_value, data, "EnumType2")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*x = EnumType2(value)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (EnumType2) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_de9f68860d540858, []int{1}
|
||||
}
|
||||
|
||||
// NestedEnumType1A comment.
|
||||
type EnumContainerMessage1_NestedEnumType1A int32
|
||||
|
||||
const (
|
||||
// NestedEnumType1A_VALUE comment.
|
||||
EnumContainerMessage1_NESTED_1A_VALUE EnumContainerMessage1_NestedEnumType1A = 0
|
||||
)
|
||||
|
||||
var EnumContainerMessage1_NestedEnumType1A_name = map[int32]string{
|
||||
0: "NESTED_1A_VALUE",
|
||||
}
|
||||
|
||||
var EnumContainerMessage1_NestedEnumType1A_value = map[string]int32{
|
||||
"NESTED_1A_VALUE": 0,
|
||||
}
|
||||
|
||||
func (x EnumContainerMessage1_NestedEnumType1A) Enum() *EnumContainerMessage1_NestedEnumType1A {
|
||||
p := new(EnumContainerMessage1_NestedEnumType1A)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x EnumContainerMessage1_NestedEnumType1A) String() string {
|
||||
return proto.EnumName(EnumContainerMessage1_NestedEnumType1A_name, int32(x))
|
||||
}
|
||||
|
||||
func (x *EnumContainerMessage1_NestedEnumType1A) UnmarshalJSON(data []byte) error {
|
||||
value, err := proto.UnmarshalJSONEnum(EnumContainerMessage1_NestedEnumType1A_value, data, "EnumContainerMessage1_NestedEnumType1A")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*x = EnumContainerMessage1_NestedEnumType1A(value)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (EnumContainerMessage1_NestedEnumType1A) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_de9f68860d540858, []int{0, 0}
|
||||
}
|
||||
|
||||
type EnumContainerMessage1_NestedEnumType1B int32
|
||||
|
||||
const (
|
||||
EnumContainerMessage1_NESTED_1B_VALUE EnumContainerMessage1_NestedEnumType1B = 0
|
||||
)
|
||||
|
||||
var EnumContainerMessage1_NestedEnumType1B_name = map[int32]string{
|
||||
0: "NESTED_1B_VALUE",
|
||||
}
|
||||
|
||||
var EnumContainerMessage1_NestedEnumType1B_value = map[string]int32{
|
||||
"NESTED_1B_VALUE": 0,
|
||||
}
|
||||
|
||||
func (x EnumContainerMessage1_NestedEnumType1B) Enum() *EnumContainerMessage1_NestedEnumType1B {
|
||||
p := new(EnumContainerMessage1_NestedEnumType1B)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x EnumContainerMessage1_NestedEnumType1B) String() string {
|
||||
return proto.EnumName(EnumContainerMessage1_NestedEnumType1B_name, int32(x))
|
||||
}
|
||||
|
||||
func (x *EnumContainerMessage1_NestedEnumType1B) UnmarshalJSON(data []byte) error {
|
||||
value, err := proto.UnmarshalJSONEnum(EnumContainerMessage1_NestedEnumType1B_value, data, "EnumContainerMessage1_NestedEnumType1B")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*x = EnumContainerMessage1_NestedEnumType1B(value)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (EnumContainerMessage1_NestedEnumType1B) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_de9f68860d540858, []int{0, 1}
|
||||
}
|
||||
|
||||
type EnumContainerMessage1 struct {
|
||||
}
|
||||
|
||||
// NestedEnumType2A comment.
|
||||
type EnumContainerMessage1_EnumContainerMessage2_NestedEnumType2A int32
|
||||
|
||||
const (
|
||||
// NestedEnumType2A_VALUE comment.
|
||||
EnumContainerMessage1_EnumContainerMessage2_NESTED_2A_VALUE EnumContainerMessage1_EnumContainerMessage2_NestedEnumType2A = 0
|
||||
)
|
||||
|
||||
var EnumContainerMessage1_EnumContainerMessage2_NestedEnumType2A_name = map[int32]string{
|
||||
0: "NESTED_2A_VALUE",
|
||||
}
|
||||
|
||||
var EnumContainerMessage1_EnumContainerMessage2_NestedEnumType2A_value = map[string]int32{
|
||||
"NESTED_2A_VALUE": 0,
|
||||
}
|
||||
|
||||
func (x EnumContainerMessage1_EnumContainerMessage2_NestedEnumType2A) Enum() *EnumContainerMessage1_EnumContainerMessage2_NestedEnumType2A {
|
||||
p := new(EnumContainerMessage1_EnumContainerMessage2_NestedEnumType2A)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x EnumContainerMessage1_EnumContainerMessage2_NestedEnumType2A) String() string {
|
||||
return proto.EnumName(EnumContainerMessage1_EnumContainerMessage2_NestedEnumType2A_name, int32(x))
|
||||
}
|
||||
|
||||
func (x *EnumContainerMessage1_EnumContainerMessage2_NestedEnumType2A) UnmarshalJSON(data []byte) error {
|
||||
value, err := proto.UnmarshalJSONEnum(EnumContainerMessage1_EnumContainerMessage2_NestedEnumType2A_value, data, "EnumContainerMessage1_EnumContainerMessage2_NestedEnumType2A")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*x = EnumContainerMessage1_EnumContainerMessage2_NestedEnumType2A(value)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (EnumContainerMessage1_EnumContainerMessage2_NestedEnumType2A) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_de9f68860d540858, []int{0, 0, 0}
|
||||
}
|
||||
|
||||
type EnumContainerMessage1_EnumContainerMessage2_NestedEnumType2B int32
|
||||
|
||||
const (
|
||||
EnumContainerMessage1_EnumContainerMessage2_NESTED_2B_VALUE EnumContainerMessage1_EnumContainerMessage2_NestedEnumType2B = 0
|
||||
)
|
||||
|
||||
var EnumContainerMessage1_EnumContainerMessage2_NestedEnumType2B_name = map[int32]string{
|
||||
0: "NESTED_2B_VALUE",
|
||||
}
|
||||
|
||||
var EnumContainerMessage1_EnumContainerMessage2_NestedEnumType2B_value = map[string]int32{
|
||||
"NESTED_2B_VALUE": 0,
|
||||
}
|
||||
|
||||
func (x EnumContainerMessage1_EnumContainerMessage2_NestedEnumType2B) Enum() *EnumContainerMessage1_EnumContainerMessage2_NestedEnumType2B {
|
||||
p := new(EnumContainerMessage1_EnumContainerMessage2_NestedEnumType2B)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x EnumContainerMessage1_EnumContainerMessage2_NestedEnumType2B) String() string {
|
||||
return proto.EnumName(EnumContainerMessage1_EnumContainerMessage2_NestedEnumType2B_name, int32(x))
|
||||
}
|
||||
|
||||
func (x *EnumContainerMessage1_EnumContainerMessage2_NestedEnumType2B) UnmarshalJSON(data []byte) error {
|
||||
value, err := proto.UnmarshalJSONEnum(EnumContainerMessage1_EnumContainerMessage2_NestedEnumType2B_value, data, "EnumContainerMessage1_EnumContainerMessage2_NestedEnumType2B")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*x = EnumContainerMessage1_EnumContainerMessage2_NestedEnumType2B(value)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (EnumContainerMessage1_EnumContainerMessage2_NestedEnumType2B) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_de9f68860d540858, []int{0, 0, 1}
|
||||
}
|
||||
|
||||
type EnumContainerMessage1_EnumContainerMessage2 struct {
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterEnum("goproto.protoc.proto2.EnumType1", EnumType1_name, EnumType1_value)
|
||||
proto.RegisterEnum("goproto.protoc.proto2.EnumType2", EnumType2_name, EnumType2_value)
|
||||
proto.RegisterEnum("goproto.protoc.proto2.EnumContainerMessage1_NestedEnumType1A", EnumContainerMessage1_NestedEnumType1A_name, EnumContainerMessage1_NestedEnumType1A_value)
|
||||
proto.RegisterEnum("goproto.protoc.proto2.EnumContainerMessage1_NestedEnumType1B", EnumContainerMessage1_NestedEnumType1B_name, EnumContainerMessage1_NestedEnumType1B_value)
|
||||
proto.RegisterEnum("goproto.protoc.proto2.EnumContainerMessage1_EnumContainerMessage2_NestedEnumType2A", EnumContainerMessage1_EnumContainerMessage2_NestedEnumType2A_name, EnumContainerMessage1_EnumContainerMessage2_NestedEnumType2A_value)
|
||||
proto.RegisterEnum("goproto.protoc.proto2.EnumContainerMessage1_EnumContainerMessage2_NestedEnumType2B", EnumContainerMessage1_EnumContainerMessage2_NestedEnumType2B_name, EnumContainerMessage1_EnumContainerMessage2_NestedEnumType2B_value)
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("proto2/enum.proto", fileDescriptor_de9f68860d540858) }
|
||||
|
||||
var fileDescriptor_de9f68860d540858 = []byte{
|
||||
// 242 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x90, 0xb1, 0x4b, 0xc4, 0x30,
|
||||
0x14, 0xc6, 0xcd, 0x39, 0x88, 0x19, 0x34, 0x56, 0x6e, 0x39, 0x70, 0xb9, 0x45, 0x38, 0xb8, 0x86,
|
||||
0x64, 0x13, 0xa7, 0x56, 0xb3, 0x69, 0x6f, 0xb0, 0x2a, 0xb8, 0x1c, 0xa1, 0x7d, 0x3c, 0x0a, 0x6d,
|
||||
0x5e, 0x69, 0xd3, 0xc1, 0xff, 0xd3, 0x3f, 0x48, 0xae, 0x81, 0xb3, 0x42, 0x75, 0xca, 0xf7, 0xe5,
|
||||
0xfb, 0xf1, 0x1b, 0x1e, 0xbf, 0x6a, 0x3b, 0xf2, 0xa4, 0x25, 0xb8, 0xa1, 0x89, 0xc7, 0x1c, 0x2d,
|
||||
0x91, 0xc6, 0x10, 0x6a, 0x11, 0x1e, 0xbd, 0xfe, 0x62, 0x7c, 0x69, 0xdc, 0xd0, 0x3c, 0x90, 0xf3,
|
||||
0xb6, 0x72, 0xd0, 0x3d, 0x43, 0xdf, 0x5b, 0x04, 0xb5, 0xaa, 0xe6, 0x07, 0xbd, 0xbe, 0xe5, 0x22,
|
||||
0x83, 0xde, 0x43, 0x79, 0x98, 0xf3, 0xcf, 0x16, 0x74, 0x12, 0x5d, 0xf3, 0xcb, 0xcc, 0xbc, 0xe4,
|
||||
0xe6, 0x71, 0xaf, 0x93, 0xfd, 0x5b, 0xf2, 0xf4, 0x6a, 0xc4, 0xc9, 0x0c, 0x98, 0x4e, 0xc1, 0xf4,
|
||||
0x6f, 0x50, 0x4d, 0x8d, 0xea, 0x1f, 0xa3, 0x9a, 0x1a, 0xd5, 0xd1, 0xb8, 0xb9, 0xe1, 0xe7, 0x47,
|
||||
0x24, 0x3a, 0xe3, 0xa7, 0xbb, 0xcc, 0x08, 0x76, 0x08, 0xf9, 0xfb, 0x4e, 0x2c, 0x36, 0xf2, 0x67,
|
||||
0xd6, 0xd1, 0x05, 0xe7, 0xe5, 0xd0, 0xd6, 0x55, 0x61, 0x3d, 0x28, 0xc1, 0x7e, 0x75, 0x2d, 0xd8,
|
||||
0x6a, 0x21, 0x58, 0x7a, 0xff, 0x71, 0x87, 0x44, 0x58, 0x43, 0x8c, 0x54, 0x5b, 0x87, 0x31, 0x75,
|
||||
0x28, 0xc7, 0x13, 0xca, 0xa2, 0x29, 0x43, 0x2a, 0xb6, 0x08, 0x6e, 0x8b, 0x24, 0x3d, 0xf4, 0xbe,
|
||||
0xb4, 0xde, 0x86, 0x6f, 0xfd, 0x1d, 0x00, 0x00, 0xff, 0xff, 0xf6, 0x53, 0xf7, 0xde, 0x8e, 0x01,
|
||||
0x00, 0x00,
|
||||
}
|
47
cmd/protoc-gen-go/testdata/proto2/enum.proto
vendored
Normal file
47
cmd/protoc-gen-go/testdata/proto2/enum.proto
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
// 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";
|
||||
|
||||
// EnumType1 comment.
|
||||
enum EnumType1 {
|
||||
// EnumType1_ONE comment.
|
||||
ONE = 1;
|
||||
// EnumType1_TWO comment.
|
||||
TWO = 2;
|
||||
}
|
||||
|
||||
enum EnumType2 {
|
||||
option allow_alias = true;
|
||||
duplicate1 = 1;
|
||||
duplicate2 = 1;
|
||||
}
|
||||
|
||||
message EnumContainerMessage1 {
|
||||
// NestedEnumType1A comment.
|
||||
enum NestedEnumType1A {
|
||||
// NestedEnumType1A_VALUE comment.
|
||||
NESTED_1A_VALUE = 0;
|
||||
}
|
||||
|
||||
enum NestedEnumType1B {
|
||||
NESTED_1B_VALUE = 0;
|
||||
}
|
||||
|
||||
message EnumContainerMessage2 {
|
||||
// NestedEnumType2A comment.
|
||||
enum NestedEnumType2A {
|
||||
// NestedEnumType2A_VALUE comment.
|
||||
NESTED_2A_VALUE = 0;
|
||||
}
|
||||
|
||||
enum NestedEnumType2B {
|
||||
NESTED_2B_VALUE = 0;
|
||||
}
|
||||
}
|
||||
}
|
53
cmd/protoc-gen-go/testdata/proto3/enum.pb.go
vendored
Normal file
53
cmd/protoc-gen-go/testdata/proto3/enum.pb.go
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: proto3/enum.proto
|
||||
|
||||
package proto3
|
||||
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
|
||||
type Enum int32
|
||||
|
||||
const (
|
||||
Enum_ZERO Enum = 0
|
||||
Enum_ONE Enum = 1
|
||||
Enum_TWO Enum = 2
|
||||
)
|
||||
|
||||
var Enum_name = map[int32]string{
|
||||
0: "ZERO",
|
||||
1: "ONE",
|
||||
2: "TWO",
|
||||
}
|
||||
|
||||
var Enum_value = map[string]int32{
|
||||
"ZERO": 0,
|
||||
"ONE": 1,
|
||||
"TWO": 2,
|
||||
}
|
||||
|
||||
func (x Enum) String() string {
|
||||
return proto.EnumName(Enum_name, int32(x))
|
||||
}
|
||||
|
||||
func (Enum) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_b4b9b1e8d161a9a6, []int{0}
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterEnum("goproto.protoc.proto3.Enum", Enum_name, Enum_value)
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("proto3/enum.proto", fileDescriptor_b4b9b1e8d161a9a6) }
|
||||
|
||||
var fileDescriptor_b4b9b1e8d161a9a6 = []byte{
|
||||
// 138 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x2c, 0x28, 0xca, 0x2f,
|
||||
0xc9, 0x37, 0xd6, 0x4f, 0xcd, 0x2b, 0xcd, 0xd5, 0x03, 0xb3, 0x85, 0x44, 0xd3, 0xf3, 0xc1, 0x0c,
|
||||
0x08, 0x37, 0x19, 0x42, 0x19, 0x6b, 0x29, 0x71, 0xb1, 0xb8, 0xe6, 0x95, 0xe6, 0x0a, 0x71, 0x70,
|
||||
0xb1, 0x44, 0xb9, 0x06, 0xf9, 0x0b, 0x30, 0x08, 0xb1, 0x73, 0x31, 0xfb, 0xfb, 0xb9, 0x0a, 0x30,
|
||||
0x82, 0x18, 0x21, 0xe1, 0xfe, 0x02, 0x4c, 0x4e, 0xd6, 0x51, 0x96, 0xe9, 0xf9, 0xf9, 0xe9, 0x39,
|
||||
0xa9, 0x7a, 0xe9, 0xf9, 0x39, 0x89, 0x79, 0xe9, 0x7a, 0xf9, 0x45, 0xe9, 0xfa, 0x60, 0xfd, 0xfa,
|
||||
0xc9, 0xb9, 0x29, 0x10, 0x56, 0xb2, 0x6e, 0x7a, 0x6a, 0x9e, 0x6e, 0x7a, 0xbe, 0x7e, 0x49, 0x6a,
|
||||
0x71, 0x49, 0x4a, 0x62, 0x49, 0x22, 0x44, 0xd8, 0x38, 0x89, 0x0d, 0x42, 0x03, 0x02, 0x00, 0x00,
|
||||
0xff, 0xff, 0x02, 0x01, 0x6a, 0x95, 0x93, 0x00, 0x00, 0x00,
|
||||
}
|
15
cmd/protoc-gen-go/testdata/proto3/enum.proto
vendored
Normal file
15
cmd/protoc-gen-go/testdata/proto3/enum.proto
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
// 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";
|
||||
|
||||
enum Enum {
|
||||
ZERO = 0;
|
||||
ONE = 1;
|
||||
TWO = 2;
|
||||
}
|
@ -305,6 +305,7 @@ type File struct {
|
||||
GoPackageName GoPackageName // name of this file's Go package
|
||||
GoImportPath GoImportPath // import path of this file's Go package
|
||||
Messages []*Message // top-level message declarations
|
||||
Enums []*Enum // top-level enum declarations
|
||||
Generate bool // true if we should generate code for this file
|
||||
|
||||
// GeneratedFilenamePrefix is used to construct filenames for generated
|
||||
@ -351,6 +352,9 @@ func newFile(gen *Plugin, p *descpb.FileDescriptorProto, packageName GoPackageNa
|
||||
for i, mdescs := 0, desc.Messages(); i < mdescs.Len(); i++ {
|
||||
f.Messages = append(f.Messages, newMessage(gen, f, nil, mdescs.Get(i)))
|
||||
}
|
||||
for i, edescs := 0, desc.Enums(); i < edescs.Len(); i++ {
|
||||
f.Enums = append(f.Enums, newEnum(gen, f, nil, edescs.Get(i)))
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
|
||||
@ -380,6 +384,7 @@ type Message struct {
|
||||
|
||||
GoIdent GoIdent // name of the generated Go type
|
||||
Messages []*Message // nested message declarations
|
||||
Enums []*Enum // nested enum declarations
|
||||
Path []int32 // location path of this message
|
||||
}
|
||||
|
||||
@ -390,15 +395,73 @@ func newMessage(gen *Plugin, f *File, parent *Message, desc protoreflect.Message
|
||||
} else {
|
||||
path = []int32{fileMessageField, int32(desc.Index())}
|
||||
}
|
||||
m := &Message{
|
||||
message := &Message{
|
||||
Desc: desc,
|
||||
GoIdent: newGoIdent(f, desc),
|
||||
Path: path,
|
||||
}
|
||||
for i, mdescs := 0, desc.Messages(); i < mdescs.Len(); i++ {
|
||||
m.Messages = append(m.Messages, newMessage(gen, f, m, mdescs.Get(i)))
|
||||
message.Messages = append(message.Messages, newMessage(gen, f, message, mdescs.Get(i)))
|
||||
}
|
||||
for i, edescs := 0, desc.Enums(); i < edescs.Len(); i++ {
|
||||
message.Enums = append(message.Enums, newEnum(gen, f, message, edescs.Get(i)))
|
||||
}
|
||||
return message
|
||||
}
|
||||
|
||||
// An Enum describes an enum.
|
||||
type Enum struct {
|
||||
Desc protoreflect.EnumDescriptor
|
||||
|
||||
GoIdent GoIdent // name of the generated Go type
|
||||
Values []*EnumValue // enum values
|
||||
Path []int32 // location path of this enum
|
||||
}
|
||||
|
||||
func newEnum(gen *Plugin, f *File, parent *Message, desc protoreflect.EnumDescriptor) *Enum {
|
||||
var path []int32
|
||||
if parent != nil {
|
||||
path = pathAppend(parent.Path, messageEnumField, int32(desc.Index()))
|
||||
} else {
|
||||
path = []int32{fileEnumField, int32(desc.Index())}
|
||||
}
|
||||
enum := &Enum{
|
||||
Desc: desc,
|
||||
GoIdent: newGoIdent(f, desc),
|
||||
Path: path,
|
||||
}
|
||||
for i, evdescs := 0, enum.Desc.Values(); i < evdescs.Len(); i++ {
|
||||
enum.Values = append(enum.Values, newEnumValue(gen, f, parent, enum, evdescs.Get(i)))
|
||||
}
|
||||
return enum
|
||||
}
|
||||
|
||||
// An EnumValue describes an enum value.
|
||||
type EnumValue struct {
|
||||
Desc protoreflect.EnumValueDescriptor
|
||||
|
||||
GoIdent GoIdent // name of the generated Go type
|
||||
Path []int32 // location path of this enum value
|
||||
}
|
||||
|
||||
func newEnumValue(gen *Plugin, f *File, message *Message, enum *Enum, desc protoreflect.EnumValueDescriptor) *EnumValue {
|
||||
// A top-level enum value's name is: EnumName_ValueName
|
||||
// An enum value contained in a message is: MessageName_ValueName
|
||||
//
|
||||
// Enum value names are not camelcased.
|
||||
parentIdent := enum.GoIdent
|
||||
if message != nil {
|
||||
parentIdent = message.GoIdent
|
||||
}
|
||||
name := parentIdent.GoName + "_" + string(desc.Name())
|
||||
return &EnumValue{
|
||||
Desc: desc,
|
||||
GoIdent: GoIdent{
|
||||
GoName: name,
|
||||
GoImportPath: f.GoImportPath,
|
||||
},
|
||||
Path: pathAppend(enum.Path, enumValueField, int32(desc.Index())),
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// A GeneratedFile is a generated file.
|
||||
@ -432,11 +495,7 @@ func (g *GeneratedFile) P(v ...interface{}) {
|
||||
for _, x := range v {
|
||||
switch x := x.(type) {
|
||||
case GoIdent:
|
||||
if x.GoImportPath != g.goImportPath {
|
||||
fmt.Fprint(&g.buf, g.goPackageName(x.GoImportPath))
|
||||
fmt.Fprint(&g.buf, ".")
|
||||
}
|
||||
fmt.Fprint(&g.buf, x.GoName)
|
||||
fmt.Fprint(&g.buf, g.QualifiedGoIdent(x))
|
||||
default:
|
||||
fmt.Fprint(&g.buf, x)
|
||||
}
|
||||
@ -444,6 +503,27 @@ func (g *GeneratedFile) P(v ...interface{}) {
|
||||
fmt.Fprintln(&g.buf)
|
||||
}
|
||||
|
||||
// QualifiedGoIdent returns the string to use for a Go identifier.
|
||||
//
|
||||
// If the identifier is from a different Go package than the generated file,
|
||||
// the returned name will be qualified (package.name) and an import statement
|
||||
// for the identifier's package will be included in the file.
|
||||
func (g *GeneratedFile) QualifiedGoIdent(ident GoIdent) string {
|
||||
if ident.GoImportPath == g.goImportPath {
|
||||
return ident.GoName
|
||||
}
|
||||
if packageName, ok := g.packageNames[ident.GoImportPath]; ok {
|
||||
return string(packageName) + "." + ident.GoName
|
||||
}
|
||||
packageName := cleanPackageName(baseName(string(ident.GoImportPath)))
|
||||
for i, orig := 1, packageName; g.usedPackageNames[packageName]; i++ {
|
||||
packageName = orig + GoPackageName(strconv.Itoa(i))
|
||||
}
|
||||
g.packageNames[ident.GoImportPath] = packageName
|
||||
g.usedPackageNames[packageName] = true
|
||||
return string(packageName) + "." + ident.GoName
|
||||
}
|
||||
|
||||
func (g *GeneratedFile) goPackageName(importPath GoImportPath) GoPackageName {
|
||||
if name, ok := g.packageNames[importPath]; ok {
|
||||
return name
|
||||
@ -522,7 +602,7 @@ const (
|
||||
// field numbers in FileDescriptorProto
|
||||
filePackageField = 2 // package
|
||||
fileMessageField = 4 // message_type
|
||||
fileenumField = 5 // enum_type
|
||||
fileEnumField = 5 // enum_type
|
||||
// field numbers in DescriptorProto
|
||||
messageFieldField = 2 // field
|
||||
messageMessageField = 3 // nested_type
|
||||
|
Loading…
x
Reference in New Issue
Block a user