xref: /aosp_15_r20/external/grpc-grpc-java/java_grpc_library.bzl (revision e07d83d3ffcef9ecfc9f7f475418ec639ff0e5fe)
1*e07d83d3SAndroid Build Coastguard Worker"""Build rule for java_grpc_library."""
2*e07d83d3SAndroid Build Coastguard Worker
3*e07d83d3SAndroid Build Coastguard Worker_JavaRpcToolchainInfo = provider(
4*e07d83d3SAndroid Build Coastguard Worker    fields = [
5*e07d83d3SAndroid Build Coastguard Worker        "java_toolchain",
6*e07d83d3SAndroid Build Coastguard Worker        "plugin",
7*e07d83d3SAndroid Build Coastguard Worker        "plugin_arg",
8*e07d83d3SAndroid Build Coastguard Worker        "protoc",
9*e07d83d3SAndroid Build Coastguard Worker        "runtime",
10*e07d83d3SAndroid Build Coastguard Worker    ],
11*e07d83d3SAndroid Build Coastguard Worker)
12*e07d83d3SAndroid Build Coastguard Worker
13*e07d83d3SAndroid Build Coastguard Workerdef _java_rpc_toolchain_impl(ctx):
14*e07d83d3SAndroid Build Coastguard Worker    return [
15*e07d83d3SAndroid Build Coastguard Worker        _JavaRpcToolchainInfo(
16*e07d83d3SAndroid Build Coastguard Worker            java_toolchain = ctx.attr._java_toolchain,
17*e07d83d3SAndroid Build Coastguard Worker            plugin = ctx.executable.plugin,
18*e07d83d3SAndroid Build Coastguard Worker            plugin_arg = ctx.attr.plugin_arg,
19*e07d83d3SAndroid Build Coastguard Worker            protoc = ctx.executable._protoc,
20*e07d83d3SAndroid Build Coastguard Worker            runtime = ctx.attr.runtime,
21*e07d83d3SAndroid Build Coastguard Worker        ),
22*e07d83d3SAndroid Build Coastguard Worker        platform_common.ToolchainInfo(),  # Magic for b/78647825
23*e07d83d3SAndroid Build Coastguard Worker    ]
24*e07d83d3SAndroid Build Coastguard Worker
25*e07d83d3SAndroid Build Coastguard Workerjava_rpc_toolchain = rule(
26*e07d83d3SAndroid Build Coastguard Worker    attrs = {
27*e07d83d3SAndroid Build Coastguard Worker        # This attribute has a "magic" name recognized by the native DexArchiveAspect (b/78647825).
28*e07d83d3SAndroid Build Coastguard Worker        "runtime": attr.label_list(
29*e07d83d3SAndroid Build Coastguard Worker            cfg = "target",
30*e07d83d3SAndroid Build Coastguard Worker            providers = [JavaInfo],
31*e07d83d3SAndroid Build Coastguard Worker        ),
32*e07d83d3SAndroid Build Coastguard Worker        "plugin": attr.label(
33*e07d83d3SAndroid Build Coastguard Worker            cfg = "exec",
34*e07d83d3SAndroid Build Coastguard Worker            executable = True,
35*e07d83d3SAndroid Build Coastguard Worker        ),
36*e07d83d3SAndroid Build Coastguard Worker        "plugin_arg": attr.string(),
37*e07d83d3SAndroid Build Coastguard Worker        "_protoc": attr.label(
38*e07d83d3SAndroid Build Coastguard Worker            cfg = "exec",
39*e07d83d3SAndroid Build Coastguard Worker            default = Label("@com_google_protobuf//:protoc"),
40*e07d83d3SAndroid Build Coastguard Worker            executable = True,
41*e07d83d3SAndroid Build Coastguard Worker        ),
42*e07d83d3SAndroid Build Coastguard Worker        "_java_toolchain": attr.label(
43*e07d83d3SAndroid Build Coastguard Worker            default = Label("@bazel_tools//tools/jdk:current_java_toolchain"),
44*e07d83d3SAndroid Build Coastguard Worker        ),
45*e07d83d3SAndroid Build Coastguard Worker    },
46*e07d83d3SAndroid Build Coastguard Worker    provides = [
47*e07d83d3SAndroid Build Coastguard Worker        _JavaRpcToolchainInfo,
48*e07d83d3SAndroid Build Coastguard Worker        platform_common.ToolchainInfo,
49*e07d83d3SAndroid Build Coastguard Worker    ],
50*e07d83d3SAndroid Build Coastguard Worker    implementation = _java_rpc_toolchain_impl,
51*e07d83d3SAndroid Build Coastguard Worker)
52*e07d83d3SAndroid Build Coastguard Worker
53*e07d83d3SAndroid Build Coastguard Worker# "repository" here is for Bazel builds that span multiple WORKSPACES.
54*e07d83d3SAndroid Build Coastguard Workerdef _path_ignoring_repository(f):
55*e07d83d3SAndroid Build Coastguard Worker    # Bazel creates a _virtual_imports directory in case the .proto source files
56*e07d83d3SAndroid Build Coastguard Worker    # need to be accessed at a path that's different from their source path:
57*e07d83d3SAndroid Build Coastguard Worker    # https://github.com/bazelbuild/bazel/blob/0.27.1/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoCommon.java#L289
58*e07d83d3SAndroid Build Coastguard Worker    #
59*e07d83d3SAndroid Build Coastguard Worker    # In that case, the import path of the .proto file is the path relative to
60*e07d83d3SAndroid Build Coastguard Worker    # the virtual imports directory of the rule in question.
61*e07d83d3SAndroid Build Coastguard Worker    virtual_imports = "/_virtual_imports/"
62*e07d83d3SAndroid Build Coastguard Worker    if virtual_imports in f.path:
63*e07d83d3SAndroid Build Coastguard Worker        return f.path.split(virtual_imports)[1].split("/", 1)[1]
64*e07d83d3SAndroid Build Coastguard Worker    elif len(f.owner.workspace_root) == 0:
65*e07d83d3SAndroid Build Coastguard Worker        # |f| is in the main repository
66*e07d83d3SAndroid Build Coastguard Worker        return f.short_path
67*e07d83d3SAndroid Build Coastguard Worker    else:
68*e07d83d3SAndroid Build Coastguard Worker        # If |f| is a generated file, it will have "bazel-out/*/genfiles" prefix
69*e07d83d3SAndroid Build Coastguard Worker        # before "external/workspace", so we need to add the starting index of "external/workspace"
70*e07d83d3SAndroid Build Coastguard Worker        return f.path[f.path.find(f.owner.workspace_root) + len(f.owner.workspace_root) + 1:]
71*e07d83d3SAndroid Build Coastguard Worker
72*e07d83d3SAndroid Build Coastguard Workerdef _java_rpc_library_impl(ctx):
73*e07d83d3SAndroid Build Coastguard Worker    if len(ctx.attr.srcs) != 1:
74*e07d83d3SAndroid Build Coastguard Worker        fail("Exactly one src value supported", "srcs")
75*e07d83d3SAndroid Build Coastguard Worker    if ctx.attr.srcs[0].label.package != ctx.label.package:
76*e07d83d3SAndroid Build Coastguard Worker        print(("in srcs attribute of {0}: Proto source with label {1} should be in " +
77*e07d83d3SAndroid Build Coastguard Worker               "same package as consuming rule").format(ctx.label, ctx.attr.srcs[0].label))
78*e07d83d3SAndroid Build Coastguard Worker
79*e07d83d3SAndroid Build Coastguard Worker    toolchain = ctx.attr._toolchain[_JavaRpcToolchainInfo]
80*e07d83d3SAndroid Build Coastguard Worker    srcs = ctx.attr.srcs[0][ProtoInfo].direct_sources
81*e07d83d3SAndroid Build Coastguard Worker    descriptor_set_in = ctx.attr.srcs[0][ProtoInfo].transitive_descriptor_sets
82*e07d83d3SAndroid Build Coastguard Worker
83*e07d83d3SAndroid Build Coastguard Worker    srcjar = ctx.actions.declare_file("%s-proto-gensrc.jar" % ctx.label.name)
84*e07d83d3SAndroid Build Coastguard Worker
85*e07d83d3SAndroid Build Coastguard Worker    args = ctx.actions.args()
86*e07d83d3SAndroid Build Coastguard Worker    args.add(toolchain.plugin, format = "--plugin=protoc-gen-rpc-plugin=%s")
87*e07d83d3SAndroid Build Coastguard Worker    args.add("--rpc-plugin_out={0}:{1}".format(toolchain.plugin_arg, srcjar.path))
88*e07d83d3SAndroid Build Coastguard Worker    args.add_joined("--descriptor_set_in", descriptor_set_in, join_with = ctx.configuration.host_path_separator)
89*e07d83d3SAndroid Build Coastguard Worker    args.add_all(srcs, map_each = _path_ignoring_repository)
90*e07d83d3SAndroid Build Coastguard Worker
91*e07d83d3SAndroid Build Coastguard Worker    ctx.actions.run(
92*e07d83d3SAndroid Build Coastguard Worker        inputs = depset([toolchain.plugin] + srcs, transitive = [descriptor_set_in]),
93*e07d83d3SAndroid Build Coastguard Worker        outputs = [srcjar],
94*e07d83d3SAndroid Build Coastguard Worker        executable = toolchain.protoc,
95*e07d83d3SAndroid Build Coastguard Worker        arguments = [args],
96*e07d83d3SAndroid Build Coastguard Worker        use_default_shell_env = True,
97*e07d83d3SAndroid Build Coastguard Worker    )
98*e07d83d3SAndroid Build Coastguard Worker
99*e07d83d3SAndroid Build Coastguard Worker    deps_java_info = java_common.merge([dep[JavaInfo] for dep in ctx.attr.deps])
100*e07d83d3SAndroid Build Coastguard Worker
101*e07d83d3SAndroid Build Coastguard Worker    java_info = java_common.compile(
102*e07d83d3SAndroid Build Coastguard Worker        ctx,
103*e07d83d3SAndroid Build Coastguard Worker        java_toolchain = toolchain.java_toolchain[java_common.JavaToolchainInfo],
104*e07d83d3SAndroid Build Coastguard Worker        source_jars = [srcjar],
105*e07d83d3SAndroid Build Coastguard Worker        output = ctx.outputs.jar,
106*e07d83d3SAndroid Build Coastguard Worker        output_source_jar = ctx.outputs.srcjar,
107*e07d83d3SAndroid Build Coastguard Worker        deps = [
108*e07d83d3SAndroid Build Coastguard Worker            java_common.make_non_strict(deps_java_info),
109*e07d83d3SAndroid Build Coastguard Worker        ] + [dep[JavaInfo] for dep in toolchain.runtime],
110*e07d83d3SAndroid Build Coastguard Worker    )
111*e07d83d3SAndroid Build Coastguard Worker
112*e07d83d3SAndroid Build Coastguard Worker    return [java_info]
113*e07d83d3SAndroid Build Coastguard Worker
114*e07d83d3SAndroid Build Coastguard Worker_java_grpc_library = rule(
115*e07d83d3SAndroid Build Coastguard Worker    attrs = {
116*e07d83d3SAndroid Build Coastguard Worker        "srcs": attr.label_list(
117*e07d83d3SAndroid Build Coastguard Worker            mandatory = True,
118*e07d83d3SAndroid Build Coastguard Worker            allow_empty = False,
119*e07d83d3SAndroid Build Coastguard Worker            providers = [ProtoInfo],
120*e07d83d3SAndroid Build Coastguard Worker        ),
121*e07d83d3SAndroid Build Coastguard Worker        "deps": attr.label_list(
122*e07d83d3SAndroid Build Coastguard Worker            mandatory = True,
123*e07d83d3SAndroid Build Coastguard Worker            allow_empty = False,
124*e07d83d3SAndroid Build Coastguard Worker            providers = [JavaInfo],
125*e07d83d3SAndroid Build Coastguard Worker        ),
126*e07d83d3SAndroid Build Coastguard Worker        "_toolchain": attr.label(
127*e07d83d3SAndroid Build Coastguard Worker            default = Label("//compiler:java_grpc_library_toolchain"),
128*e07d83d3SAndroid Build Coastguard Worker        ),
129*e07d83d3SAndroid Build Coastguard Worker    },
130*e07d83d3SAndroid Build Coastguard Worker    toolchains = ["@bazel_tools//tools/jdk:toolchain_type"],
131*e07d83d3SAndroid Build Coastguard Worker    fragments = ["java"],
132*e07d83d3SAndroid Build Coastguard Worker    outputs = {
133*e07d83d3SAndroid Build Coastguard Worker        "jar": "lib%{name}.jar",
134*e07d83d3SAndroid Build Coastguard Worker        "srcjar": "lib%{name}-src.jar",
135*e07d83d3SAndroid Build Coastguard Worker    },
136*e07d83d3SAndroid Build Coastguard Worker    provides = [JavaInfo],
137*e07d83d3SAndroid Build Coastguard Worker    implementation = _java_rpc_library_impl,
138*e07d83d3SAndroid Build Coastguard Worker)
139*e07d83d3SAndroid Build Coastguard Worker
140*e07d83d3SAndroid Build Coastguard Worker_java_lite_grpc_library = rule(
141*e07d83d3SAndroid Build Coastguard Worker    attrs = {
142*e07d83d3SAndroid Build Coastguard Worker        "srcs": attr.label_list(
143*e07d83d3SAndroid Build Coastguard Worker            mandatory = True,
144*e07d83d3SAndroid Build Coastguard Worker            allow_empty = False,
145*e07d83d3SAndroid Build Coastguard Worker            providers = [ProtoInfo],
146*e07d83d3SAndroid Build Coastguard Worker        ),
147*e07d83d3SAndroid Build Coastguard Worker        "deps": attr.label_list(
148*e07d83d3SAndroid Build Coastguard Worker            mandatory = True,
149*e07d83d3SAndroid Build Coastguard Worker            allow_empty = False,
150*e07d83d3SAndroid Build Coastguard Worker            providers = [JavaInfo],
151*e07d83d3SAndroid Build Coastguard Worker        ),
152*e07d83d3SAndroid Build Coastguard Worker        # This attribute has a "magic" name recognized by the native DexArchiveAspect (b/78647825).
153*e07d83d3SAndroid Build Coastguard Worker        "_toolchain": attr.label(
154*e07d83d3SAndroid Build Coastguard Worker            default = Label("//compiler:java_lite_grpc_library_toolchain"),
155*e07d83d3SAndroid Build Coastguard Worker        ),
156*e07d83d3SAndroid Build Coastguard Worker    },
157*e07d83d3SAndroid Build Coastguard Worker    toolchains = ["@bazel_tools//tools/jdk:toolchain_type"],
158*e07d83d3SAndroid Build Coastguard Worker    fragments = ["java"],
159*e07d83d3SAndroid Build Coastguard Worker    outputs = {
160*e07d83d3SAndroid Build Coastguard Worker        "jar": "lib%{name}.jar",
161*e07d83d3SAndroid Build Coastguard Worker        "srcjar": "lib%{name}-src.jar",
162*e07d83d3SAndroid Build Coastguard Worker    },
163*e07d83d3SAndroid Build Coastguard Worker    provides = [JavaInfo],
164*e07d83d3SAndroid Build Coastguard Worker    implementation = _java_rpc_library_impl,
165*e07d83d3SAndroid Build Coastguard Worker)
166*e07d83d3SAndroid Build Coastguard Worker
167*e07d83d3SAndroid Build Coastguard Workerdef java_grpc_library(
168*e07d83d3SAndroid Build Coastguard Worker        name,
169*e07d83d3SAndroid Build Coastguard Worker        srcs,
170*e07d83d3SAndroid Build Coastguard Worker        deps,
171*e07d83d3SAndroid Build Coastguard Worker        flavor = None,
172*e07d83d3SAndroid Build Coastguard Worker        **kwargs):
173*e07d83d3SAndroid Build Coastguard Worker    """Generates gRPC Java code for services in a `proto_library`.
174*e07d83d3SAndroid Build Coastguard Worker
175*e07d83d3SAndroid Build Coastguard Worker    This rule only generates code for services; it does not generate code for
176*e07d83d3SAndroid Build Coastguard Worker    messages. You will need a separate java_proto_library or
177*e07d83d3SAndroid Build Coastguard Worker    java_lite_proto_library rule.
178*e07d83d3SAndroid Build Coastguard Worker
179*e07d83d3SAndroid Build Coastguard Worker    Args:
180*e07d83d3SAndroid Build Coastguard Worker      name: A unique name for this rule.
181*e07d83d3SAndroid Build Coastguard Worker      srcs: (List of `labels`) a single proto_library target that contains the
182*e07d83d3SAndroid Build Coastguard Worker        schema of the service.
183*e07d83d3SAndroid Build Coastguard Worker      deps: (List of `labels`) a single java_proto_library or
184*e07d83d3SAndroid Build Coastguard Worker        java_lite_proto_library target for the proto_library in srcs.
185*e07d83d3SAndroid Build Coastguard Worker      flavor: (str) "normal" (default) for normal proto runtime. "lite"
186*e07d83d3SAndroid Build Coastguard Worker        for the lite runtime.
187*e07d83d3SAndroid Build Coastguard Worker      **kwargs: Other common attributes
188*e07d83d3SAndroid Build Coastguard Worker    """
189*e07d83d3SAndroid Build Coastguard Worker
190*e07d83d3SAndroid Build Coastguard Worker    if len(deps) > 1:
191*e07d83d3SAndroid Build Coastguard Worker        print("Multiple values in 'deps' is deprecated in " + name)
192*e07d83d3SAndroid Build Coastguard Worker
193*e07d83d3SAndroid Build Coastguard Worker    if flavor == None or flavor == "normal":
194*e07d83d3SAndroid Build Coastguard Worker        _java_grpc_library(
195*e07d83d3SAndroid Build Coastguard Worker            name = name,
196*e07d83d3SAndroid Build Coastguard Worker            srcs = srcs,
197*e07d83d3SAndroid Build Coastguard Worker            deps = deps,
198*e07d83d3SAndroid Build Coastguard Worker            **kwargs
199*e07d83d3SAndroid Build Coastguard Worker        )
200*e07d83d3SAndroid Build Coastguard Worker    elif flavor == "lite":
201*e07d83d3SAndroid Build Coastguard Worker        _java_lite_grpc_library(
202*e07d83d3SAndroid Build Coastguard Worker            name = name,
203*e07d83d3SAndroid Build Coastguard Worker            srcs = srcs,
204*e07d83d3SAndroid Build Coastguard Worker            deps = deps,
205*e07d83d3SAndroid Build Coastguard Worker            **kwargs
206*e07d83d3SAndroid Build Coastguard Worker        )
207*e07d83d3SAndroid Build Coastguard Worker    else:
208*e07d83d3SAndroid Build Coastguard Worker        fail("Flavor must be normal or lite")
209