@@ -2,14 +2,13 @@ package descriptor
22
33import (
44 "fmt"
5- "path"
6- "path/filepath"
75 "strings"
86
97 "github.com/golang/glog"
108 "github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor/openapiconfig"
119 "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options"
1210 "google.golang.org/genproto/googleapis/api/annotations"
11+ "google.golang.org/protobuf/compiler/protogen"
1312 "google.golang.org/protobuf/types/descriptorpb"
1413 "google.golang.org/protobuf/types/pluginpb"
1514)
@@ -28,9 +27,6 @@ type Registry struct {
2827 // prefix is a prefix to be inserted to golang package paths generated from proto package names.
2928 prefix string
3029
31- // 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.
32- importPath string
33-
3430 // pkgMap is a user-specified mapping from file path to proto package.
3531 pkgMap map [string ]string
3632
@@ -142,39 +138,42 @@ func NewRegistry() *Registry {
142138
143139// Load loads definitions of services, methods, messages, enumerations and fields from "req".
144140func (r * Registry ) Load (req * pluginpb.CodeGeneratorRequest ) error {
145- for _ , file := range req .GetProtoFile () {
146- r .loadFile (file )
141+ gen , err := protogen.Options {}.New (req )
142+ if err != nil {
143+ return err
147144 }
145+ return r .load (gen )
146+ }
148147
149- var targetPkg string
150- for _ , name := range req .FileToGenerate {
151- target := r .files [name ]
152- if target == nil {
153- return fmt .Errorf ("no such file: %s" , name )
154- }
155- name := r .packageIdentityName (target .FileDescriptorProto )
156- if targetPkg == "" {
157- targetPkg = name
158- } else {
159- if targetPkg != name {
160- return fmt .Errorf ("inconsistent package names: %s %s" , targetPkg , name )
161- }
162- }
148+ func (r * Registry ) LoadFromPlugin (gen * protogen.Plugin ) error {
149+ return r .load (gen )
150+ }
151+
152+ func (r * Registry ) load (gen * protogen.Plugin ) error {
153+ for filePath , f := range gen .FilesByPath {
154+ r .loadFile (filePath , f )
155+ }
163156
164- if err := r .loadServices (target ); err != nil {
157+ for filePath , f := range gen .FilesByPath {
158+ if ! f .Generate {
159+ continue
160+ }
161+ file := r .files [filePath ]
162+ if err := r .loadServices (file ); err != nil {
165163 return err
166164 }
167165 }
166+
168167 return nil
169168}
170169
171170// loadFile loads messages, enumerations and fields from "file".
172171// It does not loads services and methods in "file". You need to call
173172// loadServices after loadFiles is called for all files to load services and methods.
174- func (r * Registry ) loadFile (file * descriptorpb. FileDescriptorProto ) {
173+ func (r * Registry ) loadFile (filePath string , file * protogen. File ) {
175174 pkg := GoPackage {
176- Path : r . goPackagePath (file ),
177- Name : r . defaultGoPackageName (file ),
175+ Path : string (file . GoImportPath ),
176+ Name : string (file . GoPackageName ),
178177 }
179178 if r .standalone {
180179 pkg .Alias = "ext" + strings .Title (pkg .Name )
@@ -190,13 +189,14 @@ func (r *Registry) loadFile(file *descriptorpb.FileDescriptorProto) {
190189 }
191190 }
192191 f := & File {
193- FileDescriptorProto : file ,
194- GoPkg : pkg ,
192+ FileDescriptorProto : file .Proto ,
193+ GoPkg : pkg ,
194+ GeneratedFilenamePrefix : file .GeneratedFilenamePrefix ,
195195 }
196196
197- r .files [file . GetName () ] = f
198- r .registerMsg (f , nil , file .GetMessageType () )
199- r .registerEnum (f , nil , file .GetEnumType () )
197+ r .files [filePath ] = f
198+ r .registerMsg (f , nil , file .Proto . MessageType )
199+ r .registerEnum (f , nil , file .Proto . EnumType )
200200}
201201
202202func (r * Registry ) registerMsg (file * File , outerPath []string , msgs []* descriptorpb.DescriptorProto ) {
@@ -351,13 +351,6 @@ func (r *Registry) SetStandalone(standalone bool) {
351351 r .standalone = standalone
352352}
353353
354- // SetImportPath registers the importPath which is used as the package if no
355- // input files declare go_package. If it contains slashes, everything up to the
356- // rightmost slash is ignored.
357- func (r * Registry ) SetImportPath (importPath string ) {
358- r .importPath = importPath
359- }
360-
361354// ReserveGoPackageAlias reserves the unique alias of go package.
362355// If succeeded, the alias will be never used for other packages in generated go files.
363356// If failed, the alias is already taken by another package, so you need to use another
@@ -373,27 +366,6 @@ func (r *Registry) ReserveGoPackageAlias(alias, pkgpath string) error {
373366 return nil
374367}
375368
376- // goPackagePath returns the go package path which go files generated from "f" should have.
377- // It respects the mapping registered by AddPkgMap if exists. Or use go_package as import path
378- // if it includes a slash, Otherwide, it generates a path from the file name of "f".
379- func (r * Registry ) goPackagePath (f * descriptorpb.FileDescriptorProto ) string {
380- name := f .GetName ()
381- if pkg , ok := r .pkgMap [name ]; ok {
382- return path .Join (r .prefix , pkg )
383- }
384-
385- gopkg := f .Options .GetGoPackage ()
386- idx := strings .LastIndex (gopkg , "/" )
387- if idx >= 0 {
388- if sc := strings .LastIndex (gopkg , ";" ); sc > 0 {
389- gopkg = gopkg [:sc + 1 - 1 ]
390- }
391- return gopkg
392- }
393-
394- return path .Join (r .prefix , path .Dir (name ))
395- }
396-
397369// GetAllFQMNs returns a list of all FQMNs
398370func (r * Registry ) GetAllFQMNs () []string {
399371 var keys []string
@@ -577,57 +549,6 @@ func (r *Registry) GetOmitPackageDoc() bool {
577549 return r .omitPackageDoc
578550}
579551
580- // sanitizePackageName replaces unallowed character in package name
581- // with allowed character.
582- func sanitizePackageName (pkgName string ) string {
583- pkgName = strings .Replace (pkgName , "." , "_" , - 1 )
584- pkgName = strings .Replace (pkgName , "-" , "_" , - 1 )
585- return pkgName
586- }
587-
588- // defaultGoPackageName returns the default go package name to be used for go files generated from "f".
589- // You might need to use an unique alias for the package when you import it. Use ReserveGoPackageAlias to get a unique alias.
590- func (r * Registry ) defaultGoPackageName (f * descriptorpb.FileDescriptorProto ) string {
591- name := r .packageIdentityName (f )
592- return sanitizePackageName (name )
593- }
594-
595- // packageIdentityName returns the identity of packages.
596- // protoc-gen-grpc-gateway rejects CodeGenerationRequests which contains more than one packages
597- // as protoc-gen-go does.
598- func (r * Registry ) packageIdentityName (f * descriptorpb.FileDescriptorProto ) string {
599- if f .Options != nil && f .Options .GoPackage != nil {
600- gopkg := f .Options .GetGoPackage ()
601- idx := strings .LastIndex (gopkg , "/" )
602- if idx < 0 {
603- gopkg = gopkg [idx + 1 :]
604- }
605-
606- gopkg = gopkg [idx + 1 :]
607- // package name is overrided with the string after the
608- // ';' character
609- sc := strings .IndexByte (gopkg , ';' )
610- if sc < 0 {
611- return sanitizePackageName (gopkg )
612-
613- }
614- return sanitizePackageName (gopkg [sc + 1 :])
615- }
616- if p := r .importPath ; len (p ) != 0 {
617- if i := strings .LastIndex (p , "/" ); i >= 0 {
618- p = p [i + 1 :]
619- }
620- return p
621- }
622-
623- if f .Package == nil {
624- base := filepath .Base (f .GetName ())
625- ext := filepath .Ext (base )
626- return strings .TrimSuffix (base , ext )
627- }
628- return f .GetPackage ()
629- }
630-
631552// RegisterOpenAPIOptions registers OpenAPI options
632553func (r * Registry ) RegisterOpenAPIOptions (opts * openapiconfig.OpenAPIOptions ) error {
633554 if opts == nil {
0 commit comments