xref: /aosp_15_r20/external/cronet/third_party/protobuf/protobuf.bzl (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Workerload("@bazel_skylib//lib:versions.bzl", "versions")
2*6777b538SAndroid Build Coastguard Workerload("@rules_cc//cc:defs.bzl", "cc_library")
3*6777b538SAndroid Build Coastguard Workerload("@rules_proto//proto:defs.bzl", "ProtoInfo")
4*6777b538SAndroid Build Coastguard Workerload("@rules_python//python:defs.bzl", "py_library", "py_test")
5*6777b538SAndroid Build Coastguard Worker
6*6777b538SAndroid Build Coastguard Workerdef _GetPath(ctx, path):
7*6777b538SAndroid Build Coastguard Worker    if ctx.label.workspace_root:
8*6777b538SAndroid Build Coastguard Worker        return ctx.label.workspace_root + "/" + path
9*6777b538SAndroid Build Coastguard Worker    else:
10*6777b538SAndroid Build Coastguard Worker        return path
11*6777b538SAndroid Build Coastguard Worker
12*6777b538SAndroid Build Coastguard Workerdef _IsNewExternal(ctx):
13*6777b538SAndroid Build Coastguard Worker    # Bazel 0.4.4 and older have genfiles paths that look like:
14*6777b538SAndroid Build Coastguard Worker    #   bazel-out/local-fastbuild/genfiles/external/repo/foo
15*6777b538SAndroid Build Coastguard Worker    # After the exec root rearrangement, they look like:
16*6777b538SAndroid Build Coastguard Worker    #   ../repo/bazel-out/local-fastbuild/genfiles/foo
17*6777b538SAndroid Build Coastguard Worker    return ctx.label.workspace_root.startswith("../")
18*6777b538SAndroid Build Coastguard Worker
19*6777b538SAndroid Build Coastguard Workerdef _GenDir(ctx):
20*6777b538SAndroid Build Coastguard Worker    if _IsNewExternal(ctx):
21*6777b538SAndroid Build Coastguard Worker        # We are using the fact that Bazel 0.4.4+ provides repository-relative paths
22*6777b538SAndroid Build Coastguard Worker        # for ctx.genfiles_dir.
23*6777b538SAndroid Build Coastguard Worker        return ctx.genfiles_dir.path + (
24*6777b538SAndroid Build Coastguard Worker            "/" + ctx.attr.includes[0] if ctx.attr.includes and ctx.attr.includes[0] else ""
25*6777b538SAndroid Build Coastguard Worker        )
26*6777b538SAndroid Build Coastguard Worker
27*6777b538SAndroid Build Coastguard Worker    # This means that we're either in the old version OR the new version in the local repo.
28*6777b538SAndroid Build Coastguard Worker    # Either way, appending the source path to the genfiles dir works.
29*6777b538SAndroid Build Coastguard Worker    return ctx.var["GENDIR"] + "/" + _SourceDir(ctx)
30*6777b538SAndroid Build Coastguard Worker
31*6777b538SAndroid Build Coastguard Workerdef _SourceDir(ctx):
32*6777b538SAndroid Build Coastguard Worker    if not ctx.attr.includes:
33*6777b538SAndroid Build Coastguard Worker        return ctx.label.workspace_root
34*6777b538SAndroid Build Coastguard Worker    if not ctx.attr.includes[0]:
35*6777b538SAndroid Build Coastguard Worker        return _GetPath(ctx, ctx.label.package)
36*6777b538SAndroid Build Coastguard Worker    if not ctx.label.package:
37*6777b538SAndroid Build Coastguard Worker        return _GetPath(ctx, ctx.attr.includes[0])
38*6777b538SAndroid Build Coastguard Worker    return _GetPath(ctx, ctx.label.package + "/" + ctx.attr.includes[0])
39*6777b538SAndroid Build Coastguard Worker
40*6777b538SAndroid Build Coastguard Workerdef _CcHdrs(srcs, use_grpc_plugin = False):
41*6777b538SAndroid Build Coastguard Worker    ret = [s[:-len(".proto")] + ".pb.h" for s in srcs]
42*6777b538SAndroid Build Coastguard Worker    if use_grpc_plugin:
43*6777b538SAndroid Build Coastguard Worker        ret += [s[:-len(".proto")] + ".grpc.pb.h" for s in srcs]
44*6777b538SAndroid Build Coastguard Worker    return ret
45*6777b538SAndroid Build Coastguard Worker
46*6777b538SAndroid Build Coastguard Workerdef _CcSrcs(srcs, use_grpc_plugin = False):
47*6777b538SAndroid Build Coastguard Worker    ret = [s[:-len(".proto")] + ".pb.cc" for s in srcs]
48*6777b538SAndroid Build Coastguard Worker    if use_grpc_plugin:
49*6777b538SAndroid Build Coastguard Worker        ret += [s[:-len(".proto")] + ".grpc.pb.cc" for s in srcs]
50*6777b538SAndroid Build Coastguard Worker    return ret
51*6777b538SAndroid Build Coastguard Worker
52*6777b538SAndroid Build Coastguard Workerdef _CcOuts(srcs, use_grpc_plugin = False):
53*6777b538SAndroid Build Coastguard Worker    return _CcHdrs(srcs, use_grpc_plugin) + _CcSrcs(srcs, use_grpc_plugin)
54*6777b538SAndroid Build Coastguard Worker
55*6777b538SAndroid Build Coastguard Workerdef _PyOuts(srcs, use_grpc_plugin = False):
56*6777b538SAndroid Build Coastguard Worker    ret = [s[:-len(".proto")] + "_pb2.py" for s in srcs]
57*6777b538SAndroid Build Coastguard Worker    if use_grpc_plugin:
58*6777b538SAndroid Build Coastguard Worker        ret += [s[:-len(".proto")] + "_pb2_grpc.py" for s in srcs]
59*6777b538SAndroid Build Coastguard Worker    return ret
60*6777b538SAndroid Build Coastguard Worker
61*6777b538SAndroid Build Coastguard Workerdef _RelativeOutputPath(path, include, dest = ""):
62*6777b538SAndroid Build Coastguard Worker    if include == None:
63*6777b538SAndroid Build Coastguard Worker        return path
64*6777b538SAndroid Build Coastguard Worker
65*6777b538SAndroid Build Coastguard Worker    if not path.startswith(include):
66*6777b538SAndroid Build Coastguard Worker        fail("Include path %s isn't part of the path %s." % (include, path))
67*6777b538SAndroid Build Coastguard Worker
68*6777b538SAndroid Build Coastguard Worker    if include and include[-1] != "/":
69*6777b538SAndroid Build Coastguard Worker        include = include + "/"
70*6777b538SAndroid Build Coastguard Worker    if dest and dest[-1] != "/":
71*6777b538SAndroid Build Coastguard Worker        dest = dest + "/"
72*6777b538SAndroid Build Coastguard Worker
73*6777b538SAndroid Build Coastguard Worker    path = path[len(include):]
74*6777b538SAndroid Build Coastguard Worker    return dest + path
75*6777b538SAndroid Build Coastguard Worker
76*6777b538SAndroid Build Coastguard Workerdef _proto_gen_impl(ctx):
77*6777b538SAndroid Build Coastguard Worker    """General implementation for generating protos"""
78*6777b538SAndroid Build Coastguard Worker    srcs = ctx.files.srcs
79*6777b538SAndroid Build Coastguard Worker    deps = depset(direct=ctx.files.srcs)
80*6777b538SAndroid Build Coastguard Worker    source_dir = _SourceDir(ctx)
81*6777b538SAndroid Build Coastguard Worker    gen_dir = _GenDir(ctx).rstrip("/")
82*6777b538SAndroid Build Coastguard Worker    import_flags = []
83*6777b538SAndroid Build Coastguard Worker
84*6777b538SAndroid Build Coastguard Worker    if source_dir:
85*6777b538SAndroid Build Coastguard Worker        has_sources = any([src.is_source for src in srcs])
86*6777b538SAndroid Build Coastguard Worker        if has_sources:
87*6777b538SAndroid Build Coastguard Worker            import_flags += ["-I" + source_dir]
88*6777b538SAndroid Build Coastguard Worker    else:
89*6777b538SAndroid Build Coastguard Worker        import_flags += ["-I."]
90*6777b538SAndroid Build Coastguard Worker
91*6777b538SAndroid Build Coastguard Worker    has_generated = any([not src.is_source for src in srcs])
92*6777b538SAndroid Build Coastguard Worker    if has_generated:
93*6777b538SAndroid Build Coastguard Worker        import_flags += ["-I" + gen_dir]
94*6777b538SAndroid Build Coastguard Worker
95*6777b538SAndroid Build Coastguard Worker    import_flags = depset(direct=import_flags)
96*6777b538SAndroid Build Coastguard Worker
97*6777b538SAndroid Build Coastguard Worker    for dep in ctx.attr.deps:
98*6777b538SAndroid Build Coastguard Worker        if type(dep.proto.import_flags) == "list":
99*6777b538SAndroid Build Coastguard Worker            import_flags = depset(transitive=[import_flags], direct=dep.proto.import_flags)
100*6777b538SAndroid Build Coastguard Worker        else:
101*6777b538SAndroid Build Coastguard Worker            import_flags = depset(transitive=[import_flags, dep.proto.import_flags])
102*6777b538SAndroid Build Coastguard Worker        if type(dep.proto.deps) == "list":
103*6777b538SAndroid Build Coastguard Worker            deps = depset(transitive=[deps], direct=dep.proto.deps)
104*6777b538SAndroid Build Coastguard Worker        else:
105*6777b538SAndroid Build Coastguard Worker            deps = depset(transitive=[deps, dep.proto.deps])
106*6777b538SAndroid Build Coastguard Worker
107*6777b538SAndroid Build Coastguard Worker    if not ctx.attr.gen_cc and not ctx.attr.gen_py and not ctx.executable.plugin:
108*6777b538SAndroid Build Coastguard Worker        return struct(
109*6777b538SAndroid Build Coastguard Worker            proto = struct(
110*6777b538SAndroid Build Coastguard Worker                srcs = srcs,
111*6777b538SAndroid Build Coastguard Worker                import_flags = import_flags,
112*6777b538SAndroid Build Coastguard Worker                deps = deps,
113*6777b538SAndroid Build Coastguard Worker            ),
114*6777b538SAndroid Build Coastguard Worker        )
115*6777b538SAndroid Build Coastguard Worker
116*6777b538SAndroid Build Coastguard Worker    for src in srcs:
117*6777b538SAndroid Build Coastguard Worker        args = []
118*6777b538SAndroid Build Coastguard Worker
119*6777b538SAndroid Build Coastguard Worker        in_gen_dir = src.root.path == gen_dir
120*6777b538SAndroid Build Coastguard Worker        if in_gen_dir:
121*6777b538SAndroid Build Coastguard Worker            import_flags_real = []
122*6777b538SAndroid Build Coastguard Worker            for f in import_flags.to_list():
123*6777b538SAndroid Build Coastguard Worker                path = f.replace("-I", "")
124*6777b538SAndroid Build Coastguard Worker                import_flags_real.append("-I$(realpath -s %s)" % path)
125*6777b538SAndroid Build Coastguard Worker
126*6777b538SAndroid Build Coastguard Worker        outs = []
127*6777b538SAndroid Build Coastguard Worker        use_grpc_plugin = (ctx.attr.plugin_language == "grpc" and ctx.attr.plugin)
128*6777b538SAndroid Build Coastguard Worker        path_tpl = "$(realpath %s)" if in_gen_dir else "%s"
129*6777b538SAndroid Build Coastguard Worker        if ctx.attr.gen_cc:
130*6777b538SAndroid Build Coastguard Worker            args += [("--cpp_out=" + path_tpl) % gen_dir]
131*6777b538SAndroid Build Coastguard Worker            outs.extend(_CcOuts([src.basename], use_grpc_plugin = use_grpc_plugin))
132*6777b538SAndroid Build Coastguard Worker        if ctx.attr.gen_py:
133*6777b538SAndroid Build Coastguard Worker            args += [("--python_out=" + path_tpl) % gen_dir]
134*6777b538SAndroid Build Coastguard Worker            outs.extend(_PyOuts([src.basename], use_grpc_plugin = use_grpc_plugin))
135*6777b538SAndroid Build Coastguard Worker
136*6777b538SAndroid Build Coastguard Worker        outs = [ctx.actions.declare_file(out, sibling = src) for out in outs]
137*6777b538SAndroid Build Coastguard Worker        inputs = [src] + deps.to_list()
138*6777b538SAndroid Build Coastguard Worker        tools = [ctx.executable.protoc]
139*6777b538SAndroid Build Coastguard Worker        if ctx.executable.plugin:
140*6777b538SAndroid Build Coastguard Worker            plugin = ctx.executable.plugin
141*6777b538SAndroid Build Coastguard Worker            lang = ctx.attr.plugin_language
142*6777b538SAndroid Build Coastguard Worker            if not lang and plugin.basename.startswith("protoc-gen-"):
143*6777b538SAndroid Build Coastguard Worker                lang = plugin.basename[len("protoc-gen-"):]
144*6777b538SAndroid Build Coastguard Worker            if not lang:
145*6777b538SAndroid Build Coastguard Worker                fail("cannot infer the target language of plugin", "plugin_language")
146*6777b538SAndroid Build Coastguard Worker
147*6777b538SAndroid Build Coastguard Worker            outdir = "." if in_gen_dir else gen_dir
148*6777b538SAndroid Build Coastguard Worker
149*6777b538SAndroid Build Coastguard Worker            if ctx.attr.plugin_options:
150*6777b538SAndroid Build Coastguard Worker                outdir = ",".join(ctx.attr.plugin_options) + ":" + outdir
151*6777b538SAndroid Build Coastguard Worker            args += [("--plugin=protoc-gen-%s=" + path_tpl) % (lang, plugin.path)]
152*6777b538SAndroid Build Coastguard Worker            args += ["--%s_out=%s" % (lang, outdir)]
153*6777b538SAndroid Build Coastguard Worker            tools.append(plugin)
154*6777b538SAndroid Build Coastguard Worker
155*6777b538SAndroid Build Coastguard Worker        if not in_gen_dir:
156*6777b538SAndroid Build Coastguard Worker            ctx.actions.run(
157*6777b538SAndroid Build Coastguard Worker                inputs = inputs,
158*6777b538SAndroid Build Coastguard Worker                tools = tools,
159*6777b538SAndroid Build Coastguard Worker                outputs = outs,
160*6777b538SAndroid Build Coastguard Worker                arguments = args + import_flags.to_list() + [src.path],
161*6777b538SAndroid Build Coastguard Worker                executable = ctx.executable.protoc,
162*6777b538SAndroid Build Coastguard Worker                mnemonic = "ProtoCompile",
163*6777b538SAndroid Build Coastguard Worker                use_default_shell_env = True,
164*6777b538SAndroid Build Coastguard Worker            )
165*6777b538SAndroid Build Coastguard Worker        else:
166*6777b538SAndroid Build Coastguard Worker            for out in outs:
167*6777b538SAndroid Build Coastguard Worker                orig_command = " ".join(
168*6777b538SAndroid Build Coastguard Worker                    ["$(realpath %s)" % ctx.executable.protoc.path] + args +
169*6777b538SAndroid Build Coastguard Worker                    import_flags_real + [src.basename],
170*6777b538SAndroid Build Coastguard Worker                )
171*6777b538SAndroid Build Coastguard Worker                command = ";".join([
172*6777b538SAndroid Build Coastguard Worker                    'CMD="%s"' % orig_command,
173*6777b538SAndroid Build Coastguard Worker                    "cd %s" % src.dirname,
174*6777b538SAndroid Build Coastguard Worker                    "${CMD}",
175*6777b538SAndroid Build Coastguard Worker                    "cd -",
176*6777b538SAndroid Build Coastguard Worker                ])
177*6777b538SAndroid Build Coastguard Worker                generated_out = "/".join([gen_dir, out.basename])
178*6777b538SAndroid Build Coastguard Worker                if generated_out != out.path:
179*6777b538SAndroid Build Coastguard Worker                    command += ";mv %s %s" % (generated_out, out.path)
180*6777b538SAndroid Build Coastguard Worker                ctx.actions.run_shell(
181*6777b538SAndroid Build Coastguard Worker                    inputs = inputs,
182*6777b538SAndroid Build Coastguard Worker                    outputs = [out],
183*6777b538SAndroid Build Coastguard Worker                    command = command,
184*6777b538SAndroid Build Coastguard Worker                    mnemonic = "ProtoCompile",
185*6777b538SAndroid Build Coastguard Worker                    tools = tools,
186*6777b538SAndroid Build Coastguard Worker                    use_default_shell_env = True,
187*6777b538SAndroid Build Coastguard Worker                )
188*6777b538SAndroid Build Coastguard Worker
189*6777b538SAndroid Build Coastguard Worker    return struct(
190*6777b538SAndroid Build Coastguard Worker        proto = struct(
191*6777b538SAndroid Build Coastguard Worker            srcs = srcs,
192*6777b538SAndroid Build Coastguard Worker            import_flags = import_flags,
193*6777b538SAndroid Build Coastguard Worker            deps = deps,
194*6777b538SAndroid Build Coastguard Worker        ),
195*6777b538SAndroid Build Coastguard Worker    )
196*6777b538SAndroid Build Coastguard Worker
197*6777b538SAndroid Build Coastguard Workerproto_gen = rule(
198*6777b538SAndroid Build Coastguard Worker    attrs = {
199*6777b538SAndroid Build Coastguard Worker        "srcs": attr.label_list(allow_files = True),
200*6777b538SAndroid Build Coastguard Worker        "deps": attr.label_list(providers = ["proto"]),
201*6777b538SAndroid Build Coastguard Worker        "includes": attr.string_list(),
202*6777b538SAndroid Build Coastguard Worker        "protoc": attr.label(
203*6777b538SAndroid Build Coastguard Worker            cfg = "exec",
204*6777b538SAndroid Build Coastguard Worker            executable = True,
205*6777b538SAndroid Build Coastguard Worker            allow_single_file = True,
206*6777b538SAndroid Build Coastguard Worker            mandatory = True,
207*6777b538SAndroid Build Coastguard Worker        ),
208*6777b538SAndroid Build Coastguard Worker        "plugin": attr.label(
209*6777b538SAndroid Build Coastguard Worker            cfg = "exec",
210*6777b538SAndroid Build Coastguard Worker            allow_files = True,
211*6777b538SAndroid Build Coastguard Worker            executable = True,
212*6777b538SAndroid Build Coastguard Worker        ),
213*6777b538SAndroid Build Coastguard Worker        "plugin_language": attr.string(),
214*6777b538SAndroid Build Coastguard Worker        "plugin_options": attr.string_list(),
215*6777b538SAndroid Build Coastguard Worker        "gen_cc": attr.bool(),
216*6777b538SAndroid Build Coastguard Worker        "gen_py": attr.bool(),
217*6777b538SAndroid Build Coastguard Worker        "outs": attr.output_list(),
218*6777b538SAndroid Build Coastguard Worker    },
219*6777b538SAndroid Build Coastguard Worker    output_to_genfiles = True,
220*6777b538SAndroid Build Coastguard Worker    implementation = _proto_gen_impl,
221*6777b538SAndroid Build Coastguard Worker)
222*6777b538SAndroid Build Coastguard Worker"""Generates codes from Protocol Buffers definitions.
223*6777b538SAndroid Build Coastguard Worker
224*6777b538SAndroid Build Coastguard WorkerThis rule helps you to implement Skylark macros specific to the target
225*6777b538SAndroid Build Coastguard Workerlanguage. You should prefer more specific `cc_proto_library `,
226*6777b538SAndroid Build Coastguard Worker`py_proto_library` and others unless you are adding such wrapper macros.
227*6777b538SAndroid Build Coastguard Worker
228*6777b538SAndroid Build Coastguard WorkerArgs:
229*6777b538SAndroid Build Coastguard Worker  srcs: Protocol Buffers definition files (.proto) to run the protocol compiler
230*6777b538SAndroid Build Coastguard Worker    against.
231*6777b538SAndroid Build Coastguard Worker  deps: a list of dependency labels; must be other proto libraries.
232*6777b538SAndroid Build Coastguard Worker  includes: a list of include paths to .proto files.
233*6777b538SAndroid Build Coastguard Worker  protoc: the label of the protocol compiler to generate the sources.
234*6777b538SAndroid Build Coastguard Worker  plugin: the label of the protocol compiler plugin to be passed to the protocol
235*6777b538SAndroid Build Coastguard Worker    compiler.
236*6777b538SAndroid Build Coastguard Worker  plugin_language: the language of the generated sources
237*6777b538SAndroid Build Coastguard Worker  plugin_options: a list of options to be passed to the plugin
238*6777b538SAndroid Build Coastguard Worker  gen_cc: generates C++ sources in addition to the ones from the plugin.
239*6777b538SAndroid Build Coastguard Worker  gen_py: generates Python sources in addition to the ones from the plugin.
240*6777b538SAndroid Build Coastguard Worker  outs: a list of labels of the expected outputs from the protocol compiler.
241*6777b538SAndroid Build Coastguard Worker"""
242*6777b538SAndroid Build Coastguard Worker
243*6777b538SAndroid Build Coastguard Workerdef _adapt_proto_library_impl(ctx):
244*6777b538SAndroid Build Coastguard Worker    deps = [dep[ProtoInfo] for dep in ctx.attr.deps]
245*6777b538SAndroid Build Coastguard Worker
246*6777b538SAndroid Build Coastguard Worker    srcs = [src for dep in deps for src in dep.direct_sources]
247*6777b538SAndroid Build Coastguard Worker    return struct(
248*6777b538SAndroid Build Coastguard Worker        proto = struct(
249*6777b538SAndroid Build Coastguard Worker            srcs = srcs,
250*6777b538SAndroid Build Coastguard Worker            import_flags = ["-I{}".format(path) for dep in deps for path in dep.transitive_proto_path.to_list()],
251*6777b538SAndroid Build Coastguard Worker            deps = srcs,
252*6777b538SAndroid Build Coastguard Worker        ),
253*6777b538SAndroid Build Coastguard Worker    )
254*6777b538SAndroid Build Coastguard Worker
255*6777b538SAndroid Build Coastguard Workeradapt_proto_library = rule(
256*6777b538SAndroid Build Coastguard Worker    implementation = _adapt_proto_library_impl,
257*6777b538SAndroid Build Coastguard Worker    attrs = {
258*6777b538SAndroid Build Coastguard Worker        "deps": attr.label_list(
259*6777b538SAndroid Build Coastguard Worker            mandatory = True,
260*6777b538SAndroid Build Coastguard Worker            providers = [ProtoInfo],
261*6777b538SAndroid Build Coastguard Worker        ),
262*6777b538SAndroid Build Coastguard Worker    },
263*6777b538SAndroid Build Coastguard Worker    doc = "Adapts `proto_library` from `@rules_proto` to be used with `{cc,py}_proto_library` from this file.",
264*6777b538SAndroid Build Coastguard Worker)
265*6777b538SAndroid Build Coastguard Worker
266*6777b538SAndroid Build Coastguard Workerdef cc_proto_library(
267*6777b538SAndroid Build Coastguard Worker        name,
268*6777b538SAndroid Build Coastguard Worker        srcs = [],
269*6777b538SAndroid Build Coastguard Worker        deps = [],
270*6777b538SAndroid Build Coastguard Worker        cc_libs = [],
271*6777b538SAndroid Build Coastguard Worker        include = None,
272*6777b538SAndroid Build Coastguard Worker        protoc = "@com_google_protobuf//:protoc",
273*6777b538SAndroid Build Coastguard Worker        use_grpc_plugin = False,
274*6777b538SAndroid Build Coastguard Worker        default_runtime = "@com_google_protobuf//:protobuf",
275*6777b538SAndroid Build Coastguard Worker        **kargs):
276*6777b538SAndroid Build Coastguard Worker    """Bazel rule to create a C++ protobuf library from proto source files
277*6777b538SAndroid Build Coastguard Worker
278*6777b538SAndroid Build Coastguard Worker    NOTE: the rule is only an internal workaround to generate protos. The
279*6777b538SAndroid Build Coastguard Worker    interface may change and the rule may be removed when bazel has introduced
280*6777b538SAndroid Build Coastguard Worker    the native rule.
281*6777b538SAndroid Build Coastguard Worker
282*6777b538SAndroid Build Coastguard Worker    Args:
283*6777b538SAndroid Build Coastguard Worker      name: the name of the cc_proto_library.
284*6777b538SAndroid Build Coastguard Worker      srcs: the .proto files of the cc_proto_library.
285*6777b538SAndroid Build Coastguard Worker      deps: a list of dependency labels; must be cc_proto_library.
286*6777b538SAndroid Build Coastguard Worker      cc_libs: a list of other cc_library targets depended by the generated
287*6777b538SAndroid Build Coastguard Worker          cc_library.
288*6777b538SAndroid Build Coastguard Worker      include: a string indicating the include path of the .proto files.
289*6777b538SAndroid Build Coastguard Worker      protoc: the label of the protocol compiler to generate the sources.
290*6777b538SAndroid Build Coastguard Worker      use_grpc_plugin: a flag to indicate whether to call the grpc C++ plugin
291*6777b538SAndroid Build Coastguard Worker          when processing the proto files.
292*6777b538SAndroid Build Coastguard Worker      default_runtime: the implicitly default runtime which will be depended on by
293*6777b538SAndroid Build Coastguard Worker          the generated cc_library target.
294*6777b538SAndroid Build Coastguard Worker      **kargs: other keyword arguments that are passed to cc_library.
295*6777b538SAndroid Build Coastguard Worker    """
296*6777b538SAndroid Build Coastguard Worker
297*6777b538SAndroid Build Coastguard Worker    includes = []
298*6777b538SAndroid Build Coastguard Worker    if include != None:
299*6777b538SAndroid Build Coastguard Worker        includes = [include]
300*6777b538SAndroid Build Coastguard Worker
301*6777b538SAndroid Build Coastguard Worker    grpc_cpp_plugin = None
302*6777b538SAndroid Build Coastguard Worker    if use_grpc_plugin:
303*6777b538SAndroid Build Coastguard Worker        grpc_cpp_plugin = "//external:grpc_cpp_plugin"
304*6777b538SAndroid Build Coastguard Worker
305*6777b538SAndroid Build Coastguard Worker    gen_srcs = _CcSrcs(srcs, use_grpc_plugin)
306*6777b538SAndroid Build Coastguard Worker    gen_hdrs = _CcHdrs(srcs, use_grpc_plugin)
307*6777b538SAndroid Build Coastguard Worker    outs = gen_srcs + gen_hdrs
308*6777b538SAndroid Build Coastguard Worker
309*6777b538SAndroid Build Coastguard Worker    proto_gen(
310*6777b538SAndroid Build Coastguard Worker        name = name + "_genproto",
311*6777b538SAndroid Build Coastguard Worker        srcs = srcs,
312*6777b538SAndroid Build Coastguard Worker        deps = [s + "_genproto" for s in deps],
313*6777b538SAndroid Build Coastguard Worker        includes = includes,
314*6777b538SAndroid Build Coastguard Worker        protoc = protoc,
315*6777b538SAndroid Build Coastguard Worker        plugin = grpc_cpp_plugin,
316*6777b538SAndroid Build Coastguard Worker        plugin_language = "grpc",
317*6777b538SAndroid Build Coastguard Worker        gen_cc = 1,
318*6777b538SAndroid Build Coastguard Worker        outs = outs,
319*6777b538SAndroid Build Coastguard Worker        visibility = ["//visibility:public"],
320*6777b538SAndroid Build Coastguard Worker    )
321*6777b538SAndroid Build Coastguard Worker
322*6777b538SAndroid Build Coastguard Worker    if default_runtime and not default_runtime in cc_libs:
323*6777b538SAndroid Build Coastguard Worker        cc_libs = cc_libs + [default_runtime]
324*6777b538SAndroid Build Coastguard Worker    if use_grpc_plugin:
325*6777b538SAndroid Build Coastguard Worker        cc_libs = cc_libs + ["//external:grpc_lib"]
326*6777b538SAndroid Build Coastguard Worker    cc_library(
327*6777b538SAndroid Build Coastguard Worker        name = name,
328*6777b538SAndroid Build Coastguard Worker        srcs = gen_srcs,
329*6777b538SAndroid Build Coastguard Worker        hdrs = gen_hdrs,
330*6777b538SAndroid Build Coastguard Worker        deps = cc_libs + deps,
331*6777b538SAndroid Build Coastguard Worker        includes = includes,
332*6777b538SAndroid Build Coastguard Worker        **kargs
333*6777b538SAndroid Build Coastguard Worker    )
334*6777b538SAndroid Build Coastguard Worker
335*6777b538SAndroid Build Coastguard Workerdef _internal_gen_well_known_protos_java_impl(ctx):
336*6777b538SAndroid Build Coastguard Worker    args = ctx.actions.args()
337*6777b538SAndroid Build Coastguard Worker
338*6777b538SAndroid Build Coastguard Worker    deps = [d[ProtoInfo] for d in ctx.attr.deps]
339*6777b538SAndroid Build Coastguard Worker
340*6777b538SAndroid Build Coastguard Worker    srcjar = ctx.actions.declare_file("{}.srcjar".format(ctx.attr.name))
341*6777b538SAndroid Build Coastguard Worker    if ctx.attr.javalite:
342*6777b538SAndroid Build Coastguard Worker        java_out = "lite:%s" % srcjar.path
343*6777b538SAndroid Build Coastguard Worker    else:
344*6777b538SAndroid Build Coastguard Worker        java_out = srcjar
345*6777b538SAndroid Build Coastguard Worker
346*6777b538SAndroid Build Coastguard Worker    args.add("--java_out", java_out)
347*6777b538SAndroid Build Coastguard Worker
348*6777b538SAndroid Build Coastguard Worker    descriptors = depset(
349*6777b538SAndroid Build Coastguard Worker        transitive = [dep.transitive_descriptor_sets for dep in deps],
350*6777b538SAndroid Build Coastguard Worker    )
351*6777b538SAndroid Build Coastguard Worker    args.add_joined(
352*6777b538SAndroid Build Coastguard Worker        "--descriptor_set_in",
353*6777b538SAndroid Build Coastguard Worker        descriptors,
354*6777b538SAndroid Build Coastguard Worker        join_with = ctx.configuration.host_path_separator,
355*6777b538SAndroid Build Coastguard Worker    )
356*6777b538SAndroid Build Coastguard Worker
357*6777b538SAndroid Build Coastguard Worker    for dep in deps:
358*6777b538SAndroid Build Coastguard Worker        if "." == dep.proto_source_root:
359*6777b538SAndroid Build Coastguard Worker            args.add_all([src.path for src in dep.direct_sources])
360*6777b538SAndroid Build Coastguard Worker        else:
361*6777b538SAndroid Build Coastguard Worker            source_root = dep.proto_source_root
362*6777b538SAndroid Build Coastguard Worker            offset = len(source_root) + 1  # + '/'.
363*6777b538SAndroid Build Coastguard Worker            args.add_all([src.path[offset:] for src in dep.direct_sources])
364*6777b538SAndroid Build Coastguard Worker
365*6777b538SAndroid Build Coastguard Worker    ctx.actions.run(
366*6777b538SAndroid Build Coastguard Worker        executable = ctx.executable._protoc,
367*6777b538SAndroid Build Coastguard Worker        inputs = descriptors,
368*6777b538SAndroid Build Coastguard Worker        outputs = [srcjar],
369*6777b538SAndroid Build Coastguard Worker        arguments = [args],
370*6777b538SAndroid Build Coastguard Worker        use_default_shell_env = True,
371*6777b538SAndroid Build Coastguard Worker    )
372*6777b538SAndroid Build Coastguard Worker
373*6777b538SAndroid Build Coastguard Worker    return [
374*6777b538SAndroid Build Coastguard Worker        DefaultInfo(
375*6777b538SAndroid Build Coastguard Worker            files = depset([srcjar]),
376*6777b538SAndroid Build Coastguard Worker        ),
377*6777b538SAndroid Build Coastguard Worker    ]
378*6777b538SAndroid Build Coastguard Worker
379*6777b538SAndroid Build Coastguard Workerinternal_gen_well_known_protos_java = rule(
380*6777b538SAndroid Build Coastguard Worker    implementation = _internal_gen_well_known_protos_java_impl,
381*6777b538SAndroid Build Coastguard Worker    attrs = {
382*6777b538SAndroid Build Coastguard Worker        "deps": attr.label_list(
383*6777b538SAndroid Build Coastguard Worker            mandatory = True,
384*6777b538SAndroid Build Coastguard Worker            providers = [ProtoInfo],
385*6777b538SAndroid Build Coastguard Worker        ),
386*6777b538SAndroid Build Coastguard Worker        "javalite": attr.bool(
387*6777b538SAndroid Build Coastguard Worker            default = False,
388*6777b538SAndroid Build Coastguard Worker        ),
389*6777b538SAndroid Build Coastguard Worker        "_protoc": attr.label(
390*6777b538SAndroid Build Coastguard Worker            executable = True,
391*6777b538SAndroid Build Coastguard Worker            cfg = "exec",
392*6777b538SAndroid Build Coastguard Worker            default = "@com_google_protobuf//:protoc",
393*6777b538SAndroid Build Coastguard Worker        ),
394*6777b538SAndroid Build Coastguard Worker    },
395*6777b538SAndroid Build Coastguard Worker)
396*6777b538SAndroid Build Coastguard Worker
397*6777b538SAndroid Build Coastguard Workerdef _internal_gen_kt_protos(ctx):
398*6777b538SAndroid Build Coastguard Worker    args = ctx.actions.args()
399*6777b538SAndroid Build Coastguard Worker
400*6777b538SAndroid Build Coastguard Worker    deps = [d[ProtoInfo] for d in ctx.attr.deps]
401*6777b538SAndroid Build Coastguard Worker
402*6777b538SAndroid Build Coastguard Worker    srcjar = ctx.actions.declare_file("{}.srcjar".format(ctx.attr.name))
403*6777b538SAndroid Build Coastguard Worker    if ctx.attr.lite:
404*6777b538SAndroid Build Coastguard Worker        out = "lite:%s" % srcjar.path
405*6777b538SAndroid Build Coastguard Worker    else:
406*6777b538SAndroid Build Coastguard Worker        out = srcjar
407*6777b538SAndroid Build Coastguard Worker
408*6777b538SAndroid Build Coastguard Worker    args.add("--kotlin_out", out)
409*6777b538SAndroid Build Coastguard Worker
410*6777b538SAndroid Build Coastguard Worker    descriptors = depset(
411*6777b538SAndroid Build Coastguard Worker        transitive = [dep.transitive_descriptor_sets for dep in deps],
412*6777b538SAndroid Build Coastguard Worker    )
413*6777b538SAndroid Build Coastguard Worker    args.add_joined(
414*6777b538SAndroid Build Coastguard Worker        "--descriptor_set_in",
415*6777b538SAndroid Build Coastguard Worker        descriptors,
416*6777b538SAndroid Build Coastguard Worker        join_with = ctx.configuration.host_path_separator,
417*6777b538SAndroid Build Coastguard Worker    )
418*6777b538SAndroid Build Coastguard Worker
419*6777b538SAndroid Build Coastguard Worker    for dep in deps:
420*6777b538SAndroid Build Coastguard Worker        if "." == dep.proto_source_root:
421*6777b538SAndroid Build Coastguard Worker            args.add_all([src.path for src in dep.direct_sources])
422*6777b538SAndroid Build Coastguard Worker        else:
423*6777b538SAndroid Build Coastguard Worker            source_root = dep.proto_source_root
424*6777b538SAndroid Build Coastguard Worker            offset = len(source_root) + 1  # + '/'.
425*6777b538SAndroid Build Coastguard Worker            args.add_all([src.path[offset:] for src in dep.direct_sources])
426*6777b538SAndroid Build Coastguard Worker
427*6777b538SAndroid Build Coastguard Worker    ctx.actions.run(
428*6777b538SAndroid Build Coastguard Worker        executable = ctx.executable._protoc,
429*6777b538SAndroid Build Coastguard Worker        inputs = descriptors,
430*6777b538SAndroid Build Coastguard Worker        outputs = [srcjar],
431*6777b538SAndroid Build Coastguard Worker        arguments = [args],
432*6777b538SAndroid Build Coastguard Worker        use_default_shell_env = True,
433*6777b538SAndroid Build Coastguard Worker    )
434*6777b538SAndroid Build Coastguard Worker
435*6777b538SAndroid Build Coastguard Worker    return [
436*6777b538SAndroid Build Coastguard Worker        DefaultInfo(
437*6777b538SAndroid Build Coastguard Worker            files = depset([srcjar]),
438*6777b538SAndroid Build Coastguard Worker        ),
439*6777b538SAndroid Build Coastguard Worker    ]
440*6777b538SAndroid Build Coastguard Worker
441*6777b538SAndroid Build Coastguard Workerinternal_gen_kt_protos = rule(
442*6777b538SAndroid Build Coastguard Worker    implementation = _internal_gen_kt_protos,
443*6777b538SAndroid Build Coastguard Worker    attrs = {
444*6777b538SAndroid Build Coastguard Worker        "deps": attr.label_list(
445*6777b538SAndroid Build Coastguard Worker            mandatory = True,
446*6777b538SAndroid Build Coastguard Worker            providers = [ProtoInfo],
447*6777b538SAndroid Build Coastguard Worker        ),
448*6777b538SAndroid Build Coastguard Worker        "lite": attr.bool(
449*6777b538SAndroid Build Coastguard Worker            default = False,
450*6777b538SAndroid Build Coastguard Worker        ),
451*6777b538SAndroid Build Coastguard Worker        "_protoc": attr.label(
452*6777b538SAndroid Build Coastguard Worker            executable = True,
453*6777b538SAndroid Build Coastguard Worker            cfg = "exec",
454*6777b538SAndroid Build Coastguard Worker            default = "//:protoc",
455*6777b538SAndroid Build Coastguard Worker        ),
456*6777b538SAndroid Build Coastguard Worker    },
457*6777b538SAndroid Build Coastguard Worker)
458*6777b538SAndroid Build Coastguard Worker
459*6777b538SAndroid Build Coastguard Worker
460*6777b538SAndroid Build Coastguard Worker
461*6777b538SAndroid Build Coastguard Workerdef internal_copied_filegroup(name, srcs, strip_prefix, dest, **kwargs):
462*6777b538SAndroid Build Coastguard Worker    """Macro to copy files to a different directory and then create a filegroup.
463*6777b538SAndroid Build Coastguard Worker
464*6777b538SAndroid Build Coastguard Worker    This is used by the //:protobuf_python py_proto_library target to work around
465*6777b538SAndroid Build Coastguard Worker    an issue caused by Python source files that are part of the same Python
466*6777b538SAndroid Build Coastguard Worker    package being in separate directories.
467*6777b538SAndroid Build Coastguard Worker
468*6777b538SAndroid Build Coastguard Worker    Args:
469*6777b538SAndroid Build Coastguard Worker      srcs: The source files to copy and add to the filegroup.
470*6777b538SAndroid Build Coastguard Worker      strip_prefix: Path to the root of the files to copy.
471*6777b538SAndroid Build Coastguard Worker      dest: The directory to copy the source files into.
472*6777b538SAndroid Build Coastguard Worker      **kwargs: extra arguments that will be passesd to the filegroup.
473*6777b538SAndroid Build Coastguard Worker    """
474*6777b538SAndroid Build Coastguard Worker    outs = [_RelativeOutputPath(s, strip_prefix, dest) for s in srcs]
475*6777b538SAndroid Build Coastguard Worker
476*6777b538SAndroid Build Coastguard Worker    native.genrule(
477*6777b538SAndroid Build Coastguard Worker        name = name + "_genrule",
478*6777b538SAndroid Build Coastguard Worker        srcs = srcs,
479*6777b538SAndroid Build Coastguard Worker        outs = outs,
480*6777b538SAndroid Build Coastguard Worker        cmd_bash = " && ".join(
481*6777b538SAndroid Build Coastguard Worker            ["cp $(location %s) $(location %s)" %
482*6777b538SAndroid Build Coastguard Worker             (s, _RelativeOutputPath(s, strip_prefix, dest)) for s in srcs]),
483*6777b538SAndroid Build Coastguard Worker        cmd_bat = " && ".join(
484*6777b538SAndroid Build Coastguard Worker            ["@copy /Y $(location %s) $(location %s) >NUL" %
485*6777b538SAndroid Build Coastguard Worker             (s, _RelativeOutputPath(s, strip_prefix, dest)) for s in srcs]),
486*6777b538SAndroid Build Coastguard Worker    )
487*6777b538SAndroid Build Coastguard Worker
488*6777b538SAndroid Build Coastguard Worker    native.filegroup(
489*6777b538SAndroid Build Coastguard Worker        name = name,
490*6777b538SAndroid Build Coastguard Worker        srcs = outs,
491*6777b538SAndroid Build Coastguard Worker        **kwargs
492*6777b538SAndroid Build Coastguard Worker    )
493*6777b538SAndroid Build Coastguard Worker
494*6777b538SAndroid Build Coastguard Workerdef py_proto_library(
495*6777b538SAndroid Build Coastguard Worker        name,
496*6777b538SAndroid Build Coastguard Worker        srcs = [],
497*6777b538SAndroid Build Coastguard Worker        deps = [],
498*6777b538SAndroid Build Coastguard Worker        py_libs = [],
499*6777b538SAndroid Build Coastguard Worker        py_extra_srcs = [],
500*6777b538SAndroid Build Coastguard Worker        include = None,
501*6777b538SAndroid Build Coastguard Worker        default_runtime = "@com_google_protobuf//:protobuf_python",
502*6777b538SAndroid Build Coastguard Worker        protoc = "@com_google_protobuf//:protoc",
503*6777b538SAndroid Build Coastguard Worker        use_grpc_plugin = False,
504*6777b538SAndroid Build Coastguard Worker        **kargs):
505*6777b538SAndroid Build Coastguard Worker    """Bazel rule to create a Python protobuf library from proto source files
506*6777b538SAndroid Build Coastguard Worker
507*6777b538SAndroid Build Coastguard Worker    NOTE: the rule is only an internal workaround to generate protos. The
508*6777b538SAndroid Build Coastguard Worker    interface may change and the rule may be removed when bazel has introduced
509*6777b538SAndroid Build Coastguard Worker    the native rule.
510*6777b538SAndroid Build Coastguard Worker
511*6777b538SAndroid Build Coastguard Worker    Args:
512*6777b538SAndroid Build Coastguard Worker      name: the name of the py_proto_library.
513*6777b538SAndroid Build Coastguard Worker      srcs: the .proto files of the py_proto_library.
514*6777b538SAndroid Build Coastguard Worker      deps: a list of dependency labels; must be py_proto_library.
515*6777b538SAndroid Build Coastguard Worker      py_libs: a list of other py_library targets depended by the generated
516*6777b538SAndroid Build Coastguard Worker          py_library.
517*6777b538SAndroid Build Coastguard Worker      py_extra_srcs: extra source files that will be added to the output
518*6777b538SAndroid Build Coastguard Worker          py_library. This attribute is used for internal bootstrapping.
519*6777b538SAndroid Build Coastguard Worker      include: a string indicating the include path of the .proto files.
520*6777b538SAndroid Build Coastguard Worker      default_runtime: the implicitly default runtime which will be depended on by
521*6777b538SAndroid Build Coastguard Worker          the generated py_library target.
522*6777b538SAndroid Build Coastguard Worker      protoc: the label of the protocol compiler to generate the sources.
523*6777b538SAndroid Build Coastguard Worker      use_grpc_plugin: a flag to indicate whether to call the Python C++ plugin
524*6777b538SAndroid Build Coastguard Worker          when processing the proto files.
525*6777b538SAndroid Build Coastguard Worker      **kargs: other keyword arguments that are passed to py_library.
526*6777b538SAndroid Build Coastguard Worker
527*6777b538SAndroid Build Coastguard Worker    """
528*6777b538SAndroid Build Coastguard Worker    outs = _PyOuts(srcs, use_grpc_plugin)
529*6777b538SAndroid Build Coastguard Worker
530*6777b538SAndroid Build Coastguard Worker    includes = []
531*6777b538SAndroid Build Coastguard Worker    if include != None:
532*6777b538SAndroid Build Coastguard Worker        includes = [include]
533*6777b538SAndroid Build Coastguard Worker
534*6777b538SAndroid Build Coastguard Worker    grpc_python_plugin = None
535*6777b538SAndroid Build Coastguard Worker    if use_grpc_plugin:
536*6777b538SAndroid Build Coastguard Worker        grpc_python_plugin = "//external:grpc_python_plugin"
537*6777b538SAndroid Build Coastguard Worker        # Note: Generated grpc code depends on Python grpc module. This dependency
538*6777b538SAndroid Build Coastguard Worker        # is not explicitly listed in py_libs. Instead, host system is assumed to
539*6777b538SAndroid Build Coastguard Worker        # have grpc installed.
540*6777b538SAndroid Build Coastguard Worker
541*6777b538SAndroid Build Coastguard Worker    proto_gen(
542*6777b538SAndroid Build Coastguard Worker        name = name + "_genproto",
543*6777b538SAndroid Build Coastguard Worker        srcs = srcs,
544*6777b538SAndroid Build Coastguard Worker        deps = [s + "_genproto" for s in deps],
545*6777b538SAndroid Build Coastguard Worker        includes = includes,
546*6777b538SAndroid Build Coastguard Worker        protoc = protoc,
547*6777b538SAndroid Build Coastguard Worker        gen_py = 1,
548*6777b538SAndroid Build Coastguard Worker        outs = outs,
549*6777b538SAndroid Build Coastguard Worker        visibility = ["//visibility:public"],
550*6777b538SAndroid Build Coastguard Worker        plugin = grpc_python_plugin,
551*6777b538SAndroid Build Coastguard Worker        plugin_language = "grpc",
552*6777b538SAndroid Build Coastguard Worker    )
553*6777b538SAndroid Build Coastguard Worker
554*6777b538SAndroid Build Coastguard Worker    if default_runtime and not default_runtime in py_libs + deps:
555*6777b538SAndroid Build Coastguard Worker        py_libs = py_libs + [default_runtime]
556*6777b538SAndroid Build Coastguard Worker    py_library(
557*6777b538SAndroid Build Coastguard Worker        name = name,
558*6777b538SAndroid Build Coastguard Worker        srcs = outs + py_extra_srcs,
559*6777b538SAndroid Build Coastguard Worker        deps = py_libs + deps,
560*6777b538SAndroid Build Coastguard Worker        imports = includes,
561*6777b538SAndroid Build Coastguard Worker        **kargs
562*6777b538SAndroid Build Coastguard Worker    )
563*6777b538SAndroid Build Coastguard Worker
564*6777b538SAndroid Build Coastguard Workerdef internal_protobuf_py_tests(
565*6777b538SAndroid Build Coastguard Worker        name,
566*6777b538SAndroid Build Coastguard Worker        modules = [],
567*6777b538SAndroid Build Coastguard Worker        **kargs):
568*6777b538SAndroid Build Coastguard Worker    """Bazel rules to create batch tests for protobuf internal.
569*6777b538SAndroid Build Coastguard Worker
570*6777b538SAndroid Build Coastguard Worker    Args:
571*6777b538SAndroid Build Coastguard Worker      name: the name of the rule.
572*6777b538SAndroid Build Coastguard Worker      modules: a list of modules for tests. The macro will create a py_test for
573*6777b538SAndroid Build Coastguard Worker          each of the parameter with the source "google/protobuf/%s.py"
574*6777b538SAndroid Build Coastguard Worker      kargs: extra parameters that will be passed into the py_test.
575*6777b538SAndroid Build Coastguard Worker
576*6777b538SAndroid Build Coastguard Worker    """
577*6777b538SAndroid Build Coastguard Worker    for m in modules:
578*6777b538SAndroid Build Coastguard Worker        s = "python/google/protobuf/internal/%s.py" % m
579*6777b538SAndroid Build Coastguard Worker        py_test(
580*6777b538SAndroid Build Coastguard Worker            name = "py_%s" % m,
581*6777b538SAndroid Build Coastguard Worker            srcs = [s],
582*6777b538SAndroid Build Coastguard Worker            main = s,
583*6777b538SAndroid Build Coastguard Worker            **kargs
584*6777b538SAndroid Build Coastguard Worker        )
585*6777b538SAndroid Build Coastguard Worker
586*6777b538SAndroid Build Coastguard Workerdef check_protobuf_required_bazel_version():
587*6777b538SAndroid Build Coastguard Worker    """For WORKSPACE files, to check the installed version of bazel.
588*6777b538SAndroid Build Coastguard Worker
589*6777b538SAndroid Build Coastguard Worker    This ensures bazel supports our approach to proto_library() depending on a
590*6777b538SAndroid Build Coastguard Worker    copied filegroup. (Fixed in bazel 0.5.4)
591*6777b538SAndroid Build Coastguard Worker    """
592*6777b538SAndroid Build Coastguard Worker    versions.check(minimum_bazel_version = "0.5.4")
593