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  }