1# Copyright 2023 The Bazel Authors. All rights reserved. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15""" 16Definition of JavaInfo and JavaPluginInfo provider. 17""" 18 19load("@rules_cc//cc/common:cc_common.bzl", "cc_common") 20load("@rules_cc//cc/common:cc_info.bzl", "CcInfo") 21load("//java/common:java_semantics.bzl", "semantics") 22load(":native.bzl", "get_internal_java_common") 23 24# copybara: default visibility 25 26_JavaOutputInfo = provider( 27 doc = "The outputs of Java compilation.", 28 fields = { 29 "class_jar": "(File) A classes jar file.", 30 "compile_jar": "(File) An interface jar file.", 31 "ijar": "Deprecated: Please use compile_jar.", 32 "compile_jdeps": "(File) Compile time dependencies information (deps.proto file).", 33 "generated_class_jar": "(File) A jar containing classes generated via annotation processing.", 34 "generated_source_jar": "(File) The source jar created as a result of annotation processing.", 35 "native_headers_jar": "(File) A jar of CC header files supporting native method implementation.", 36 "manifest_proto": "(File) The manifest protobuf file of the manifest generated from JavaBuilder.", 37 "jdeps": "(File) The jdeps protobuf file of the manifest generated from JavaBuilder.", 38 "source_jars": "(depset[File]) A depset of sources archive files.", 39 "source_jar": "Deprecated: Please use source_jars instead.", 40 }, 41) 42_ModuleFlagsInfo = provider( 43 doc = "Provider for the runtime classpath contributions of a Java binary.", 44 fields = { 45 "add_exports": "(depset[str]) Add-Exports configuration.", 46 "add_opens": "(depset[str]) Add-Opens configuration.", 47 }, 48) 49_EMPTY_MODULE_FLAGS_INFO = _ModuleFlagsInfo(add_exports = depset(), add_opens = depset()) 50 51def _create_module_flags_info(*, add_exports, add_opens): 52 if add_exports or add_opens: 53 return _ModuleFlagsInfo(add_exports = add_exports, add_opens = add_opens) 54 return _EMPTY_MODULE_FLAGS_INFO 55 56_JavaRuleOutputJarsInfo = provider( 57 doc = "Deprecated: use java_info.java_outputs. Information about outputs of a Java rule.", 58 fields = { 59 "jdeps": "Deprecated: Use java_info.java_outputs.", 60 "native_headers": "Deprecated: Use java_info.java_outputs[i].jdeps.", 61 "jars": "Deprecated: Use java_info.java_outputs[i].native_headers_jar.", 62 }, 63) 64_JavaGenJarsInfo = provider( 65 doc = "Deprecated: Information about jars that are a result of annotation processing for a Java rule.", 66 fields = { 67 "enabled": "Deprecated. Returns true if annotation processing was applied on this target.", 68 "class_jar": "Deprecated: Please use JavaInfo.java_outputs.generated_class_jar instead.", 69 "source_jar": "Deprecated: Please use JavaInfo.java_outputs.generated_source_jar instead.", 70 "transitive_class_jars": "Deprecated. A transitive set of class file jars from annotation " + 71 "processing of this rule and its dependencies.", 72 "transitive_source_jars": "Deprecated. A transitive set of source archives from annotation " + 73 "processing of this rule and its dependencies.", 74 "processor_classpath": "Deprecated: Please use JavaInfo.plugins instead.", 75 "processor_classnames": "Deprecated: Please use JavaInfo.plugins instead.", 76 }, 77) 78 79JavaCompilationInfo = provider( 80 doc = "Compilation information in Java rules, for perusal of aspects and tools.", 81 fields = { 82 "boot_classpath": "Boot classpath for this Java target.", 83 "javac_options": """Depset of options to the java compiler. To get the 84 exact list of options passed to javac in the correct order, use the 85 tokenize_javacopts utility in rules_java""", 86 "compilation_classpath": "Compilation classpath for this Java target.", 87 "runtime_classpath": "Run-time classpath for this Java target.", 88 }, 89) 90 91def merge( 92 providers, 93 # private to @_builtins: 94 merge_java_outputs = True, 95 merge_source_jars = True): 96 """Merges the given providers into a single JavaInfo. 97 98 Args: 99 providers: ([JavaInfo]) The list of providers to merge. 100 merge_java_outputs: (bool) 101 merge_source_jars: (bool) 102 103 Returns: 104 (JavaInfo) The merged JavaInfo 105 """ 106 _validate_provider_list(providers, "providers", JavaInfo) 107 108 plugin_info = merge_plugin_info_without_outputs(providers) 109 110 source_jars = [] # [File] 111 transitive_source_jars = [] # [depset[File]] 112 java_outputs = [] # [_JavaOutputInfo] 113 runtime_output_jars = [] # [File] 114 transitive_runtime_jars = [] # [depset[File]] 115 transitive_compile_time_jars = [] # [depset[File]] 116 compile_jars = [] # [depset[File]] 117 full_compile_jars = [] # [depset[File]] 118 _transitive_full_compile_time_jars = [] # [depset[File]] 119 _compile_time_java_dependencies = [] # [depset[File]] 120 add_exports = [] # [depset[str]] 121 add_opens = [] # [depset[str]] 122 _neverlink = False 123 _constraints = [] # [str] 124 for p in providers: 125 if merge_source_jars: 126 source_jars.extend(p.source_jars) 127 transitive_source_jars.append(p.transitive_source_jars) 128 if merge_java_outputs: 129 java_outputs.extend(p.java_outputs) 130 runtime_output_jars.extend(p.runtime_output_jars) 131 transitive_runtime_jars.append(p.transitive_runtime_jars) 132 transitive_compile_time_jars.append(p.transitive_compile_time_jars) 133 compile_jars.append(p.compile_jars) 134 full_compile_jars.append(p.full_compile_jars) 135 _transitive_full_compile_time_jars.append(p._transitive_full_compile_time_jars) 136 _compile_time_java_dependencies.append(p._compile_time_java_dependencies) 137 add_exports.append(p.module_flags_info.add_exports) 138 add_opens.append(p.module_flags_info.add_opens) 139 _neverlink = _neverlink or p._neverlink 140 _constraints.extend(p._constraints) 141 142 transitive_runtime_jars = depset(order = "preorder", transitive = transitive_runtime_jars) 143 transitive_compile_time_jars = depset(order = "preorder", transitive = transitive_compile_time_jars) 144 145 # java_outputs is a list so we uniquify to avoid https://github.com/bazelbuild/bazel/issues/17170 146 java_outputs = depset(java_outputs).to_list() 147 result = { 148 "transitive_runtime_jars": transitive_runtime_jars, 149 "transitive_compile_time_jars": transitive_compile_time_jars, 150 "compile_jars": depset(order = "preorder", transitive = compile_jars), 151 "full_compile_jars": depset(order = "preorder", transitive = full_compile_jars), 152 "_transitive_full_compile_time_jars": depset(order = "preorder", transitive = _transitive_full_compile_time_jars), 153 "_compile_time_java_dependencies": depset(order = "preorder", transitive = _compile_time_java_dependencies), 154 # runtime_output_jars is a list so we uniquify to avoid https://github.com/bazelbuild/bazel/issues/17170 155 "runtime_output_jars": depset(runtime_output_jars).to_list(), 156 # source_jars is a list so we uniquify to avoid https://github.com/bazelbuild/bazel/issues/17170 157 "source_jars": depset(source_jars).to_list(), 158 "transitive_source_jars": depset(transitive = transitive_source_jars), 159 "java_outputs": java_outputs, 160 "outputs": _JavaRuleOutputJarsInfo(jars = java_outputs, jdeps = None, native_headers = None), 161 "module_flags_info": _create_module_flags_info( 162 add_exports = depset(transitive = add_exports), 163 add_opens = depset(transitive = add_opens), 164 ), 165 "plugins": plugin_info.plugins, 166 "api_generating_plugins": plugin_info.api_generating_plugins, 167 "_neverlink": bool(_neverlink), 168 "_constraints": depset(_constraints).to_list(), 169 "annotation_processing": None, 170 "compilation_info": None, 171 } 172 173 if get_internal_java_common().google_legacy_api_enabled(): 174 cc_info = semantics.minimize_cc_info(cc_common.merge_cc_infos(cc_infos = [p.cc_link_params_info for p in providers])) 175 result.update( 176 cc_link_params_info = cc_info, 177 transitive_native_libraries = cc_info.transitive_native_libraries(), 178 ) 179 else: 180 result.update( 181 transitive_native_libraries = depset( 182 order = "topological", 183 transitive = [p.transitive_native_libraries for p in providers], 184 ), 185 ) 186 return get_internal_java_common().wrap_java_info(_new_javainfo(**result)) 187 188def to_java_binary_info(java_info, compilation_info): 189 """Get a copy of the given JavaInfo with minimal info returned by a java_binary 190 191 Args: 192 java_info: (JavaInfo) A JavaInfo provider instance 193 compilation_info: (JavaCompilationInfo) 194 Returns: 195 (JavaInfo) A JavaInfo instance representing a java_binary target 196 """ 197 result = { 198 "transitive_runtime_jars": depset(), 199 "transitive_compile_time_jars": depset(), 200 "compile_jars": depset(), 201 "full_compile_jars": depset(), 202 "_transitive_full_compile_time_jars": depset(), 203 "_compile_time_java_dependencies": depset(), 204 "runtime_output_jars": [], 205 "plugins": _EMPTY_PLUGIN_DATA, 206 "api_generating_plugins": _EMPTY_PLUGIN_DATA, 207 "module_flags_info": _EMPTY_MODULE_FLAGS_INFO, 208 "_neverlink": False, 209 "_constraints": [], 210 "annotation_processing": java_info.annotation_processing, 211 "transitive_native_libraries": java_info.transitive_native_libraries, 212 "source_jars": java_info.source_jars, 213 "transitive_source_jars": java_info.transitive_source_jars, 214 } 215 if hasattr(java_info, "cc_link_params_info"): 216 result.update(cc_link_params_info = java_info.cc_link_params_info) 217 218 result["compilation_info"] = compilation_info 219 220 java_outputs = [ 221 _JavaOutputInfo( 222 compile_jar = None, 223 ijar = None, # deprecated 224 compile_jdeps = None, 225 class_jar = output.class_jar, 226 generated_class_jar = output.generated_class_jar, 227 generated_source_jar = output.generated_source_jar, 228 native_headers_jar = output.native_headers_jar, 229 manifest_proto = output.manifest_proto, 230 jdeps = output.jdeps, 231 source_jars = output.source_jars, 232 source_jar = output.source_jar, # deprecated 233 ) 234 for output in java_info.java_outputs 235 ] 236 all_jdeps = [output.jdeps for output in java_info.java_outputs if output.jdeps] 237 all_native_headers = [output.native_headers_jar for output in java_info.java_outputs if output.native_headers_jar] 238 result.update( 239 java_outputs = java_outputs, 240 outputs = _JavaRuleOutputJarsInfo( 241 jars = java_outputs, 242 jdeps = all_jdeps[0] if len(all_jdeps) == 1 else None, 243 native_headers = all_native_headers[0] if len(all_native_headers) == 1 else None, 244 ), 245 ) 246 247 # so that translation into native JavaInfo does not add JavaCompilationArgsProvider 248 result.update(_is_binary = True) 249 return _new_javainfo(**result) 250 251def _to_mutable_dict(java_info): 252 return { 253 key: getattr(java_info, key) 254 for key in dir(java_info) 255 if key not in ["to_json", "to_proto"] 256 } 257 258def add_constraints(java_info, constraints = []): 259 """Returns a copy of the given JavaInfo with the given constraints added. 260 261 Args: 262 java_info: (JavaInfo) The JavaInfo to enhance 263 constraints: ([str]) Constraints to add 264 265 Returns: 266 (JavaInfo) 267 """ 268 result = _to_mutable_dict(java_info) 269 old_constraints = java_info._constraints if java_info._constraints else [] 270 result.update( 271 _constraints = depset(constraints + old_constraints).to_list(), 272 ) 273 return _new_javainfo(**result) 274 275def make_non_strict(java_info): 276 """Returns a new JavaInfo instance whose direct-jars part is the union of both the direct and indirect jars of the given Java provider. 277 278 Args: 279 java_info: (JavaInfo) The java info to make non-strict. 280 281 Returns: 282 (JavaInfo) 283 """ 284 result = _to_mutable_dict(java_info) 285 result.update( 286 compile_jars = java_info.transitive_compile_time_jars, 287 full_compile_jars = java_info._transitive_full_compile_time_jars, 288 ) 289 290 # Omit jdeps, which aren't available transitively and aren't useful for reduced classpath 291 # pruning for non-strict targets: the direct classpath and transitive classpath are the same, 292 # so there's nothing to prune, and reading jdeps at compile-time isn't free. 293 result.update( 294 _compile_time_java_dependencies = depset(), 295 ) 296 return _new_javainfo(**result) 297 298def add_module_flags(java_info, add_exports = [], add_opens = []): 299 """Returns a new JavaInfo instance with the additional add_exports/add_opens 300 301 Args: 302 java_info: (JavaInfo) The java info to enhance. 303 add_exports: ([str]) The <module>/<package>s given access to. 304 add_opens: ([str]) The <module>/<package>s given reflective access to. 305 Returns: 306 (JavaInfo) 307 """ 308 if not add_exports and not add_opens: 309 return java_info 310 311 result = _to_mutable_dict(java_info) 312 result.update( 313 module_flags_info = _create_module_flags_info( 314 add_exports = depset(add_exports, transitive = [java_info.module_flags_info.add_exports]), 315 add_opens = depset(add_opens, transitive = [java_info.module_flags_info.add_opens]), 316 ), 317 ) 318 return _new_javainfo(**result) 319 320def set_annotation_processing( 321 java_info, 322 enabled = False, 323 processor_classnames = [], 324 processor_classpath = None, 325 class_jar = None, 326 source_jar = None): 327 """Returns a copy of the given JavaInfo with the given annotation_processing info. 328 329 Args: 330 java_info: (JavaInfo) The JavaInfo to enhance. 331 enabled: (bool) Whether the rule uses annotation processing. 332 processor_classnames: ([str]) Class names of annotation processors applied. 333 processor_classpath: (depset[File]) Class names of annotation processors applied. 334 class_jar: (File) Optional. Jar that is the result of annotation processing. 335 source_jar: (File) Optional. Source archive resulting from annotation processing. 336 337 Returns: 338 (JavaInfo) 339 """ 340 gen_jars_info = java_info.annotation_processing 341 if gen_jars_info: 342 # Existing Jars would be a problem b/c we can't remove them from transitiveXxx sets 343 if gen_jars_info.class_jar and gen_jars_info.class_jar != class_jar: 344 fail("Existing gen_class_jar:", gen_jars_info.class_jar) 345 if gen_jars_info.source_jar and gen_jars_info.source_jar != source_jar: 346 fail("Existing gen_source_jar:", gen_jars_info.class_jar) 347 transitive_class_jars = depset([class_jar] if class_jar else [], transitive = [gen_jars_info.transitive_class_jars]) 348 transitive_source_jars = depset([source_jar] if source_jar else [], transitive = [gen_jars_info.transitive_source_jars]) 349 else: 350 transitive_class_jars = depset([class_jar] if class_jar else []) 351 transitive_source_jars = depset([source_jar] if source_jar else []) 352 353 result = _to_mutable_dict(java_info) 354 result.update( 355 annotation_processing = _JavaGenJarsInfo( 356 enabled = enabled, 357 class_jar = class_jar, 358 source_jar = source_jar, 359 processor_classnames = processor_classnames, 360 processor_classpath = processor_classpath if processor_classpath else depset(), 361 transitive_class_jars = transitive_class_jars, 362 transitive_source_jars = transitive_source_jars, 363 ), 364 ) 365 return _new_javainfo(**result) 366 367def java_info_for_compilation( 368 output_jar, 369 compile_jar, 370 source_jar, 371 generated_class_jar, 372 generated_source_jar, 373 plugin_info, 374 deps, 375 runtime_deps, 376 exports, 377 exported_plugins, 378 compile_jdeps, 379 jdeps, 380 native_headers_jar, 381 manifest_proto, 382 native_libraries, 383 neverlink, 384 add_exports, 385 add_opens, 386 direct_runtime_jars, 387 compilation_info): 388 """Creates a JavaInfo instance represiting the result of java compilation. 389 390 Args: 391 output_jar: (File) The jar that was created as a result of a compilation. 392 compile_jar: (File) A jar that is the compile-time dependency in lieu of `output_jar`. 393 source_jar: (File) The source jar that was used to create the output jar. 394 generated_class_jar: (File) A jar file containing class files compiled from sources 395 generated during annotation processing. 396 generated_source_jar: (File) The source jar that was created as a result of annotation 397 processing. 398 plugin_info: (JavaPluginInfo) Information about annotation processing. 399 deps: ([JavaInfo]) Compile time dependencies that were used to create the output jar. 400 runtime_deps: ([JavaInfo]) Runtime dependencies that are needed for this library. 401 exports: ([JavaInfo]) Libraries to make available for users of this library. 402 exported_plugins: ([JavaPluginInfo]) A list of exported plugins. 403 compile_jdeps: (File) jdeps information about compile time dependencies to be consumed by 404 JavaCompileAction. This should be a binary proto encoded using the deps.proto protobuf 405 included with Bazel. If available this file is typically produced by a header compiler. 406 jdeps: (File) jdeps information for the rule output (if available). This should be a binary 407 proto encoded using the deps.proto protobuf included with Bazel. If available this file 408 is typically produced by a compiler. IDEs and other tools can use this information for 409 more efficient processing. 410 native_headers_jar: (File) A jar containing CC header files supporting native method 411 implementation (typically output of javac -h). 412 manifest_proto: (File) Manifest information for the rule output (if available). This should 413 be a binary proto encoded using the manifest.proto protobuf included with Bazel. IDEs 414 and other tools can use this information for more efficient processing. 415 native_libraries: ([CcInfo]) Native library dependencies that are needed for this library. 416 neverlink: (bool) If true, only use this library for compilation and not at runtime. 417 add_exports: ([str]) The <module>/<package>s this library was given access to. 418 add_opens: ([str]) The <module>/<package>s this library was given reflective access to. 419 direct_runtime_jars: ([File]) The class jars needed directly by this library at runtime. 420 This is usually just the output_jar or empty if there were no sources/resources. 421 compilation_info: (struct) Information for IDE/tools 422 423 Returns: 424 (JavaInfo) the JavaInfo instance 425 """ 426 result, concatenated_deps = _javainfo_init_base( 427 output_jar, 428 compile_jar, 429 source_jar, 430 deps, 431 runtime_deps, 432 exports, 433 exported_plugins, 434 jdeps, 435 compile_jdeps, 436 native_headers_jar, 437 manifest_proto, 438 generated_class_jar, 439 generated_source_jar, 440 native_libraries, 441 neverlink, 442 ) 443 444 # this differs ever so slightly from the usual JavaInfo in that direct_runtime_jars 445 # does not contain the output_jar is there were no sources/resources 446 transitive_runtime_jars = depset() if neverlink else depset( 447 order = "preorder", 448 direct = direct_runtime_jars, 449 transitive = [dep.transitive_runtime_jars for dep in concatenated_deps.exports_deps + runtime_deps], 450 ) 451 result.update( 452 runtime_output_jars = direct_runtime_jars, 453 transitive_runtime_jars = transitive_runtime_jars, 454 transitive_source_jars = depset( 455 direct = [source_jar], 456 # only differs from the usual java_info.transitive_source_jars in the order of deps 457 transitive = [dep.transitive_source_jars for dep in concatenated_deps.runtimedeps_exports_deps], 458 ), 459 # the JavaInfo constructor does not add flags from runtime_deps 460 module_flags_info = _create_module_flags_info( 461 add_exports = depset(add_exports, transitive = [ 462 dep.module_flags_info.add_exports 463 for dep in concatenated_deps.runtimedeps_exports_deps 464 ]), 465 add_opens = depset(add_opens, transitive = [ 466 dep.module_flags_info.add_opens 467 for dep in concatenated_deps.runtimedeps_exports_deps 468 ]), 469 ), 470 ) 471 if compilation_info: 472 result.update( 473 compilation_info = JavaCompilationInfo( 474 javac_options = compilation_info.javac_options, 475 boot_classpath = compilation_info.boot_classpath, 476 compilation_classpath = compilation_info.compilation_classpath, 477 runtime_classpath = compilation_info.runtime_classpath, 478 ), 479 annotation_processing = _JavaGenJarsInfo( 480 enabled = compilation_info.uses_annotation_processing, 481 class_jar = result["annotation_processing"].class_jar, 482 source_jar = result["annotation_processing"].source_jar, 483 processor_classnames = plugin_info.plugins.processor_classes.to_list(), 484 processor_classpath = plugin_info.plugins.processor_jars, 485 transitive_class_jars = result["annotation_processing"].transitive_class_jars, 486 transitive_source_jars = result["annotation_processing"].transitive_source_jars, 487 ), 488 ) 489 else: 490 result.update( 491 compilation_info = None, 492 annotation_processing = None, 493 ) 494 return get_internal_java_common().wrap_java_info(_new_javainfo(**result)) 495 496def _validate_provider_list(provider_list, what, expected_provider_type): 497 get_internal_java_common().check_provider_instances(provider_list, what, expected_provider_type) 498 499def _compute_concatenated_deps(deps, runtime_deps, exports): 500 deps_exports = [] 501 deps_exports.extend(deps) 502 deps_exports.extend(exports) 503 504 exports_deps = [] 505 exports_deps.extend(exports) 506 exports_deps.extend(deps) 507 508 runtimedeps_exports_deps = [] 509 runtimedeps_exports_deps.extend(runtime_deps) 510 runtimedeps_exports_deps.extend(exports_deps) 511 512 return struct( 513 deps_exports = deps_exports, 514 exports_deps = exports_deps, 515 runtimedeps_exports_deps = runtimedeps_exports_deps, 516 ) 517 518def _javainfo_init_base( 519 output_jar, 520 compile_jar, 521 source_jar, 522 deps, 523 runtime_deps, 524 exports, 525 exported_plugins, 526 jdeps, 527 compile_jdeps, 528 native_headers_jar, 529 manifest_proto, 530 generated_class_jar, 531 generated_source_jar, 532 native_libraries, 533 neverlink): 534 _validate_provider_list(deps, "deps", JavaInfo) 535 _validate_provider_list(runtime_deps, "runtime_deps", JavaInfo) 536 _validate_provider_list(exports, "exports", JavaInfo) 537 _validate_provider_list(native_libraries, "native_libraries", CcInfo) 538 539 concatenated_deps = _compute_concatenated_deps(deps, runtime_deps, exports) 540 541 source_jars = [source_jar] if source_jar else [] 542 plugin_info = merge_plugin_info_without_outputs(exported_plugins + exports) 543 transitive_compile_time_jars = depset( 544 order = "preorder", 545 direct = [compile_jar] if compile_jar else [], 546 transitive = [dep.transitive_compile_time_jars for dep in concatenated_deps.exports_deps], 547 ) 548 java_outputs = [_JavaOutputInfo( 549 class_jar = output_jar, 550 compile_jar = compile_jar, 551 ijar = compile_jar, # deprecated 552 compile_jdeps = compile_jdeps, 553 generated_class_jar = generated_class_jar, 554 generated_source_jar = generated_source_jar, 555 native_headers_jar = native_headers_jar, 556 manifest_proto = manifest_proto, 557 jdeps = jdeps, 558 source_jars = depset(source_jars), 559 source_jar = source_jar, # deprecated 560 )] 561 result = { 562 "transitive_compile_time_jars": transitive_compile_time_jars, 563 "compile_jars": depset( 564 order = "preorder", 565 direct = [compile_jar] if compile_jar else [], 566 transitive = [dep.compile_jars for dep in exports], 567 ), 568 "full_compile_jars": depset( 569 order = "preorder", 570 direct = [output_jar], 571 transitive = [ 572 dep.full_compile_jars 573 for dep in exports 574 ], 575 ), 576 "source_jars": source_jars, 577 "runtime_output_jars": [output_jar], 578 "plugins": plugin_info.plugins, 579 "api_generating_plugins": plugin_info.api_generating_plugins, 580 "java_outputs": java_outputs, 581 # deprecated 582 "outputs": _JavaRuleOutputJarsInfo( 583 jars = java_outputs, 584 jdeps = jdeps, 585 native_headers = native_headers_jar, 586 ), 587 "annotation_processing": _JavaGenJarsInfo( 588 enabled = False, 589 class_jar = generated_class_jar, 590 source_jar = generated_source_jar, 591 transitive_class_jars = depset( 592 direct = [generated_class_jar] if generated_class_jar else [], 593 transitive = [ 594 dep.annotation_processing.transitive_class_jars 595 for dep in concatenated_deps.deps_exports 596 if dep.annotation_processing 597 ], 598 ), 599 transitive_source_jars = depset( 600 direct = [generated_source_jar] if generated_source_jar else [], 601 transitive = [ 602 dep.annotation_processing.transitive_source_jars 603 for dep in concatenated_deps.deps_exports 604 if dep.annotation_processing 605 ], 606 ), 607 processor_classnames = [], 608 processor_classpath = depset(), 609 ), 610 "_transitive_full_compile_time_jars": depset( 611 order = "preorder", 612 direct = [output_jar], 613 transitive = [dep._transitive_full_compile_time_jars for dep in concatenated_deps.exports_deps], 614 ), 615 "_compile_time_java_dependencies": depset( 616 order = "preorder", 617 transitive = [dep._compile_time_java_dependencies for dep in exports] + 618 ([depset([compile_jdeps])] if compile_jdeps else []), 619 ), 620 "_neverlink": bool(neverlink), 621 "compilation_info": None, 622 "_constraints": [], 623 } 624 625 if get_internal_java_common().google_legacy_api_enabled(): 626 transitive_cc_infos = [dep.cc_link_params_info for dep in concatenated_deps.runtimedeps_exports_deps] 627 transitive_cc_infos.extend(native_libraries) 628 cc_info = semantics.minimize_cc_info(cc_common.merge_cc_infos(cc_infos = transitive_cc_infos)) 629 result.update( 630 cc_link_params_info = cc_info, 631 transitive_native_libraries = cc_info.transitive_native_libraries(), 632 ) 633 else: 634 result.update( 635 transitive_native_libraries = depset( 636 order = "topological", 637 transitive = [dep.transitive_native_libraries for dep in concatenated_deps.runtimedeps_exports_deps] + 638 ([cc_common.merge_cc_infos(cc_infos = native_libraries).transitive_native_libraries()] if native_libraries else []), 639 ), 640 ) 641 return result, concatenated_deps 642 643def _javainfo_init( 644 output_jar, 645 compile_jar, 646 source_jar = None, 647 compile_jdeps = None, 648 generated_class_jar = None, 649 generated_source_jar = None, 650 native_headers_jar = None, 651 manifest_proto = None, 652 neverlink = False, 653 deps = [], 654 runtime_deps = [], 655 exports = [], 656 exported_plugins = [], 657 jdeps = None, 658 native_libraries = [], 659 add_exports = [], 660 add_opens = []): 661 """The JavaInfo constructor 662 663 Args: 664 output_jar: (File) The jar that was created as a result of a compilation. 665 compile_jar: (File) A jar that is the compile-time dependency in lieu of `output_jar`. 666 source_jar: (File) The source jar that was used to create the output jar. Optional. 667 compile_jdeps: (File) jdeps information about compile time dependencies to be consumed by 668 JavaCompileAction. This should be a binary proto encoded using the deps.proto protobuf 669 included with Bazel. If available this file is typically produced by a header compiler. 670 Optional. 671 generated_class_jar: (File) A jar file containing class files compiled from sources 672 generated during annotation processing. Optional. 673 generated_source_jar: (File) The source jar that was created as a result of annotation 674 processing. Optional. 675 native_headers_jar: (File) A jar containing CC header files supporting native method 676 implementation (typically output of javac -h). Optional. 677 manifest_proto: (File) Manifest information for the rule output (if available). This should 678 be a binary proto encoded using the manifest.proto protobuf included with Bazel. IDEs 679 and other tools can use this information for more efficient processing. Optional. 680 neverlink: (bool) If true, only use this library for compilation and not at runtime. 681 deps: ([JavaInfo]) Compile time dependencies that were used to create the output jar. 682 runtime_deps: ([JavaInfo]) Runtime dependencies that are needed for this library. 683 exports: ([JavaInfo]) Libraries to make available for users of this library. 684 exported_plugins: ([JavaPluginInfo]) Optional. A list of exported plugins. 685 jdeps: (File) jdeps information for the rule output (if available). This should be a binary 686 proto encoded using the deps.proto protobuf included with Bazel. If available this file 687 is typically produced by a compiler. IDEs and other tools can use this information for 688 more efficient processing. Optional. 689 native_libraries: ([CcInfo]) Native library dependencies that are needed for this library. 690 add_exports: ([str]) The <module>/<package>s this library was given access to. 691 add_opens: ([str]) The <module>/<package>s this library was given reflective access to. 692 693 Returns: 694 (dict) arguments to the JavaInfo provider constructor 695 """ 696 if add_exports or add_opens: 697 semantics.check_java_info_opens_exports() 698 699 result, concatenated_deps = _javainfo_init_base( 700 output_jar, 701 compile_jar, 702 source_jar, 703 deps, 704 runtime_deps, 705 exports, 706 exported_plugins, 707 jdeps, 708 compile_jdeps, 709 native_headers_jar, 710 manifest_proto, 711 generated_class_jar, 712 generated_source_jar, 713 native_libraries, 714 neverlink, 715 ) 716 717 if neverlink: 718 transitive_runtime_jars = depset() 719 else: 720 transitive_runtime_jars = depset( 721 order = "preorder", 722 direct = [output_jar], 723 transitive = [dep.transitive_runtime_jars for dep in concatenated_deps.exports_deps + runtime_deps], 724 ) 725 726 # For backward compatibility, we use deps_exports for add_exports/add_opens 727 # for the JavaInfo constructor rather than runtimedeps_exports_deps (used 728 # by java_info_for_compilation). However, runtimedeps_exports_deps makes 729 # more sense, since add_exports/add_opens from runtime_deps are needed at 730 # runtime anyway. 731 # 732 # TODO: When this flag is removed, move this logic into _javainfo_init_base 733 # and remove the special case from java_info_for_compilation. 734 module_flags_deps = concatenated_deps.deps_exports 735 if get_internal_java_common().incompatible_java_info_merge_runtime_module_flags(): 736 module_flags_deps = concatenated_deps.runtimedeps_exports_deps 737 738 result.update( 739 transitive_runtime_jars = transitive_runtime_jars, 740 transitive_source_jars = depset( 741 direct = [source_jar] if source_jar else [], 742 # TODO(hvd): native also adds source jars from deps, but this should be unnecessary 743 transitive = [ 744 dep.transitive_source_jars 745 for dep in deps + runtime_deps + exports 746 ], 747 ), 748 module_flags_info = _create_module_flags_info( 749 add_exports = depset(add_exports, transitive = [ 750 dep.module_flags_info.add_exports 751 for dep in module_flags_deps 752 ]), 753 add_opens = depset(add_opens, transitive = [ 754 dep.module_flags_info.add_opens 755 for dep in module_flags_deps 756 ]), 757 ), 758 ) 759 return result 760 761JavaInfo, _new_javainfo = provider( 762 doc = "Info object encapsulating all information by java rules.", 763 fields = { 764 "transitive_runtime_jars": """(depset[File]) A transitive set of jars required on the 765 runtime classpath. 766 <p/>Note: for binary targets (such as java_binary and java_test), this is empty, since such 767 targets are not intended to be dependencies of other Java targets. 768 """, 769 "transitive_compile_time_jars": """(depset[File]) The transitive set of jars required to 770 build the target. 771 <p/>Note: for binary targets (such as java_binary and java_test), this is empty, since such 772 targets are not intended to be dependencies of other Java targets. 773 """, 774 "compile_jars": """(depset[File]) The jars required directly at compile time. They can be interface jars 775 (ijar or hjar), regular jars or both, depending on whether rule 776 implementations chose to create interface jars or not.""", 777 "full_compile_jars": """(depset[File]) The regular, full compile time Jars required by this target directly. 778 They can be: 779 - the corresponding regular Jars of the interface Jars returned by JavaInfo.compile_jars 780 - the regular (full) Jars returned by JavaInfo.compile_jars 781 782 Note: JavaInfo.compile_jars can return a mix of interface Jars and 783 regular Jars.<p>Only use this method if interface Jars don't work with 784 your rule set(s) (e.g. some Scala targets) If you're working with 785 Java-only targets it's preferable to use interface Jars via 786 JavaInfo.compile_jars""", 787 "source_jars": """([File]) A list of Jars with all the source files (including those generated by 788 annotations) of the target itself, i.e. NOT including the sources of the 789 transitive dependencies.""", 790 "outputs": "Deprecated: use java_outputs.", 791 "annotation_processing": "Deprecated: Please use plugins instead.", 792 "runtime_output_jars": "([File]) A list of runtime Jars created by this Java/Java-like target.", 793 "transitive_source_jars": "(depset[File]) The Jars of all source files in the transitive closure.", 794 "transitive_native_libraries": """(depset[LibraryToLink]) The transitive set of CC native 795 libraries required by the target.""", 796 "cc_link_params_info": "Deprecated. Do not use. C++ libraries to be linked into Java targets.", 797 "module_flags_info": "(_ModuleFlagsInfo) The Java module flag configuration.", 798 "plugins": """(_JavaPluginDataInfo) Data about all plugins that a consuming target should 799 apply. 800 This is typically either a `java_plugin` itself or a `java_library` exporting 801 one or more plugins. 802 A `java_library` runs annotation processing with all plugins from this field 803 appearing in <code>deps</code> and `plugins` attributes.""", 804 "api_generating_plugins": """"(_JavaPluginDataInfo) Data about API generating plugins 805 defined or exported by this target. 806 Those annotation processors are applied to a Java target before 807 producing its header jars (which contain method signatures). When 808 no API plugins are present, header jars are generated from the 809 sources, reducing critical path. 810 The `api_generating_plugins` is a subset of `plugins`.""", 811 "java_outputs": "(_JavaOutputInfo) Information about outputs of this Java/Java-like target.", 812 "compilation_info": """(java_compilation_info) Compilation information for this 813 Java/Java-like target.""", 814 "_transitive_full_compile_time_jars": "internal API, do not use", 815 "_compile_time_java_dependencies": "internal API, do not use", 816 "_neverlink": "internal API, do not use", 817 "_constraints": "internal API, do not use", 818 "_is_binary": "internal API, do not use", 819 }, 820 init = _javainfo_init, 821) 822 823JavaPluginDataInfo = provider( 824 doc = "Provider encapsulating information about a Java compatible plugin.", 825 fields = { 826 "processor_classes": "depset(str) The fully qualified classnames of entry points for the compiler", 827 "processor_jars": "depset(file) Deps containing an annotation processor", 828 "processor_data": "depset(file) Files needed during execution", 829 }, 830) 831 832_EMPTY_PLUGIN_DATA = JavaPluginDataInfo( 833 processor_classes = depset(), 834 processor_jars = depset(), 835 processor_data = depset(), 836) 837 838def _create_plugin_data_info(*, processor_classes, processor_jars, processor_data): 839 if processor_classes or processor_jars or processor_data: 840 return JavaPluginDataInfo( 841 processor_classes = processor_classes, 842 processor_jars = processor_jars, 843 processor_data = processor_data, 844 ) 845 else: 846 return _EMPTY_PLUGIN_DATA 847 848def disable_plugin_info_annotation_processing(plugin_info): 849 """Returns a copy of the provided JavaPluginInfo without annotation processing info 850 851 Args: 852 plugin_info: (JavaPluginInfo) the instance to transform 853 854 Returns: 855 (JavaPluginInfo) a new, transformed instance. 856 """ 857 return _new_javaplugininfo( 858 plugins = _create_plugin_data_info( 859 processor_classes = depset(order = "preorder"), 860 # Preserve the processor path, since it may contain Error Prone plugins 861 # which will be service-loaded by JavaBuilder. 862 processor_jars = plugin_info.plugins.processor_jars, 863 # Preserve data, which may be used by Error Prone plugins. 864 processor_data = plugin_info.plugins.processor_data, 865 ), 866 api_generating_plugins = _EMPTY_PLUGIN_DATA, 867 java_outputs = plugin_info.java_outputs, 868 ) 869 870def merge_plugin_info_without_outputs(infos): 871 """ Merge plugin information from a list of JavaPluginInfo or JavaInfo 872 873 Args: 874 infos: ([JavaPluginInfo|JavaInfo]) list of providers to merge 875 876 Returns: 877 (JavaPluginInfo) 878 """ 879 plugins = [] 880 api_generating_plugins = [] 881 for info in infos: 882 if _has_plugin_data(info.plugins): 883 plugins.append(info.plugins) 884 if _has_plugin_data(info.api_generating_plugins): 885 api_generating_plugins.append(info.api_generating_plugins) 886 return _new_javaplugininfo( 887 plugins = _merge_plugin_data(plugins), 888 api_generating_plugins = _merge_plugin_data(api_generating_plugins), 889 java_outputs = [], 890 ) 891 892def _has_plugin_data(plugin_data): 893 return plugin_data and ( 894 plugin_data.processor_classes or 895 plugin_data.processor_jars or 896 plugin_data.processor_data 897 ) 898 899def _merge_plugin_data(datas): 900 return _create_plugin_data_info( 901 processor_classes = depset(transitive = [p.processor_classes for p in datas]), 902 processor_jars = depset(transitive = [p.processor_jars for p in datas]), 903 processor_data = depset(transitive = [p.processor_data for p in datas]), 904 ) 905 906def _javaplugininfo_init( 907 runtime_deps, 908 processor_class, 909 data = [], 910 generates_api = False): 911 """ Constructs JavaPluginInfo 912 913 Args: 914 runtime_deps: ([JavaInfo]) list of deps containing an annotation 915 processor. 916 processor_class: (String) The fully qualified class name that the Java 917 compiler uses as an entry point to the annotation processor. 918 data: (depset[File]) The files needed by this annotation 919 processor during execution. 920 generates_api: (boolean) Set to true when this annotation processor 921 generates API code. Such an annotation processor is applied to a 922 Java target before producing its header jars (which contains method 923 signatures). When no API plugins are present, header jars are 924 generated from the sources, reducing the critical path. 925 WARNING: This parameter affects build performance, use it only if 926 necessary. 927 928 Returns: 929 (JavaPluginInfo) 930 """ 931 932 java_infos = merge(runtime_deps) 933 processor_data = data if type(data) == "depset" else depset(data) 934 plugins = _create_plugin_data_info( 935 processor_classes = depset([processor_class]) if processor_class else depset(), 936 processor_jars = java_infos.transitive_runtime_jars, 937 processor_data = processor_data, 938 ) 939 return { 940 "plugins": plugins, 941 "api_generating_plugins": plugins if generates_api else _EMPTY_PLUGIN_DATA, 942 "java_outputs": java_infos.java_outputs, 943 } 944 945JavaPluginInfo, _new_javaplugininfo = provider( 946 doc = "Provider encapsulating information about Java plugins.", 947 fields = { 948 "plugins": """ 949 Returns data about all plugins that a consuming target should apply. 950 This is typically either a <code>java_plugin</code> itself or a 951 <code>java_library</code> exporting one or more plugins. 952 A <code>java_library</code> runs annotation processing with all 953 plugins from this field appearing in <code>deps</code> and 954 <code>plugins</code> attributes.""", 955 "api_generating_plugins": """ 956 Returns data about API generating plugins defined or exported by 957 this target. 958 Those annotation processors are applied to a Java target before 959 producing its header jars (which contain method signatures). When 960 no API plugins are present, header jars are generated from the 961 sources, reducing critical path. 962 The <code>api_generating_plugins</code> is a subset of 963 <code>plugins</code>.""", 964 "java_outputs": """ 965 Returns information about outputs of this Java/Java-like target. 966 """, 967 }, 968 init = _javaplugininfo_init, 969) 970