# Copyright 2023 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
Definition of JavaInfo and JavaPluginInfo provider.
"""

load("@rules_cc//cc/common:cc_common.bzl", "cc_common")
load("@rules_cc//cc/common:cc_info.bzl", "CcInfo")
load("//java/common:java_semantics.bzl", "semantics")
load(":native.bzl", "get_internal_java_common")

# copybara: default visibility

_JavaOutputInfo = provider(
    doc = "The outputs of Java compilation.",
    fields = {
        "class_jar": "(File) A classes jar file.",
        "compile_jar": "(File) An interface jar file.",
        "header_compilation_jar": "(File) An header compilation jar file.",
        "ijar": "Deprecated: Please use compile_jar.",
        "compile_jdeps": "(File) Compile time dependencies information (deps.proto file).",
        "generated_class_jar": "(File) A jar containing classes generated via annotation processing.",
        "generated_source_jar": "(File) The source jar created as a result of annotation processing.",
        "native_headers_jar": "(File) A jar of CC header files supporting native method implementation.",
        "manifest_proto": "(File) The manifest protobuf file of the manifest generated from JavaBuilder.",
        "jdeps": "(File) The jdeps protobuf file of the manifest generated from JavaBuilder.",
        "source_jars": "(depset[File]) A depset of sources archive files.",
        "source_jar": "Deprecated: Please use source_jars instead.",
    },
)
_ModuleFlagsInfo = provider(
    doc = "Provider for the runtime classpath contributions of a Java binary.",
    fields = {
        "add_exports": "(depset[str]) Add-Exports configuration.",
        "add_opens": "(depset[str]) Add-Opens configuration.",
    },
)
_EMPTY_MODULE_FLAGS_INFO = _ModuleFlagsInfo(add_exports = depset(), add_opens = depset())

def _create_module_flags_info(*, add_exports, add_opens):
    if add_exports or add_opens:
        return _ModuleFlagsInfo(add_exports = add_exports, add_opens = add_opens)
    return _EMPTY_MODULE_FLAGS_INFO

_JavaRuleOutputJarsInfo = provider(
    doc = "Deprecated: use java_info.java_outputs. Information about outputs of a Java rule.",
    fields = {
        "jdeps": "Deprecated: Use java_info.java_outputs.",
        "native_headers": "Deprecated: Use java_info.java_outputs[i].jdeps.",
        "jars": "Deprecated: Use java_info.java_outputs[i].native_headers_jar.",
    },
)
_JavaGenJarsInfo = provider(
    doc = "Deprecated: Information about jars that are a result of annotation processing for a Java rule.",
    fields = {
        "enabled": "Deprecated. Returns true if annotation processing was applied on this target.",
        "class_jar": "Deprecated: Please use JavaInfo.java_outputs.generated_class_jar instead.",
        "source_jar": "Deprecated: Please use JavaInfo.java_outputs.generated_source_jar instead.",
        "transitive_class_jars": "Deprecated. A transitive set of class file jars from annotation " +
                                 "processing of this rule and its dependencies.",
        "transitive_source_jars": "Deprecated. A transitive set of source archives from annotation " +
                                  "processing of this rule and its dependencies.",
        "processor_classpath": "Deprecated: Please use JavaInfo.plugins instead.",
        "processor_classnames": "Deprecated: Please use JavaInfo.plugins instead.",
    },
)

JavaCompilationInfo = provider(
    doc = "Compilation information in Java rules, for perusal of aspects and tools.",
    fields = {
        "boot_classpath": "Boot classpath for this Java target.",
        "javac_options": """Depset of options to the java compiler. To get the
            exact list of options passed to javac in the correct order, use the
            tokenize_javacopts utility in rules_java""",
        "compilation_classpath": "Compilation classpath for this Java target.",
        "runtime_classpath": "Run-time classpath for this Java target.",
    },
)

def merge(
        providers,
        # private to @_builtins:
        merge_java_outputs = True,
        merge_source_jars = True):
    """Merges the given providers into a single JavaInfo.

    Args:
        providers: ([JavaInfo]) The list of providers to merge.
        merge_java_outputs: (bool)
        merge_source_jars: (bool)

    Returns:
        (JavaInfo) The merged JavaInfo
    """
    _validate_provider_list(providers, "providers", JavaInfo)

    plugin_info = merge_plugin_info_without_outputs(providers)

    source_jars = []  # [File]
    transitive_source_jars = []  # [depset[File]]
    java_outputs = []  # [_JavaOutputInfo]
    runtime_output_jars = []  # [File]
    transitive_runtime_jars = []  # [depset[File]]
    transitive_compile_time_jars = []  # [depset[File]]
    compile_jars = []  # [depset[File]]
    header_compilation_direct_deps = []  # [depset[File]]
    full_compile_jars = []  # [depset[File]]
    _transitive_full_compile_time_jars = []  # [depset[File]]
    _compile_time_java_dependencies = []  # [depset[File]]
    add_exports = []  # [depset[str]]
    add_opens = []  # [depset[str]]
    _neverlink = False
    _constraints = []  # [str]
    for p in providers:
        if merge_source_jars:
            source_jars.extend(p.source_jars)
            transitive_source_jars.append(p.transitive_source_jars)
        if merge_java_outputs:
            java_outputs.extend(p.java_outputs)
            runtime_output_jars.extend(p.runtime_output_jars)
        transitive_runtime_jars.append(p.transitive_runtime_jars)
        transitive_compile_time_jars.append(p.transitive_compile_time_jars)
        compile_jars.append(p.compile_jars)
        header_compilation_direct_deps.append(p.header_compilation_direct_deps)
        full_compile_jars.append(p.full_compile_jars)
        _transitive_full_compile_time_jars.append(p._transitive_full_compile_time_jars)
        _compile_time_java_dependencies.append(p._compile_time_java_dependencies)
        add_exports.append(p.module_flags_info.add_exports)
        add_opens.append(p.module_flags_info.add_opens)
        _neverlink = _neverlink or p._neverlink
        _constraints.extend(p._constraints)

    transitive_runtime_jars = depset(order = "preorder", transitive = transitive_runtime_jars)
    transitive_compile_time_jars = depset(order = "preorder", transitive = transitive_compile_time_jars)

    # java_outputs is a list so we uniquify to avoid https://github.com/bazelbuild/bazel/issues/17170
    java_outputs = depset(java_outputs).to_list()
    result = {
        "transitive_runtime_jars": transitive_runtime_jars,
        "transitive_compile_time_jars": transitive_compile_time_jars,
        "compile_jars": depset(order = "preorder", transitive = compile_jars),
        "header_compilation_direct_deps": depset(order = "preorder", transitive = header_compilation_direct_deps),
        "full_compile_jars": depset(order = "preorder", transitive = full_compile_jars),
        "_transitive_full_compile_time_jars": depset(order = "preorder", transitive = _transitive_full_compile_time_jars),
        "_compile_time_java_dependencies": depset(order = "preorder", transitive = _compile_time_java_dependencies),
        # runtime_output_jars is a list so we uniquify to avoid https://github.com/bazelbuild/bazel/issues/17170
        "runtime_output_jars": depset(runtime_output_jars).to_list(),
        # source_jars is a list so we uniquify to avoid https://github.com/bazelbuild/bazel/issues/17170
        "source_jars": depset(source_jars).to_list(),
        "transitive_source_jars": depset(transitive = transitive_source_jars),
        "java_outputs": java_outputs,
        "outputs": _JavaRuleOutputJarsInfo(jars = java_outputs, jdeps = None, native_headers = None),
        "module_flags_info": _create_module_flags_info(
            add_exports = depset(transitive = add_exports),
            add_opens = depset(transitive = add_opens),
        ),
        "plugins": plugin_info.plugins,
        "api_generating_plugins": plugin_info.api_generating_plugins,
        "_neverlink": bool(_neverlink),
        "_constraints": depset(_constraints).to_list(),
        "annotation_processing": None,
        "compilation_info": None,
    }

    if get_internal_java_common().google_legacy_api_enabled():
        cc_info = semantics.minimize_cc_info(cc_common.merge_cc_infos(cc_infos = [p.cc_link_params_info for p in providers]))
        result.update(
            cc_link_params_info = cc_info,
            transitive_native_libraries = cc_info.transitive_native_libraries(),
        )
    else:
        result.update(
            transitive_native_libraries = depset(
                order = "topological",
                transitive = [p.transitive_native_libraries for p in providers],
            ),
        )
    return _new_javainfo(**result)

def to_java_binary_info(java_info, compilation_info):
    """Get a copy of the given JavaInfo with minimal info returned by a java_binary

    Args:
        java_info: (JavaInfo) A JavaInfo provider instance
        compilation_info: (JavaCompilationInfo)
    Returns:
        (JavaInfo) A JavaInfo instance representing a java_binary target
    """
    result = {
        "transitive_runtime_jars": depset(),
        "transitive_compile_time_jars": depset(),
        "compile_jars": depset(),
        "header_compilation_direct_deps": depset(),
        "full_compile_jars": depset(),
        "_transitive_full_compile_time_jars": depset(),
        "_compile_time_java_dependencies": depset(),
        "runtime_output_jars": [],
        "plugins": _EMPTY_PLUGIN_DATA,
        "api_generating_plugins": _EMPTY_PLUGIN_DATA,
        "module_flags_info": _EMPTY_MODULE_FLAGS_INFO,
        "_neverlink": False,
        "_constraints": [],
        "annotation_processing": java_info.annotation_processing,
        "transitive_native_libraries": java_info.transitive_native_libraries,
        "source_jars": java_info.source_jars,
        "transitive_source_jars": java_info.transitive_source_jars,
    }
    if hasattr(java_info, "cc_link_params_info"):
        result.update(cc_link_params_info = java_info.cc_link_params_info)

    result["compilation_info"] = compilation_info

    java_outputs = [
        _JavaOutputInfo(
            compile_jar = None,
            header_compilation_jar = None,
            ijar = None,  # deprecated
            compile_jdeps = None,
            class_jar = output.class_jar,
            generated_class_jar = output.generated_class_jar,
            generated_source_jar = output.generated_source_jar,
            native_headers_jar = output.native_headers_jar,
            manifest_proto = output.manifest_proto,
            jdeps = output.jdeps,
            source_jars = output.source_jars,
            source_jar = output.source_jar,  # deprecated
        )
        for output in java_info.java_outputs
    ]
    all_jdeps = [output.jdeps for output in java_info.java_outputs if output.jdeps]
    all_native_headers = [output.native_headers_jar for output in java_info.java_outputs if output.native_headers_jar]
    result.update(
        java_outputs = java_outputs,
        outputs = _JavaRuleOutputJarsInfo(
            jars = java_outputs,
            jdeps = all_jdeps[0] if len(all_jdeps) == 1 else None,
            native_headers = all_native_headers[0] if len(all_native_headers) == 1 else None,
        ),
    )

    # so that translation into native JavaInfo does not add JavaCompilationArgsProvider
    result.update(_is_binary = True)
    return _new_javainfo(**result)

def to_implicit_exportable(java_info, neverlink = False):
    result = {
        "transitive_runtime_jars": depset() if neverlink else java_info.transitive_runtime_jars,
        "transitive_compile_time_jars": java_info.transitive_compile_time_jars,
        "compile_jars": java_info.compile_jars,
        "header_compilation_direct_deps": java_info.header_compilation_direct_deps,
        "full_compile_jars": java_info.full_compile_jars,
        "_transitive_full_compile_time_jars": java_info._transitive_full_compile_time_jars,
        "_compile_time_java_dependencies": java_info._compile_time_java_dependencies,
        "_neverlink": neverlink,
        # unset defaults
        "source_jars": [],
        "outputs": _JavaRuleOutputJarsInfo(jars = [], jdeps = None, native_headers = None),
        "annotation_processing": None,
        "runtime_output_jars": [],
        "transitive_source_jars": depset(),
        "transitive_native_libraries": depset(),
        "cc_link_params_info": CcInfo(),
        "module_flags_info": _EMPTY_MODULE_FLAGS_INFO,
        "plugins": _EMPTY_PLUGIN_DATA,
        "api_generating_plugins": _EMPTY_PLUGIN_DATA,
        "java_outputs": [],
        "compilation_info": None,
        "_constraints": [],
        "_is_binary": getattr(java_info, "_is_binary", False),
    }
    return _new_javainfo(**result)

def _to_mutable_dict(java_info):
    return {
        key: getattr(java_info, key)
        for key in dir(java_info)
        if key not in ["to_json", "to_proto"]
    }

def add_constraints(java_info, constraints = []):
    """Returns a copy of the given JavaInfo with the given constraints added.

    Args:
        java_info: (JavaInfo) The JavaInfo to enhance
        constraints: ([str]) Constraints to add

    Returns:
        (JavaInfo)
    """
    result = _to_mutable_dict(java_info)
    old_constraints = java_info._constraints if java_info._constraints else []
    result.update(
        _constraints = depset(constraints + old_constraints).to_list(),
    )
    return _new_javainfo(**result)

def make_non_strict(java_info):
    """Returns a new JavaInfo instance whose direct-jars part is the union of both the direct and indirect jars of the given Java provider.

    Args:
        java_info: (JavaInfo) The java info to make non-strict.

    Returns:
        (JavaInfo)
    """
    result = _to_mutable_dict(java_info)
    result.update(
        compile_jars = java_info.transitive_compile_time_jars,
        full_compile_jars = java_info._transitive_full_compile_time_jars,
        header_compilation_direct_deps = java_info.transitive_compile_time_jars,
    )

    # Omit jdeps, which aren't available transitively and aren't useful for reduced classpath
    # pruning for non-strict targets: the direct classpath and transitive classpath are the same,
    # so there's nothing to prune, and reading jdeps at compile-time isn't free.
    result.update(
        _compile_time_java_dependencies = depset(),
    )
    return _new_javainfo(**result)

def add_module_flags(java_info, add_exports = [], add_opens = []):
    """Returns a new JavaInfo instance with the additional add_exports/add_opens

    Args:
        java_info: (JavaInfo) The java info to enhance.
        add_exports: ([str]) The <module>/<package>s given access to.
        add_opens: ([str]) The <module>/<package>s given reflective access to.
    Returns:
        (JavaInfo)
    """
    if not add_exports and not add_opens:
        return java_info

    result = _to_mutable_dict(java_info)
    result.update(
        module_flags_info = _create_module_flags_info(
            add_exports = depset(add_exports, transitive = [java_info.module_flags_info.add_exports]),
            add_opens = depset(add_opens, transitive = [java_info.module_flags_info.add_opens]),
        ),
    )
    return _new_javainfo(**result)

def set_annotation_processing(
        java_info,
        enabled = False,
        processor_classnames = [],
        processor_classpath = None,
        class_jar = None,
        source_jar = None):
    """Returns a copy of the given JavaInfo with the given annotation_processing info.

    Args:
        java_info: (JavaInfo) The JavaInfo to enhance.
        enabled: (bool) Whether the rule uses annotation processing.
        processor_classnames: ([str]) Class names of annotation processors applied.
        processor_classpath: (depset[File]) Class names of annotation processors applied.
        class_jar: (File) Optional. Jar that is the result of annotation processing.
        source_jar: (File) Optional. Source archive resulting from annotation processing.

    Returns:
        (JavaInfo)
    """
    gen_jars_info = java_info.annotation_processing
    if gen_jars_info:
        # Existing Jars would be a problem b/c we can't remove them from transitiveXxx sets
        if gen_jars_info.class_jar and gen_jars_info.class_jar != class_jar:
            fail("Existing gen_class_jar:", gen_jars_info.class_jar)
        if gen_jars_info.source_jar and gen_jars_info.source_jar != source_jar:
            fail("Existing gen_source_jar:", gen_jars_info.class_jar)
        transitive_class_jars = depset([class_jar] if class_jar else [], transitive = [gen_jars_info.transitive_class_jars])
        transitive_source_jars = depset([source_jar] if source_jar else [], transitive = [gen_jars_info.transitive_source_jars])
    else:
        transitive_class_jars = depset([class_jar] if class_jar else [])
        transitive_source_jars = depset([source_jar] if source_jar else [])

    result = _to_mutable_dict(java_info)
    result.update(
        annotation_processing = _JavaGenJarsInfo(
            enabled = enabled,
            class_jar = class_jar,
            source_jar = source_jar,
            processor_classnames = processor_classnames,
            processor_classpath = processor_classpath if processor_classpath else depset(),
            transitive_class_jars = transitive_class_jars,
            transitive_source_jars = transitive_source_jars,
        ),
    )
    return _new_javainfo(**result)

def java_info_for_compilation(
        output_jar,
        compile_jar,
        source_jar,
        generated_class_jar,
        generated_source_jar,
        plugin_info,
        deps,
        runtime_deps,
        exports,
        exported_plugins,
        compile_jdeps,
        jdeps,
        native_headers_jar,
        manifest_proto,
        native_libraries,
        neverlink,
        add_exports,
        add_opens,
        direct_runtime_jars,
        compilation_info,
        header_compilation_jar):
    """Creates a JavaInfo instance represiting the result of java compilation.

    Args:
        output_jar: (File) The jar that was created as a result of a compilation.
        compile_jar: (File) A jar that is the compile-time dependency in lieu of `output_jar`.
        header_compilation_jar: (File) A jar that is used for header compilation in lieu of
            compile_jar or output_jar.
        source_jar: (File) The source jar that was used to create the output jar.
        generated_class_jar: (File) A jar file containing class files compiled from sources
            generated during annotation processing.
        generated_source_jar: (File) The source jar that was created as a result of annotation
            processing.
        plugin_info: (JavaPluginInfo) Information about annotation processing.
        deps: ([JavaInfo]) Compile time dependencies that were used to create the output jar.
        runtime_deps: ([JavaInfo]) Runtime dependencies that are needed for this library.
        exports: ([JavaInfo]) Libraries to make available for users of this library.
        exported_plugins: ([JavaPluginInfo]) A list of exported plugins.
        compile_jdeps: (File) jdeps information about compile time dependencies to be consumed by
            JavaCompileAction. This should be a binary proto encoded using the deps.proto protobuf
            included with Bazel. If available this file is typically produced by a header compiler.
        jdeps: (File) jdeps information for the rule output (if available). This should be a binary
            proto encoded using the deps.proto protobuf included with Bazel. If available this file
            is typically produced by a compiler. IDEs and other tools can use this information for
            more efficient processing.
        native_headers_jar: (File) A jar containing CC header files supporting native method
            implementation (typically output of javac -h).
        manifest_proto: (File) Manifest information for the rule output (if available). This should
            be a binary proto encoded using the manifest.proto protobuf included with Bazel. IDEs
            and other tools can use this information for more efficient processing.
        native_libraries: ([CcInfo]) Native library dependencies that are needed for this library.
        neverlink: (bool) If true, only use this library for compilation and not at runtime.
        add_exports: ([str]) The <module>/<package>s this library was given access to.
        add_opens: ([str]) The <module>/<package>s this library was given reflective access to.
        direct_runtime_jars: ([File]) The class jars needed directly by this library at runtime.
            This is usually just the output_jar or empty if there were no sources/resources.
        compilation_info: (struct) Information for IDE/tools

    Returns:
        (JavaInfo) the JavaInfo instance
    """
    result, concatenated_deps = _javainfo_init_base(
        output_jar,
        compile_jar,
        source_jar,
        deps,
        runtime_deps,
        exports,
        exported_plugins,
        jdeps,
        compile_jdeps,
        native_headers_jar,
        manifest_proto,
        generated_class_jar,
        generated_source_jar,
        native_libraries,
        neverlink,
        header_compilation_jar,
    )

    # this differs ever so slightly from the usual JavaInfo in that direct_runtime_jars
    # does not contain the output_jar is there were no sources/resources
    transitive_runtime_jars = depset() if neverlink else depset(
        order = "preorder",
        direct = direct_runtime_jars,
        transitive = [dep.transitive_runtime_jars for dep in concatenated_deps.exports_deps + runtime_deps],
    )
    result.update(
        runtime_output_jars = direct_runtime_jars,
        transitive_runtime_jars = transitive_runtime_jars,
        transitive_source_jars = depset(
            direct = [source_jar],
            # only differs from the usual java_info.transitive_source_jars in the order of deps
            transitive = [dep.transitive_source_jars for dep in concatenated_deps.runtimedeps_exports_deps],
        ),
        # the JavaInfo constructor does not add flags from runtime_deps
        module_flags_info = _create_module_flags_info(
            add_exports = depset(add_exports, transitive = [
                dep.module_flags_info.add_exports
                for dep in concatenated_deps.runtimedeps_exports_deps
            ]),
            add_opens = depset(add_opens, transitive = [
                dep.module_flags_info.add_opens
                for dep in concatenated_deps.runtimedeps_exports_deps
            ]),
        ),
    )
    if compilation_info:
        result.update(
            compilation_info = JavaCompilationInfo(
                javac_options = compilation_info.javac_options,
                boot_classpath = compilation_info.boot_classpath,
                compilation_classpath = compilation_info.compilation_classpath,
                runtime_classpath = compilation_info.runtime_classpath,
            ),
            annotation_processing = _JavaGenJarsInfo(
                enabled = compilation_info.uses_annotation_processing,
                class_jar = result["annotation_processing"].class_jar,
                source_jar = result["annotation_processing"].source_jar,
                processor_classnames = plugin_info.plugins.processor_classes.to_list(),
                processor_classpath = plugin_info.plugins.processor_jars,
                transitive_class_jars = result["annotation_processing"].transitive_class_jars,
                transitive_source_jars = result["annotation_processing"].transitive_source_jars,
            ),
        )
    else:
        result.update(
            compilation_info = None,
            annotation_processing = None,
        )
    return _new_javainfo(**result)

def _validate_provider_list(provider_list, what, expected_provider_type):
    get_internal_java_common().check_provider_instances(provider_list, what, expected_provider_type)

def _compute_concatenated_deps(deps, runtime_deps, exports):
    deps_exports = []
    deps_exports.extend(deps)
    deps_exports.extend(exports)

    exports_deps = []
    exports_deps.extend(exports)
    exports_deps.extend(deps)

    runtimedeps_exports_deps = []
    runtimedeps_exports_deps.extend(runtime_deps)
    runtimedeps_exports_deps.extend(exports_deps)

    return struct(
        deps_exports = deps_exports,
        exports_deps = exports_deps,
        runtimedeps_exports_deps = runtimedeps_exports_deps,
    )

def _javainfo_init_base(
        output_jar,
        compile_jar,
        source_jar,
        deps,
        runtime_deps,
        exports,
        exported_plugins,
        jdeps,
        compile_jdeps,
        native_headers_jar,
        manifest_proto,
        generated_class_jar,
        generated_source_jar,
        native_libraries,
        neverlink,
        header_compilation_jar = None):
    _validate_provider_list(deps, "deps", JavaInfo)
    _validate_provider_list(runtime_deps, "runtime_deps", JavaInfo)
    _validate_provider_list(exports, "exports", JavaInfo)
    _validate_provider_list(native_libraries, "native_libraries", CcInfo)

    # For clients that don't create a header_compilation_jar (e.g. java_import), fall back to using
    # the compile jar.
    if compile_jar and not header_compilation_jar:
        header_compilation_jar = compile_jar

    concatenated_deps = _compute_concatenated_deps(deps, runtime_deps, exports)

    source_jars = [source_jar] if source_jar else []
    plugin_info = merge_plugin_info_without_outputs(exported_plugins + exports)
    transitive_compile_time_jars = depset(
        order = "preorder",
        direct = [compile_jar] if compile_jar else [],
        transitive = [dep.transitive_compile_time_jars for dep in concatenated_deps.exports_deps],
    )
    java_outputs = [_JavaOutputInfo(
        class_jar = output_jar,
        compile_jar = compile_jar,
        header_compilation_jar = header_compilation_jar,
        ijar = compile_jar,  # deprecated
        compile_jdeps = compile_jdeps,
        generated_class_jar = generated_class_jar,
        generated_source_jar = generated_source_jar,
        native_headers_jar = native_headers_jar,
        manifest_proto = manifest_proto,
        jdeps = jdeps,
        source_jars = depset(source_jars),
        source_jar = source_jar,  # deprecated
    )]
    result = {
        "transitive_compile_time_jars": transitive_compile_time_jars,
        "compile_jars": depset(
            order = "preorder",
            direct = [compile_jar] if compile_jar else [],
            transitive = [dep.compile_jars for dep in exports],
        ),
        "header_compilation_direct_deps": depset(
            order = "preorder",
            direct = [header_compilation_jar] if header_compilation_jar else [],
            transitive = [dep.header_compilation_direct_deps for dep in exports],
        ),
        "full_compile_jars": depset(
            order = "preorder",
            direct = [output_jar],
            transitive = [
                dep.full_compile_jars
                for dep in exports
            ],
        ),
        "source_jars": source_jars,
        "runtime_output_jars": [output_jar],
        "plugins": plugin_info.plugins,
        "api_generating_plugins": plugin_info.api_generating_plugins,
        "java_outputs": java_outputs,
        # deprecated
        "outputs": _JavaRuleOutputJarsInfo(
            jars = java_outputs,
            jdeps = jdeps,
            native_headers = native_headers_jar,
        ),
        "annotation_processing": _JavaGenJarsInfo(
            enabled = False,
            class_jar = generated_class_jar,
            source_jar = generated_source_jar,
            transitive_class_jars = depset(
                direct = [generated_class_jar] if generated_class_jar else [],
                transitive = [
                    dep.annotation_processing.transitive_class_jars
                    for dep in concatenated_deps.deps_exports
                    if dep.annotation_processing
                ],
            ),
            transitive_source_jars = depset(
                direct = [generated_source_jar] if generated_source_jar else [],
                transitive = [
                    dep.annotation_processing.transitive_source_jars
                    for dep in concatenated_deps.deps_exports
                    if dep.annotation_processing
                ],
            ),
            processor_classnames = [],
            processor_classpath = depset(),
        ),
        "_transitive_full_compile_time_jars": depset(
            order = "preorder",
            direct = [output_jar],
            transitive = [dep._transitive_full_compile_time_jars for dep in concatenated_deps.exports_deps],
        ),
        "_compile_time_java_dependencies": depset(
            order = "preorder",
            transitive = [dep._compile_time_java_dependencies for dep in exports] +
                         ([depset([compile_jdeps])] if compile_jdeps else []),
        ),
        "_neverlink": bool(neverlink),
        "compilation_info": None,
        "_constraints": [],
    }

    if get_internal_java_common().google_legacy_api_enabled():
        transitive_cc_infos = [dep.cc_link_params_info for dep in concatenated_deps.runtimedeps_exports_deps]
        transitive_cc_infos.extend(native_libraries)
        cc_info = semantics.minimize_cc_info(cc_common.merge_cc_infos(cc_infos = transitive_cc_infos))
        result.update(
            cc_link_params_info = cc_info,
            transitive_native_libraries = cc_info.transitive_native_libraries(),
        )
    else:
        result.update(
            transitive_native_libraries = depset(
                order = "topological",
                transitive = [dep.transitive_native_libraries for dep in concatenated_deps.runtimedeps_exports_deps] +
                             ([cc_common.merge_cc_infos(cc_infos = native_libraries).transitive_native_libraries()] if native_libraries else []),
            ),
        )
    return result, concatenated_deps

def _javainfo_init(
        output_jar,
        compile_jar,
        header_compilation_jar = None,
        source_jar = None,
        compile_jdeps = None,
        generated_class_jar = None,
        generated_source_jar = None,
        native_headers_jar = None,
        manifest_proto = None,
        neverlink = False,
        deps = [],
        runtime_deps = [],
        exports = [],
        exported_plugins = [],
        jdeps = None,
        native_libraries = [],
        add_exports = [],
        add_opens = []):
    """The JavaInfo constructor

    Args:
        output_jar: (File) The jar that was created as a result of a compilation.
        compile_jar: (File) A jar that is the compile-time dependency in lieu of `output_jar`.
        header_compilation_jar: (File) A jar that is used for header compilation in lieu of
            compile_jar or output_jar.
        source_jar: (File) The source jar that was used to create the output jar. Optional.
        compile_jdeps: (File) jdeps information about compile time dependencies to be consumed by
            JavaCompileAction. This should be a binary proto encoded using the deps.proto protobuf
            included with Bazel. If available this file is typically produced by a header compiler.
            Optional.
        generated_class_jar: (File) A jar file containing class files compiled from sources
            generated during annotation processing. Optional.
        generated_source_jar: (File) The source jar that was created as a result of annotation
            processing. Optional.
        native_headers_jar: (File) A jar containing CC header files supporting native method
            implementation (typically output of javac -h). Optional.
        manifest_proto: (File) Manifest information for the rule output (if available). This should
            be a binary proto encoded using the manifest.proto protobuf included with Bazel. IDEs
            and other tools can use this information for more efficient processing. Optional.
        neverlink: (bool) If true, only use this library for compilation and not at runtime.
        deps: ([JavaInfo]) Compile time dependencies that were used to create the output jar.
        runtime_deps: ([JavaInfo]) Runtime dependencies that are needed for this library.
        exports: ([JavaInfo]) Libraries to make available for users of this library.
        exported_plugins: ([JavaPluginInfo]) Optional. A list of exported plugins.
        jdeps: (File) jdeps information for the rule output (if available). This should be a binary
            proto encoded using the deps.proto protobuf included with Bazel. If available this file
            is typically produced by a compiler. IDEs and other tools can use this information for
            more efficient processing. Optional.
        native_libraries: ([CcInfo]) Native library dependencies that are needed for this library.
        add_exports: ([str]) The <module>/<package>s this library was given access to.
        add_opens: ([str]) The <module>/<package>s this library was given reflective access to.

    Returns:
        (dict) arguments to the JavaInfo provider constructor
    """
    if add_exports or add_opens:
        semantics.check_java_info_opens_exports()

    result, concatenated_deps = _javainfo_init_base(
        output_jar,
        compile_jar,
        source_jar,
        deps,
        runtime_deps,
        exports,
        exported_plugins,
        jdeps,
        compile_jdeps,
        native_headers_jar,
        manifest_proto,
        generated_class_jar,
        generated_source_jar,
        native_libraries,
        neverlink,
        header_compilation_jar = header_compilation_jar,
    )

    if neverlink:
        transitive_runtime_jars = depset()
    else:
        transitive_runtime_jars = depset(
            order = "preorder",
            direct = [output_jar],
            transitive = [dep.transitive_runtime_jars for dep in concatenated_deps.exports_deps + runtime_deps],
        )

    # For backward compatibility, we use deps_exports for add_exports/add_opens
    # for the JavaInfo constructor rather than runtimedeps_exports_deps (used
    # by java_info_for_compilation). However, runtimedeps_exports_deps makes
    # more sense, since add_exports/add_opens from runtime_deps are needed at
    # runtime anyway.
    #
    # TODO: When this flag is removed, move this logic into _javainfo_init_base
    #  and remove the special case from java_info_for_compilation.
    module_flags_deps = concatenated_deps.deps_exports
    if get_internal_java_common().incompatible_java_info_merge_runtime_module_flags():
        module_flags_deps = concatenated_deps.runtimedeps_exports_deps

    result.update(
        transitive_runtime_jars = transitive_runtime_jars,
        transitive_source_jars = depset(
            direct = [source_jar] if source_jar else [],
            # TODO(hvd): native also adds source jars from deps, but this should be unnecessary
            transitive = [
                dep.transitive_source_jars
                for dep in deps + runtime_deps + exports
            ],
        ),
        module_flags_info = _create_module_flags_info(
            add_exports = depset(add_exports, transitive = [
                dep.module_flags_info.add_exports
                for dep in module_flags_deps
            ]),
            add_opens = depset(add_opens, transitive = [
                dep.module_flags_info.add_opens
                for dep in module_flags_deps
            ]),
        ),
    )
    return result

JavaInfo, _new_javainfo = provider(
    doc = "Info object encapsulating all information by java rules.",
    fields = {
        "transitive_runtime_jars": """(depset[File]) A transitive set of jars required on the
        runtime classpath.
        <p/>Note: for binary targets (such as java_binary and java_test), this is empty, since such
        targets are not intended to be dependencies of other Java targets.
        """,
        "transitive_compile_time_jars": """(depset[File]) The transitive set of jars required to
        build the target.
        <p/>Note: for binary targets (such as java_binary and java_test), this is empty, since such
        targets are not intended to be dependencies of other Java targets.
        """,
        "compile_jars": """(depset[File]) The jars required directly at compile time. They can be interface jars
                (ijar or hjar), regular jars or both, depending on whether rule
                implementations chose to create interface jars or not.""",
        "header_compilation_direct_deps": """(depset[File]) The header compilation jars required
                directly at compile time.""",
        "full_compile_jars": """(depset[File]) The regular, full compile time Jars required by this target directly.
                They can be:
                 - the corresponding regular Jars of the interface Jars returned by JavaInfo.compile_jars
                 - the regular (full) Jars returned by JavaInfo.compile_jars

                Note: JavaInfo.compile_jars can return a mix of interface Jars and
                regular Jars.<p>Only use this method if interface Jars don't work with
                your rule set(s) (e.g. some Scala targets) If you're working with
                Java-only targets it's preferable to use interface Jars via
                JavaInfo.compile_jars""",
        "source_jars": """([File]) A list of Jars with all the source files (including those generated by
                annotations) of the target itself, i.e. NOT including the sources of the
                transitive dependencies.""",
        "outputs": "Deprecated: use java_outputs.",
        "annotation_processing": "Deprecated: Please use plugins instead.",
        "runtime_output_jars": "([File]) A list of runtime Jars created by this Java/Java-like target.",
        "transitive_source_jars": "(depset[File]) The Jars of all source files in the transitive closure.",
        "transitive_native_libraries": """(depset[LibraryToLink]) The transitive set of CC native
                libraries required by the target.""",
        "cc_link_params_info": "Deprecated. Do not use. C++ libraries to be linked into Java targets.",
        "module_flags_info": "(_ModuleFlagsInfo) The Java module flag configuration.",
        "plugins": """(_JavaPluginDataInfo) Data about all plugins that a consuming target should
               apply.
               This is typically either a `java_plugin` itself or a `java_library` exporting
               one or more plugins.
               A `java_library` runs annotation processing with all plugins from this field
               appearing in <code>deps</code> and `plugins` attributes.""",
        "api_generating_plugins": """"(_JavaPluginDataInfo) Data about API generating plugins
               defined or exported by this target.
               Those annotation processors are applied to a Java target before
               producing its header jars (which contain method signatures). When
               no API plugins are present, header jars are generated from the
               sources, reducing critical path.
               The `api_generating_plugins` is a subset of `plugins`.""",
        "java_outputs": "(_JavaOutputInfo) Information about outputs of this Java/Java-like target.",
        "compilation_info": """(java_compilation_info) Compilation information for this
               Java/Java-like target.""",
        "_transitive_full_compile_time_jars": "internal API, do not use",
        "_compile_time_java_dependencies": "internal API, do not use",
        "_neverlink": "internal API, do not use",
        "_constraints": "internal API, do not use",
        "_is_binary": "internal API, do not use",
    },
    init = _javainfo_init,
)

JavaPluginDataInfo = provider(
    doc = "Provider encapsulating information about a Java compatible plugin.",
    fields = {
        "processor_classes": "depset(str) The fully qualified classnames of entry points for the compiler",
        "processor_jars": "depset(file) Deps containing an annotation processor",
        "processor_data": "depset(file) Files needed during execution",
    },
)

_EMPTY_PLUGIN_DATA = JavaPluginDataInfo(
    processor_classes = depset(),
    processor_jars = depset(),
    processor_data = depset(),
)

def _create_plugin_data_info(*, processor_classes, processor_jars, processor_data):
    if processor_classes or processor_jars or processor_data:
        return JavaPluginDataInfo(
            processor_classes = processor_classes,
            processor_jars = processor_jars,
            processor_data = processor_data,
        )
    else:
        return _EMPTY_PLUGIN_DATA

def disable_plugin_info_annotation_processing(plugin_info):
    """Returns a copy of the provided JavaPluginInfo without annotation processing info

    Args:
        plugin_info: (JavaPluginInfo) the instance to transform

    Returns:
        (JavaPluginInfo) a new, transformed instance.
     """
    return _new_javaplugininfo(
        plugins = _create_plugin_data_info(
            processor_classes = depset(order = "preorder"),
            # Preserve the processor path, since it may contain Error Prone plugins
            # which will be service-loaded by JavaBuilder.
            processor_jars = plugin_info.plugins.processor_jars,
            # Preserve data, which may be used by Error Prone plugins.
            processor_data = plugin_info.plugins.processor_data,
        ),
        api_generating_plugins = _EMPTY_PLUGIN_DATA,
        java_outputs = plugin_info.java_outputs,
    )

def merge_plugin_info_without_outputs(infos):
    """ Merge plugin information from a list of JavaPluginInfo or JavaInfo

    Args:
        infos: ([JavaPluginInfo|JavaInfo]) list of providers to merge

    Returns:
        (JavaPluginInfo)
    """
    plugins = []
    api_generating_plugins = []
    for info in infos:
        if _has_plugin_data(info.plugins):
            plugins.append(info.plugins)
        if _has_plugin_data(info.api_generating_plugins):
            api_generating_plugins.append(info.api_generating_plugins)
    return _new_javaplugininfo(
        plugins = _merge_plugin_data(plugins),
        api_generating_plugins = _merge_plugin_data(api_generating_plugins),
        java_outputs = [],
    )

def _has_plugin_data(plugin_data):
    return plugin_data and (
        plugin_data.processor_classes or
        plugin_data.processor_jars or
        plugin_data.processor_data
    )

def _merge_plugin_data(datas):
    return _create_plugin_data_info(
        processor_classes = depset(transitive = [p.processor_classes for p in datas]),
        processor_jars = depset(transitive = [p.processor_jars for p in datas]),
        processor_data = depset(transitive = [p.processor_data for p in datas]),
    )

def _javaplugininfo_init(
        runtime_deps,
        processor_class = None,
        processor_classes = [],
        data = [],
        generates_api = False):
    """ Constructs JavaPluginInfo

    Args:
        runtime_deps: ([JavaInfo]) list of deps containing an annotation
             processor.
        processor_class: (String) The fully qualified class name that the Java
             compiler uses as an entry point to the annotation processor.
        processor_classes: ([String]) Fully qualified class names that the
            Java compiler uses as an entry point to the annotation processor.
        data: (depset[File]) The files needed by this annotation
             processor during execution.
        generates_api: (boolean) Set to true when this annotation processor
            generates API code. Such an annotation processor is applied to a
            Java target before producing its header jars (which contains method
            signatures). When no API plugins are present, header jars are
            generated from the sources, reducing the critical path.
            WARNING: This parameter affects build performance, use it only if
            necessary.

    Returns:
        (JavaPluginInfo)
    """

    java_infos = merge(runtime_deps)
    processor_data = data if type(data) == "depset" else depset(data)
    plugins = _create_plugin_data_info(
        processor_classes = depset([processor_class] + processor_classes) if processor_class else depset(processor_classes),
        processor_jars = java_infos.transitive_runtime_jars,
        processor_data = processor_data,
    )
    return {
        "plugins": plugins,
        "api_generating_plugins": plugins if generates_api else _EMPTY_PLUGIN_DATA,
        "java_outputs": java_infos.java_outputs,
    }

JavaPluginInfo, _new_javaplugininfo = provider(
    doc = "Provider encapsulating information about Java plugins.",
    fields = {
        "plugins": """
            Returns data about all plugins that a consuming target should apply.
            This is typically either a <code>java_plugin</code> itself or a
            <code>java_library</code> exporting one or more plugins.
            A <code>java_library</code> runs annotation processing with all
            plugins from this field appearing in <code>deps</code> and
            <code>plugins</code> attributes.""",
        "api_generating_plugins": """
            Returns data about API generating plugins defined or exported by
            this target.
            Those annotation processors are applied to a Java target before
            producing its header jars (which contain method signatures). When
            no API plugins are present, header jars are generated from the
            sources, reducing critical path.
            The <code>api_generating_plugins</code> is a subset of
            <code>plugins</code>.""",
        "java_outputs": """
            Returns information about outputs of this Java/Java-like target.
        """,
    },
    init = _javaplugininfo_init,
)
