github.com/stackb/rules_proto@v0.0.0-20240221195024-5428336c51f1/pkg/plugin/gogo/protobuf/protoc-gen-gogo.go (about) 1 package protobuf 2 3 import ( 4 "path" 5 "strings" 6 7 "github.com/bazelbuild/bazel-gazelle/label" 8 "github.com/stackb/rules_proto/pkg/protoc" 9 ) 10 11 const gogoGrpcPluginOption = "plugins=grpc" 12 13 func init() { 14 for _, variant := range []string{ 15 "combo", 16 "gogo", 17 "gogofast", 18 "gogofaster", 19 "gogoslick", 20 "gogotypes", 21 "gostring", 22 } { 23 protoc.Plugins().MustRegisterPlugin(&GogoPlugin{variant}) 24 } 25 } 26 27 // GogoPlugin implements Plugin for the the gogo_* family of plugins. 28 type GogoPlugin struct { 29 variant string 30 } 31 32 // Name implements part of the Plugin interface. 33 func (p *GogoPlugin) Name() string { 34 return "gogo:protobuf:protoc-gen-" + p.variant 35 } 36 37 // Configure implements part of the Plugin interface. 38 func (p *GogoPlugin) Configure(ctx *protoc.PluginContext) *protoc.PluginConfiguration { 39 if !p.shouldApply(ctx.ProtoLibrary) { 40 return nil 41 } 42 43 grpcOptions := p.grpcOptions(ctx.Rel, ctx.PluginConfig, ctx.ProtoLibrary) 44 return &protoc.PluginConfiguration{ 45 Label: label.New("build_stack_rules_proto", "plugin/gogo/protobuf", "protoc-gen-"+p.variant), 46 Outputs: p.outputs(ctx.ProtoLibrary), 47 Options: append(grpcOptions, ctx.PluginConfig.GetOptions()...), 48 } 49 } 50 51 func (p *GogoPlugin) shouldApply(lib protoc.ProtoLibrary) bool { 52 for _, f := range lib.Files() { 53 if f.HasMessages() || f.HasEnums() || f.HasServices() { 54 return true 55 } 56 } 57 return false 58 } 59 60 func (p *GogoPlugin) outputs(lib protoc.ProtoLibrary) []string { 61 srcs := make([]string, 0) 62 for _, f := range lib.Files() { 63 base := f.Name 64 pkg := f.Package() 65 // see https://github.com/gogo/protobuf/blob/master/protoc-gen-gogo/generator/generator.go#L347 66 if goPackage, _, ok := protoc.GoPackageOption(f.Options()); ok { 67 base = path.Join(goPackage, base) 68 } else if pkg.Name != "" { 69 base = path.Join(strings.ReplaceAll(pkg.Name, ".", "/"), base) 70 } 71 srcs = append(srcs, base+".pb.go") 72 } 73 return srcs 74 } 75 76 func (p *GogoPlugin) grpcOptions(rel string, cfg protoc.LanguagePluginConfig, lib protoc.ProtoLibrary) []string { 77 // if the configuration specifically states that we don't want grpc, return 78 // early 79 if want, ok := cfg.Options[gogoGrpcPluginOption]; ok && !want { 80 return nil 81 } 82 83 for _, f := range lib.Files() { 84 if f.HasServices() { 85 return []string{gogoGrpcPluginOption} 86 } 87 } 88 89 return nil 90 }