// Copyright 2016 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.
package com.google.devtools.build.lib.rules.java;

import static com.google.common.collect.MoreCollectors.onlyElement;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.common.truth.Truth8.assertThat;
import static com.google.devtools.build.lib.actions.util.ActionsTestUtil.prettyArtifactNames;
import static com.google.devtools.build.lib.rules.java.JavaCompileActionTestHelper.getProcessorNames;
import static com.google.devtools.build.lib.rules.java.JavaCompileActionTestHelper.getProcessorPath;
import static java.util.Arrays.stream;
import static java.util.stream.Collectors.joining;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.Action;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.CommandLineExpansionException;
import com.google.devtools.build.lib.actions.util.ActionsTestUtil;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction;
import com.google.devtools.build.lib.analysis.test.InstrumentedFilesInfo;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.Depset;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.packages.Info;
import com.google.devtools.build.lib.packages.Provider;
import com.google.devtools.build.lib.packages.StarlarkProvider;
import com.google.devtools.build.lib.packages.StructImpl;
import com.google.devtools.build.lib.rules.cpp.CcInfo;
import com.google.devtools.build.lib.rules.cpp.LibraryToLink;
import com.google.devtools.build.lib.rules.java.JavaPluginInfo.JavaPluginData;
import com.google.devtools.build.lib.rules.java.JavaRuleOutputJarsProvider.JavaOutput;
import com.google.devtools.build.lib.starlarkbuildapi.java.JavaCommonApi;
import com.google.devtools.build.lib.testutil.TestConstants;
import com.google.devtools.build.lib.util.FileType;
import com.google.devtools.build.lib.util.OS;
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
import com.google.testing.junit.testparameterinjector.TestParameters;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import net.starlark.java.annot.StarlarkMethod;
import net.starlark.java.eval.EvalException;
import net.starlark.java.eval.Sequence;
import net.starlark.java.eval.StarlarkList;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

/** Tests Starlark API for Java rules. */
@RunWith(TestParameterInjector.class)
public class JavaStarlarkApiTest extends BuildViewTestCase {
  @Before
  public void setupMyInfo() throws Exception {
    scratch.file("myinfo/myinfo.bzl", "MyInfo = provider()");

    scratch.file("myinfo/BUILD");
  }

  private StructImpl getMyInfoFromTarget(ConfiguredTarget configuredTarget) throws Exception {
    Provider.Key key =
        new StarlarkProvider.Key(Label.parseCanonical("//myinfo:myinfo.bzl"), "MyInfo");
    return (StructImpl) configuredTarget.get(key);
  }

