internal/cmd/generate-protos: generate internal descfield package
Generate a list of descriptor fields from the descriptor.proto itself
as an internal package. Use these fields for the internal implementation.
Change-Id: Ib1ab0c5c6deb332ba6c8018ef55136b7e5974944
Reviewed-on: https://go-review.googlesource.com/c/164864
Reviewed-by: Herbie Ong <herbie@google.com>
diff --git a/internal/cmd/generate-protos/main.go b/internal/cmd/generate-protos/main.go
index 8698346..cf7c688 100644
--- a/internal/cmd/generate-protos/main.go
+++ b/internal/cmd/generate-protos/main.go
@@ -12,6 +12,7 @@
"io/ioutil"
"os"
"os/exec"
+ "path"
"path/filepath"
"regexp"
"strings"
@@ -19,6 +20,7 @@
gengogrpc "github.com/golang/protobuf/v2/cmd/protoc-gen-go-grpc/internal_gengogrpc"
gengo "github.com/golang/protobuf/v2/cmd/protoc-gen-go/internal_gengo"
"github.com/golang/protobuf/v2/protogen"
+ "github.com/golang/protobuf/v2/reflect/protoreflect"
)
func init() {
@@ -31,6 +33,7 @@
if file.Generate {
gengo.GenerateFile(gen, file)
gengogrpc.GenerateFile(gen, file)
+ generateDescriptorFields(gen, file)
}
}
return nil
@@ -43,6 +46,15 @@
run bool
protoRoot string
repoRoot string
+
+ generatedPreamble = []string{
+ "// Copyright 2019 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.",
+ "",
+ "// Code generated by generate-protos. DO NOT EDIT.",
+ "",
+ }
)
func main() {
@@ -152,6 +164,44 @@
check(err)
}
+// generateDescriptorFields generates an internal package for descriptor.proto.
+func generateDescriptorFields(gen *protogen.Plugin, file *protogen.File) {
+ if file.Desc.Path() != "google/protobuf/descriptor.proto" {
+ return
+ }
+
+ const importPath = "github.com/golang/protobuf/v2/internal/descfield"
+ g := gen.NewGeneratedFile(importPath+"/field_gen.go", importPath)
+ for _, s := range generatedPreamble {
+ g.P(s)
+ }
+ g.P("// Package descfield contains constants for field numbers in descriptor.proto.")
+ g.P("package ", path.Base(importPath))
+ g.P("")
+
+ var processMessages func([]*protogen.Message)
+ processMessages = func(messages []*protogen.Message) {
+ for _, message := range messages {
+ g.P("// Field numbers for ", message.Desc.FullName(), ".")
+ g.P("const (")
+ for _, field := range message.Fields {
+ fd := field.Desc
+ typeName := fd.Kind().String()
+ switch fd.Kind() {
+ case protoreflect.EnumKind:
+ typeName = string(fd.EnumType().FullName())
+ case protoreflect.MessageKind, protoreflect.GroupKind:
+ typeName = string(fd.MessageType().FullName())
+ }
+ g.P(message.GoIdent.GoName, "_", field.GoName, "=", fd.Number(), "// ", fd.Cardinality(), " ", typeName)
+ }
+ g.P(")")
+ processMessages(message.Messages)
+ }
+ }
+ processMessages(file.Messages)
+}
+
func syncOutput(dstDir, srcDir string) {
filepath.Walk(srcDir, func(srcPath string, _ os.FileInfo, _ error) error {
if !strings.HasSuffix(srcPath, ".go") && !strings.HasSuffix(srcPath, ".meta") {