• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (c) 2009-2024, Google LLC
2# All rights reserved.
3#
4# Use of this source code is governed by a BSD-style
5# license that can be found in the LICENSE file or at
6# https://developers.google.com/open-source/licenses/bsd
7"""A Starlark implementation of the java_lite_proto_library rule."""
8
9load("@rules_java//java/common:java_common.bzl", "java_common")
10load("@rules_java//java/common:java_info.bzl", "JavaInfo")
11load("@rules_java//java/common:proguard_spec_info.bzl", "ProguardSpecInfo")
12load("//bazel/common:proto_common.bzl", "proto_common")
13load("//bazel/common:proto_info.bzl", "ProtoInfo")
14load("//bazel/private:java_proto_support.bzl", "JavaProtoAspectInfo", "java_compile_for_protos", "java_info_merge_for_protos")
15load("//bazel/private:toolchain_helpers.bzl", "toolchains")
16
17_PROTO_TOOLCHAIN_ATTR = "_aspect_proto_toolchain_for_javalite"
18
19_JAVA_LITE_PROTO_TOOLCHAIN = Label("//bazel/private:javalite_toolchain_type")
20
21def _aspect_impl(target, ctx):
22    """Generates and compiles Java code for a proto_library dependency graph.
23
24    Args:
25      target: (Target) The `proto_library` target.
26      ctx: (RuleContext) The rule context.
27
28    Returns:
29      ([JavaInfo, JavaProtoAspectInfo]) A JavaInfo describing compiled Java
30      version of`proto_library` and `JavaProtoAspectInfo` with all source and
31      runtime jars.
32    """
33
34    deps = [dep[JavaInfo] for dep in ctx.rule.attr.deps]
35    exports = [exp[JavaInfo] for exp in ctx.rule.attr.exports]
36    proto_toolchain_info = toolchains.find_toolchain(
37        ctx,
38        "_aspect_proto_toolchain_for_javalite",
39        _JAVA_LITE_PROTO_TOOLCHAIN,
40    )
41    source_jar = None
42
43    if proto_common.experimental_should_generate_code(target[ProtoInfo], proto_toolchain_info, "java_lite_proto_library", target.label):
44        source_jar = ctx.actions.declare_file(ctx.label.name + "-lite-src.jar")
45        proto_common.compile(
46            ctx.actions,
47            target[ProtoInfo],
48            proto_toolchain_info,
49            [source_jar],
50            experimental_output_files = "single",
51        )
52        runtime = proto_toolchain_info.runtime
53        if runtime:
54            deps.append(runtime[JavaInfo])
55
56    java_info, jars = java_compile_for_protos(
57        ctx,
58        "-lite.jar",
59        source_jar,
60        deps,
61        exports,
62        injecting_rule_kind = "java_lite_proto_library",
63    )
64    transitive_jars = [dep[JavaProtoAspectInfo].jars for dep in ctx.rule.attr.deps]
65
66    return [
67        java_info,
68        JavaProtoAspectInfo(jars = depset(jars, transitive = transitive_jars)),
69    ]
70
71_java_lite_proto_aspect = aspect(
72    implementation = _aspect_impl,
73    attr_aspects = ["deps", "exports"],
74    attrs = toolchains.if_legacy_toolchain({
75        _PROTO_TOOLCHAIN_ATTR: attr.label(
76            default = configuration_field(fragment = "proto", name = "proto_toolchain_for_java_lite"),
77        ),
78    }),
79    fragments = ["java"],
80    required_providers = [ProtoInfo],
81    provides = [JavaInfo, JavaProtoAspectInfo],
82    toolchains = ["@bazel_tools//tools/jdk:toolchain_type"] +
83                 toolchains.use_toolchain(_JAVA_LITE_PROTO_TOOLCHAIN),
84)
85
86def _rule_impl(ctx):
87    """Merges results of `java_proto_aspect` in `deps`.
88
89    `java_lite_proto_library` is identical to `java_proto_library` in every respect, except it
90    builds JavaLite protos.
91    Implementation of this rule is built on the implementation of `java_proto_library`.
92
93    Args:
94      ctx: (RuleContext) The rule context.
95    Returns:
96      ([JavaInfo, DefaultInfo, OutputGroupInfo, ProguardSpecInfo])
97    """
98
99    proto_toolchain_info = toolchains.find_toolchain(
100        ctx,
101        "_aspect_proto_toolchain_for_javalite",
102        _JAVA_LITE_PROTO_TOOLCHAIN,
103    )
104    for dep in ctx.attr.deps:
105        proto_common.check_collocated(ctx.label, dep[ProtoInfo], proto_toolchain_info)
106
107    runtime = proto_toolchain_info.runtime
108
109    if runtime:
110        proguard_provider_specs = runtime[ProguardSpecInfo]
111    else:
112        proguard_provider_specs = ProguardSpecInfo(specs = depset())
113
114    java_info = java_info_merge_for_protos([dep[JavaInfo] for dep in ctx.attr.deps], merge_java_outputs = False)
115
116    transitive_src_and_runtime_jars = depset(transitive = [dep[JavaProtoAspectInfo].jars for dep in ctx.attr.deps])
117    transitive_runtime_jars = depset(transitive = [java_info.transitive_runtime_jars])
118
119    if hasattr(java_common, "add_constraints"):
120        java_info = java_common.add_constraints(java_info, constraints = ["android"])
121
122    return [
123        java_info,
124        DefaultInfo(
125            files = transitive_src_and_runtime_jars,
126            runfiles = ctx.runfiles(transitive_files = transitive_runtime_jars),
127        ),
128        OutputGroupInfo(default = depset()),
129        proguard_provider_specs,
130    ]
131
132java_lite_proto_library = rule(
133    implementation = _rule_impl,
134    doc = """
135<p>
136<code>java_lite_proto_library</code> generates Java code from <code>.proto</code> files.
137</p>
138
139<p>
140<code>deps</code> must point to <a href="protocol-buffer.html#proto_library"><code>proto_library
141</code></a> rules.
142</p>
143
144<p>
145Example:
146</p>
147
148<pre class="code">
149<code class="lang-starlark">
150java_library(
151    name = "lib",
152    runtime_deps = [":foo"],
153)
154
155java_lite_proto_library(
156    name = "foo",
157    deps = [":bar"],
158)
159
160proto_library(
161    name = "bar",
162)
163</code>
164</pre>
165""",
166    attrs = {
167        "deps": attr.label_list(providers = [ProtoInfo], aspects = [_java_lite_proto_aspect], doc = """
168The list of <a href="protocol-buffer.html#proto_library"><code>proto_library</code></a>
169rules to generate Java code for.
170"""),
171    } | toolchains.if_legacy_toolchain({
172        _PROTO_TOOLCHAIN_ATTR: attr.label(
173            default = configuration_field(fragment = "proto", name = "proto_toolchain_for_java_lite"),
174        ),
175    }),
176    provides = [JavaInfo],
177    toolchains = toolchains.use_toolchain(_JAVA_LITE_PROTO_TOOLCHAIN),
178)
179