  @Test
  public void testJavaRuntimeProviderJavaAbsolute() throws Exception {
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'jrule')",
        "load('"
            + TestConstants.TOOLS_REPOSITORY
            + "//tools/jdk:java_toolchain_alias.bzl', 'java_runtime_alias')",
        "java_runtime(name='jvm', srcs=[], java_home='/foo/bar')",
        "java_runtime_alias(name='alias')",
        "jrule(name='r')",
        "toolchain(",
        "    name = 'java_runtime_toolchain',",
        "    toolchain = ':jvm',",
        "    toolchain_type = '"
            + TestConstants.TOOLS_REPOSITORY
            + "//tools/jdk:runtime_toolchain_type',",
        ")");

    scratch.file(
        "a/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  provider = ctx.attr._java_runtime[java_common.JavaRuntimeInfo]",
        "  return MyInfo(",
        "    java_home_exec_path = provider.java_home,",
        "    java_executable_exec_path = provider.java_executable_exec_path,",
        "    java_home_runfiles_path = provider.java_home_runfiles_path,",
        "    java_executable_runfiles_path = provider.java_executable_runfiles_path,",
        "  )",
        "jrule = rule(_impl, attrs = { '_java_runtime': attr.label(default=Label('//a:alias'))})");

    useConfiguration("--extra_toolchains=//a:all");
    ConfiguredTarget ct = getConfiguredTarget("//a:r");
    StructImpl myInfo = getMyInfoFromTarget(ct);
    String javaHomeExecPath = (String) myInfo.getValue("java_home_exec_path");
    assertThat(javaHomeExecPath).isEqualTo("/foo/bar");
    String javaExecutableExecPath = (String) myInfo.getValue("java_executable_exec_path");
    assertThat(javaExecutableExecPath).startsWith("/foo/bar/bin/java");
    String javaHomeRunfilesPath = (String) myInfo.getValue("java_home_runfiles_path");
    assertThat(javaHomeRunfilesPath).isEqualTo("/foo/bar");
    String javaExecutableRunfiles = (String) myInfo.getValue("java_executable_runfiles_path");
    assertThat(javaExecutableRunfiles).startsWith("/foo/bar/bin/java");
  }

  @Test
  public void testJavaRuntimeProviderJavaHermetic() throws Exception {
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'jrule')",
        "load('"
            + TestConstants.TOOLS_REPOSITORY
            + "//tools/jdk:java_toolchain_alias.bzl', 'java_runtime_alias')",
        "java_runtime(name='jvm', srcs=[], java_home='foo/bar')",
        "java_runtime_alias(name='alias')",
        "jrule(name='r')",
        "toolchain(",
        "    name = 'java_runtime_toolchain',",
        "    toolchain = ':jvm',",
        "    toolchain_type = '"
            + TestConstants.TOOLS_REPOSITORY
            + "//tools/jdk:runtime_toolchain_type',",
        ")");

    scratch.file(
        "a/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  provider = ctx.attr._java_runtime[java_common.JavaRuntimeInfo]",
        "  return MyInfo(",
        "    java_home_exec_path = provider.java_home,",
        "    java_executable_exec_path = provider.java_executable_exec_path,",
        "    java_home_runfiles_path = provider.java_home_runfiles_path,",
        "    java_executable_runfiles_path = provider.java_executable_runfiles_path,",
        "  )",
        "jrule = rule(_impl, attrs = { '_java_runtime': attr.label(default=Label('//a:alias'))})");

    useConfiguration("--extra_toolchains=//a:all");
    ConfiguredTarget ct = getConfiguredTarget("//a:r");
    StructImpl myInfo = getMyInfoFromTarget(ct);
    String javaHomeExecPath = (String) myInfo.getValue("java_home_exec_path");
    assertThat(javaHomeExecPath).isEqualTo("a/foo/bar");
    String javaExecutableExecPath = (String) myInfo.getValue("java_executable_exec_path");
    assertThat(javaExecutableExecPath).startsWith("a/foo/bar/bin/java");
    String javaHomeRunfilesPath = (String) myInfo.getValue("java_home_runfiles_path");
    assertThat(javaHomeRunfilesPath).isEqualTo("a/foo/bar");
    String javaExecutableRunfiles = (String) myInfo.getValue("java_executable_runfiles_path");
    assertThat(javaExecutableRunfiles).startsWith("a/foo/bar/bin/java");
  }

  @Test
  public void testJavaRuntimeProviderJavaGenerated() throws Exception {
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'jrule')",
        "load('"
            + TestConstants.TOOLS_REPOSITORY
            + "//tools/jdk:java_toolchain_alias.bzl', 'java_runtime_alias')",
        "genrule(name='gen', cmd='', outs=['foo/bar/bin/java'])",
        "java_runtime(name='jvm', srcs=[], java='foo/bar/bin/java')",
        "java_runtime_alias(name='alias')",
        "jrule(name='r')",
        "toolchain(",
        "    name = 'java_runtime_toolchain',",
        "    toolchain = ':jvm',",
        "    toolchain_type = '"
            + TestConstants.TOOLS_REPOSITORY
            + "//tools/jdk:runtime_toolchain_type',",
        ")");

    scratch.file(
        "a/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  provider = ctx.attr._java_runtime[java_common.JavaRuntimeInfo]",
        "  return MyInfo(",
        "    java_home_exec_path = provider.java_home,",
        "    java_executable_exec_path = provider.java_executable_exec_path,",
        "    java_home_runfiles_path = provider.java_home_runfiles_path,",
        "    java_executable_runfiles_path = provider.java_executable_runfiles_path,",
        "  )",
        "jrule = rule(_impl, attrs = { '_java_runtime': attr.label(default=Label('//a:alias'))})");

    useConfiguration("--extra_toolchains=//a:all");
    ConfiguredTarget genrule = getConfiguredTarget("//a:gen");
    ConfiguredTarget ct = getConfiguredTarget("//a:r");
    StructImpl myInfo = getMyInfoFromTarget(ct);
    String javaHomeExecPath = (String) myInfo.getValue("java_home_exec_path");
    assertThat(javaHomeExecPath)
        .isEqualTo(getGenfilesArtifact("foo/bar", genrule).getExecPathString());
    String javaExecutableExecPath = (String) myInfo.getValue("java_executable_exec_path");
    assertThat(javaExecutableExecPath)
        .startsWith(getGenfilesArtifact("foo/bar/bin/java", genrule).getExecPathString());
    String javaHomeRunfilesPath = (String) myInfo.getValue("java_home_runfiles_path");
    assertThat(javaHomeRunfilesPath).isEqualTo("a/foo/bar");
    String javaExecutableRunfiles = (String) myInfo.getValue("java_executable_runfiles_path");
    assertThat(javaExecutableRunfiles).startsWith("a/foo/bar/bin/java");
  }

  @Test
  public void testExposesJavaCommonProvider() throws Exception {
    scratch.file(
        "java/test/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "java_library(",
        "  name = 'dep',",
        "  srcs = [ 'Dep.java'],",
        ")",
        "my_rule(",
        "  name = 'my',",
        "  dep = ':dep',",
        ")");
    scratch.file(
        "java/test/extension.bzl",
        "result = provider()",
        "def impl(ctx):",
        "   depj = ctx.attr.dep[java_common.provider]",
        "   return [result(",
        "             transitive_runtime_jars = depj.transitive_runtime_jars,",
        "             transitive_compile_time_jars = depj.transitive_compile_time_jars,",
        "             compile_jars = depj.compile_jars,",
        "             full_compile_jars = depj.full_compile_jars,",
        "             source_jars = depj.source_jars,",
        "             outputs = depj.outputs,",
        "          )]",
        "my_rule = rule(impl, attrs = { 'dep' : attr.label() })");

    ConfiguredTarget configuredTarget = getConfiguredTarget("//java/test:my");
    StructImpl info =
        (StructImpl)
            configuredTarget.get(
                new StarlarkProvider.Key(
                    Label.parseCanonical("//java/test:extension.bzl"), "result"));

    Depset transitiveRuntimeJars = ((Depset) info.getValue("transitive_runtime_jars"));
    Depset transitiveCompileTimeJars = ((Depset) info.getValue("transitive_compile_time_jars"));
    Depset compileJars = ((Depset) info.getValue("compile_jars"));
    Depset fullCompileJars = ((Depset) info.getValue("full_compile_jars"));
    @SuppressWarnings("unchecked")
    Sequence<Artifact> sourceJars = ((Sequence<Artifact>) info.getValue("source_jars"));
    JavaRuleOutputJarsProvider outputs =
        JavaRuleOutputJarsProvider.fromStarlark(info.getValue("outputs"));

    assertThat(artifactFilesNames(transitiveRuntimeJars.toList(Artifact.class)))
        .containsExactly("libdep.jar");
    assertThat(artifactFilesNames(transitiveCompileTimeJars.toList(Artifact.class)))
        .containsExactly("libdep-hjar.jar");
    assertThat(transitiveCompileTimeJars.toList()).containsExactlyElementsIn(compileJars.toList());
    assertThat(artifactFilesNames(fullCompileJars.toList(Artifact.class)))
        .containsExactly("libdep.jar");
    assertThat(artifactFilesNames(sourceJars)).containsExactly("libdep-src.jar");

    assertThat(outputs.getJavaOutputs()).hasSize(1);
    JavaOutput javaOutput = outputs.getJavaOutputs().get(0);
    assertThat(javaOutput.getClassJar().getFilename()).isEqualTo("libdep.jar");
    assertThat(javaOutput.getCompileJar().getFilename()).isEqualTo("libdep-hjar.jar");
    assertThat(artifactFilesNames(javaOutput.getSourceJarsAsList()))
        .containsExactly("libdep-src.jar");
    assertThat(javaOutput.getJdeps().getFilename()).isEqualTo("libdep.jdeps");
    assertThat(javaOutput.getCompileJdeps().getFilename()).isEqualTo("libdep-hjar.jdeps");
  }

  @Test
  public void javaPlugin_exposesJavaOutputs() throws Exception {
    scratch.file(
        "java/test/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "java_library(",
        "  name = 'lib',",
        "  srcs = [ 'Lib.java'],",
        ")",
        "java_plugin(",
        "  name = 'dep',",
        "  srcs = [ 'Dep.java'],",
        "  deps = [':lib'],",
        ")",
        "my_rule(",
        "  name = 'my',",
        "  dep = ':dep',",
        ")");
    scratch.file(
        "java/test/extension.bzl",
        "result = provider()",
        "def impl(ctx):",
        "   depj = ctx.attr.dep[JavaPluginInfo]",
        "   return [result(",
        "             outputs = depj.java_outputs,",
        "          )]",
        "my_rule = rule(impl, attrs = { 'dep' : attr.label() })");

    ConfiguredTarget configuredTarget = getConfiguredTarget("//java/test:my");
    StructImpl info =
        (StructImpl)
            configuredTarget.get(
                new StarlarkProvider.Key(
                    Label.parseCanonical("//java/test:extension.bzl"), "result"));

    @SuppressWarnings("unchecked") // deserialization
    StarlarkList<JavaOutput> javaOutputs = ((StarlarkList<JavaOutput>) info.getValue("outputs"));

    assertThat(javaOutputs.size()).isEqualTo(1);
    JavaOutput javaOutput = javaOutputs.get(0);
    assertThat(javaOutput.getClassJar().getFilename()).isEqualTo("libdep.jar");
    assertThat(javaOutput.getCompileJar().getFilename()).isEqualTo("libdep-hjar.jar");
    assertThat(artifactFilesNames(javaOutput.getSourceJarsAsList()))
        .containsExactly("libdep-src.jar");
    assertThat(javaOutput.getJdeps().getFilename()).isEqualTo("libdep.jdeps");
    assertThat(javaOutput.getCompileJdeps().getFilename()).isEqualTo("libdep-hjar.jdeps");
  }

  @Test
  public void javaToolchainInfo_jacocoRunnerAttribute() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file("java/test/B.jar");
    scratch.file(
        "java/test/BUILD",
        "load(':custom_rule.bzl', 'java_custom_library')",
        "java_custom_library(name = 'dep')");
    scratch.file(
        "java/test/custom_rule.bzl",
        "def _impl(ctx):",
        "  jacoco = ctx.attr._java_toolchain[java_common.JavaToolchainInfo].jacocorunner",
        "  return [",
        "      DefaultInfo(",
        "          files = depset([jacoco.executable]),",
        "      ),",
        "  ]",
        "java_custom_library = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    '_java_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),",
        "  },",
        "  fragments = ['java']",
        ")");

    ConfiguredTarget configuredTarget = getConfiguredTarget("//java/test:dep");

    assertThat(ActionsTestUtil.baseArtifactNames(getFilesToBuild(configuredTarget)))
        .containsExactly("jacocorunner.jar");
  }

  @Test
  public void testJavaCommonCompileExposesOutputJarProvider() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file("java/test/B.jar");
    scratch.file(
        "java/test/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "load(':custom_rule.bzl', 'java_custom_library')",
        "java_custom_library(",
        "name = 'dep',",
        "srcs = ['Main.java'],",
        "sourcepath = [':B.jar']",
        ")",
        "my_rule(",
        "  name = 'my',",
        "  dep = ':dep',",
        ")");
    scratch.file(
        "java/test/extension.bzl",
        "result = provider()",
        "def impl(ctx):",
        "   depj = ctx.attr.dep[java_common.provider]",
        "   return [result(",
        "             transitive_runtime_jars = depj.transitive_runtime_jars,",
        "             transitive_compile_time_jars = depj.transitive_compile_time_jars,",
        "             compile_jars = depj.compile_jars,",
        "             full_compile_jars = depj.full_compile_jars,",
        "             source_jars = depj.source_jars,",
        "             outputs = depj.outputs,",
        "          )]",
        "my_rule = rule(impl, attrs = { 'dep' : attr.label() })");
    scratch.file(
        "java/test/custom_rule.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib' + ctx.label.name + '.jar')",
        "  compilation_provider = java_common.compile(",
        "    ctx,",
        "    source_files = ctx.files.srcs,",
        "    output = output_jar,",
        "    deps = [],",
        "    sourcepath = ctx.files.sourcepath,",
        "    strict_deps = 'ERROR',",
        "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
        "  )",
        "  return [",
        "      DefaultInfo(",
        "          files = depset([output_jar]),",
        "      ),",
        "      compilation_provider",
        "  ]",
        "java_custom_library = rule(",
        "  implementation = _impl,",
        "  outputs = {",
        "    'my_output': 'lib%{name}.jar'",
        "  },",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files=['.java']),",
        "    'sourcepath': attr.label_list(allow_files=['.jar']),",
        "    '_java_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),",
        "  },",
        "  toolchains = ['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java']",
        ")");

    ConfiguredTarget configuredTarget = getConfiguredTarget("//java/test:my");
    StructImpl info =
        (StructImpl)
            configuredTarget.get(
                new StarlarkProvider.Key(
                    Label.parseCanonical("//java/test:extension.bzl"), "result"));

    JavaRuleOutputJarsProvider outputs =
        JavaRuleOutputJarsProvider.fromStarlark(info.getValue("outputs"));
    assertThat(outputs.getJavaOutputs()).hasSize(1);

    JavaOutput javaOutput = outputs.getJavaOutputs().get(0);
    assertThat(javaOutput.getClassJar().getFilename()).isEqualTo("libdep.jar");
    assertThat(javaOutput.getCompileJar().getFilename()).isEqualTo("libdep-hjar.jar");
    assertThat(prettyArtifactNames(javaOutput.getSourceJarsAsList()))
        .containsExactly("java/test/libdep-src.jar");
    assertThat(javaOutput.getJdeps().getFilename()).isEqualTo("libdep.jdeps");
    assertThat(javaOutput.getNativeHeadersJar().getFilename())
        .isEqualTo("libdep-native-header.jar");
    assertThat(javaOutput.getCompileJdeps().getFilename()).isEqualTo("libdep-hjar.jdeps");
  }

  @Test
  public void javaCommonCompile_setsRuntimeDeps() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file(
        "java/test/BUILD",
        "load(':custom_rule.bzl', 'java_custom_library')",
        "java_custom_library(",
        "  name = 'custom',",
        "  srcs = ['Main.java'],",
        "  deps = [':dep'],",
        "  runtime_deps = [':runtime'],",
        ")",
        "java_library(",
        "  name = 'dep',",
        "  srcs = [ 'Dep.java'],",
        ")",
        "java_library(",
        "  name = 'runtime',",
        "  srcs = [ 'Runtime.java'],",
        ")");
    scratch.file(
        "java/test/custom_rule.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib' + ctx.label.name + '.jar')",
        "  deps = [dep[JavaInfo] for dep in ctx.attr.deps]",
        "  runtime_deps = [dep[JavaInfo] for dep in ctx.attr.runtime_deps]",
        "  compilation_provider = java_common.compile(",
        "    ctx,",
        "    source_files = ctx.files.srcs,",
        "    output = output_jar,",
        "    deps = deps,",
        "    runtime_deps = runtime_deps,",
        "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
        "  )",
        "  return [",
        "      DefaultInfo(",
        "          files = depset([output_jar])",
        "      ),",
        "      compilation_provider",
        "  ]",
        "java_custom_library = rule(",
        "  implementation = _impl,",
        "  outputs = {",
        "    'my_output': 'lib%{name}.jar',",
        "    'my_src_output': 'lib%{name}-src.jar'",
        "  },",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files=['.java']),",
        "    'deps': attr.label_list(),",
        "    'runtime_deps': attr.label_list(),",
        "    '_java_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),",
        "  },",
        "  toolchains = ['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java']",
        ")");

    ConfiguredTarget configuredTarget = getConfiguredTarget("//java/test:custom");
    JavaInfo info = configuredTarget.get(JavaInfo.PROVIDER);
    JavaCompilationArgsProvider compilationArgs =
        info.getProvider(JavaCompilationArgsProvider.class);
    JavaCompilationInfoProvider compilationInfo = info.getCompilationInfoProvider();
    JavaSourceJarsProvider sourceJarsProvider = info.getProvider(JavaSourceJarsProvider.class);

    assertThat(prettyArtifactNames(compilationArgs.getRuntimeJars()))
        .containsExactly(
            "java/test/libcustom.jar", "java/test/libdep.jar", "java/test/libruntime.jar")
        .inOrder();
    assertThat(prettyArtifactNames(info.getDirectRuntimeJars()))
        .containsExactly("java/test/libcustom.jar");
    assertThat(
            prettyArtifactNames(compilationInfo.getCompilationClasspath().toList(Artifact.class)))
        .containsExactly("java/test/libdep-hjar.jar");
    assertThat(prettyArtifactNames(compilationInfo.getRuntimeClasspath().toList(Artifact.class)))
        .containsExactly(
            "java/test/libcustom.jar", "java/test/libruntime.jar", "java/test/libdep.jar")
        .inOrder();
    assertThat(prettyArtifactNames(sourceJarsProvider.getTransitiveSourceJars()))
        .containsExactly(
            "java/test/libruntime-src.jar",
            "java/test/libdep-src.jar",
            "java/test/libcustom-src.jar")
        .inOrder();
  }

  /**
   * Tests that JavaInfo.java_annotation_processing returned from java_common.compile looks as
   * expected, and specifically, looks as if java_library was used instead.
   */
  @Test
  public void testJavaCommonCompileExposesAnnotationProcessingInfo() throws Exception {
    // Set up a Starlark rule that uses java_common.compile and supports annotation processing in
    // the same way as java_library, then use a helper method to test that the custom rule produces
    // the same annotation processing information as java_library would.
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file(
        "java/test/custom_rule.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib' + ctx.label.name + '.jar')",
        "  return java_common.compile(",
        "    ctx,",
        "    source_files = ctx.files.srcs,",
        "    deps = [d[JavaInfo] for d in ctx.attr.deps],",
        "    exports = [e[JavaInfo] for e in ctx.attr.exports],",
        "    plugins = [p[JavaPluginInfo] for p in ctx.attr.plugins],",
        "    output = output_jar,",
        "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
        "  )",
        "java_custom_library = rule(",
        "  implementation = _impl,",
        "  outputs = {",
        "    'my_output': 'lib%{name}.jar'",
        "  },",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files=['.java']),",
        "    'deps': attr.label_list(),",
        "    'exports': attr.label_list(),",
        "    'plugins': attr.label_list(),",
        "    '_java_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),",
        "  },",
        "  toolchains = ['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java']",
        ")");

    testAnnotationProcessingInfoIsStarlarkAccessible(
        /* toBeProcessedRuleName= */ "java_custom_library",
        /* extraLoad= */ "load(':custom_rule.bzl', 'java_custom_library')");
  }

  /**
   * Test that plugin parameter of java_common.compile does not accept JavaInfo when
   * incompatible_require_javaplugininfo_in_javacommon is flipped.
   */
  @Test
  public void javaCommonCompile_requiresJavaPluginInfo() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file(
        "java/test/custom_rule.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib' + ctx.label.name + '.jar')",
        "  return java_common.compile(",
        "    ctx,",
        "    source_files = ctx.files.srcs,",
        "    plugins = [p[JavaInfo] for p in ctx.attr.deps],",
        "    output = output_jar,",
        "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
        "  )",
        "java_custom_library = rule(",
        "  implementation = _impl,",
        "  outputs = {",
        "    'my_output': 'lib%{name}.jar'",
        "  },",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files=['.java']),",
        "    'deps': attr.label_list(),",
        "    '_java_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),",
        "  },",
        "  toolchains = ['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java']",
        ")");
    scratch.file(
        "java/test/BUILD",
        "load(':custom_rule.bzl', 'java_custom_library')",
        "java_library(name = 'dep',",
        "    srcs = [ 'ProcessorDep.java'])",
        "java_custom_library(",
        "    name = 'to_be_processed',",
        "    deps = [':dep'],",
        "    srcs = ['ToBeProcessed.java'],",
        ")");

    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//java/test:to_be_processed");

    assertContainsEvent("at index 0 of plugins, got element of type JavaInfo, want JavaPluginInfo");
  }

  @Test
  public void testJavaCommonCompileCompilationInfo() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file(
        "java/test/BUILD",
        "load(':custom_rule.bzl', 'java_custom_library')",
        "java_custom_library(",
        "  name = 'custom',",
        "  srcs = ['Main.java'],",
        "  deps = [':dep']",
        ")",
        "java_library(",
        "  name = 'dep',",
        "  srcs = [ 'Dep.java'],",
        ")");
    scratch.file(
        "java/test/custom_rule.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib' + ctx.label.name + '.jar')",
        "  deps = [dep[java_common.provider] for dep in ctx.attr.deps]",
        "  compilation_provider = java_common.compile(",
        "    ctx,",
        "    source_files = ctx.files.srcs,",
        "    output = output_jar,",
        "    deps = deps,",
        "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
        "    javac_opts = ['-XDone -XDtwo'],",
        "  )",
        "  return [",
        "      DefaultInfo(",
        "          files = depset([output_jar] + compilation_provider.source_jars)",
        "      ),",
        "      compilation_provider",
        "  ]",
        "java_custom_library = rule(",
        "  implementation = _impl,",
        "  outputs = {",
        "    'my_output': 'lib%{name}.jar',",
        "    'my_src_output': 'lib%{name}-src.jar'",
        "  },",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files=['.java']),",
        "    'deps': attr.label_list(),",
        "    '_java_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),",
        "  },",
        "  toolchains = ['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java']",
        ")");

    ConfiguredTarget configuredTarget = getConfiguredTarget("//java/test:custom");
    JavaInfo info = configuredTarget.get(JavaInfo.PROVIDER);
    JavaCompilationInfoProvider compilationInfo = info.getCompilationInfoProvider();
    assertThat(
            prettyArtifactNames(compilationInfo.getCompilationClasspath().toList(Artifact.class)))
        .containsExactly("java/test/libdep-hjar.jar");

    assertThat(prettyArtifactNames(compilationInfo.getRuntimeClasspath().toList(Artifact.class)))
        .containsExactly("java/test/libdep.jar", "java/test/libcustom.jar");

    assertThat(compilationInfo.getJavacOpts()).contains("-XDone");
  }

  @Test
  public void testJavaCommonCompileTransitiveSourceJars() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file(
        "java/test/BUILD",
        "load(':custom_rule.bzl', 'java_custom_library')",
        "java_custom_library(",
        "  name = 'custom',",
        "  srcs = ['Main.java'],",
        "  deps = [':dep']",
        ")",
        "java_library(",
        "  name = 'dep',",
        "  srcs = [ 'Dep.java'],",
        ")");
    scratch.file(
        "java/test/custom_rule.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib' + ctx.label.name + '.jar')",
        "  deps = [dep[java_common.provider] for dep in ctx.attr.deps]",
        "  compilation_provider = java_common.compile(",
        "    ctx,",
        "    source_files = ctx.files.srcs,",
        "    output = output_jar,",
        "    deps = deps,",
        "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
        "  )",
        "  return [",
        "      DefaultInfo(",
        "          files = depset([output_jar] + compilation_provider.source_jars),",
        "      ),",
        "      compilation_provider",
        "  ]",
        "java_custom_library = rule(",
        "  implementation = _impl,",
        "  outputs = {",
        "    'my_output': 'lib%{name}.jar',",
        "    'my_src_output': 'lib%{name}-src.jar'",
        "  },",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files=['.java']),",
        "    'deps': attr.label_list(),",
        "    '_java_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),",
        "  },",
        "  toolchains = ['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java']",
        ")");

    ConfiguredTarget configuredTarget = getConfiguredTarget("//java/test:custom");
    JavaInfo info = configuredTarget.get(JavaInfo.PROVIDER);
    Sequence<Artifact> sourceJars = info.getSourceJars();
    NestedSet<Artifact> transitiveSourceJars =
        info.getTransitiveSourceJars().getSet(Artifact.class);
    assertThat(artifactFilesNames(sourceJars)).containsExactly("libcustom-src.jar");
    assertThat(artifactFilesNames(transitiveSourceJars))
        .containsExactly("libdep-src.jar", "libcustom-src.jar");

    assertThat(getGeneratingAction(configuredTarget, "java/test/libcustom-src.jar")).isNotNull();
  }

  @Test
  public void testJavaCommonCompileSourceJarName() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file(
        "java/test/BUILD",
        "load(':custom_rule.bzl', 'java_custom_library')",
        "java_custom_library(",
        "  name = 'custom',",
        "  srcs = ['Main.java'],",
        "  deps = [':dep']",
        ")",
        "java_library(",
        "  name = 'dep',",
        "  srcs = [ 'Dep.java'],",
        ")");
    scratch.file(
        "java/test/custom_rule.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('amazing.jar')",
        "  other_output_jar = ctx.actions.declare_file('wonderful.jar')",
        "  deps = [dep[java_common.provider] for dep in ctx.attr.deps]",
        "  compilation_provider = java_common.compile(",
        "    ctx,",
        "    source_files = ctx.files.srcs,",
        "    output = output_jar,",
        "    deps = deps,",
        "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
        "  )",
        "  other_compilation_provider = java_common.compile(",
        "    ctx,",
        "    source_files = ctx.files.srcs,",
        "    output = other_output_jar,",
        "    deps = deps,",
        "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
        "  )",
        "  result_provider = java_common.merge([compilation_provider, other_compilation_provider])",
        "  return [",
        "      DefaultInfo(",
        "          files = depset([output_jar])",
        "      ),",
        "      result_provider",
        "  ]",
        "java_custom_library = rule(",
        "  implementation = _impl,",
        "  outputs = {",
        "    'my_output': 'amazing.jar',",
        "    'my_second_output': 'wonderful.jar'",
        "  },",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files=['.java']),",
        "    'deps': attr.label_list(),",
        "    '_java_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),",
        "  },",
        "  toolchains = ['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java']",
        ")");

    ConfiguredTarget configuredTarget = getConfiguredTarget("//java/test:custom");
    JavaInfo info = configuredTarget.get(JavaInfo.PROVIDER);
    Sequence<Artifact> sourceJars = info.getSourceJars();
    NestedSet<Artifact> transitiveSourceJars =
        info.getTransitiveSourceJars().getSet(Artifact.class);
    assertThat(artifactFilesNames(sourceJars))
        .containsExactly("amazing-src.jar", "wonderful-src.jar");
    assertThat(artifactFilesNames(transitiveSourceJars))
        .containsExactly("libdep-src.jar", "amazing-src.jar", "wonderful-src.jar");
  }

  @Test
  public void testJavaCommonCompileWithOnlyOneSourceJar() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file(
        "java/test/BUILD",
        "load(':custom_rule.bzl', 'java_custom_library')",
        "java_custom_library(",
        "  name = 'custom',",
        "  srcs = ['myjar-src.jar'],",
        ")");
    scratch.file(
        "java/test/custom_rule.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib' + ctx.label.name + '.jar')",
        "  compilation_provider = java_common.compile(",
        "    ctx,",
        "    source_jars = ctx.files.srcs,",
        "    output = output_jar,",
        "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
        "  )",
        "  return [",
        "      DefaultInfo(",
        "          files = depset([output_jar]),",
        "      ),",
        "      compilation_provider",
        "  ]",
        "java_custom_library = rule(",
        "  implementation = _impl,",
        "  outputs = {",
        "    'my_output': 'lib%{name}.jar'",
        "  },",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files=['.jar']),",
        "    '_java_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),",
        "  },",
        "  toolchains = ['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java']",
        ")");

    ConfiguredTarget configuredTarget = getConfiguredTarget("//java/test:custom");
    JavaInfo info = configuredTarget.get(JavaInfo.PROVIDER);
    Sequence<Artifact> sourceJars = info.getSourceJars();
    assertThat(artifactFilesNames(sourceJars)).containsExactly("libcustom-src.jar");
    ImmutableList<JavaOutput> javaOutputs = info.getJavaOutputs();
    assertThat(javaOutputs).hasSize(1);
    JavaOutput javaOutput = javaOutputs.get(0);
    assertThat(javaOutput.getClassJar().getFilename()).isEqualTo("libcustom.jar");
    assertThat(javaOutput.getSrcJar().getFilename()).isEqualTo("libcustom-src.jar");
    assertThat(javaOutput.getCompileJar().getFilename()).isEqualTo("libcustom-hjar.jar");
    assertThat(javaOutput.getJdeps().getFilename()).isEqualTo("libcustom.jdeps");
    assertThat(javaOutput.getCompileJdeps().getFilename()).isEqualTo("libcustom-hjar.jdeps");
  }

  @Test
  public void testJavaCommonCompile_noSources() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file(
        "java/test/BUILD",
        "load(':custom_rule.bzl', 'java_custom_library')",
        "java_custom_library(",
        "  name = 'custom',",
        ")");
    scratch.file(
        "java/test/custom_rule.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib' + ctx.label.name + '.jar')",
        "  compilation_provider = java_common.compile(",
        "    ctx,",
        "    output = output_jar,",
        "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
        "  )",
        "  return [",
        "      DefaultInfo(",
        "          files = depset([output_jar]),",
        "      ),",
        "      compilation_provider",
        "  ]",
        "java_custom_library = rule(",
        "  implementation = _impl,",
        "  outputs = {",
        "    'my_output': 'lib%{name}.jar'",
        "  },",
        "  attrs = {",
        "    '_java_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),",
        "  },",
        "  toolchains = ['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java']",
        ")");

    ConfiguredTarget configuredTarget = getConfiguredTarget("//java/test:custom");
    JavaInfo info = configuredTarget.get(JavaInfo.PROVIDER);
    Sequence<Artifact> sourceJars = info.getSourceJars();
    assertThat(artifactFilesNames(sourceJars)).containsExactly("libcustom-src.jar");
    ImmutableList<JavaOutput> javaOutputs = info.getJavaOutputs();
    assertThat(javaOutputs).hasSize(1);
    JavaOutput javaOutput = javaOutputs.get(0);
    assertThat(javaOutput.getClassJar().getFilename()).isEqualTo("libcustom.jar");
    assertThat(javaOutput.getSrcJar().getFilename()).isEqualTo("libcustom-src.jar");
  }

  @Test
  public void testJavaCommonCompileCustomSourceJar() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file(
        "java/test/BUILD",
        "load(':custom_rule.bzl', 'java_custom_library')",
        "java_custom_library(",
        "  name = 'custom',",
        "  srcs = ['myjar-src.jar'],",
        ")");
    scratch.file(
        "java/test/custom_rule.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib' + ctx.label.name + '.jar')",
        "  output_source_jar = ctx.actions.declare_file('lib' + ctx.label.name + '-mysrc.jar')",
        "  compilation_provider = java_common.compile(",
        "    ctx,",
        "    source_jars = ctx.files.srcs,",
        "    output = output_jar,",
        "    output_source_jar = output_source_jar,",
        "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
        "  )",
        "  return [",
        "      DefaultInfo(",
        "          files = depset([output_source_jar]),",
        "      ),",
        "      compilation_provider",
        "  ]",
        "java_custom_library = rule(",
        "  implementation = _impl,",
        "  outputs = {",
        "    'my_output': 'lib%{name}.jar'",
        "  },",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files=['.jar']),",
        "    '_java_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),",
        "  },",
        "  toolchains = ['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java']",
        ")");

    ConfiguredTarget configuredTarget = getConfiguredTarget("//java/test:custom");
    JavaInfo info = configuredTarget.get(JavaInfo.PROVIDER);
    Sequence<Artifact> sourceJars = info.getSourceJars();
    assertThat(artifactFilesNames(sourceJars)).containsExactly("libcustom-mysrc.jar");
    ImmutableList<JavaOutput> javaOutputs = info.getJavaOutputs();
    assertThat(javaOutputs).hasSize(1);
    JavaOutput javaOutput = javaOutputs.get(0);
    assertThat(javaOutput.getClassJar().getFilename()).isEqualTo("libcustom.jar");
    assertThat(javaOutput.getSrcJar().getFilename()).isEqualTo("libcustom-mysrc.jar");
    assertThat(javaOutput.getCompileJar().getFilename()).isEqualTo("libcustom-hjar.jar");
    assertThat(javaOutput.getJdeps().getFilename()).isEqualTo("libcustom.jdeps");
    assertThat(javaOutput.getCompileJdeps().getFilename()).isEqualTo("libcustom-hjar.jdeps");
  }

  @Test
  public void testJavaCommonCompileAdditionalInputsAndOutputs() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file(
        "java/test/BUILD",
        "load(':custom_rule.bzl', 'java_custom_library')",
        "java_custom_library(",
        "  name = 'custom',",
        "  srcs = ['myjar-src.jar'],",
        "  additional_inputs = ['additional_input.bin'],",
        ")");
    scratch.file(
        "java/test/custom_rule.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib' + ctx.label.name + '.jar')",
        "  compilation_provider = java_common.compile(",
        "    ctx,",
        "    source_jars = ctx.files.srcs,",
        "    output = output_jar,",
        "    annotation_processor_additional_inputs = ctx.files.additional_inputs,",
        "    annotation_processor_additional_outputs = [ctx.outputs.additional_output],",
        "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
        "  )",
        "  return [DefaultInfo(files = depset([output_jar]))]",
        "java_custom_library = rule(",
        "  implementation = _impl,",
        "  outputs = {",
        "    'additional_output': '%{name}_additional_output',",
        "  },",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files=['.jar']),",
        "    'additional_inputs': attr.label_list(allow_files=['.bin']),",
        "    '_java_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),",
        "  },",
        "  toolchains = ['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java']",
        ")");

    ConfiguredTarget configuredTarget = getConfiguredTarget("//java/test:custom");
    Action javaAction = getGeneratingAction(configuredTarget, "java/test/libcustom.jar");
    assertThat(artifactFilesNames(javaAction.getInputs())).contains("additional_input.bin");
    assertThat(artifactFilesNames(javaAction.getOutputs())).contains("custom_additional_output");
  }

  private static ImmutableList<String> artifactFilesNames(NestedSet<Artifact> artifacts) {
    return artifactFilesNames(artifacts.toList());
  }

  private static ImmutableList<String> artifactFilesNames(Iterable<Artifact> artifacts) {
    ImmutableList.Builder<String> result = ImmutableList.builder();
    for (Artifact artifact : artifacts) {
      result.add(artifact.getFilename());
    }
    return result.build();
  }

  /**
   * Tests that a java_library exposes java_processing_info as expected when annotation processing
   * is used.
   */
  @Test
  public void testJavaPlugin() throws Exception {
    testAnnotationProcessingInfoIsStarlarkAccessible(
        /* toBeProcessedRuleName= */ "java_library", /* extraLoad= */ "");
  }

  /**
   * Tests that JavaInfo's java_annotation_processing looks as expected with a target that's assumed
   * to use annotation processing itself and has a dep and an export that likewise use annotation
   * processing.
   */
  private void testAnnotationProcessingInfoIsStarlarkAccessible(
      String toBeProcessedRuleName, String extraLoad) throws Exception {
    scratch.file(
        "java/test/extension.bzl",
        "result = provider()",
        "def impl(ctx):",
        "   depj = ctx.attr.dep[JavaInfo]",
        "   return [result(",
        "             enabled = depj.annotation_processing.enabled,",
        "             class_jar = depj.outputs.jars[0].generated_class_jar,",
        "             source_jar = depj.outputs.jars[0].generated_source_jar,",
        "             old_class_jar = depj.annotation_processing.class_jar,",
        "             old_source_jar = depj.annotation_processing.source_jar,",
        "             processor_classpath = depj.annotation_processing.processor_classpath,",
        "             processor_classnames = depj.annotation_processing.processor_classnames,",
        "             transitive_class_jars = depj.annotation_processing.transitive_class_jars,",
        "             transitive_source_jars = depj.annotation_processing.transitive_source_jars,",
        "          )]",
        "my_rule = rule(impl, attrs = { 'dep' : attr.label() })");
    scratch.file(
        "java/test/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "java_library(name = 'plugin_dep',",
        "    srcs = [ 'ProcessorDep.java'])",
        "java_plugin(name = 'plugin',",
        "    srcs = ['AnnotationProcessor.java'],",
        "    processor_class = 'com.google.process.stuff',",
        "    deps = [ ':plugin_dep' ])",
        extraLoad,
        toBeProcessedRuleName + "(",
        "    name = 'to_be_processed',",
        "    plugins = [':plugin'],",
        "    srcs = ['ToBeProcessed.java'],",
        "    deps = [':dep'],",
        "    exports = [':export'],",
        ")",
        "java_library(",
        "  name = 'dep',",
        "  srcs = ['Dep.java'],",
        "  plugins = [':plugin']",
        ")",
        "java_library(",
        "  name = 'export',",
        "  srcs = ['Export.java'],",
        "  plugins = [':plugin']",
        ")",
        "my_rule(name = 'my', dep = ':to_be_processed')");

    // Assert that java_annotation_processing for :to_be_processed looks as expected:
    // the target itself uses :plugin as the processor, and transitive information includes
    // the target's own as well as :dep's and :export's annotation processing outputs, since those
    // two targets also use annotation processing.
    ConfiguredTarget configuredTarget = getConfiguredTarget("//java/test:my");
    StructImpl info =
        (StructImpl)
            configuredTarget.get(
                new StarlarkProvider.Key(
                    Label.parseCanonical("//java/test:extension.bzl"), "result"));

    assertThat(info.getValue("enabled")).isEqualTo(Boolean.TRUE);
    assertThat(info.getValue("class_jar")).isNotNull();
    assertThat(info.getValue("source_jar")).isNotNull();
    assertThat(info.getValue("class_jar")).isEqualTo(info.getValue("old_class_jar"));
    assertThat(info.getValue("source_jar")).isEqualTo(info.getValue("old_source_jar"));
    assertThat((List<?>) info.getValue("processor_classnames"))
        .containsExactly("com.google.process.stuff");
    assertThat(
            Iterables.transform(
                ((Depset) info.getValue("processor_classpath")).toList(Artifact.class),
                Artifact::getFilename))
        .containsExactly("libplugin.jar", "libplugin_dep.jar");
    assertThat(((Depset) info.getValue("transitive_class_jars")).toList())
        .hasSize(3); // from to_be_processed, dep, and export
    assertThat(((Depset) info.getValue("transitive_class_jars")).toList())
        .contains(info.getValue("class_jar"));
    assertThat(((Depset) info.getValue("transitive_source_jars")).toList())
        .hasSize(3); // from to_be_processed, dep, and export
    assertThat(((Depset) info.getValue("transitive_source_jars")).toList())
        .contains(info.getValue("source_jar"));
  }

  /** Retrieves Java plugin data from a target via Starlark. */
  private JavaPluginData retrieveStarlarkPluginData(
      String target, String provider, boolean apiGenerating) throws Exception {
    String pkg = apiGenerating ? "java/getplugininfo" : "java/getapiplugininfo";
    scratch.file(
        pkg + "/extension.bzl",
        "result = provider()",
        "def impl(ctx):",
        "   depj = ctx.attr.dep[" + provider + "]",
        "   plugin_data = " + (apiGenerating ? "depj.api_generating_plugins" : "depj.plugins"),
        "   return [result(",
        "             processor_classpath = plugin_data.processor_jars,",
        "             processor_classnames = plugin_data.processor_classes,",
        "             processor_data = plugin_data.processor_data,",
        "          )]",
        "get_plugininfo = rule(impl, attrs = { 'dep' : attr.label() })");
    scratch.file(
        pkg + "/BUILD",
        "load(':extension.bzl', 'get_plugininfo')",
        "get_plugininfo(name = 'plugininfo', dep = '" + target + "')");

    ConfiguredTarget configuredTarget = getConfiguredTarget("//" + pkg + ":plugininfo");
    StructImpl info =
        (StructImpl)
            configuredTarget.get(
                new StarlarkProvider.Key(
                    Label.parseCanonical("//" + pkg + ":extension.bzl"), "result"));

    return JavaPluginData.create(
        ((Depset) info.getValue("processor_classnames")).getSet(String.class),
        ((Depset) info.getValue("processor_classpath")).getSet(Artifact.class),
        ((Depset) info.getValue("processor_data")).getSet(Artifact.class));
  }

  /** Tests that java_plugin exposes plugin information to Starlark. */
  @Test
  public void javaPlugin_exposesPluginsToStarlark() throws Exception {
    scratch.file(
        "java/test/BUILD",
        "java_library(",
        "    name = 'plugin_dep',",
        "    srcs = ['ProcessorDep.java'],",
        "    data = ['depfile.dat'],",
        ")",
        "java_plugin(",
        "    name = 'plugin',",
        "    srcs = ['AnnotationProcessor.java'],",
        "    processor_class = 'com.google.process.stuff',",
        "    deps = [':plugin_dep'],",
        "    data = ['pluginfile.dat'],",
        ")");

    JavaPluginData pluginData =
        retrieveStarlarkPluginData(
            "//java/test:plugin", /* provider= */ "JavaPluginInfo", /* apiGenerating= */ false);
    JavaPluginData apiPluginData =
        retrieveStarlarkPluginData(
            "//java/test:plugin", /* provider= */ "JavaPluginInfo", /* apiGenerating= */ true);

    assertThat(pluginData.processorClasses().toList()).containsExactly("com.google.process.stuff");
    assertThat(pluginData.processorClasspath().toList().stream().map(Artifact::getFilename))
        .containsExactly("libplugin.jar", "libplugin_dep.jar");
    assertThat(pluginData.data().toList().stream().map(Artifact::getFilename))
        .containsExactly("pluginfile.dat");
    assertThat(apiPluginData).isEqualTo(JavaPluginData.empty());
  }

  /** Tests that api generating java_plugin exposes plugin information to Starlark. */
  @Test
  public void apiGeneratingjavaPlugin_exposesPluginsToStarlark() throws Exception {
    scratch.file(
        "java/test/BUILD",
        "java_library(",
        "    name = 'plugin_dep',",
        "    srcs = ['ProcessorDep.java'],",
        "    data = ['depfile.dat'],",
        ")",
        "java_plugin(",
        "    name = 'plugin',",
        "    generates_api = True,",
        "    srcs = ['AnnotationProcessor.java'],",
        "    processor_class = 'com.google.process.stuff',",
        "    deps = [':plugin_dep'],",
        "    data = ['pluginfile.dat'],",
        ")");

    JavaPluginData pluginData =
        retrieveStarlarkPluginData(
            "//java/test:plugin", /* provider= */ "JavaPluginInfo", /* apiGenerating= */ false);
    JavaPluginData apiPluginData =
        retrieveStarlarkPluginData(
            "//java/test:plugin", /* provider= */ "JavaPluginInfo", /* apiGenerating= */ true);

    assertThat(apiPluginData.processorClasses().toList())
        .containsExactly("com.google.process.stuff");
    assertThat(apiPluginData.processorClasspath().toList().stream().map(Artifact::getFilename))
        .containsExactly("libplugin.jar", "libplugin_dep.jar");
    assertThat(apiPluginData.data().toList().stream().map(Artifact::getFilename))
        .containsExactly("pluginfile.dat");
    assertThat(apiPluginData).isEqualTo(pluginData);
  }

  /** Tests that java_library exposes exported plugin information to Starlark. */
  @Test
  public void javaLibrary_exposesPluginsToStarlark() throws Exception {
    scratch.file(
        "java/test/BUILD",
        "java_library(name = 'plugin_dep1', srcs = ['A.java'], data = ['depfile1.dat'])",
        "java_library(name = 'plugin_dep2', srcs = ['B.java'], data = ['depfile2.dat'])",
        "java_plugin(",
        "    name = 'plugin',",
        "    srcs = ['AnnotationProcessor1.java'],",
        "    processor_class = 'com.google.process.stuff',",
        "    deps = [':plugin_dep1'],",
        "    data = ['pluginfile1.dat'],",
        ")",
        "java_plugin(",
        "    name = 'apiplugin',",
        "    generates_api = True,",
        "    srcs = ['AnnotationProcessor2.java'],",
        "    processor_class = 'com.google.process.apistuff',",
        "    deps = [':plugin_dep2'],",
        "    data = ['pluginfile2.dat'],",
        ")",
        "java_library(",
        "    name = 'library',",
        "    exported_plugins = [':plugin', ':apiplugin']",
        ")");

    JavaPluginData pluginData =
        retrieveStarlarkPluginData(
            "//java/test:library", /* provider= */ "JavaInfo", /* apiGenerating= */ false);
    JavaPluginData apiPluginData =
        retrieveStarlarkPluginData(
            "//java/test:library", /* provider= */ "JavaInfo", /* apiGenerating= */ true);

    assertThat(pluginData.processorClasses().toList())
        .containsExactly("com.google.process.stuff", "com.google.process.apistuff");
    assertThat(pluginData.processorClasspath().toList().stream().map(Artifact::getFilename))
        .containsExactly(
            "libplugin.jar", "libplugin_dep1.jar", "libapiplugin.jar", "libplugin_dep2.jar");
    assertThat(pluginData.data().toList().stream().map(Artifact::getFilename))
        .containsExactly("pluginfile1.dat", "pluginfile2.dat");
    assertThat(apiPluginData.processorClasses().toList())
        .containsExactly("com.google.process.apistuff");
    assertThat(apiPluginData.processorClasspath().toList().stream().map(Artifact::getFilename))
        .containsExactly("libapiplugin.jar", "libplugin_dep2.jar");
    assertThat(apiPluginData.data().toList().stream().map(Artifact::getFilename))
        .containsExactly("pluginfile2.dat");
  }

  /** Tests the JavaPluginInfo provider's constructor. */
  @Test
  public void javaPluginInfo_create() throws Exception {
    scratch.file(
        "java/test/myplugin.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib.jar')",
        "  ctx.actions.write(output_jar, '')",
        "  dep = JavaInfo(output_jar = output_jar, compile_jar = None,",
        "    deps = [d[JavaInfo] for d in ctx.attr.deps])",
        "  return [JavaPluginInfo(",
        "    runtime_deps = [dep],",
        "    processor_class = ctx.attr.processor_class,",
        "    data = ctx.files.data,",
        "  )]",
        "myplugin = rule(implementation = _impl,",
        "  attrs = {",
        "    'deps': attr.label_list(),",
        "    'processor_class': attr.string(),",
        "    'data': attr.label_list(allow_files = True),",
        "  })");
    scratch.file(
        "java/test/BUILD",
        "load(':myplugin.bzl', 'myplugin')",
        "java_library(name = 'plugin_dep1', srcs = ['A.java'], data = ['depfile1.dat'])",
        "myplugin(",
        "    name = 'plugin',",
        "    processor_class = 'com.google.process.stuff',",
        "    deps = [':plugin_dep1'],",
        "    data = ['pluginfile1.dat'],",
        ")");

    JavaPluginInfo pluginInfo =
        getConfiguredTarget("//java/test:plugin").get(JavaPluginInfo.PROVIDER);
    JavaPluginData pluginData = pluginInfo.plugins();
    JavaPluginData apiPluginData = pluginInfo.apiGeneratingPlugins();

    assertThat(pluginData.processorClasses().toList()).containsExactly("com.google.process.stuff");
    assertThat(pluginData.processorClasspath().toList().stream().map(Artifact::getFilename))
        .containsExactly("lib.jar", "libplugin_dep1.jar");
    assertThat(pluginData.data().toList().stream().map(Artifact::getFilename))
        .containsExactly("pluginfile1.dat");
    assertThat(apiPluginData.processorClasses().toList()).isEmpty();
    assertThat(apiPluginData.processorClasspath().toList()).isEmpty();
    assertThat(apiPluginData.data().toList()).isEmpty();
  }

  /** Tests the JavaPluginInfo provider's constructor for api generating plugin. */
  @Test
  public void javaPluginInfo_createApiPlugin() throws Exception {
    scratch.file(
        "java/test/myplugin.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib.jar')",
        "  ctx.actions.write(output_jar, '')",
        "  dep = JavaInfo(output_jar = output_jar, compile_jar = None,",
        "    deps = [d[JavaInfo] for d in ctx.attr.deps])",
        "  return [JavaPluginInfo(",
        "    runtime_deps = [dep],",
        "    processor_class = ctx.attr.processor_class,",
        "    data = ctx.files.data,",
        "    generates_api = True,",
        "  )]",
        "myplugin = rule(implementation = _impl,",
        "  attrs = {",
        "    'deps': attr.label_list(),",
        "    'processor_class': attr.string(),",
        "    'data': attr.label_list(allow_files = True),",
        "  })");
    scratch.file(
        "java/test/BUILD",
        "load(':myplugin.bzl', 'myplugin')",
        "java_library(name = 'plugin_dep1', srcs = ['A.java'], data = ['depfile1.dat'])",
        "myplugin(",
        "    name = 'plugin',",
        "    processor_class = 'com.google.process.stuff',",
        "    deps = [':plugin_dep1'],",
        "    data = ['pluginfile1.dat'],",
        ")");

    JavaPluginInfo pluginInfo =
        getConfiguredTarget("//java/test:plugin").get(JavaPluginInfo.PROVIDER);
    JavaPluginData pluginData = pluginInfo.plugins();
    JavaPluginData apiPluginData = pluginInfo.apiGeneratingPlugins();

    assertThat(apiPluginData.processorClasses().toList())
        .containsExactly("com.google.process.stuff");
    assertThat(apiPluginData.processorClasspath().toList().stream().map(Artifact::getFilename))
        .containsExactly("lib.jar", "libplugin_dep1.jar");
    assertThat(apiPluginData.data().toList().stream().map(Artifact::getFilename))
        .containsExactly("pluginfile1.dat");
    assertThat(apiPluginData).isEqualTo(pluginData);
  }

  /** Tests the JavaPluginInfo provider's constructor without processor class. */
  @Test
  public void javaPluginInfo_createWithoutProcessorClass() throws Exception {
    scratch.file(
        "java/test/myplugin.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib.jar')",
        "  ctx.actions.write(output_jar, '')",
        "  dep = JavaInfo(output_jar = output_jar, compile_jar = None,",
        "    deps = [d[JavaInfo] for d in ctx.attr.deps])",
        "  return [JavaPluginInfo(",
        "    runtime_deps = [dep],",
        "    processor_class = None,",
        "    data = ctx.files.data,",
        "  )]",
        "myplugin = rule(implementation = _impl,",
        "  attrs = {",
        "    'deps': attr.label_list(),",
        "    'data': attr.label_list(allow_files = True),",
        "  })");
    scratch.file(
        "java/test/BUILD",
        "load(':myplugin.bzl', 'myplugin')",
        "java_library(name = 'plugin_dep1', srcs = ['A.java'], data = ['depfile1.dat'])",
        "myplugin(",
        "    name = 'plugin',",
        "    deps = [':plugin_dep1'],",
        "    data = ['pluginfile1.dat'],",
        ")");

    JavaPluginInfo pluginInfo =
        getConfiguredTarget("//java/test:plugin").get(JavaPluginInfo.PROVIDER);
    JavaPluginData pluginData = pluginInfo.plugins();
    JavaPluginData apiPluginData = pluginInfo.apiGeneratingPlugins();

    assertThat(pluginData.processorClasses().toList()).isEmpty();
    assertThat(pluginData.processorClasspath().toList().stream().map(Artifact::getFilename))
        .containsExactly("lib.jar", "libplugin_dep1.jar");
    assertThat(pluginData.data().toList().stream().map(Artifact::getFilename))
        .containsExactly("pluginfile1.dat");
    assertThat(apiPluginData.processorClasses().toList()).isEmpty();
    assertThat(apiPluginData.processorClasspath().toList()).isEmpty();
    assertThat(apiPluginData.data().toList()).isEmpty();
  }

  /** Tests the JavaPluginInfo provider's constructor with data given as depset. */
  @Test
  public void javaPluginInfo_createWithDataDepset() throws Exception {
    scratch.file(
        "java/test/myplugin.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib.jar')",
        "  ctx.actions.write(output_jar, '')",
        "  dep = JavaInfo(output_jar = output_jar, compile_jar = None,",
        "    deps = [d[JavaInfo] for d in ctx.attr.deps])",
        "  return [JavaPluginInfo(",
        "    runtime_deps = [dep],",
        "    processor_class = ctx.attr.processor_class,",
        "    data = depset(ctx.files.data),",
        "  )]",
        "myplugin = rule(implementation = _impl,",
        "  attrs = {",
        "    'deps': attr.label_list(),",
        "    'processor_class': attr.string(),",
        "    'data': attr.label_list(allow_files = True),",
        "  })");
    scratch.file(
        "java/test/BUILD",
        "load(':myplugin.bzl', 'myplugin')",
        "java_library(name = 'plugin_dep1', srcs = ['A.java'], data = ['depfile1.dat'])",
        "myplugin(",
        "    name = 'plugin',",
        "    processor_class = 'com.google.process.stuff',",
        "    deps = [':plugin_dep1'],",
        "    data = ['pluginfile1.dat'],",
        ")");

    JavaPluginInfo pluginInfo =
        getConfiguredTarget("//java/test:plugin").get(JavaPluginInfo.PROVIDER);
    JavaPluginData pluginData = pluginInfo.plugins();
    JavaPluginData apiPluginData = pluginInfo.apiGeneratingPlugins();

    assertThat(pluginData.processorClasses().toList()).containsExactly("com.google.process.stuff");
    assertThat(pluginData.processorClasspath().toList().stream().map(Artifact::getFilename))
        .containsExactly("lib.jar", "libplugin_dep1.jar");
    assertThat(pluginData.data().toList().stream().map(Artifact::getFilename))
        .containsExactly("pluginfile1.dat");
    assertThat(apiPluginData.processorClasses().toList()).isEmpty();
    assertThat(apiPluginData.processorClasspath().toList()).isEmpty();
    assertThat(apiPluginData.data().toList()).isEmpty();
  }

  @Test
  public void testJavaProviderFieldsAreStarlarkAccessible() throws Exception {
    // The Starlark evaluation itself will test that compile_jars and
    // transitive_runtime_jars are returning a list readable by Starlark with
    // the expected number of entries.
    scratch.file(
        "java/test/extension.bzl",
        "result = provider()",
        "def impl(ctx):",
        "   java_provider = ctx.attr.dep[JavaInfo]",
        "   return [result(",
        "             compile_jars = java_provider.compile_jars,",
        "             transitive_runtime_jars = java_provider.transitive_runtime_jars,",
        "             transitive_compile_time_jars = java_provider.transitive_compile_time_jars,",
        "          )]",
        "my_rule = rule(impl, attrs = { ",
        "  'dep' : attr.label(), ",
        "  'cnt_cjar' : attr.int(), ",
        "  'cnt_rjar' : attr.int(), ",
        "})");
    scratch.file(
        "java/test/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "java_library(name = 'parent',",
        "    srcs = [ 'Parent.java'])",
        "java_library(name = 'jl',",
        "    srcs = ['Jl.java'],",
        "    deps = [ ':parent' ])",
        "my_rule(name = 'my', dep = ':jl', cnt_cjar = 1, cnt_rjar = 2)");
    // Now, get that information and ensure it is equal to what the jl java_library
    // was presenting
    ConfiguredTarget myConfiguredTarget = getConfiguredTarget("//java/test:my");
    ConfiguredTarget javaLibraryTarget = getConfiguredTarget("//java/test:jl");

    // Extract out the information from Starlark rule
    StructImpl info =
        (StructImpl)
            myConfiguredTarget.get(
                new StarlarkProvider.Key(
                    Label.parseCanonical("//java/test:extension.bzl"), "result"));

    Depset rawMyCompileJars = (Depset) info.getValue("compile_jars");
    Depset rawMyTransitiveRuntimeJars = (Depset) info.getValue("transitive_runtime_jars");
    Depset rawMyTransitiveCompileTimeJars = (Depset) info.getValue("transitive_compile_time_jars");

    NestedSet<Artifact> myCompileJars = rawMyCompileJars.getSet(Artifact.class);
    NestedSet<Artifact> myTransitiveRuntimeJars = rawMyTransitiveRuntimeJars.getSet(Artifact.class);
    NestedSet<Artifact> myTransitiveCompileTimeJars =
        rawMyTransitiveCompileTimeJars.getSet(Artifact.class);

    // Extract out information from native rule
    JavaCompilationArgsProvider jlJavaCompilationArgsProvider =
        JavaInfo.getProvider(JavaCompilationArgsProvider.class, javaLibraryTarget);
    NestedSet<Artifact> jlCompileJars = jlJavaCompilationArgsProvider.getDirectCompileTimeJars();
    NestedSet<Artifact> jlTransitiveRuntimeJars = jlJavaCompilationArgsProvider.getRuntimeJars();
    NestedSet<Artifact> jlTransitiveCompileTimeJars =
        jlJavaCompilationArgsProvider.getTransitiveCompileTimeJars();

    // Using reference equality since should be precisely identical
    assertThat(myCompileJars).isSameInstanceAs(jlCompileJars);
    assertThat(myTransitiveRuntimeJars).isSameInstanceAs(jlTransitiveRuntimeJars);
    assertThat(myTransitiveCompileTimeJars).isEqualTo(jlTransitiveCompileTimeJars);
  }

  @Test
  public void javaProviderExposedOnJavaLibrary() throws Exception {
    scratch.file(
        "foo/extension.bzl",
        "my_provider = provider()",
        "def _impl(ctx):",
        "  dep_params = ctx.attr.dep[JavaInfo]",
        "  return [my_provider(p = dep_params)]",
        "my_rule = rule(_impl, attrs = { 'dep' : attr.label() })");
    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "java_library(name = 'jl', srcs = ['java/A.java'])",
        "my_rule(name = 'r', dep = ':jl')");

    ConfiguredTarget myRuleTarget = getConfiguredTarget("//foo:r");
    ConfiguredTarget javaLibraryTarget = getConfiguredTarget("//foo:jl");
    StarlarkProvider.Key myProviderKey =
        new StarlarkProvider.Key(Label.parseCanonical("//foo:extension.bzl"), "my_provider");
    StructImpl declaredProvider = (StructImpl) myRuleTarget.get(myProviderKey);
    // attempting to wrap will error out if not a JavaInfo
    Object javaProvider = JavaInfo.PROVIDER.wrap(declaredProvider.getValue("p", Info.class));
    assertThat(javaLibraryTarget.get(JavaInfo.PROVIDER)).isEqualTo(javaProvider);
  }

  @Test
  public void javaProviderPropagation() throws Exception {
    scratch.file(
        "foo/extension.bzl",
        "def _impl(ctx):",
        "  dep_params = ctx.attr.dep[JavaInfo]",
        "  return [dep_params]",
        "my_rule = rule(_impl, attrs = { 'dep' : attr.label() })");
    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "java_library(name = 'jl', srcs = ['java/A.java'])",
        "my_rule(name = 'r', dep = ':jl')",
        "java_library(name = 'jl_top', srcs = ['java/C.java'], deps = [':r'])");

    ConfiguredTarget myRuleTarget = getConfiguredTarget("//foo:r");
    ConfiguredTarget javaLibraryTarget = getConfiguredTarget("//foo:jl");
    ConfiguredTarget topJavaLibraryTarget = getConfiguredTarget("//foo:jl_top");

    Object javaProvider = myRuleTarget.get(JavaInfo.PROVIDER);
    assertThat(javaProvider).isInstanceOf(JavaInfo.class);

    JavaInfo jlJavaInfo = javaLibraryTarget.get(JavaInfo.PROVIDER);

    assertThat(jlJavaInfo).isEqualTo(javaProvider);

    JavaInfo jlTopJavaInfo = topJavaLibraryTarget.get(JavaInfo.PROVIDER);

    javaCompilationArgsHaveTheSameParent(
        jlJavaInfo.getProvider(JavaCompilationArgsProvider.class),
        jlTopJavaInfo.getProvider(JavaCompilationArgsProvider.class));
  }

  @Test
  public void starlarkJavaToJavaLibraryAttributes() throws Exception {
    scratch.file(
        "foo/extension.bzl",
        "def _impl(ctx):",
        "  dep_params = ctx.attr.dep[JavaInfo]",
        "  return [dep_params]",
        "my_rule = rule(_impl, attrs = { 'dep' : attr.label() })");
    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "java_library(name = 'jl_bottom_for_deps', srcs = ['java/A.java'])",
        "java_library(name = 'jl_bottom_for_exports', srcs = ['java/A2.java'])",
        "java_library(name = 'jl_bottom_for_runtime_deps', srcs = ['java/A2.java'])",
        "my_rule(name = 'mya', dep = ':jl_bottom_for_deps')",
        "my_rule(name = 'myb', dep = ':jl_bottom_for_exports')",
        "my_rule(name = 'myc', dep = ':jl_bottom_for_runtime_deps')",
        "java_library(name = 'lib_exports', srcs = ['java/B.java'], deps = [':mya'],",
        "  exports = [':myb'], runtime_deps = [':myc'])",
        "java_library(name = 'lib_interm', srcs = ['java/C.java'], deps = [':lib_exports'])",
        "java_library(name = 'lib_top', srcs = ['java/D.java'], deps = [':lib_interm'])");
    assertNoEvents();

    // Test that all bottom jars are on the runtime classpath of lib_exports.
    ConfiguredTarget jlExports = getConfiguredTarget("//foo:lib_exports");
    JavaCompilationArgsProvider jlExportsProvider =
        JavaInfo.getProvider(JavaCompilationArgsProvider.class, jlExports);
    assertThat(prettyArtifactNames(jlExportsProvider.getRuntimeJars()))
        .containsAtLeast(
            "foo/libjl_bottom_for_deps.jar",
            "foo/libjl_bottom_for_runtime_deps.jar",
            "foo/libjl_bottom_for_exports.jar");

    // Test that libjl_bottom_for_exports.jar is in the recursive java compilation args of lib_top.
    ConfiguredTarget jlTop = getConfiguredTarget("//foo:lib_interm");
    JavaCompilationArgsProvider jlTopProvider =
        JavaInfo.getProvider(JavaCompilationArgsProvider.class, jlTop);
    assertThat(prettyArtifactNames(jlTopProvider.getRuntimeJars()))
        .contains("foo/libjl_bottom_for_exports.jar");
  }

  @Test
  public void starlarkJavaToJavaBinaryAttributes() throws Exception {
    scratch.file(
        "foo/extension.bzl",
        "def _impl(ctx):",
        "  dep_params = ctx.attr.dep[JavaInfo]",
        "  return [dep_params]",
        "my_rule = rule(_impl, attrs = { 'dep' : attr.label() })");
    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "java_library(name = 'jl_bottom_for_deps', srcs = ['java/A.java'])",
        "java_library(name = 'jl_bottom_for_runtime_deps', srcs = ['java/A2.java'])",
        "my_rule(name = 'mya', dep = ':jl_bottom_for_deps')",
        "my_rule(name = 'myb', dep = ':jl_bottom_for_runtime_deps')",
        "java_binary(name = 'binary', srcs = ['java/B.java'], main_class = 'foo.A',",
        "  deps = [':mya'], runtime_deps = [':myb'])");
    assertNoEvents();

    setBuildLanguageOptions("--experimental_google_legacy_api");
    // Test that all bottom jars are on the runtime classpath.
    ConfiguredTarget binary = getConfiguredTarget("//foo:binary");
    assertThat(
            prettyArtifactNames(
                binary
                    .get(JavaInfo.PROVIDER)
                    .getCompilationInfoProvider()
                    .getRuntimeClasspath()
                    .getSet(Artifact.class)))
        .containsAtLeast("foo/libjl_bottom_for_deps.jar", "foo/libjl_bottom_for_runtime_deps.jar");
  }

  @Test
  public void starlarkJavaToJavaImportAttributes() throws Exception {
    scratch.file(
        "foo/extension.bzl",
        "def _impl(ctx):",
        "  dep_params = ctx.attr.dep[JavaInfo]",
        "  return [dep_params]",
        "my_rule = rule(_impl, attrs = { 'dep' : attr.label() })");
    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "java_library(name = 'jl_bottom_for_deps', srcs = ['java/A.java'])",
        "java_library(name = 'jl_bottom_for_runtime_deps', srcs = ['java/A2.java'])",
        "my_rule(name = 'mya', dep = ':jl_bottom_for_deps')",
        "my_rule(name = 'myb', dep = ':jl_bottom_for_runtime_deps')",
        "java_import(name = 'import', jars = ['B.jar'], deps = [':mya'], runtime_deps = [':myb'])");
    assertNoEvents();

    // Test that all bottom jars are on the runtime classpath.
    ConfiguredTarget importTarget = getConfiguredTarget("//foo:import");
    JavaCompilationArgsProvider compilationProvider =
        JavaInfo.getProvider(JavaCompilationArgsProvider.class, importTarget);
    assertThat(prettyArtifactNames(compilationProvider.getRuntimeJars()))
        .containsAtLeast("foo/libjl_bottom_for_deps.jar", "foo/libjl_bottom_for_runtime_deps.jar");
  }

  @Test
  public void testJavaInfoSequenceParametersTypeChecked() throws Exception {
    scratch.file(
        "foo/bad_rules.bzl",
        "def make_file(ctx):",
        "  f = ctx.actions.declare_file('out')",
        "  ctx.actions.write(f, 'out')",
        "  return f",
        "def _deps_impl(ctx):",
        "  f = make_file(ctx)",
        "  return JavaInfo(output_jar=f, compile_jar=f, deps=[f])",
        "def _runtime_deps_impl(ctx):",
        "  f = make_file(ctx)",
        "  return JavaInfo(output_jar=f, compile_jar=f, runtime_deps=[f])",
        "def _exports_impl(ctx):",
        "  f = make_file(ctx)",
        "  return JavaInfo(output_jar=f, compile_jar=f, exports=[f])",
        "def _nativelibs_impl(ctx):",
        "  f = make_file(ctx)",
        "  return JavaInfo(output_jar=f, compile_jar=f, native_libraries=[f])",
        "bad_deps = rule(_deps_impl)",
        "bad_runtime_deps = rule(_runtime_deps_impl)",
        "bad_exports = rule(_exports_impl)",
        "bad_libs = rule(_nativelibs_impl)");
    scratch.file(
        "foo/BUILD",
        "load(':bad_rules.bzl', 'bad_deps', 'bad_runtime_deps', 'bad_exports', 'bad_libs')",
        "bad_deps(name='bad_deps')",
        "bad_runtime_deps(name='bad_runtime_deps')",
        "bad_exports(name='bad_exports')",
        "bad_libs(name='bad_libs')");

    checkError("//foo:bad_deps", "at index 0 of deps, got element of type File, want JavaInfo");
    checkError(
        "//foo:bad_runtime_deps",
        "at index 0 of runtime_deps, got element of type File, want JavaInfo");
    checkError(
        "//foo:bad_exports", "at index 0 of exports, got element of type File, want JavaInfo");
    checkError(
        "//foo:bad_libs", "at index 0 of native_libraries, got element of type File, want CcInfo");
  }

  @Test
  public void javaInfo_compileJarSet() throws Exception {
    scratch.file(
        "foo/javainfo_rules.bzl",
        "def make_file(ctx):",
        "  f = ctx.actions.declare_file('out')",
        "  ctx.actions.write(f, 'out')",
        "  return f",
        "def _bothset_impl(ctx):",
        "  f = make_file(ctx)",
        "  return [JavaInfo(output_jar=f, compile_jar=f)]",
        "bothset = rule(_bothset_impl)");
    scratch.file("foo/BUILD", "load(':javainfo_rules.bzl', 'bothset')", "bothset(name='bothset')");

    getConfiguredTarget("//foo:bothset");
    assertNoEvents();
  }

  @Test
  public void javaInfo_compileJarNotSet() throws Exception {
    scratch.file(
        "foo/javainfo_rules.bzl",
        "def make_file(ctx):",
        "  f = ctx.actions.declare_file('out')",
        "  ctx.actions.write(f, 'out')",
        "  return f",
        "def _only_outputjar_impl(ctx):",
        "  f = make_file(ctx)",
        "  return [JavaInfo(output_jar=f)]",
        "only_outputjar = rule(_only_outputjar_impl)");
    scratch.file(
        "foo/BUILD",
        "load(':javainfo_rules.bzl', 'only_outputjar')",
        "only_outputjar(name='only_outputjar')");

    checkError("//foo:only_outputjar", "missing 1 required positional argument: compile_jar");
  }

  @Test
  public void javaInfo_compileJarSetToNone() throws Exception {
    scratch.file(
        "foo/javainfo_rules.bzl",
        "def make_file(ctx):",
        "  f = ctx.actions.declare_file('out')",
        "  ctx.actions.write(f, 'out')",
        "  return f",
        "def _compilejar_none_impl(ctx):",
        "  f = make_file(ctx)",
        "  return [JavaInfo(output_jar=f, compile_jar=None)]",
        "compilejar_none = rule(_compilejar_none_impl)");
    scratch.file(
        "foo/BUILD",
        "load(':javainfo_rules.bzl', 'compilejar_none')",
        "compilejar_none(name='compilejar_none')");

    getConfiguredTarget("//foo:compilejar_none");

    assertNoEvents();
  }

  @Test
  public void javaInfoSourceJarsExposed() throws Exception {
    scratch.file(
        "foo/extension.bzl",
        "result = provider()",
        "def _impl(ctx):",
        "  return [result(source_jars = ctx.attr.dep[JavaInfo].source_jars)]",
        "my_rule = rule(_impl, attrs = { 'dep' : attr.label() })");
    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "java_library(name = 'my_java_lib_b', srcs = ['java/B.java'])",
        "java_library(name = 'my_java_lib_a', srcs = ['java/A.java'] , deps = [':my_java_lib_b'])",
        "my_rule(name = 'my_starlark_rule', dep = ':my_java_lib_a')");
    assertNoEvents();
    ConfiguredTarget myRuleTarget = getConfiguredTarget("//foo:my_starlark_rule");
    StructImpl info =
        (StructImpl)
            myRuleTarget.get(
                new StarlarkProvider.Key(Label.parseCanonical("//foo:extension.bzl"), "result"));
    @SuppressWarnings("unchecked")
    Sequence<Artifact> sourceJars = (Sequence<Artifact>) info.getValue("source_jars");
    assertThat(prettyArtifactNames(sourceJars)).containsExactly("foo/libmy_java_lib_a-src.jar");

    assertThat(prettyArtifactNames(sourceJars)).doesNotContain("foo/libmy_java_lib_b-src.jar");
  }

  @Test
  public void testJavaInfoGetTransitiveSourceJars() throws Exception {
    scratch.file(
        "foo/extension.bzl",
        "result = provider()",
        "def _impl(ctx):",
        "  return [result(property = ctx.attr.dep[JavaInfo].transitive_source_jars)]",
        "my_rule = rule(_impl, attrs = { 'dep' : attr.label() })");

    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "java_library(name = 'my_java_lib_c', srcs = ['java/C.java'])",
        "java_library(name = 'my_java_lib_b', srcs = ['java/B.java'], deps = [':my_java_lib_c'])",
        "java_library(name = 'my_java_lib_a', srcs = ['java/A.java'], deps = [':my_java_lib_b'])",
        "my_rule(name = 'my_starlark_rule', dep = ':my_java_lib_a')");
    assertNoEvents();
    ConfiguredTarget myRuleTarget = getConfiguredTarget("//foo:my_starlark_rule");
    StructImpl info =
        (StructImpl)
            myRuleTarget.get(
                new StarlarkProvider.Key(Label.parseCanonical("//foo:extension.bzl"), "result"));

    Depset sourceJars = (Depset) info.getValue("property");

    assertThat(prettyArtifactNames(sourceJars.getSet(Artifact.class)))
        .containsExactly(
            "foo/libmy_java_lib_a-src.jar",
            "foo/libmy_java_lib_b-src.jar",
            "foo/libmy_java_lib_c-src.jar");
  }

  @Test
  public void testJavaInfoGetTransitiveDeps() throws Exception {
    scratch.file(
        "foo/extension.bzl",
        "result = provider()",
        "def _impl(ctx):",
        "  return [result(property = ctx.attr.dep[JavaInfo].transitive_compile_time_jars)]",
        "my_rule = rule(_impl, attrs = { 'dep' : attr.label() })");

    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "java_library(name = 'my_java_lib_c', srcs = ['java/C.java'])",
        "java_library(name = 'my_java_lib_b', srcs = ['java/B.java'], deps = [':my_java_lib_c'])",
        "java_library(name = 'my_java_lib_a', srcs = ['java/A.java'], deps = [':my_java_lib_b'])",
        "my_rule(name = 'my_starlark_rule', dep = ':my_java_lib_a')");
    assertNoEvents();
    ConfiguredTarget myRuleTarget = getConfiguredTarget("//foo:my_starlark_rule");
    StructImpl info =
        (StructImpl)
            myRuleTarget.get(
                new StarlarkProvider.Key(Label.parseCanonical("//foo:extension.bzl"), "result"));

    Depset sourceJars = (Depset) info.getValue("property");

    assertThat(prettyArtifactNames(sourceJars.getSet(Artifact.class)))
        .containsExactly(
            "foo/libmy_java_lib_a-hjar.jar",
            "foo/libmy_java_lib_b-hjar.jar",
            "foo/libmy_java_lib_c-hjar.jar");
  }

  @Test
  public void testJavaInfoGetTransitiveRuntimeDeps() throws Exception {
    scratch.file(
        "foo/extension.bzl",
        "result = provider()",
        "def _impl(ctx):",
        "  return [result(property = ctx.attr.dep[JavaInfo].transitive_runtime_jars)]",
        "my_rule = rule(_impl, attrs = { 'dep' : attr.label() })");

    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "java_library(name = 'my_java_lib_c', srcs = ['java/C.java'])",
        "java_library(name = 'my_java_lib_b', srcs = ['java/B.java'], deps = [':my_java_lib_c'])",
        "java_library(name = 'my_java_lib_a', srcs = ['java/A.java'], deps = [':my_java_lib_b'])",
        "my_rule(name = 'my_starlark_rule', dep = ':my_java_lib_a')");
    assertNoEvents();
    ConfiguredTarget myRuleTarget = getConfiguredTarget("//foo:my_starlark_rule");
    StructImpl info =
        (StructImpl)
            myRuleTarget.get(
                new StarlarkProvider.Key(Label.parseCanonical("//foo:extension.bzl"), "result"));

    Depset sourceJars = (Depset) info.getValue("property");

    assertThat(prettyArtifactNames(sourceJars.getSet(Artifact.class)))
        .containsExactly(
            "foo/libmy_java_lib_a.jar", "foo/libmy_java_lib_b.jar", "foo/libmy_java_lib_c.jar");
  }

  /** Tests that JavaInfo provides information about transitive native libraries in Starlark. */
  @Test
  public void javaInfo_getTransitiveNativeLibraries() throws Exception {
    scratch.file(
        "foo/extension.bzl",
        "result = provider()",
        "def _impl(ctx):",
        "  return [result(property = ctx.attr.dep[JavaInfo].transitive_native_libraries)]",
        "my_rule = rule(_impl, attrs = { 'dep' : attr.label() })");

    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "cc_library(name = 'my_cc_lib_c.so', srcs = ['cc/c.cc'])",
        "cc_library(name = 'my_cc_lib_b.so', srcs = ['cc/b.cc'])",
        "cc_library(name = 'my_cc_lib_a.so', srcs = ['cc/a.cc'])",
        "java_library(name = 'my_java_lib_c', srcs = ['java/C.java'], deps = ['my_cc_lib_c.so'])",
        "java_library(name = 'my_java_lib_b', srcs = ['java/B.java'], deps = ['my_cc_lib_b.so'])",
        "java_library(name = 'my_java_lib_a', srcs = ['java/A.java'], ",
        "             deps = [':my_java_lib_b', ':my_java_lib_c', 'my_cc_lib_a.so'])",
        "my_rule(name = 'my_starlark_rule', dep = ':my_java_lib_a')");
    assertNoEvents();
    ConfiguredTarget myRuleTarget = getConfiguredTarget("//foo:my_starlark_rule");
    StructImpl info =
        (StructImpl)
            myRuleTarget.get(
                new StarlarkProvider.Key(Label.parseCanonical("//foo:extension.bzl"), "result"));

    Depset nativeLibs = (Depset) info.getValue("property");

    assertThat(
            nativeLibs.getSet(LibraryToLink.class).toList().stream()
                .map(LibraryToLink::getLibraryIdentifier))
        .containsExactly("foo/libmy_cc_lib_a.so", "foo/libmy_cc_lib_b.so", "foo/libmy_cc_lib_c.so");
  }

  /**
   * Tests that java_library propagates direct native library information from JavaInfo provider.
   */
  @Test
  public void javaLibrary_propagatesDirectNativeLibrariesInJavaInfo() throws Exception {
    scratch.file(
        "foo/extension.bzl",
        "def _impl(ctx):",
        "  dep_params = ctx.attr.dep[JavaInfo]",
        "  cc_dep_params = ctx.attr.cc_dep[CcInfo]",
        "  java_info = JavaInfo(output_jar = dep_params.java_outputs[0].class_jar,",
        "    compile_jar = None,",
        "    native_libraries = [cc_dep_params])",
        "  return [java_common.merge([dep_params, java_info])]",
        "my_rule = rule(_impl, attrs = { 'dep': attr.label(), 'cc_dep': attr.label() })");
    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "cc_library(name = 'native', srcs = ['cc/x.cc'])",
        "java_library(name = 'jl', srcs = ['java/A.java'], deps = [':native'])",
        "cc_library(name = 'ccl', srcs = ['cc/x.cc'])",
        "my_rule(name = 'r', dep = ':jl', cc_dep = ':ccl')",
        "java_library(name = 'jl_top', srcs = ['java/C.java'], deps = [':r'])");

    ConfiguredTarget topJavaLibrary = getConfiguredTarget("//foo:jl_top");

    NestedSet<LibraryToLink> librariesForTopTarget =
        topJavaLibrary.get(JavaInfo.PROVIDER).getTransitiveNativeLibraries();
    assertThat(librariesForTopTarget.toList().stream().map(LibraryToLink::getLibraryIdentifier))
        .containsExactly("foo/libnative", "foo/libccl")
        .inOrder();
  }

  /** Tests that java_binary propagates direct native library information from JavaInfo provider. */
  @Test
  public void javaBinary_propagatesDirectNativeLibrariesInJavaInfo() throws Exception {
    scratch.file(
        "foo/extension.bzl",
        "def _impl(ctx):",
        "  dep_params = ctx.attr.dep[JavaInfo]",
        "  cc_dep_params = ctx.attr.cc_dep[CcInfo]",
        "  java_info = JavaInfo(output_jar = dep_params.java_outputs[0].class_jar,",
        "    compile_jar = None,",
        "    native_libraries = [cc_dep_params])",
        "  return [java_common.merge([dep_params, java_info])]",
        "my_rule = rule(_impl, attrs = { 'dep': attr.label(), 'cc_dep': attr.label() })");
    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "cc_binary(name = 'native', srcs = ['cc/x.cc'], linkshared=1, linkstatic=1)",
        "java_library(name = 'jl', srcs = ['java/A.java'], data = [':native'])",
        "cc_binary(name = 'ccl', srcs = ['cc/x.cc'], linkshared=1, linkstatic=1)",
        "my_rule(name = 'r', dep = ':jl', cc_dep = ':ccl')",
        "java_binary(name = 'binary', main_class = 'C', srcs = ['java/C.java'], deps = [':r'])");

    setBuildLanguageOptions("--experimental_google_legacy_api");
    ConfiguredTarget testTarget = getConfiguredTarget("//foo:binary");

    // Check that the directory name is on the java.library.path
    assertThat(getJvmFlags(getExecutable(testTarget)))
        .containsMatch("-Djava.library.path=\\$\\{JAVA_RUNFILES\\}/.*/foo");
  }

  /** Tests that java_test propagates direct native library information from JavaInfo provider. */
  @Test
  public void javaTest_propagatesDirectNativeLibrariesInJavaInfo() throws Exception {
    scratch.file(
        "foo/extension.bzl",
        "def _impl(ctx):",
        "  dep_params = ctx.attr.dep[JavaInfo]",
        "  cc_dep_params = ctx.attr.cc_dep[CcInfo]",
        "  java_info = JavaInfo(output_jar = dep_params.java_outputs[0].class_jar,",
        "    compile_jar = None,",
        "    native_libraries = [cc_dep_params])",
        "  return [java_common.merge([dep_params, java_info])]",
        "my_rule = rule(_impl, attrs = { 'dep': attr.label(), 'cc_dep': attr.label() })");
    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "cc_binary(name = 'native', srcs = ['cc/x.cc'], linkshared=1, linkstatic=1)",
        "java_library(name = 'jl', srcs = ['java/A.java'], data = [':native'])",
        "cc_binary(name = 'ccl', srcs = ['cc/x.cc'], linkshared=1, linkstatic=1)",
        "my_rule(name = 'r', dep = ':jl', cc_dep = ':ccl')",
        "java_test(name = 'test', test_class='test', srcs = ['Test.java'], deps = [':r'])");

    ConfiguredTarget testTarget = getConfiguredTarget("//foo:test");
    // Check that the directory name is on the java.library.path
    assertThat(getJvmFlags(getExecutable(testTarget)))
        .containsMatch("-Djava.library.path=\\$\\{JAVA_RUNFILES\\}/.*/foo");
  }

  /** Tests that java_library exposes native library info to Starlark. */
  @Test
  public void javaLibrary_exposesNativeLibraryInfoToStarlark() throws Exception {
    scratch.file(
        "foo/extension.bzl",
        "my_provider = provider()",
        "def _impl(ctx):",
        "  dep_params = ctx.attr.dep[JavaInfo].transitive_native_libraries",
        "  return [my_provider(p = dep_params)]",
        "my_rule = rule(_impl, attrs = { 'dep' : attr.label() })");
    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "cc_binary(name = 'native.so', srcs = ['cc/x.cc'], linkshared = True)",
        "java_library(name = 'jl', srcs = ['java/A.java'], deps = [':native.so'])",
        "my_rule(name = 'r', dep = ':jl')");

    ConfiguredTarget myRuleTarget = getConfiguredTarget("//foo:r");
    ConfiguredTarget javaLibraryTarget = getConfiguredTarget("//foo:jl");

    JavaInfo javaInfo = javaLibraryTarget.get(JavaInfo.PROVIDER);
    StarlarkProvider.Key myProviderKey =
        new StarlarkProvider.Key(Label.parseCanonical("//foo:extension.bzl"), "my_provider");
    StructImpl declaredProvider = (StructImpl) myRuleTarget.get(myProviderKey);
    Object nativeLibrariesFromStarlark = declaredProvider.getValue("p");
    assertThat(nativeLibrariesFromStarlark)
        .isEqualTo(javaInfo.getTransitiveNativeLibrariesForStarlark());
    assertThat(
            javaInfo
                .getTransitiveNativeLibraries()
                .getSingleton()
                .getDynamicLibrary()
                .getFilename())
        .isEqualTo("native.so");
  }

  /** Tests that JavaInfo propagates native libraries from deps, runtime_deps, and exports. */
  @Test
  public void javaInfo_nativeLibrariesPropagate() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file(
        "java/test/BUILD",
        "load(':custom_rule.bzl', 'java_custom_library')",
        "java_custom_library(",
        "  name = 'custom',",
        "  srcs = ['A.java'],",
        "  deps = [':lib_deps'],",
        "  runtime_deps = [':lib_runtime_deps'],",
        "  exports = [':lib_exports'],",
        ")",
        "java_library(name = 'lib_deps', srcs = ['B.java'], deps = [':native_deps1.so'])",
        "cc_library(name = 'native_deps1.so', srcs = ['a.cc'])",
        "java_library(name = 'lib_runtime_deps', srcs = ['C.java'], deps = [':native_rdeps1.so'])",
        "cc_library(name = 'native_rdeps1.so', srcs = ['c.cc'])",
        "java_library(name = 'lib_exports', srcs = ['D.java'], deps = [':native_exports1.so'])",
        "cc_library(name = 'native_exports1.so', srcs = ['e.cc'])");
    scratch.file(
        "java/test/custom_rule.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib' + ctx.label.name + '.jar')",
        "  ctx.actions.write(output_jar, '')",
        "  compilation_provider = JavaInfo(",
        "    output_jar = output_jar,",
        "    compile_jar = None,",
        "    deps = [dep[JavaInfo] for dep in ctx.attr.deps if JavaInfo in dep],",
        "    runtime_deps = [dep[JavaInfo] for dep in ctx.attr.runtime_deps if JavaInfo in dep],",
        "    exports = [dep[JavaInfo] for dep in ctx.attr.exports if JavaInfo in dep],",
        "  )",
        "  return [",
        "      compilation_provider",
        "  ]",
        "java_custom_library = rule(",
        "  implementation = _impl,",
        "  outputs = {",
        "    'my_output': 'lib%{name}.jar'",
        "  },",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files=True),",
        "    'deps': attr.label_list(),",
        "    'runtime_deps': attr.label_list(),",
        "    'exports': attr.label_list(),",
        "    '_java_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),",
        "  },",
        "  fragments = ['java']",
        ")");

    ConfiguredTarget configuredTarget = getConfiguredTarget("//java/test:custom");

    JavaInfo info = configuredTarget.get(JavaInfo.PROVIDER);
    NestedSet<LibraryToLink> nativeLibraries = info.getTransitiveNativeLibraries();
    assertThat(nativeLibraries.toList().stream().map(LibraryToLink::getLibraryIdentifier))
        .containsExactly(
            "java/test/libnative_rdeps1.so",
            "java/test/libnative_exports1.so",
            "java/test/libnative_deps1.so")
        .inOrder();
  }

  @Test
  public void testJavaInfoGetGenJarsProvider() throws Exception {
    scratch.file(
        "foo/extension.bzl",
        "result = provider()",
        "def _impl(ctx):",
        "  return [result(property = ctx.attr.dep[JavaInfo].annotation_processing)]",
        "my_rule = rule(_impl, attrs = { 'dep' : attr.label() })");

    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "java_library(name = 'my_java_lib_a', srcs = ['java/A.java'], ",
        "             javacopts = ['-processor com.google.process.Processor'])",
        "my_rule(name = 'my_starlark_rule', dep = ':my_java_lib_a')");
    assertNoEvents();
    ConfiguredTarget myRuleTarget = getConfiguredTarget("//foo:my_starlark_rule");
    StructImpl info =
        (StructImpl)
            myRuleTarget.get(
                new StarlarkProvider.Key(Label.parseCanonical("//foo:extension.bzl"), "result"));

    JavaGenJarsProvider javaGenJarsProvider = JavaGenJarsProvider.from(info.getValue("property"));

    assertThat(javaGenJarsProvider.getGenClassJar().getFilename())
        .isEqualTo("libmy_java_lib_a-gen.jar");
    assertThat(javaGenJarsProvider.getGenSourceJar().getFilename())
        .isEqualTo("libmy_java_lib_a-gensrc.jar");
  }

  @Test
  public void javaInfoGetCompilationInfoProvider() throws Exception {
    scratch.file(
        "foo/extension.bzl",
        "result = provider()",
        "def _impl(ctx):",
        "  return [result(property = ctx.attr.dep[JavaInfo].compilation_info)]",
        "my_rule = rule(_impl, attrs = { 'dep' : attr.label() })");

    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "java_library(name = 'my_java_lib_a', srcs = ['java/A.java'], javacopts = ['opt1'])",
        "my_rule(name = 'my_starlark_rule', dep = ':my_java_lib_a')");
    assertNoEvents();
    ConfiguredTarget myRuleTarget = getConfiguredTarget("//foo:my_starlark_rule");
    StructImpl info =
        (StructImpl)
            myRuleTarget.get(
                new StarlarkProvider.Key(Label.parseCanonical("//foo:extension.bzl"), "result"));

    JavaCompilationInfoProvider javaCompilationInfoProvider =
        JavaCompilationInfoProvider.fromStarlarkCompilationInfo(info.getValue("property"));

    assertThat(
            prettyArtifactNames(
                javaCompilationInfoProvider.getRuntimeClasspath().getSet(Artifact.class)))
        .containsExactly("foo/libmy_java_lib_a.jar");
    assertThat(javaCompilationInfoProvider.getJavacOpts()).contains("opt1");
    assertThat(javaCompilationInfoProvider.getJavacOptsList()).contains("opt1");
  }

  @Test
  public void javaInfoStarlarkCompilationInfoJavacOpts() throws Exception {
    scratch.file(
        "foo/extension.bzl",
        "result = provider()",
        "def _impl(ctx):",
        "  return [result(property = ctx.attr.dep[JavaInfo].compilation_info.javac_options_list)]",
        "my_rule = rule(_impl, attrs = { 'dep' : attr.label() })");
    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "java_library(name = 'my_java_lib_a', srcs = ['java/A.java'], javacopts = ['opt1',"
            + " 'opt2'])",
        "my_rule(name = 'my_starlark_rule', dep = ':my_java_lib_a')");
    assertNoEvents();
    ConfiguredTarget myRuleTarget = getConfiguredTarget("//foo:my_starlark_rule");

    StructImpl info =
        (StructImpl)
            myRuleTarget.get(
                new StarlarkProvider.Key(Label.parseCanonical("//foo:extension.bzl"), "result"));
    Sequence<String> javacOptionsList =
        Sequence.cast(info.getValue("property"), String.class, "javac_options_list");

    assertThat(javacOptionsList).containsAtLeast("opt1", "opt2").inOrder();
  }

  /* Test inspired by {@link AbstractJavaLibraryConfiguredTargetTest#testNeverlink}.*/
  @Test
  public void javaCommonCompileNeverlink() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file(
        "java/test/BUILD",
        "load(':custom_rule.bzl', 'java_custom_library')",
        "java_binary(name = 'plugin',",
        "    deps = [ ':somedep'],",
        "    srcs = [ 'Plugin.java'],",
        "    main_class = 'plugin.start')",
        "java_custom_library(name = 'somedep',",
        "    srcs = ['Dependency.java'],",
        "    deps = [ ':eclipse' ])",
        "java_custom_library(name = 'eclipse',",
        "    neverlink = 1,",
        "    srcs = ['EclipseDependency.java'])");
    scratch.file(
        "java/test/custom_rule.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib' + ctx.label.name + '.jar')",
        "  deps = [dep[java_common.provider] for dep in ctx.attr.deps]",
        "  compilation_provider = java_common.compile(",
        "    ctx,",
        "    source_files = ctx.files.srcs,",
        "    output = output_jar,",
        "    neverlink = ctx.attr.neverlink,",
        "    deps = deps,",
        "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
        "  )",
        "  return [",
        "      DefaultInfo(",
        "          files = depset([output_jar]),",
        "      ),",
        "      compilation_provider",
        "  ]",
        "java_custom_library = rule(",
        "  implementation = _impl,",
        "  outputs = {",
        "    'my_output': 'lib%{name}.jar'",
        "  },",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files=['.java']),",
        "    'neverlink': attr.bool(),",
        "     'deps': attr.label_list(),",
        "    '_java_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),",
        "  },",
        "  toolchains = ['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java']",
        ")");

    setBuildLanguageOptions("--experimental_google_legacy_api");
    ConfiguredTarget target = getConfiguredTarget("//java/test:plugin");
    assertThat(
            actionsTestUtil()
                .predecessorClosureAsCollection(getFilesToBuild(target), JavaSemantics.JAVA_SOURCE))
        .containsExactly("Plugin.java", "Dependency.java", "EclipseDependency.java");
    assertThat(
            ActionsTestUtil.baseNamesOf(
                FileType.filter(
                    getRunfilesSupport(target).getRunfilesSymlinkTargets(), JavaSemantics.JAR)))
        .isEqualTo("plugin.jar libsomedep.jar");
  }

  @Test
  public void javaInfoConstructorWithNeverlink() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file(
        "java/test/BUILD",
        "load(':custom_rule.bzl', 'java_custom_library')",
        "java_custom_library(name = 'somedep')");
    scratch.file(
        "java/test/custom_rule.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib' + ctx.label.name + '.jar')",
        "  ctx.actions.write(output_jar, '')",
        "  java_info = JavaInfo(",
        "    output_jar = output_jar,",
        "    compile_jar = None,",
        "    neverlink = True,",
        "  )",
        "  return [",
        "      java_info",
        "  ]",
        "java_custom_library = rule(",
        "  implementation = _impl,",
        "  fragments = ['java'],",
        "  provides = [JavaInfo],",
        ")");

    ConfiguredTarget target = getConfiguredTarget("//java/test:somedep");

    JavaInfo javaInfo = target.get(JavaInfo.PROVIDER);
    assertThat(javaInfo.isNeverlink()).isTrue();
  }

  @Test
  public void javaCommonMergeWithNeverlink() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file(
        "java/test/BUILD",
        "load(':custom_rule.bzl', 'java_custom_library')",
        "java_custom_library(name = 'somedep')");
    scratch.file(
        "java/test/custom_rule.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib' + ctx.label.name + '.jar')",
        "  ctx.actions.write(output_jar, '')",
        "  java_info_with_neverlink = JavaInfo(",
        "    output_jar = output_jar,",
        "    compile_jar = None,",
        "    neverlink = True,",
        "  )",
        "  java_info_without_neverlink = JavaInfo(",
        "    output_jar = output_jar,",
        "    compile_jar = None,",
        "  )",
        "  java_info = java_common.merge([java_info_with_neverlink, java_info_without_neverlink])",
        "  return [",
        "      java_info",
        "  ]",
        "java_custom_library = rule(",
        "  implementation = _impl,",
        "  fragments = ['java'],",
        "  provides = [JavaInfo],",
        ")");

    ConfiguredTarget target = getConfiguredTarget("//java/test:somedep");

    JavaInfo javaInfo = target.get(JavaInfo.PROVIDER);
    assertThat(javaInfo.isNeverlink()).isTrue();
  }

  @Test
  public void javaCommonCompileWithNeverlink() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file(
        "java/test/BUILD",
        "load(':custom_rule.bzl', 'java_custom_library')",
        "java_custom_library(name = 'somedep',",
        "    srcs = ['Dependency.java'])");
    scratch.file(
        "java/test/custom_rule.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib' + ctx.label.name + '.jar')",
        "  java_info = java_common.compile(",
        "    ctx,",
        "    source_files = ctx.files.srcs,",
        "    output = output_jar,",
        "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
        "    neverlink = True,",
        "  )",
        "  return [",
        "      java_info",
        "  ]",
        "java_custom_library = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files=['.java']),",
        "    '_java_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),",
        "  },",
        "  toolchains = ['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java'],",
        "  provides = [JavaInfo],",
        ")");

    ConfiguredTarget target = getConfiguredTarget("//java/test:somedep");

    JavaInfo javaInfo = target.get(JavaInfo.PROVIDER);
    assertThat(javaInfo.isNeverlink()).isTrue();
  }

  /**
   * Tests that java_common.compile propagates native libraries from deps, runtime_deps, and
   * exports.
   */
  @Test
  public void javaCommonCompile_nativeLibrariesPropagate() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file(
        "java/test/BUILD",
        "load(':custom_rule.bzl', 'java_custom_library')",
        "java_custom_library(",
        "  name = 'custom',",
        "  srcs = ['A.java'],",
        "  deps = [':lib_deps'],",
        "  runtime_deps = [':lib_runtime_deps'],",
        "  exports = [':lib_exports'],",
        ")",
        "java_library(name = 'lib_deps', srcs = ['B.java'], deps = [':native_deps1.so'])",
        "cc_library(name = 'native_deps1.so', srcs = ['a.cc'])",
        "java_library(name = 'lib_runtime_deps', srcs = ['C.java'], deps = [':native_rdeps1.so'])",
        "cc_library(name = 'native_rdeps1.so', srcs = ['c.cc'])",
        "java_library(name = 'lib_exports', srcs = ['D.java'], deps = [':native_exports1.so'])",
        "cc_library(name = 'native_exports1.so', srcs = ['e.cc'])");
    scratch.file(
        "java/test/custom_rule.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib' + ctx.label.name + '.jar')",
        "  compilation_provider = java_common.compile(",
        "    ctx,",
        "    source_files = ctx.files.srcs,",
        "    output = output_jar,",
        "    deps = [dep[JavaInfo] for dep in ctx.attr.deps if JavaInfo in dep],",
        "    runtime_deps = [dep[JavaInfo] for dep in ctx.attr.runtime_deps if JavaInfo in dep],",
        "    exports = [dep[JavaInfo] for dep in ctx.attr.exports if JavaInfo in dep],",
        "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
        "  )",
        "  return [",
        "      compilation_provider",
        "  ]",
        "java_custom_library = rule(",
        "  implementation = _impl,",
        "  outputs = {",
        "    'my_output': 'lib%{name}.jar'",
        "  },",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files=True),",
        "    'deps': attr.label_list(),",
        "    'runtime_deps': attr.label_list(),",
        "    'exports': attr.label_list(),",
        "    '_java_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),",
        "  },",
        "  toolchains = ['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java']",
        ")");

    ConfiguredTarget configuredTarget = getConfiguredTarget("//java/test:custom");

    JavaInfo info = configuredTarget.get(JavaInfo.PROVIDER);
    NestedSet<LibraryToLink> nativeLibraries = info.getTransitiveNativeLibraries();
    assertThat(nativeLibraries.toList().stream().map(LibraryToLink::getLibraryIdentifier))
        .containsExactly(
            "java/test/libnative_rdeps1.so",
            "java/test/libnative_exports1.so",
            "java/test/libnative_deps1.so")
        .inOrder();
  }

  /**
   * Tests that java_common.compile propagates native libraries passed by native_libraries argument.
   */
  @Test
  public void javaCommonCompile_directNativeLibraries() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file(
        "java/test/BUILD",
        "load(':custom_rule.bzl', 'java_custom_library')",
        "java_custom_library(",
        "  name = 'custom',",
        "  srcs = ['A.java'],",
        "  ccdeps = [':native.so'],",
        ")",
        "cc_library(",
        "  name = 'native.so',",
        "  srcs = ['a.cc'],",
        ")");
    scratch.file(
        "java/test/custom_rule.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib' + ctx.label.name + '.jar')",
        "  compilation_provider = java_common.compile(",
        "    ctx,",
        "    source_files = ctx.files.srcs,",
        "    output = output_jar,",
        "    native_libraries = [dep[CcInfo] for dep in ctx.attr.ccdeps if CcInfo in dep],",
        "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
        "  )",
        "  return [",
        "      compilation_provider",
        "  ]",
        "java_custom_library = rule(",
        "  implementation = _impl,",
        "  outputs = {",
        "    'my_output': 'lib%{name}.jar'",
        "  },",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files=True),",
        "    'ccdeps': attr.label_list(),",
        "    '_java_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),",
        "  },",
        "  toolchains = ['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java']",
        ")");

    ConfiguredTarget configuredTarget = getConfiguredTarget("//java/test:custom");

    JavaInfo info = configuredTarget.get(JavaInfo.PROVIDER);
    NestedSet<LibraryToLink> nativeLibraries = info.getTransitiveNativeLibraries();
    assertThat(nativeLibraries.toList().stream().map(LibraryToLink::getLibraryIdentifier))
        .containsExactly("java/test/libnative.so")
        .inOrder();
  }

  @Test
  public void strictDepsEnabled() throws Exception {
    scratch.file(
        "foo/custom_library.bzl",
        "def _impl(ctx):",
        "  java_provider = java_common.merge([dep[JavaInfo] for dep in ctx.attr.deps])",
        "  if not ctx.attr.strict_deps:",
        "    java_provider = java_common.make_non_strict(java_provider)",
        "  return [java_provider]",
        "custom_library = rule(",
        "  attrs = {",
        "    'deps': attr.label_list(),",
        "    'strict_deps': attr.bool()",
        "  },",
        "  implementation = _impl",
        ")");
    scratch.file(
        "foo/BUILD",
        "load(':custom_library.bzl', 'custom_library')",
        "custom_library(name = 'custom', deps = [':a'], strict_deps = True)",
        "java_library(name = 'a', srcs = ['java/A.java'], deps = [':b'])",
        "java_library(name = 'b', srcs = ['java/B.java'])");

    ConfiguredTarget myRuleTarget = getConfiguredTarget("//foo:custom");
    JavaCompilationArgsProvider javaCompilationArgsProvider =
        JavaInfo.getProvider(JavaCompilationArgsProvider.class, myRuleTarget);
    List<String> directJars =
        prettyArtifactNames(javaCompilationArgsProvider.getDirectCompileTimeJars());
    assertThat(directJars).containsExactly("foo/liba-hjar.jar");
  }

  @Test
  public void strictDepsDisabled() throws Exception {
    scratch.file(
        "foo/custom_library.bzl",
        "def _impl(ctx):",
        "  java_provider = java_common.merge([dep[JavaInfo] for dep in ctx.attr.deps])",
        "  if not ctx.attr.strict_deps:",
        "    java_provider = java_common.make_non_strict(java_provider)",
        "  return [java_provider]",
        "custom_library = rule(",
        "  attrs = {",
        "    'deps': attr.label_list(),",
        "    'strict_deps': attr.bool()",
        "  },",
        "  implementation = _impl",
        ")");
    scratch.file(
        "foo/BUILD",
        "load(':custom_library.bzl', 'custom_library')",
        "custom_library(name = 'custom', deps = [':a'], strict_deps = False)",
        "java_library(name = 'a', srcs = ['java/A.java'], deps = [':b'])",
        "java_library(name = 'b', srcs = ['java/B.java'])");

    ConfiguredTarget myRuleTarget = getConfiguredTarget("//foo:custom");
    JavaCompilationArgsProvider javaCompilationArgsProvider =
        JavaInfo.getProvider(JavaCompilationArgsProvider.class, myRuleTarget);
    List<String> directJars = prettyArtifactNames(javaCompilationArgsProvider.getRuntimeJars());
    assertThat(directJars).containsExactly("foo/liba.jar", "foo/libb.jar");
  }

  @Test
  public void strictJavaDepsFlagExposed_default() throws Exception {
    scratch.file(
        "foo/rule.bzl",
        "result = provider()",
        "def _impl(ctx):",
        "  return [result(strict_java_deps=ctx.fragments.java.strict_java_deps)]",
        "myrule = rule(",
        "  implementation=_impl,",
        "  fragments = ['java']",
        ")");
    scratch.file("foo/BUILD", "load(':rule.bzl', 'myrule')", "myrule(name='myrule')");
    ConfiguredTarget configuredTarget = getConfiguredTarget("//foo:myrule");
    StructImpl info =
        (StructImpl)
            configuredTarget.get(
                new StarlarkProvider.Key(Label.parseCanonical("//foo:rule.bzl"), "result"));
    assertThat(((String) info.getValue("strict_java_deps"))).isEqualTo("default");
  }

  @Test
  public void strictJavaDepsFlagExposed_error() throws Exception {
    scratch.file(
        "foo/rule.bzl",
        "result = provider()",
        "def _impl(ctx):",
        "  return [result(strict_java_deps=ctx.fragments.java.strict_java_deps)]",
        "myrule = rule(",
        "  implementation=_impl,",
        "  fragments = ['java']",
        ")");
    scratch.file("foo/BUILD", "load(':rule.bzl', 'myrule')", "myrule(name='myrule')");
    useConfiguration("--strict_java_deps=ERROR");
    ConfiguredTarget configuredTarget = getConfiguredTarget("//foo:myrule");
    StructImpl info =
        (StructImpl)
            configuredTarget.get(
                new StarlarkProvider.Key(Label.parseCanonical("//foo:rule.bzl"), "result"));
    assertThat(((String) info.getValue("strict_java_deps"))).isEqualTo("error");
  }

  @Test
  public void mergeRuntimeOutputJarsTest() throws Exception {
    scratch.file(
        "foo/custom_library.bzl",
        "def _impl(ctx):",
        "  java_provider = java_common.merge([dep[JavaInfo] for dep in ctx.attr.deps])",
        "  return [java_provider]",
        "custom_library = rule(",
        "  attrs = {",
        "    'deps': attr.label_list(),",
        "    'strict_deps': attr.bool()",
        "  },",
        "  implementation = _impl",
        ")");
    scratch.file(
        "foo/BUILD",
        "load(':custom_library.bzl', 'custom_library')",
        "custom_library(name = 'custom', deps = [':a', ':b'])",
        "java_library(name = 'a', srcs = ['java/A.java'])",
        "java_library(name = 'b', srcs = ['java/B.java'])");

    ConfiguredTarget myRuleTarget = getConfiguredTarget("//foo:custom");
    JavaInfo javaInfo = myRuleTarget.get(JavaInfo.PROVIDER);
    List<String> directJars = prettyArtifactNames(javaInfo.getRuntimeOutputJars());
    assertThat(directJars).containsExactly("foo/liba.jar", "foo/libb.jar");
  }

  @Test
  public void javaToolchainFlag_default() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file(
        "foo/rule.bzl",
        "result = provider()",
        "def _impl(ctx):",
        "  return [result(java_toolchain_label=ctx.attr._java_toolchain)]",
        "myrule = rule(",
        "  implementation=_impl,",
        "  fragments = ['java'],",
        "  attrs = { '_java_toolchain': attr.label(default=Label('//foo:alias')) }",
        ")");
    scratch.file(
        "foo/BUILD",
        "load(':rule.bzl', 'myrule')",
        "load('"
            + TestConstants.TOOLS_REPOSITORY
            + "//tools/jdk:java_toolchain_alias.bzl', 'java_toolchain_alias')",
        "java_toolchain_alias(name='alias')",
        "myrule(name='myrule')");
    ConfiguredTarget configuredTarget = getConfiguredTarget("//foo:myrule");
    StructImpl info =
        (StructImpl)
            configuredTarget.get(
                new StarlarkProvider.Key(Label.parseCanonical("//foo:rule.bzl"), "result"));
    JavaToolchainProvider javaToolchainProvider =
        JavaToolchainProvider.from((ConfiguredTarget) info.getValue("java_toolchain_label"));
    Label javaToolchainLabel = javaToolchainProvider.getToolchainLabel();
    assertWithMessage(javaToolchainLabel.toString())
        .that(
            javaToolchainLabel.toString().endsWith("jdk:remote_toolchain")
                || javaToolchainLabel.toString().endsWith("jdk:toolchain")
                || javaToolchainLabel.toString().endsWith("jdk:toolchain_host"))
        .isTrue();
  }

  @Test
  public void javaToolchainFlag_set() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file(
        "foo/rule.bzl",
        "result = provider()",
        "def _impl(ctx):",
        "  return [result(java_toolchain_label=ctx.attr._java_toolchain)]",
        "myrule = rule(",
        "  implementation=_impl,",
        "  fragments = ['java'],",
        "  attrs = { '_java_toolchain': attr.label(default=Label('//foo:alias')) }",
        ")");
    scratch.file(
        "foo/BUILD",
        "load(':rule.bzl', 'myrule')",
        "load('"
            + TestConstants.TOOLS_REPOSITORY
            + "//tools/jdk:java_toolchain_alias.bzl', 'java_toolchain_alias')",
        "java_toolchain_alias(name='alias')",
        "myrule(name='myrule')");
    useConfiguration("--extra_toolchains=//java/com/google/test:all");
    ConfiguredTarget configuredTarget = getConfiguredTarget("//foo:myrule");
    StructImpl info =
        (StructImpl)
            configuredTarget.get(
                new StarlarkProvider.Key(Label.parseCanonical("//foo:rule.bzl"), "result"));
    JavaToolchainProvider javaToolchainProvider =
        JavaToolchainProvider.from((ConfiguredTarget) info.getValue("java_toolchain_label"));
    Label javaToolchainLabel = javaToolchainProvider.getToolchainLabel();
    assertThat(javaToolchainLabel.toString()).isEqualTo("//java/com/google/test:toolchain");
  }

  private static boolean javaCompilationArgsHaveTheSameParent(
      JavaCompilationArgsProvider args, JavaCompilationArgsProvider otherArgs) {
    if (!nestedSetsOfArtifactHaveTheSameParent(
        args.getTransitiveCompileTimeJars(), otherArgs.getTransitiveCompileTimeJars())) {
      return false;
    }
    if (!nestedSetsOfArtifactHaveTheSameParent(args.getRuntimeJars(), otherArgs.getRuntimeJars())) {
      return false;
    }
    return true;
  }

  private static boolean nestedSetsOfArtifactHaveTheSameParent(
      NestedSet<Artifact> artifacts, NestedSet<Artifact> otherArtifacts) {
    Iterator<Artifact> iterator = artifacts.toList().iterator();
    Iterator<Artifact> otherIterator = otherArtifacts.toList().iterator();
    while (iterator.hasNext() && otherIterator.hasNext()) {
      Artifact artifact = iterator.next();
      Artifact otherArtifact = otherIterator.next();
      if (!artifact
          .getPath()
          .getParentDirectory()
          .equals(otherArtifact.getPath().getParentDirectory())) {
        return false;
      }
    }
    if (iterator.hasNext() || otherIterator.hasNext()) {
      return false;
    }
    return true;
  }

  @Test
  public void testCompileExports() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file(
        "java/test/BUILD",
        "load(':custom_rule.bzl', 'java_custom_library')",
        "java_custom_library(",
        "  name = 'custom',",
        "  srcs = ['Main.java'],",
        "  exports = [':dep']",
        ")",
        "java_library(",
        "  name = 'dep',",
        "  srcs = [ 'Dep.java'],",
        ")");
    scratch.file(
        "java/test/custom_rule.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('amazing.jar')",
        "  exports = [export[java_common.provider] for export in ctx.attr.exports]",
        "  compilation_provider = java_common.compile(",
        "    ctx,",
        "    source_files = ctx.files.srcs,",
        "    output = output_jar,",
        "    exports = exports,",
        "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
        "  )",
        "  return [",
        "      DefaultInfo(",
        "          files = depset([output_jar]),",
        "      ),",
        "      compilation_provider",
        "  ]",
        "java_custom_library = rule(",
        "  implementation = _impl,",
        "  outputs = {",
        "    'output': 'amazing.jar',",
        "  },",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files=['.java']),",
        "    'exports': attr.label_list(),",
        "    '_java_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),",
        "  },",
        "  toolchains = ['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java']",
        ")");

    JavaInfo info = getConfiguredTarget("//java/test:custom").get(JavaInfo.PROVIDER);
    assertThat(prettyArtifactNames(info.getTransitiveSourceJars().getSet(Artifact.class)))
        .containsExactly("java/test/amazing-src.jar", "java/test/libdep-src.jar");
    JavaCompilationArgsProvider provider = info.getProvider(JavaCompilationArgsProvider.class);
    assertThat(prettyArtifactNames(provider.getDirectCompileTimeJars()))
        .containsExactly("java/test/amazing-hjar.jar", "java/test/libdep-hjar.jar");
    assertThat(prettyArtifactNames(provider.getCompileTimeJavaDependencyArtifacts()))
        .containsExactly("java/test/amazing-hjar.jdeps", "java/test/libdep-hjar.jdeps");
  }

  @Test
  public void testCompileOutputJarHasManifestProto() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file(
        "foo/java_custom_library.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib%s.jar' % ctx.label.name)",
        "  compilation_provider = java_common.compile(",
        "    ctx,",
        "    source_files = ctx.files.srcs,",
        "    output = output_jar,",
        "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
        "  )",
        "  return [compilation_provider]",
        "java_custom_library = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files=['.java']),",
        "    '_java_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),",
        "  },",
        "  toolchains = ['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java'],",
        ")");
    scratch.file(
        "foo/BUILD",
        "load(':java_custom_library.bzl', 'java_custom_library')",
        "java_custom_library(name = 'b', srcs = ['java/B.java'])");

    ConfiguredTarget configuredTarget = getConfiguredTarget("//foo:b");
    JavaInfo info = configuredTarget.get(JavaInfo.PROVIDER);
    ImmutableList<JavaOutput> javaOutputs = info.getJavaOutputs();
    assertThat(javaOutputs).hasSize(1);
    JavaOutput output = javaOutputs.get(0);
    assertThat(output.getManifestProto().getFilename()).isEqualTo("libb.jar_manifest_proto");
  }

  @Test
  public void testCompileWithNeverlinkDeps() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file(
        "foo/java_custom_library.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib%s.jar' % ctx.label.name)",
        "  deps = [deps[JavaInfo] for deps in ctx.attr.deps]",
        "  compilation_provider = java_common.compile(",
        "    ctx,",
        "    source_files = ctx.files.srcs,",
        "    output = output_jar,",
        "    deps = deps,",
        "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
        "  )",
        "  return [compilation_provider]",
        "java_custom_library = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files=['.java']),",
        "    'deps': attr.label_list(),",
        "    '_java_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),",
        "  },",
        "  toolchains = ['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java'],",
        ")");
    scratch.file(
        "foo/BUILD",
        "load(':java_custom_library.bzl', 'java_custom_library')",
        "java_library(name = 'b', srcs = ['java/B.java'], neverlink = 1)",
        "java_custom_library(name = 'a', srcs = ['java/A.java'], deps = [':b'])");

    ConfiguredTarget configuredTarget = getConfiguredTarget("//foo:a");
    JavaInfo info = configuredTarget.get(JavaInfo.PROVIDER);
    assertThat(artifactFilesNames(info.getTransitiveRuntimeJars().toList(Artifact.class)))
        .containsExactly("liba.jar");
    assertThat(artifactFilesNames(info.getTransitiveSourceJars().getSet(Artifact.class)))
        .containsExactly("liba-src.jar", "libb-src.jar");
    assertThat(artifactFilesNames(info.getTransitiveCompileTimeJars().toList(Artifact.class)))
        .containsExactly("liba-hjar.jar", "libb-hjar.jar");
  }

  @Test
  public void testCompileOutputJarNotInRuntimePathWithoutAnySourcesDefined() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file(
        "foo/java_custom_library.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib%s.jar' % ctx.label.name)",
        "  exports = [export[JavaInfo] for export in ctx.attr.exports]",
        "  compilation_provider = java_common.compile(",
        "    ctx,",
        "    source_files = ctx.files.srcs,",
        "    output = output_jar,",
        "    exports = exports,",
        "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
        "  )",
        "  return [compilation_provider]",
        "java_custom_library = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files=['.java']),",
        "    'exports': attr.label_list(),",
        "    '_java_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),",
        "  },",
        "  toolchains = ['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java'],",
        ")");
    scratch.file(
        "foo/BUILD",
        "load(':java_custom_library.bzl', 'java_custom_library')",
        "java_library(name = 'b', srcs = ['java/B.java'])",
        "java_custom_library(name = 'c', srcs = [], exports = [':b'])");

    ConfiguredTarget configuredTarget = getConfiguredTarget("//foo:c");
    JavaInfo info = configuredTarget.get(JavaInfo.PROVIDER);
    assertThat(artifactFilesNames(info.getTransitiveRuntimeJars().toList(Artifact.class)))
        .containsExactly("libb.jar");
    assertThat(artifactFilesNames(info.getTransitiveCompileTimeJars().toList(Artifact.class)))
        .containsExactly("libb-hjar.jar");
    ImmutableList<JavaOutput> javaOutputs = info.getJavaOutputs();
    assertThat(javaOutputs).hasSize(1);
    JavaOutput output = javaOutputs.get(0);
    assertThat(output.getClassJar().getFilename()).isEqualTo("libc.jar");
    assertThat(output.getCompileJar()).isNull();
  }

  @Test
  public void testConfiguredTargetToolchain() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);

    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'jrule')",
        "java_runtime(name='jvm', srcs=[], java_home='/foo/bar')",
        "jrule(name='r', srcs=['S.java'])");

    scratch.file(
        "a/rule.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib' + ctx.label.name + '.jar')",
        "  java_common.compile(",
        "    ctx,",
        "    source_files = ctx.files.srcs,",
        "    output = output_jar,",
        "    java_toolchain = ctx.attr._java_toolchain[platform_common.ToolchainInfo],",
        "  )",
        "  return []",
        "jrule = rule(",
        "  implementation = _impl,",
        "  outputs = {",
        "    'my_output': 'lib%{name}.jar'",
        "  },",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files=['.java']),",
        "    '_java_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),",
        "  },",
        "  toolchains = ['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java'])");

    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//a:r");
    assertContainsEvent("got value of type 'ToolchainInfo', want 'JavaToolchainInfo'");
  }

  @Test
  public void defaultJavacOpts() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file(
        "a/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  return MyInfo(",
        "    javac_opts = java_common.default_javac_opts(",
        "        java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo])",
        "    )",
        "get_javac_opts = rule(",
        "  _impl,",
        "  attrs = {",
        "    '_java_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),",
        "  }",
        ");");

    scratch.file("a/BUILD", "load(':rule.bzl', 'get_javac_opts')", "get_javac_opts(name='r')");

    ConfiguredTarget r = getConfiguredTarget("//a:r");
    @SuppressWarnings("unchecked") // Use an extra variable in order to suppress the warning.
    Sequence<String> javacopts = (Sequence<String>) getMyInfoFromTarget(r).getValue("javac_opts");
    assertThat(String.join(" ", javacopts)).contains("-source 6 -target 6");
  }

  @Test
  public void defaultJavacOpts_asDepset() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file(
        "a/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  return MyInfo(",
        "    javac_opts = java_common.default_javac_opts_depset(",
        "        java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
        "    ))",
        "get_javac_opts = rule(",
        "  _impl,",
        "  attrs = {",
        "    '_java_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),",
        "  }",
        ");");

    scratch.file("a/BUILD", "load(':rule.bzl', 'get_javac_opts')", "get_javac_opts(name='r')");

    ConfiguredTarget r = getConfiguredTarget("//a:r");
    NestedSet<String> javacopts =
        Depset.cast(getMyInfoFromTarget(r).getValue("javac_opts"), String.class, "javac_opts");

    assertThat(String.join(" ", javacopts.toList())).contains("-source 6 -target 6");
  }

  @Test
  public void defaultJavacOpts_toolchainProvider() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file(
        "a/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  return MyInfo(",
        "    javac_opts = java_common.default_javac_opts(",
        "        java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo])",
        "    )",
        "get_javac_opts = rule(",
        "  _impl,",
        "  attrs = {",
        "    '_java_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),",
        "  }",
        ");");

    scratch.file("a/BUILD", "load(':rule.bzl', 'get_javac_opts')", "get_javac_opts(name='r')");

    ConfiguredTarget r = getConfiguredTarget("//a:r");
    @SuppressWarnings("unchecked") // Use an extra variable in order to suppress the warning.
    Sequence<String> javacopts = (Sequence<String>) getMyInfoFromTarget(r).getValue("javac_opts");
    assertThat(String.join(" ", javacopts)).contains("-source 6 -target 6");
  }

  @Test
  public void testJavaRuntimeProviderFiles() throws Exception {
    scratch.file("a/a.txt", "hello");
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'jrule')",
        "load('"
            + TestConstants.TOOLS_REPOSITORY
            + "//tools/jdk:java_toolchain_alias.bzl', 'java_runtime_alias')",
        "java_runtime(name='jvm', srcs=['a.txt'], java_home='foo/bar')",
        "java_runtime_alias(name='alias')",
        "jrule(name='r')",
        "toolchain(",
        "    name = 'java_runtime_toolchain',",
        "    toolchain = ':jvm',",
        "    toolchain_type = '"
            + TestConstants.TOOLS_REPOSITORY
            + "//tools/jdk:runtime_toolchain_type',",
        ")");

    scratch.file(
        "a/rule.bzl",
        "def _impl(ctx):",
        "  provider = ctx.attr._java_runtime[java_common.JavaRuntimeInfo]",
        "  return DefaultInfo(",
        "    files = provider.files,",
        "  )",
        "jrule = rule(_impl, attrs = { '_java_runtime': attr.label(default=Label('//a:alias'))})");

    useConfiguration("--extra_toolchains=//a:all");
    ConfiguredTarget ct = getConfiguredTarget("//a:r");
    Depset files = (Depset) ct.get("files");
    assertThat(prettyArtifactNames(files.toList(Artifact.class))).containsExactly("a/a.txt");
  }

  @Test
  public void testJavaLibraryCollectsCoverageDependenciesFromResources() throws Exception {
    useConfiguration("--collect_code_coverage");

    scratch.file(
        "java/BUILD",
        "java_library(",
        "    name = 'lib',",
        "    resources = [':libjni.so'],",
        ")",
        "",
        "cc_binary(",
        "    name = 'libjni.so',",
        "    srcs = ['jni.cc'],",
        "    linkshared = 1,",
        ")");

    InstrumentedFilesInfo target = getInstrumentedFilesProvider("//java:lib");

    assertThat(prettyArtifactNames(target.getInstrumentedFiles())).containsExactly("java/jni.cc");
    assertThat(prettyArtifactNames(target.getInstrumentationMetadataFiles()))
        .containsExactly("java/_objs/libjni.so/jni.gcno");
  }

  @Test
  public void testSkipAnnotationProcessing() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file(
        "foo/custom_rule.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib' + ctx.label.name + '.jar')",
        "  compilation_provider = java_common.compile(",
        "    ctx,",
        "    source_files = ctx.files.srcs,",
        "    output = output_jar,",
        "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
        "    deps = [p[JavaInfo] for p in ctx.attr.deps],",
        "    plugins = [p[JavaPluginInfo] for p in ctx.attr.plugins],",
        "    enable_annotation_processing = False,",
        "  )",
        "  return struct(",
        "    files = depset([output_jar]),",
        "    providers = [compilation_provider]",
        "  )",
        "java_custom_library = rule(",
        "  implementation = _impl,",
        "  outputs = {",
        "    'my_output': 'lib%{name}.jar'",
        "  },",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files=True),",
        "    'deps': attr.label_list(providers=[JavaInfo]),",
        "    'plugins': attr.label_list(providers=[JavaPluginInfo]),",
        "    '_java_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),",
        "  },",
        "  toolchains = ['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java']",
        ")");
    scratch.file(
        "foo/BUILD",
        "load(':custom_rule.bzl', 'java_custom_library')",
        "java_plugin(",
        "  name = 'processor',",
        "  srcs = ['processor.java'],",
        "  processor_class = 'Foo',",
        "  generates_api = 1,", // so Turbine would normally run it
        "  data = ['processor_data.txt'],",
        ")",
        "java_library(",
        "  name = 'exports_processor',",
        "  exported_plugins = [':processor'],",
        ")",
        "java_custom_library(",
        "  srcs = ['custom.java'],",
        "  name = 'custom',",
        "  deps = [':exports_processor'],",
        "  plugins = [':processor'],",
        ")",
        "java_custom_library(",
        "  srcs = ['custom.java'],",
        "  name = 'custom_noproc',",
        ")");

    ConfiguredTarget custom = getConfiguredTarget("//foo:custom");
    ConfiguredTarget customNoproc = getConfiguredTarget("//foo:custom_noproc");
    assertNoEvents();

    JavaCompileAction javacAction =
        (JavaCompileAction) getGeneratingActionForLabel("//foo:libcustom.jar");
    assertThat(javacAction.getMnemonic()).isEqualTo("Javac");
    assertThat(getProcessorNames(javacAction)).isEmpty();
    assertThat(getProcessorPath(javacAction)).isNotEmpty();
    assertThat(artifactFilesNames(javacAction.getInputs())).contains("processor_data.txt");

    JavaCompileAction turbineAction =
        (JavaCompileAction) getGeneratingAction(getBinArtifact("libcustom-hjar.jar", custom));
    assertThat(turbineAction.getMnemonic()).isEqualTo("JavacTurbine");
    ImmutableList<String> args = turbineAction.getArguments();
    assertThat(args).doesNotContain("--processors");

    // enable_annotation_processing=False shouldn't disable direct classpaths if there are no
    // annotation processors that need to be disabled
    SpawnAction turbineActionNoProc =
        (SpawnAction)
            getGeneratingAction(getBinArtifact("libcustom_noproc-hjar.jar", customNoproc));
    assertThat(turbineActionNoProc.getMnemonic()).isEqualTo("Turbine");
    assertThat(turbineActionNoProc.getArguments()).doesNotContain("--processors");
  }

  @Test
  public void testCompileWithDisablingCompileJarIsPrivateApi() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file(
        "foo/custom_rule.bzl",
        "def _impl(ctx):",
        "  java_common.compile(",
        "    ctx,",
        "    output = ctx.actions.declare_file('output.jar'),",
        "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
        "    enable_compile_jar_action = False,",
        "  )",
        "  return []",
        "java_custom_library = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    'srcs': attr.label_list(),",
        "    '_java_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),",
        "  },",
        "  toolchains = ['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java']",
        ")");
    scratch.file(
        "foo/BUILD",
        "load(':custom_rule.bzl', 'java_custom_library')",
        "java_custom_library(name = 'custom')");
    reporter.removeHandler(failFastHandler);

    getConfiguredTarget("//foo:custom");

    assertContainsEvent("got unexpected keyword argument: enable_compile_jar_action");
  }

  @Test
  public void testCompileWithClasspathResourcesIsPrivateApi() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file("foo/resource.txt", "Totally real resource content");
    scratch.file(
        "foo/custom_rule.bzl",
        "def _impl(ctx):",
        "  java_common.compile(",
        "    ctx,",
        "    output = ctx.actions.declare_file('output.jar'),",
        "    classpath_resources = ctx.files.classpath_resources,",
        "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
        "  )",
        "  return []",
        "java_custom_library = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    'srcs': attr.label_list(),",
        "    'classpath_resources': attr.label_list(allow_files = True),",
        "    '_java_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),",
        "  },",
        "  toolchains = ['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java']",
        ")");
    scratch.file(
        "foo/BUILD",
        "load(':custom_rule.bzl', 'java_custom_library')",
        "java_custom_library(name = 'custom', classpath_resources = ['resource.txt'])");
    reporter.removeHandler(failFastHandler);

    getConfiguredTarget("//foo:custom");

    assertContainsEvent("got unexpected keyword argument: classpath_resources");
  }

  @Test
  public void testInjectingRuleKindIsPrivateApi() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file(
        "foo/custom_rule.bzl",
        "def _impl(ctx):",
        "  java_common.compile(",
        "    ctx,",
        "    output = ctx.actions.declare_file('output.jar'),",
        "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
        "    injecting_rule_kind = 'example_rule_kind',",
        "  )",
        "  return []",
        "java_custom_library = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    'srcs': attr.label_list(),",
        "    '_java_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),",
        "  },",
        "  toolchains = ['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java']",
        ")");
    scratch.file(
        "foo/BUILD",
        "load(':custom_rule.bzl', 'java_custom_library')",
        "java_custom_library(name = 'custom')");
    reporter.removeHandler(failFastHandler);

    getConfiguredTarget("//foo:custom");

    assertContainsEvent("got unexpected keyword argument: injecting_rule_kind");
  }

  @Test
  public void testEnableJSpecifyIsPrivateApi() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file(
        "foo/custom_rule.bzl",
        "def _impl(ctx):",
        "  java_common.compile(",
        "    ctx,",
        "    output = ctx.actions.declare_file('output.jar'),",
        "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
        "    enable_jspecify = False,",
        "  )",
        "  return []",
        "java_custom_library = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    'srcs': attr.label_list(),",
        "    '_java_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),",
        "  },",
        "  toolchains = ['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java']",
        ")");
    scratch.file(
        "foo/BUILD",
        "load(':custom_rule.bzl', 'java_custom_library')",
        "java_custom_library(name = 'custom')");
    reporter.removeHandler(failFastHandler);

    getConfiguredTarget("//foo:custom");

    assertContainsEvent("got unexpected keyword argument: enable_jspecify");
  }

  @Test
  public void testMergeJavaOutputsIsPrivateApi() throws Exception {
    scratch.file(
        "foo/custom_rule.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib.jar')",
        "  java_info = JavaInfo(output_jar = output_jar, compile_jar = None)",
        "  java_common.merge([java_info],",
        "    merge_java_outputs = False",
        "  )",
        "  return []",
        "java_custom_library = rule(",
        "  implementation = _impl,",
        "  fragments = ['java']",
        ")");
    scratch.file(
        "foo/BUILD",
        "load(':custom_rule.bzl', 'java_custom_library')",
        "java_custom_library(name = 'custom')");
    reporter.removeHandler(failFastHandler);

    getConfiguredTarget("//foo:custom");

    assertContainsEvent("got unexpected keyword argument: merge_java_outputs");
  }

  @Test
  public void testMergeSourceJarsIsPrivateApi() throws Exception {
    scratch.file(
        "foo/custom_rule.bzl",
        "def _impl(ctx):",
        "  output_jar = ctx.actions.declare_file('lib.jar')",
        "  java_info = JavaInfo(output_jar = output_jar, compile_jar = None)",
        "  java_common.merge([java_info],",
        "    merge_source_jars = False",
        "  )",
        "  return []",
        "java_custom_library = rule(",
        "  implementation = _impl,",
        "  fragments = ['java']",
        ")");
    scratch.file(
        "foo/BUILD",
        "load(':custom_rule.bzl', 'java_custom_library')",
        "java_custom_library(name = 'custom')");
    reporter.removeHandler(failFastHandler);

    getConfiguredTarget("//foo:custom");

    assertContainsEvent("got unexpected keyword argument: merge_source_jars");
  }

  @Test
  public void testCompileIncludeCompilationInfoIsPrivateApi() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file(
        "foo/custom_rule.bzl",
        "def _impl(ctx):",
        "  java_common.compile(",
        "    ctx,",
        "    output = ctx.actions.declare_file('output.jar'),",
        "    java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo],",
        "    include_compilation_info = False,",
        "  )",
        "  return []",
        "java_custom_library = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    'srcs': attr.label_list(),",
        "    '_java_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),",
        "  },",
        "  toolchains = ['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java']",
        ")");
    scratch.file(
        "foo/BUILD",
        "load(':custom_rule.bzl', 'java_custom_library')",
        "java_custom_library(name = 'custom')");
    reporter.removeHandler(failFastHandler);

    getConfiguredTarget("//foo:custom");

    assertContainsEvent("got unexpected keyword argument: include_compilation_info");
  }

  @Test
  public void testCompileWithResourceJarsIsPrivateApi() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file(
        "foo/custom_rule.bzl",
        "def _impl(ctx):",
        "  java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo]",
        "  java_common.compile(",
        "    ctx,",
        "    output = ctx.actions.declare_file('output.jar'),",
        "    java_toolchain = java_toolchain,",
        "    resource_jars = ['foo.jar'],",
        "  )",
        "  return []",
        "java_custom_library = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    'srcs': attr.label_list(),",
        "    '_java_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),",
        "  },",
        "  toolchains = ['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java']",
        ")");
    scratch.file(
        "foo/BUILD",
        "load(':custom_rule.bzl', 'java_custom_library')",
        "java_custom_library(name = 'custom')");
    reporter.removeHandler(failFastHandler);

    getConfiguredTarget("//foo:custom");

    assertContainsEvent("got unexpected keyword argument: resource_jars");
  }

  @Test
  public void disallowJavaImportEmptyJars_fails() throws Exception {
    scratch.file(
        "foo/rule.bzl",
        "result = provider()",
        "def _impl(ctx):",
        "  ctx.fragments.java.disallow_java_import_empty_jars()",
        "  return []",
        "myrule = rule(",
        "  implementation=_impl,",
        "  fragments = ['java']",
        ")");
    scratch.file("foo/BUILD", "load(':rule.bzl', 'myrule')", "myrule(name='myrule')");
    reporter.removeHandler(failFastHandler);

    getConfiguredTarget("//foo:myrule");

    assertContainsEvent("file '//foo:rule.bzl' cannot use private API");
  }

  @Test
  public void testRunIjarWithOutputParameterIsPrivateApi() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file(
        "foo/custom_rule.bzl",
        "def _impl(ctx):",
        "  java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo]",
        "  java_common.run_ijar(",
        "    ctx.actions,",
        "    jar = ctx.actions.declare_file('input.jar'),",
        "    output = ctx.actions.declare_file('output.jar'),",
        "    java_toolchain = java_toolchain,",
        "  )",
        "  return []",
        "java_custom_library = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    '_java_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),",
        "  },",
        "  toolchains = ['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java']",
        ")");
    scratch.file(
        "foo/BUILD",
        "load(':custom_rule.bzl', 'java_custom_library')",
        "java_custom_library(name = 'custom')");
    reporter.removeHandler(failFastHandler);

    getConfiguredTarget("//foo:custom");

    assertContainsEvent("got unexpected keyword argument: output");
  }

  @Test
  public void testPackSourcesWithExternalResourceArtifact() throws Exception {
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file(
        "foo/custom_rule.bzl",
        "def _impl(ctx):",
        "  out = ctx.actions.declare_file('output.jar')",
        "  java_toolchain = ctx.attr._java_toolchain[java_common.JavaToolchainInfo]",
        "  java_common.pack_sources(",
        "    ctx.actions,",
        "    java_toolchain = java_toolchain,",
        "    output_source_jar = out,",
        "    sources = ctx.files.srcs,",
        "  )",
        "  return [DefaultInfo(files = depset([out]))]",
        "java_custom_library = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files = True),",
        "    '_java_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),",
        "  },",
        "  toolchains = ['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java']",
        ")");
    scratch.file("my_other_repo/WORKSPACE");
    scratch.file("my_other_repo/external-file.txt");
    scratch.file("my_other_repo/BUILD", "exports_files(['external-file.txt'])");
    rewriteWorkspace("local_repository(name = 'other_repo', path = './my_other_repo')");
    scratch.file(
        "foo/BUILD",
        "load(':custom_rule.bzl', 'java_custom_library')",
        "java_custom_library(",
        "  name = 'custom',",
        "  srcs = [",
        "    'internal-file.txt',",
        "    '@other_repo//:external-file.txt',",
        "  ]",
        ")");

    List<String> arguments =
        ((SpawnAction) getGeneratingAction(getConfiguredTarget("//foo:custom"), "foo/output.jar"))
            .getArguments();

    assertThat(arguments)
        .containsAtLeast(
            "--resources",
            "foo/internal-file.txt:foo/internal-file.txt",
            "external/other_repo/external-file.txt:external-file.txt")
        .inOrder();
  }

  @Test
  public void mergeAddExports() throws Exception {
    scratch.file(
        "foo/custom_library.bzl",
        "def _impl(ctx):",
        "  java_provider = java_common.merge([dep[JavaInfo] for dep in ctx.attr.deps])",
        "  return [java_provider]",
        "custom_library = rule(",
        "  attrs = {",
        "    'deps': attr.label_list(),",
        "  },",
        "  implementation = _impl",
        ")");
    scratch.file(
        "foo/BUILD",
        "load(':custom_library.bzl', 'custom_library')",
        "custom_library(name = 'custom', deps = [':a'])",
        "java_library(name = 'a', srcs = ['java/A.java'], add_exports = ['java.base/java.lang'])");

    ConfiguredTarget myRuleTarget = getConfiguredTarget("//foo:custom");
    JavaModuleFlagsProvider provider =
        JavaInfo.getProvider(JavaModuleFlagsProvider.class, myRuleTarget);
    assertThat(provider.toFlags()).containsExactly("--add-exports=java.base/java.lang=ALL-UNNAMED");
  }

  private InstrumentedFilesInfo getInstrumentedFilesProvider(String label) throws Exception {
    return getConfiguredTarget(label).get(InstrumentedFilesInfo.STARLARK_CONSTRUCTOR);
  }

  @Test
  public void hermeticStaticLibs() throws Exception {
    scratch.file("a/libStatic.a");
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'jrule')",
        "load('"
            + TestConstants.TOOLS_REPOSITORY
            + "//tools/jdk:java_toolchain_alias.bzl', 'java_runtime_alias')",
        "genrule(name='gen', cmd='', outs=['foo/bar/bin/java'])",
        "cc_import(name='libs', static_library = 'libStatic.a')",
        "cc_library(name = 'jdk_static_libs00', data = ['libStatic.a'], linkstatic = 1)",
        "java_runtime(name='jvm', srcs=[], java='foo/bar/bin/java', lib_modules='lib/modules', "
            + "hermetic_srcs = ['lib/hermetic.properties'], hermetic_static_libs = ['libs'])",
        "java_runtime_alias(name='alias')",
        "jrule(name='r')",
        "toolchain(",
        "    name = 'java_runtime_toolchain',",
        "    toolchain = ':jvm',",
        "    toolchain_type = '"
            + TestConstants.TOOLS_REPOSITORY
            + "//tools/jdk:runtime_toolchain_type',",
        ")");
    scratch.file(
        "a/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  provider = ctx.attr._java_runtime[java_common.JavaRuntimeInfo]",
        "  return MyInfo(",
        "    hermetic_static_libs = provider.hermetic_static_libs,",
        "  )",
        "jrule = rule(_impl, attrs = { '_java_runtime': attr.label(default=Label('//a:alias'))})");

    useConfiguration("--extra_toolchains=//a:all");
    ConfiguredTarget ct = getConfiguredTarget("//a:r");
    StructImpl myInfo = getMyInfoFromTarget(ct);
    @SuppressWarnings("unchecked")
    Sequence<CcInfo> hermeticStaticLibs =
        (Sequence<CcInfo>) myInfo.getValue("hermetic_static_libs");
    assertThat(hermeticStaticLibs).hasSize(1);
    assertThat(
            hermeticStaticLibs.get(0).getCcLinkingContext().getLibraries().toList().stream()
                .map(LibraryToLink::getLibraryIdentifier))
        .containsExactly("a/libStatic");
  }

  @Test
  public void implicitLibCtSym() throws Exception {
    scratch.file("a/libStatic.a");
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'jrule')",
        "load('"
            + TestConstants.TOOLS_REPOSITORY
            + "//tools/jdk:java_toolchain_alias.bzl', 'java_runtime_alias')",
        "java_runtime(",
        "    name='jvm',",
        "    srcs=[",
        "        'foo/bar/bin/java',",
        "        'foo/bar/lib/ct.sym',",
        "    ],",
        "    java='foo/bar/bin/java',",
        ")",
        "java_runtime_alias(name='alias')",
        "jrule(name='r')",
        "toolchain(",
        "    name = 'java_runtime_toolchain',",
        "    toolchain = ':jvm',",
        "    toolchain_type = '"
            + TestConstants.TOOLS_REPOSITORY
            + "//tools/jdk:runtime_toolchain_type',",
        ")");
    scratch.file(
        "a/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  provider = ctx.attr._java_runtime[java_common.JavaRuntimeInfo]",
        "  return MyInfo(",
        "    lib_ct_sym = provider.lib_ct_sym,",
        "  )",
        "jrule = rule(_impl, attrs = { '_java_runtime': attr.label(default=Label('//a:alias'))})");

    useConfiguration("--extra_toolchains=//a:all");
    ConfiguredTarget ct = getConfiguredTarget("//a:r");
    StructImpl myInfo = getMyInfoFromTarget(ct);
    @SuppressWarnings("unchecked")
    Artifact libCtSym = (Artifact) myInfo.getValue("lib_ct_sym");
    assertThat(libCtSym).isNotNull();
    assertThat(libCtSym.getExecPathString()).isEqualTo("a/foo/bar/lib/ct.sym");
  }

  @Test
  public void explicitLibCtSym() throws Exception {
    scratch.file("a/libStatic.a");
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'jrule')",
        "load('"
            + TestConstants.TOOLS_REPOSITORY
            + "//tools/jdk:java_toolchain_alias.bzl', 'java_runtime_alias')",
        "java_runtime(",
        "    name='jvm',",
        "    srcs=[",
        "        'foo/bar/bin/java',",
        "        'foo/bar/lib/ct.sym',",
        "    ],",
        "    java='foo/bar/bin/java',",
        "    lib_ct_sym='lib/ct.sym',",
        ")",
        "java_runtime_alias(name='alias')",
        "jrule(name='r')",
        "toolchain(",
        "    name = 'java_runtime_toolchain',",
        "    toolchain = ':jvm',",
        "    toolchain_type = '"
            + TestConstants.TOOLS_REPOSITORY
            + "//tools/jdk:runtime_toolchain_type',",
        ")");
    scratch.file(
        "a/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  provider = ctx.attr._java_runtime[java_common.JavaRuntimeInfo]",
        "  return MyInfo(",
        "    lib_ct_sym = provider.lib_ct_sym,",
        "  )",
        "jrule = rule(_impl, attrs = { '_java_runtime': attr.label(default=Label('//a:alias'))})");

    useConfiguration("--extra_toolchains=//a:all");
    ConfiguredTarget ct = getConfiguredTarget("//a:r");
    StructImpl myInfo = getMyInfoFromTarget(ct);
    @SuppressWarnings("unchecked")
    Artifact libCtSym = (Artifact) myInfo.getValue("lib_ct_sym");
    assertThat(libCtSym).isNotNull();
    assertThat(libCtSym.getExecPathString()).isEqualTo("a/lib/ct.sym");
  }

  @Test
  @TestParameters({
    "{module: java_config, api: use_ijars}",
    "{module: java_config, api: disallow_java_import_exports}",
    "{module: java_config, api: enforce_explicit_java_test_deps}",
    "{module: java_config, api: use_header_compilation}",
    "{module: java_config, api: generate_java_deps}",
    "{module: java_config, api: reduce_java_classpath}",
  })
  public void testNoArgsPrivateAPIsAreIndeedPrivate(String module, String api) throws Exception {
    setBuildLanguageOptions("--experimental_builtins_injection_override=+java_import");
    JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
    scratch.file(
        "foo/custom_rule.bzl",
        "def _impl(ctx):",
        "  java_config = ctx.fragments.java",
        "  java_toolchain = ctx.toolchains['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'].java",
        "  " + module + "." + api + "()",
        "  return []",
        "java_custom_library = rule(",
        "  implementation = _impl,",
        "  toolchains = ['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
        "  fragments = ['java']",
        ")");
    scratch.file(
        "foo/BUILD",
        "load(':custom_rule.bzl', 'java_custom_library')",
        "java_custom_library(name = 'custom')");
    reporter.removeHandler(failFastHandler);

    getConfiguredTarget("//foo:custom");

    assertContainsEvent(
        "Error in " + api + ": file '//foo:custom_rule.bzl' cannot use private API");
  }

  @Test
  @TestParameters({
    "{api: create_header_compilation_action}",
    "{api: create_compilation_action}",
    "{api: target_kind}",
    "{api: get_build_info}",
    "{api: collect_native_deps_dirs}",
    "{api: get_runtime_classpath_for_archive}",
    "{api: check_provider_instances}",
    "{api: _google_legacy_api_enabled}",
    "{api: _check_java_toolchain_is_declared_on_rule}",
    "{api: _incompatible_depset_for_java_output_source_jars}",
    "{api: wrap_java_info}",
    "{api: intern_javac_opts}",
  })
  public void testJavaCommonPrivateApis_areNotVisibleToPublicStarlark(String api) throws Exception {
    // validate that this api is present on the module, so this test fails when the API is deleted
    var unused =
        stream(JavaCommonApi.class.getDeclaredMethods())
            .filter(method -> method.isAnnotationPresent(StarlarkMethod.class))
            .filter(method -> method.getAnnotation(StarlarkMethod.class).name().equals(api))
            .findAny()
            .orElseThrow(
                () -> new IllegalArgumentException("API not declared on java_common: " + api));
    scratch.file(
        "foo/custom_rule.bzl",
        "def _impl(ctx):",
        "  java_common." + api + "()",
        "  return []",
        "custom_rule = rule(implementation = _impl)");
    scratch.file(
        "foo/BUILD",
        //
        "load(':custom_rule.bzl', 'custom_rule')",
        "custom_rule(name = 'custom')");
    reporter.removeHandler(failFastHandler);

    getConfiguredTarget("//foo:custom");

    assertContainsEvent("no field or method '" + api + "'");
  }

  @Test
  public void testProviderValidationPrintsProviderName() throws Exception {
    scratch.file(
        "foo/rule.bzl",
        "def _impl(ctx):",
        "  cc_info = ctx.attr.dep[CcInfo]",
        "  JavaInfo(output_jar = None, compile_jar = None, deps = [cc_info])",
        "  return []",
        "myrule = rule(",
        "  implementation=_impl,",
        "  attrs = {'dep' : attr.label()},",
        "  fragments = []",
        ")");
    scratch.file(
        "foo/BUILD",
        "load(':rule.bzl', 'myrule')",
        "cc_library(name = 'cc_lib')",
        "myrule(name='myrule',",
        "    dep = ':cc_lib',",
        ")");
    reporter.removeHandler(failFastHandler);

    getConfiguredTarget("//foo:myrule");

    assertContainsEvent("got element of type CcInfo, want JavaInfo");
  }

  @Test
  public void testNativeJavaInfoPrintableType_isJavaInfo() {
    String type = JavaStarlarkCommon.printableType(JavaInfo.EMPTY);

    assertThat(type).isEqualTo("JavaInfo");
  }

  private String getJvmFlags(Artifact executable)
      throws CommandLineExpansionException, InterruptedException, EvalException {
    if (OS.getCurrent() == OS.WINDOWS) {
      return getGeneratingSpawnActionArgs(executable).stream()
          .filter(a -> a.startsWith("jvm_flags="))
          .flatMap(a -> stream(a.substring("jvm_flags=".length()).split("\t")))
          .collect(joining(" "));
    } else {
      return ((TemplateExpansionAction) getGeneratingAction(executable))
          .getSubstitutions().stream()
              .filter(s -> Objects.equals(s.getKey(), "%jvm_flags%"))
              .collect(onlyElement())
              .getValue();
    }
  }
}
