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