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