Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor registry and generator to use protogen #1756

Merged
merged 6 commits into from
Oct 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -373,20 +373,14 @@ google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.0.0/go.mod h1:6Kw0yEErY5E/yWrBt
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967 h1:DwkfSP6tZMxKX50J0dBSqEgJvJdFYP1Gvzbjtvkmrug=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0 h1:qdOKuR/EIArgaWNjetjgTzgVTAZ+S/WXVrq9HW9zimw=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0 h1:cJv5/xdbk1NnMPR1VP9+HU6gupuG9MLBoH1r6RHZ2MY=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
2 changes: 2 additions & 0 deletions internal/descriptor/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ go_library(
"@com_github_ghodss_yaml//:go_default_library",
"@com_github_golang_glog//:go_default_library",
"@go_googleapis//google/api:annotations_go_proto",
"@org_golang_google_protobuf//compiler/protogen:go_default_library",
"@org_golang_google_protobuf//encoding/protojson:go_default_library",
"@org_golang_google_protobuf//proto:go_default_library",
"@org_golang_google_protobuf//types/descriptorpb:go_default_library",
Expand All @@ -43,6 +44,7 @@ go_test(
"//internal/descriptor/openapiconfig:go_default_library",
"//internal/httprule:go_default_library",
"//protoc-gen-openapiv2/options:go_default_library",
"@org_golang_google_protobuf//compiler/protogen:go_default_library",
"@org_golang_google_protobuf//encoding/prototext:go_default_library",
"@org_golang_google_protobuf//proto:go_default_library",
"@org_golang_google_protobuf//types/descriptorpb:go_default_library",
Expand Down
139 changes: 30 additions & 109 deletions internal/descriptor/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@ package descriptor

import (
"fmt"
"path"
"path/filepath"
"strings"

"github.com/golang/glog"
"github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor/openapiconfig"
"github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options"
"google.golang.org/genproto/googleapis/api/annotations"
"google.golang.org/protobuf/compiler/protogen"
"google.golang.org/protobuf/types/descriptorpb"
"google.golang.org/protobuf/types/pluginpb"
)
Expand All @@ -28,9 +27,6 @@ type Registry struct {
// prefix is a prefix to be inserted to golang package paths generated from proto package names.
prefix string

// importPath is used as the package if no input files declare go_package. If it contains slashes, everything up to the rightmost slash is ignored.
importPath string

// pkgMap is a user-specified mapping from file path to proto package.
pkgMap map[string]string

Expand Down Expand Up @@ -142,39 +138,42 @@ func NewRegistry() *Registry {

// Load loads definitions of services, methods, messages, enumerations and fields from "req".
func (r *Registry) Load(req *pluginpb.CodeGeneratorRequest) error {
for _, file := range req.GetProtoFile() {
r.loadFile(file)
gen, err := protogen.Options{}.New(req)
if err != nil {
return err
}
return r.load(gen)
}

var targetPkg string
for _, name := range req.FileToGenerate {
target := r.files[name]
if target == nil {
return fmt.Errorf("no such file: %s", name)
}
name := r.packageIdentityName(target.FileDescriptorProto)
if targetPkg == "" {
targetPkg = name
} else {
if targetPkg != name {
return fmt.Errorf("inconsistent package names: %s %s", targetPkg, name)
}
}
func (r *Registry) LoadFromPlugin(gen *protogen.Plugin) error {
return r.load(gen)
}

func (r *Registry) load(gen *protogen.Plugin) error {
for filePath, f := range gen.FilesByPath {
r.loadFile(filePath, f)
}

if err := r.loadServices(target); err != nil {
for filePath, f := range gen.FilesByPath {
if !f.Generate {
continue
}
file := r.files[filePath]
if err := r.loadServices(file); err != nil {
return err
}
}

return nil
}

// loadFile loads messages, enumerations and fields from "file".
// It does not loads services and methods in "file". You need to call
// loadServices after loadFiles is called for all files to load services and methods.
func (r *Registry) loadFile(file *descriptorpb.FileDescriptorProto) {
func (r *Registry) loadFile(filePath string, file *protogen.File) {
pkg := GoPackage{
Path: r.goPackagePath(file),
Name: r.defaultGoPackageName(file),
Path: string(file.GoImportPath),
Name: string(file.GoPackageName),
}
if r.standalone {
pkg.Alias = "ext" + strings.Title(pkg.Name)
Expand All @@ -190,13 +189,14 @@ func (r *Registry) loadFile(file *descriptorpb.FileDescriptorProto) {
}
}
f := &File{
FileDescriptorProto: file,
GoPkg: pkg,
FileDescriptorProto: file.Proto,
GoPkg: pkg,
GeneratedFilenamePrefix: file.GeneratedFilenamePrefix,
}

r.files[file.GetName()] = f
r.registerMsg(f, nil, file.GetMessageType())
r.registerEnum(f, nil, file.GetEnumType())
r.files[filePath] = f
r.registerMsg(f, nil, file.Proto.MessageType)
r.registerEnum(f, nil, file.Proto.EnumType)
}

func (r *Registry) registerMsg(file *File, outerPath []string, msgs []*descriptorpb.DescriptorProto) {
Expand Down Expand Up @@ -351,13 +351,6 @@ func (r *Registry) SetStandalone(standalone bool) {
r.standalone = standalone
}

// SetImportPath registers the importPath which is used as the package if no
// input files declare go_package. If it contains slashes, everything up to the
// rightmost slash is ignored.
func (r *Registry) SetImportPath(importPath string) {
r.importPath = importPath
}

// ReserveGoPackageAlias reserves the unique alias of go package.
// If succeeded, the alias will be never used for other packages in generated go files.
// If failed, the alias is already taken by another package, so you need to use another
Expand All @@ -373,27 +366,6 @@ func (r *Registry) ReserveGoPackageAlias(alias, pkgpath string) error {
return nil
}

// goPackagePath returns the go package path which go files generated from "f" should have.
// It respects the mapping registered by AddPkgMap if exists. Or use go_package as import path
// if it includes a slash, Otherwide, it generates a path from the file name of "f".
func (r *Registry) goPackagePath(f *descriptorpb.FileDescriptorProto) string {
name := f.GetName()
if pkg, ok := r.pkgMap[name]; ok {
return path.Join(r.prefix, pkg)
}

gopkg := f.Options.GetGoPackage()
idx := strings.LastIndex(gopkg, "/")
if idx >= 0 {
if sc := strings.LastIndex(gopkg, ";"); sc > 0 {
gopkg = gopkg[:sc+1-1]
}
return gopkg
}

return path.Join(r.prefix, path.Dir(name))
}

// GetAllFQMNs returns a list of all FQMNs
func (r *Registry) GetAllFQMNs() []string {
var keys []string
Expand Down Expand Up @@ -577,57 +549,6 @@ func (r *Registry) GetOmitPackageDoc() bool {
return r.omitPackageDoc
}

// sanitizePackageName replaces unallowed character in package name
// with allowed character.
func sanitizePackageName(pkgName string) string {
pkgName = strings.Replace(pkgName, ".", "_", -1)
pkgName = strings.Replace(pkgName, "-", "_", -1)
return pkgName
}

// defaultGoPackageName returns the default go package name to be used for go files generated from "f".
// You might need to use an unique alias for the package when you import it. Use ReserveGoPackageAlias to get a unique alias.
func (r *Registry) defaultGoPackageName(f *descriptorpb.FileDescriptorProto) string {
name := r.packageIdentityName(f)
return sanitizePackageName(name)
}

// packageIdentityName returns the identity of packages.
// protoc-gen-grpc-gateway rejects CodeGenerationRequests which contains more than one packages
// as protoc-gen-go does.
func (r *Registry) packageIdentityName(f *descriptorpb.FileDescriptorProto) string {
if f.Options != nil && f.Options.GoPackage != nil {
gopkg := f.Options.GetGoPackage()
idx := strings.LastIndex(gopkg, "/")
if idx < 0 {
gopkg = gopkg[idx+1:]
}

gopkg = gopkg[idx+1:]
// package name is overrided with the string after the
// ';' character
sc := strings.IndexByte(gopkg, ';')
if sc < 0 {
return sanitizePackageName(gopkg)

}
return sanitizePackageName(gopkg[sc+1:])
}
if p := r.importPath; len(p) != 0 {
if i := strings.LastIndex(p, "/"); i >= 0 {
p = p[i+1:]
}
return p
}

if f.Package == nil {
base := filepath.Base(f.GetName())
ext := filepath.Ext(base)
return strings.TrimSuffix(base, ext)
}
return f.GetPackage()
}

// RegisterOpenAPIOptions registers OpenAPI options
func (r *Registry) RegisterOpenAPIOptions(opts *openapiconfig.OpenAPIOptions) error {
if opts == nil {
Expand Down
Loading