@@ -15,10 +15,14 @@ load("//bazel/common:proto_common.bzl", "proto_common")
15
15
load ("//bazel/common:proto_info.bzl" , "ProtoInfo" )
16
16
load ("//bazel/private:toolchain_helpers.bzl" , "toolchains" )
17
17
18
- STRICT_DEPS_FLAG_TEMPLATE = (
19
- #
18
+ DIRECT_DEPS_FLAG_TEMPLATE = (
20
19
"--direct_dependencies_violation_msg=" +
21
- "%%s is imported, but %s doesn't directly depend on a proto_library that 'srcs' it."
20
+ "%%s is imported, but %s doesn't have direct `deps` on a proto_library that 'srcs' it."
21
+ )
22
+
23
+ OPTION_DEPS_FLAG_TEMPLATE = (
24
+ "--option_dependencies_violation_msg=" +
25
+ "%%s is option imported, but %s doesn't have direct `option_deps` on a proto_library that 'srcs' it."
22
26
)
23
27
24
28
def _check_srcs_package (target_package , srcs ):
@@ -63,6 +67,7 @@ def _proto_library_impl(ctx):
63
67
_check_srcs_package (ctx .label .package , ctx .attr .srcs )
64
68
srcs = ctx .files .srcs
65
69
deps = [dep [ProtoInfo ] for dep in ctx .attr .deps ]
70
+ option_deps = [dep [ProtoInfo ] for dep in ctx .attr .option_deps ]
66
71
exports = [dep [ProtoInfo ] for dep in ctx .attr .exports ]
67
72
import_prefix = _get_import_prefix (ctx )
68
73
strip_import_prefix = _get_strip_import_prefix (ctx )
@@ -77,17 +82,19 @@ def _proto_library_impl(ctx):
77
82
78
83
proto_path , virtual_srcs = _process_srcs (ctx , srcs , import_prefix , strip_import_prefix )
79
84
descriptor_set = ctx .actions .declare_file (ctx .label .name + "-descriptor-set.proto.bin" )
85
+
80
86
proto_info = ProtoInfo (
81
87
srcs = virtual_srcs ,
82
88
deps = deps ,
83
89
descriptor_set = descriptor_set ,
90
+ option_deps = option_deps ,
84
91
proto_path = proto_path ,
85
92
workspace_root = ctx .label .workspace_root ,
86
93
bin_dir = ctx .bin_dir .path ,
87
94
allow_exports = ctx .attr .allow_exports ,
88
95
)
89
96
90
- _write_descriptor_set (ctx , proto_info , deps , exports , descriptor_set )
97
+ _write_descriptor_set (ctx , proto_info , deps , option_deps , exports , descriptor_set )
91
98
92
99
# We assume that the proto sources will not have conflicting artifacts
93
100
# with the same root relative path
@@ -154,13 +161,13 @@ def _symlink_to_virtual_imports(ctx, srcs, import_prefix, strip_import_prefix):
154
161
virtual_srcs .append (virtual_src )
155
162
return proto_path , virtual_srcs
156
163
157
- def _write_descriptor_set (ctx , proto_info , deps , exports , descriptor_set ):
164
+ def _write_descriptor_set (ctx , proto_info , deps , option_deps , exports , descriptor_set ):
158
165
"""Writes descriptor set."""
159
166
if proto_info .direct_sources == []:
160
167
ctx .actions .write (descriptor_set , "" )
161
168
return
162
169
163
- dependencies_descriptor_sets = depset (transitive = [dep .transitive_descriptor_sets for dep in deps ])
170
+ dependencies_descriptor_sets = depset (transitive = [dep .transitive_descriptor_sets for dep in deps + option_deps ])
164
171
165
172
args = ctx .actions .args ()
166
173
@@ -191,7 +198,22 @@ def _write_descriptor_set(ctx, proto_info, deps, exports, descriptor_set):
191
198
args .add ("--direct_dependencies=" )
192
199
193
200
# Set `-direct_dependencies_violation_msg=`
194
- args .add (ctx .label , format = STRICT_DEPS_FLAG_TEMPLATE )
201
+ args .add (ctx .label , format = DIRECT_DEPS_FLAG_TEMPLATE )
202
+
203
+ # option_deps can't be set unless sources is non-empty.
204
+ option_importable_sources = depset (
205
+ direct = proto_info .direct_sources ,
206
+ transitive = [dep .check_deps_sources for dep in option_deps ],
207
+ )
208
+ args .add_joined (
209
+ "--option_dependencies" ,
210
+ option_importable_sources ,
211
+ map_each = proto_common .get_import_path ,
212
+ join_with = ":" ,
213
+ )
214
+
215
+ # Set `-option_dependencies_violation_msg=`
216
+ args .add (ctx .label , format = OPTION_DEPS_FLAG_TEMPLATE )
195
217
196
218
strict_imports = ctx .attr ._strict_public_imports [BuildSettingInfo ].value
197
219
if strict_imports :
@@ -206,6 +228,7 @@ def _write_descriptor_set(ctx, proto_info, deps, exports, descriptor_set):
206
228
map_each = proto_common .get_import_path ,
207
229
join_with = ":" ,
208
230
)
231
+
209
232
if proto_common .INCOMPATIBLE_ENABLE_PROTO_TOOLCHAIN_RESOLUTION :
210
233
toolchain = ctx .toolchains [toolchains .PROTO_TOOLCHAIN ]
211
234
if not toolchain :
@@ -283,6 +306,13 @@ This pattern can be used to e.g. export a public api under a persistent name."""
283
306
doc = """
284
307
The list of other <code>proto_library</code> rules that the target depends upon.
285
308
A <code>proto_library</code> may only depend on other <code>proto_library</code>
309
+ targets. It may not depend on language-specific libraries.""" ,
310
+ ),
311
+ "option_deps" : attr .label_list (
312
+ providers = [ProtoInfo ],
313
+ doc = """
314
+ The list of other <code>proto_library</code> rules that the target depends upon for options only.
315
+ A <code>proto_library</code> may only depend on other <code>proto_library</code>
286
316
targets. It may not depend on language-specific libraries.""" ,
287
317
),
288
318
"exports" : attr .label_list (
0 commit comments