1616 "@bazel_skylib//lib:paths.bzl" ,
1717 "paths" ,
1818)
19+ load (
20+ "@rules_proto//proto:proto_common.bzl" ,
21+ "ProtoLangToolchainInfo" ,
22+ proto_toolchains = "toolchains" ,
23+ )
1924load (
2025 "//go:def.bzl" ,
2126 "GoLibrary" ,
3136 "go_reset_target" ,
3237)
3338
39+ # This is actually a misuse of Proto toolchains: The proper way to use `protoc` would be to go
40+ # through a Go-specific `proto_lang_toolchain` and use the methods on `proto_common` to interact
41+ # with `protoc`. Since rules_go has a very bespoke setup with customizable compilers and the need
42+ # to apply reset transitions in case `protoc` *is* built from source, this would require major
43+ # changes.
44+ # TODO: Revisit this after --incompatible_enable_proto_toolchain_resolution has been enabled by
45+ # default.
46+ _PROTO_TOOLCHAIN_TYPE = "@rules_proto//proto:toolchain_type"
47+
3448GoProtoCompiler = provider (
3549 doc = "Information and dependencies needed to generate Go code from protos" ,
3650 fields = {
@@ -104,7 +118,7 @@ def go_proto_compile(go, compiler, protos, imports, importpath):
104118 transitive_descriptor_sets = depset (direct = [], transitive = desc_sets )
105119
106120 args = go .actions .args ()
107- args .add ("-protoc" , compiler .internal .protoc )
121+ args .add ("-protoc" , compiler .internal .protoc . executable )
108122 args .add ("-importpath" , importpath )
109123 args .add ("-out_path" , outpath )
110124 args .add ("-plugin" , compiler .internal .plugin )
@@ -122,7 +136,6 @@ def go_proto_compile(go, compiler, protos, imports, importpath):
122136 inputs = depset (
123137 direct = [
124138 compiler .internal .go_protoc ,
125- compiler .internal .protoc ,
126139 compiler .internal .plugin ,
127140 ],
128141 transitive = [transitive_descriptor_sets ],
@@ -132,6 +145,7 @@ def go_proto_compile(go, compiler, protos, imports, importpath):
132145 mnemonic = "GoProtocGen" ,
133146 executable = compiler .internal .go_protoc ,
134147 toolchain = GO_TOOLCHAIN_LABEL ,
148+ tools = [compiler .internal .protoc ],
135149 arguments = [args ],
136150 env = go .env ,
137151 # We may need the shell environment (potentially augmented with --action_env)
@@ -172,6 +186,11 @@ def _go_proto_compiler_impl(ctx):
172186 go = go_context (ctx )
173187 library = go .new_library (go )
174188 source = go .library_to_source (go , ctx .attr , library , ctx .coverage_instrumented ())
189+ proto_toolchain = proto_toolchains .find_toolchain (
190+ ctx ,
191+ legacy_attr = "_legacy_proto_toolchain" ,
192+ toolchain_type = _PROTO_TOOLCHAIN_TYPE ,
193+ )
175194 return [
176195 GoProtoCompiler (
177196 deps = ctx .attr .deps ,
@@ -181,7 +200,7 @@ def _go_proto_compiler_impl(ctx):
181200 options = ctx .attr .options ,
182201 suffix = ctx .attr .suffix ,
183202 suffixes = ctx .attr .suffixes ,
184- protoc = ctx . executable . _protoc ,
203+ protoc = proto_toolchain . proto_compiler ,
185204 go_protoc = ctx .executable ._go_protoc ,
186205 plugin = ctx .executable .plugin ,
187206 import_path_option = ctx .attr .import_path_option ,
@@ -210,16 +229,20 @@ _go_proto_compiler = rule(
210229 cfg = "exec" ,
211230 default = "//go/tools/builders:go-protoc" ,
212231 ),
213- "_protoc" : attr .label (
214- executable = True ,
215- cfg = "exec" ,
216- default = "//proto:protoc" ,
217- ),
218232 "_go_context_data" : attr .label (
219233 default = "//:go_context_data" ,
220234 ),
221- },
222- toolchains = [GO_TOOLCHAIN ],
235+ } | proto_toolchains .if_legacy_toolchain ({
236+ "_legacy_proto_toolchain" : attr .label (
237+ # Setting cfg = "exec" here as the legacy_proto_toolchain target
238+ # already needs to apply the non_go_tool_transition. Flipping the
239+ # two would be more idiomatic, but proto_toolchains.find_toolchain
240+ # doesn't support split transitions.
241+ cfg = "exec" ,
242+ default = "//proto/private:legacy_proto_toolchain" ,
243+ ),
244+ }),
245+ toolchains = [GO_TOOLCHAIN ] + proto_toolchains .use_toolchain (_PROTO_TOOLCHAIN_TYPE ),
223246)
224247
225248def go_proto_compiler (name , ** kwargs ):
0 commit comments