// Copyright 2018 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.ImmutableList.toImmutableList;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static com.google.devtools.build.lib.actions.util.ActionsTestUtil.prettyArtifactNames;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.ArtifactRoot;
import com.google.devtools.build.lib.actions.ArtifactRoot.RootType;
import com.google.devtools.build.lib.actions.util.ActionsTestUtil;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
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.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.packages.Info;
import com.google.devtools.build.lib.packages.StarlarkInfo;
import com.google.devtools.build.lib.packages.StarlarkProvider;
import com.google.devtools.build.lib.packages.StructImpl;
import com.google.devtools.build.lib.packages.StructProvider;
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.testutil.TestConstants;
import com.google.devtools.build.lib.vfs.Path;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.io.IOException;
import java.util.Map;
import net.starlark.java.eval.Starlark;
import net.starlark.java.eval.StarlarkList;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests JavaInfo API for Starlark. */
@RunWith(JUnit4.class)
public class JavaInfoStarlarkApiTest extends BuildViewTestCase {

  @Test
  public void buildHelperCreateJavaInfoWithOutputJarOnly() throws Exception {
    ruleBuilder().build();
    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "my_rule(",
        "  name = 'my_starlark_rule',",
        "  output_jar = 'my_starlark_rule_lib.jar',",
        "  source_jars = ['my_starlark_rule_src.jar']",
        ")");
    assertNoEvents();

    JavaCompilationArgsProvider javaCompilationArgsProvider =
        fetchJavaInfo().getProvider(JavaCompilationArgsProvider.class);

    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectCompileTimeJars()))
        .containsExactly("foo/my_starlark_rule_lib.jar");
    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectFullCompileTimeJars()))
        .containsExactly("foo/my_starlark_rule_lib.jar");
    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getRuntimeJars()))
        .containsExactly("foo/my_starlark_rule_lib.jar");
    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getTransitiveCompileTimeJars()))
        .containsExactly("foo/my_starlark_rule_lib.jar");
  }

  @Test
  public void buildHelperCreateJavaInfoWithOutputJarAndUseIJar() throws Exception {

    ruleBuilder().withIJar().build();

    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "my_rule(",
        "  name = 'my_starlark_rule',",
        "  output_jar = 'my_starlark_rule_lib.jar',",
        "  source_jars = ['my_starlark_rule_src.jar']",
        ")");
    assertNoEvents();

    JavaCompilationArgsProvider javaCompilationArgsProvider =
        fetchJavaInfo().getProvider(JavaCompilationArgsProvider.class);

    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectCompileTimeJars()))
        .containsExactly("foo/my_starlark_rule_lib-ijar.jar");
    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectFullCompileTimeJars()))
        .containsExactly("foo/my_starlark_rule_lib.jar");

    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getRuntimeJars()))
        .containsExactly("foo/my_starlark_rule_lib.jar");
    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getTransitiveCompileTimeJars()))
        .containsExactly("foo/my_starlark_rule_lib-ijar.jar");
  }

  @Test
  public void buildHelperCreateJavaInfoJavaRuleOutputJarsProviderSourceJarOutputJarAndUseIJar()
      throws Exception {
    ruleBuilder().withIJar().build();

    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "my_rule(",
        "  name = 'my_starlark_rule',",
        "  output_jar = 'my_starlark_rule_lib.jar',",
        "  source_jars = ['my_starlark_rule_src.jar'],",
        ")");
    assertNoEvents();

    JavaRuleOutputJarsProvider javaRuleOutputJarsProvider =
        fetchJavaInfo().getProvider(JavaRuleOutputJarsProvider.class);

    assertThat(prettyArtifactNames(javaRuleOutputJarsProvider.getAllSrcOutputJars()))
        .containsExactly("foo/my_starlark_rule_src.jar");

    assertThat(prettyArtifactNames(javaRuleOutputJarsProvider.getAllClassOutputJars()))
        .containsExactly("foo/my_starlark_rule_lib.jar");

    assertThat(javaRuleOutputJarsProvider.getJavaOutputs()).hasSize(1);
    JavaOutput javaOutput = javaRuleOutputJarsProvider.getJavaOutputs().get(0);

    assertThat(javaOutput.getCompileJar().prettyPrint())
        .isEqualTo("foo/my_starlark_rule_lib-ijar.jar");
  }

  @Test
  public void buildHelperCreateJavaInfoWithDeps() throws Exception {
    ruleBuilder().build();
    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "java_library(name = 'my_java_lib_direct', srcs = ['java/A.java'])",
        "my_rule(name = 'my_starlark_rule',",
        "        output_jar = 'my_starlark_rule_lib.jar',",
        "        source_jars = ['my_starlark_rule_src.jar'],",
        "        dep = [':my_java_lib_direct']",
        ")");
    assertNoEvents();

    JavaCompilationArgsProvider javaCompilationArgsProvider =
        fetchJavaInfo().getProvider(JavaCompilationArgsProvider.class);

    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectCompileTimeJars()))
        .containsExactly("foo/my_starlark_rule_lib.jar");
    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectFullCompileTimeJars()))
        .containsExactly("foo/my_starlark_rule_lib.jar");
    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getRuntimeJars()))
        .containsExactly("foo/my_starlark_rule_lib.jar", "foo/libmy_java_lib_direct.jar");
    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getTransitiveCompileTimeJars()))
        .containsExactly("foo/my_starlark_rule_lib.jar", "foo/libmy_java_lib_direct-hjar.jar");
  }

  @Test
  public void buildHelperCreateJavaInfoWithRunTimeDeps() throws Exception {
    ruleBuilder().build();
    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "java_library(name = 'my_java_lib_direct', srcs = ['java/A.java'])",
        "my_rule(name = 'my_starlark_rule',",
        "        output_jar = 'my_starlark_rule_lib.jar',",
        "        source_jars = ['my_starlark_rule_src.jar'],",
        "        dep_runtime = [':my_java_lib_direct']",
        ")");
    assertNoEvents();

    JavaCompilationArgsProvider javaCompilationArgsProvider =
        fetchJavaInfo().getProvider(JavaCompilationArgsProvider.class);

    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectCompileTimeJars()))
        .containsExactly("foo/my_starlark_rule_lib.jar");
    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectFullCompileTimeJars()))
        .containsExactly("foo/my_starlark_rule_lib.jar");
    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getRuntimeJars()))
        .containsExactly("foo/my_starlark_rule_lib.jar", "foo/libmy_java_lib_direct.jar");
    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getTransitiveCompileTimeJars()))
        .containsExactly("foo/my_starlark_rule_lib.jar");
  }

  /** Tests that JavaInfo can be constructed with CC native libraries as dependencies. */
  @Test
  public void javaInfo_setNativeLibraries() throws Exception {
    ruleBuilder().build();
    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "cc_library(name = 'my_cc_lib_direct', srcs = ['cc/a.cc'])",
        "my_rule(name = 'my_starlark_rule',",
        "        output_jar = 'my_starlark_rule_lib.jar',",
        "        source_jars = ['my_starlark_rule_src.jar'],",
        "        cc_dep = [':my_cc_lib_direct']",
        ")");
    assertNoEvents();

    JavaInfo javaInfoProvider = fetchJavaInfo();

    NestedSet<LibraryToLink> librariesForTopTarget =
        javaInfoProvider.getTransitiveNativeLibraries();
    assertThat(librariesForTopTarget.toList().stream().map(LibraryToLink::getLibraryIdentifier))
        .contains("foo/libmy_cc_lib_direct");
  }

  @Test
  public void buildHelperCreateJavaInfoWithDepsAndNeverLink() throws Exception {
    ruleBuilder().withNeverLink().build();

    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "java_library(name = 'my_java_lib_direct', srcs = ['java/A.java'])",
        "my_rule(name = 'my_starlark_rule',",
        "        output_jar = 'my_starlark_rule_lib.jar',",
        "        source_jars = ['my_starlark_rule_src.jar'],",
        "        dep = [':my_java_lib_direct']",
        ")");
    assertNoEvents();

    JavaCompilationArgsProvider javaCompilationArgsProvider =
        fetchJavaInfo().getProvider(JavaCompilationArgsProvider.class);

    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectCompileTimeJars()))
        .containsExactly("foo/my_starlark_rule_lib.jar");
    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectFullCompileTimeJars()))
        .containsExactly("foo/my_starlark_rule_lib.jar");
    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getRuntimeJars())).isEmpty();
    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getTransitiveCompileTimeJars()))
        .containsExactly("foo/my_starlark_rule_lib.jar", "foo/libmy_java_lib_direct-hjar.jar");
  }

  @Test
  public void buildHelperCreateJavaInfoSourceJarsProviderWithSourceJars() throws Exception {
    ruleBuilder().build();
    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "my_rule(name = 'my_starlark_rule',",
        "        output_jar = 'my_starlark_rule_lib.jar',",
        "        source_jars = ['my_starlark_rule_src.jar']",
        ")");
    assertNoEvents();

    JavaSourceJarsProvider sourceJarsProvider =
        fetchJavaInfo().getProvider(JavaSourceJarsProvider.class);

    assertThat(prettyArtifactNames(sourceJarsProvider.getSourceJars()))
        .containsExactly("foo/my_starlark_rule_src.jar");

    assertThat(prettyArtifactNames(sourceJarsProvider.getTransitiveSourceJars()))
        .containsExactly("foo/my_starlark_rule_src.jar");
  }

  @Test
  public void buildHelperPackSources_repackSingleJar() throws Exception {
    ruleBuilder().withSourceFiles().build();
    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "my_rule(name = 'my_starlark_rule',",
        "        output_jar = 'my_starlark_rule_lib.jar',",
        "        source_jars = ['my_starlark_rule_src.jar']",
        ")");
    assertNoEvents();

    JavaSourceJarsProvider sourceJarsProvider =
        fetchJavaInfo().getProvider(JavaSourceJarsProvider.class);

    assertThat(prettyArtifactNames(sourceJarsProvider.getSourceJars()))
        .containsExactly("foo/my_starlark_rule_lib-src.jar");

    assertThat(prettyArtifactNames(sourceJarsProvider.getTransitiveSourceJars()))
        .containsExactly("foo/my_starlark_rule_lib-src.jar");
  }

  @Test
  public void buildHelperCreateJavaInfoWithSourcesFiles() throws Exception {
    ruleBuilder().withSourceFiles().build();

    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "my_rule(",
        "  name = 'my_starlark_rule',",
        "  output_jar = 'my_starlark_rule_lib.jar',",
        "  sources = ['ClassA.java', 'ClassB.java', 'ClassC.java', 'ClassD.java'],",
        ")");
    assertNoEvents();

    JavaRuleOutputJarsProvider javaRuleOutputJarsProvider =
        fetchJavaInfo().getProvider(JavaRuleOutputJarsProvider.class);

    assertThat(prettyArtifactNames(javaRuleOutputJarsProvider.getAllSrcOutputJars()))
        .containsExactly("foo/my_starlark_rule_lib-src.jar");

    JavaSourceJarsProvider sourceJarsProvider =
        fetchJavaInfo().getProvider(JavaSourceJarsProvider.class);

    assertThat(prettyArtifactNames(sourceJarsProvider.getSourceJars()))
        .containsExactly("foo/my_starlark_rule_lib-src.jar");

    assertThat(prettyArtifactNames(sourceJarsProvider.getTransitiveSourceJars()))
        .containsExactly("foo/my_starlark_rule_lib-src.jar");
  }

  @Test
  public void buildHelperCreateJavaInfoWithSourcesFilesAndSourcesJars() throws Exception {
    ruleBuilder().withSourceFiles().build();

    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "my_rule(",
        "  name = 'my_starlark_rule',",
        "  output_jar = 'my_starlark_rule_lib.jar',",
        "  sources = ['ClassA.java', 'ClassB.java', 'ClassC.java', 'ClassD.java'],",
        "  source_jars = ['my_starlark_rule_src-A.jar']",
        ")");
    assertNoEvents();

    JavaRuleOutputJarsProvider javaRuleOutputJarsProvider =
        fetchJavaInfo().getProvider(JavaRuleOutputJarsProvider.class);

    assertThat(prettyArtifactNames(javaRuleOutputJarsProvider.getAllSrcOutputJars()))
        .containsExactly("foo/my_starlark_rule_lib-src.jar");

    JavaSourceJarsProvider sourceJarsProvider =
        fetchJavaInfo().getProvider(JavaSourceJarsProvider.class);

    assertThat(prettyArtifactNames(sourceJarsProvider.getSourceJars()))
        .containsExactly("foo/my_starlark_rule_lib-src.jar");

    assertThat(prettyArtifactNames(sourceJarsProvider.getTransitiveSourceJars()))
        .containsExactly("foo/my_starlark_rule_lib-src.jar");
  }

  @Test
  public void buildHelperCreateJavaInfoSourceJarsProviderWithDeps() throws Exception {
    ruleBuilder().build();
    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "java_library(name = 'my_java_lib_direct', srcs = ['java/A.java'])",
        "my_rule(name = 'my_starlark_rule',",
        "        output_jar = 'my_starlark_rule_lib.jar',",
        "        source_jars = ['my_starlark_rule_src.jar'],",
        "        dep = [':my_java_lib_direct']",
        ")");
    assertNoEvents();

    JavaSourceJarsProvider sourceJarsProvider =
        fetchJavaInfo().getProvider(JavaSourceJarsProvider.class);

    assertThat(prettyArtifactNames(sourceJarsProvider.getSourceJars()))
        .containsExactly("foo/my_starlark_rule_src.jar");

    assertThat(prettyArtifactNames(sourceJarsProvider.getTransitiveSourceJars()))
        .containsExactly("foo/my_starlark_rule_src.jar", "foo/libmy_java_lib_direct-src.jar");
  }

  @Test
  public void buildHelperCreateJavaInfoJavaSourceJarsProviderAndRuntimeDeps() throws Exception {
    ruleBuilder().build();
    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "java_library(name = 'my_java_lib_direct', srcs = ['java/A.java'])",
        "my_rule(name = 'my_starlark_rule',",
        "        output_jar = 'my_starlark_rule_lib.jar',",
        "        source_jars = ['my_starlark_rule_src.jar'],",
        "        dep_runtime = [':my_java_lib_direct']",
        ")");
    assertNoEvents();

    JavaSourceJarsProvider sourceJarsProvider =
        fetchJavaInfo().getProvider(JavaSourceJarsProvider.class);

    assertThat(prettyArtifactNames(sourceJarsProvider.getSourceJars()))
        .containsExactly("foo/my_starlark_rule_src.jar");

    assertThat(prettyArtifactNames(sourceJarsProvider.getTransitiveSourceJars()))
        .containsExactly("foo/my_starlark_rule_src.jar", "foo/libmy_java_lib_direct-src.jar");
  }

  @Test
  public void buildHelperCreateJavaInfoJavaSourceJarsProviderAndTransitiveDeps() throws Exception {
    ruleBuilder().build();
    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "java_library(name = 'my_java_lib_transitive', srcs = ['java/B.java'])",
        "java_library(name = 'my_java_lib_direct',",
        "             srcs = ['java/A.java'],",
        "             deps = [':my_java_lib_transitive'])",
        "my_rule(name = 'my_starlark_rule',",
        "        output_jar = 'my_starlark_rule_lib.jar',",
        "        source_jars = ['my_starlark_rule_src.jar'],",
        "        dep = [':my_java_lib_direct']",
        ")");
    assertNoEvents();

    JavaSourceJarsProvider sourceJarsProvider =
        fetchJavaInfo().getProvider(JavaSourceJarsProvider.class);

    assertThat(prettyArtifactNames(sourceJarsProvider.getSourceJars()))
        .containsExactly("foo/my_starlark_rule_src.jar");

    assertThat(prettyArtifactNames(sourceJarsProvider.getTransitiveSourceJars()))
        .containsExactly(
            "foo/my_starlark_rule_src.jar",
            "foo/libmy_java_lib_direct-src.jar",
            "foo/libmy_java_lib_transitive-src.jar");
  }

  @Test
  public void buildHelperCreateJavaInfoJavaSourceJarsProviderAndTransitiveRuntimeDeps()
      throws Exception {
    ruleBuilder().build();
    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "java_library(name = 'my_java_lib_transitive', srcs = ['java/B.java'])",
        "java_library(name = 'my_java_lib_direct',",
        "             srcs = ['java/A.java'],",
        "             deps = [':my_java_lib_transitive'])",
        "my_rule(name = 'my_starlark_rule',",
        "        output_jar = 'my_starlark_rule_lib.jar',",
        "        source_jars = ['my_starlark_rule_src.jar'],",
        "        dep = [':my_java_lib_direct']",
        ")");
    assertNoEvents();

    JavaSourceJarsProvider sourceJarsProvider =
        fetchJavaInfo().getProvider(JavaSourceJarsProvider.class);

    assertThat(prettyArtifactNames(sourceJarsProvider.getSourceJars()))
        .containsExactly("foo/my_starlark_rule_src.jar");

    assertThat(prettyArtifactNames(sourceJarsProvider.getTransitiveSourceJars()))
        .containsExactly(
            "foo/my_starlark_rule_src.jar",
            "foo/libmy_java_lib_direct-src.jar",
            "foo/libmy_java_lib_transitive-src.jar");
  }

  /** Test exports adds dependencies to JavaCompilationArgsProvider. */
  @Test
  public void buildHelperCreateJavaInfoExportProviderExportsDepsAdded() throws Exception {
    ruleBuilder().build();
    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "java_library(name = 'my_java_lib_exports', srcs = ['java/A.java'])",
        "my_rule(name = 'my_starlark_rule',",
        "        output_jar = 'my_starlark_rule_lib.jar',",
        "        dep_exports = [':my_java_lib_exports']",
        ")");
    assertNoEvents();

    JavaInfo javaInfo = fetchJavaInfo();

    JavaSourceJarsProvider javaSourceJarsProvider =
        javaInfo.getProvider(JavaSourceJarsProvider.class);

    assertThat(javaSourceJarsProvider.getSourceJars()).isEmpty();

    JavaCompilationArgsProvider javaCompilationArgsProvider =
        javaInfo.getProvider(JavaCompilationArgsProvider.class);

    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectCompileTimeJars()))
        .containsExactly("foo/my_starlark_rule_lib.jar", "foo/libmy_java_lib_exports-hjar.jar");
    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectFullCompileTimeJars()))
        .containsExactly("foo/my_starlark_rule_lib.jar", "foo/libmy_java_lib_exports.jar");
    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getRuntimeJars()))
        .containsExactly("foo/my_starlark_rule_lib.jar", "foo/libmy_java_lib_exports.jar");
    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getTransitiveCompileTimeJars()))
        .containsExactly("foo/my_starlark_rule_lib.jar", "foo/libmy_java_lib_exports-hjar.jar");
  }

  /** Test exports adds itself and recursive dependencies to JavaCompilationArgsProvider. */
  @Test
  public void buildHelperCreateJavaInfoExportProvider() throws Exception {
    ruleBuilder().build();
    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'])",
        "java_library(name = 'my_java_lib_a', srcs = ['java/A.java'],",
        "             deps = [':my_java_lib_b', ':my_java_lib_c'],",
        "             exports = [':my_java_lib_b']",
        "            )",
        "my_rule(name = 'my_starlark_rule',",
        "        output_jar = 'my_starlark_rule_lib.jar',",
        "        dep_exports = [':my_java_lib_a']",
        ")");
    assertNoEvents();

    JavaInfo javaInfo = fetchJavaInfo();

    JavaCompilationArgsProvider javaCompilationArgsProvider =
        javaInfo.getProvider(JavaCompilationArgsProvider.class);

    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectCompileTimeJars()))
        .containsExactly(
            "foo/my_starlark_rule_lib.jar",
            "foo/libmy_java_lib_a-hjar.jar",
            "foo/libmy_java_lib_b-hjar.jar");

    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectFullCompileTimeJars()))
        .containsExactly(
            "foo/my_starlark_rule_lib.jar", "foo/libmy_java_lib_a.jar", "foo/libmy_java_lib_b.jar");

    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getRuntimeJars()))
        .containsExactly(
            "foo/my_starlark_rule_lib.jar",
            "foo/libmy_java_lib_a.jar",
            "foo/libmy_java_lib_b.jar",
            "foo/libmy_java_lib_c.jar");

    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getTransitiveCompileTimeJars()))
        .containsExactly(
            "foo/my_starlark_rule_lib.jar",
            "foo/libmy_java_lib_a-hjar.jar",
            "foo/libmy_java_lib_b-hjar.jar",
            "foo/libmy_java_lib_c-hjar.jar");
  }

  /**
   * Tests case: my_lib // \ a c // \\ b d
   *
   * <p>where single line is normal dependency and double is exports dependency.
   */
  @Test
  public void buildHelperCreateJavaInfoExportProvider001() throws Exception {
    ruleBuilder().build();
    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'],",
        "             exports = [':my_java_lib_b']",
        "            )",
        "java_library(name = 'my_java_lib_d', srcs = ['java/D.java'])",
        "java_library(name = 'my_java_lib_c', srcs = ['java/C.java'],",
        "             deps = [':my_java_lib_d'],",
        "             exports = [':my_java_lib_d']",
        "            )",
        "my_rule(name = 'my_starlark_rule',",
        "        output_jar = 'my_starlark_rule_lib.jar',",
        "        dep = [':my_java_lib_a', ':my_java_lib_c'],",
        "        dep_exports = [':my_java_lib_a']",
        ")");
    assertNoEvents();

    JavaInfo javaInfo = fetchJavaInfo();

    JavaCompilationArgsProvider javaCompilationArgsProvider =
        javaInfo.getProvider(JavaCompilationArgsProvider.class);

    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectCompileTimeJars()))
        .containsExactly(
            "foo/my_starlark_rule_lib.jar",
            "foo/libmy_java_lib_a-hjar.jar",
            "foo/libmy_java_lib_b-hjar.jar");

    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectFullCompileTimeJars()))
        .containsExactly(
            "foo/my_starlark_rule_lib.jar", "foo/libmy_java_lib_a.jar", "foo/libmy_java_lib_b.jar");

    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getRuntimeJars()))
        .containsExactly(
            "foo/my_starlark_rule_lib.jar",
            "foo/libmy_java_lib_a.jar",
            "foo/libmy_java_lib_b.jar",
            "foo/libmy_java_lib_c.jar",
            "foo/libmy_java_lib_d.jar");

    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getTransitiveCompileTimeJars()))
        .containsExactly(
            "foo/my_starlark_rule_lib.jar",
            "foo/libmy_java_lib_a-hjar.jar",
            "foo/libmy_java_lib_b-hjar.jar",
            "foo/libmy_java_lib_c-hjar.jar",
            "foo/libmy_java_lib_d-hjar.jar");
  }

  @Test
  public void buildHelperCreateJavaInfoPluginsFromExports() throws Exception {
    ruleBuilder().build();
    scratch.file(
        "foo/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' ])",
        "java_library(",
        "  name = 'export',",
        "  exported_plugins = [ ':plugin'],",
        ")",
        "my_rule(name = 'my_starlark_rule',",
        "        output_jar = 'my_starlark_rule_lib.jar',",
        "        dep_exports = [':export']",
        ")");
    assertNoEvents();

    assertThat(fetchJavaInfo().getJavaPluginInfo().plugins().processorClasses().toList())
        .containsExactly("com.google.process.stuff");
  }

  @Test
  public void buildHelperCreateJavaInfoWithPlugins() throws Exception {
    ruleBuilder().build();
    scratch.file(
        "foo/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' ])",
        "my_rule(name = 'my_starlark_rule',",
        "        output_jar = 'my_starlark_rule_lib.jar',",
        "        dep_exported_plugins = [':plugin']",
        ")");
    assertNoEvents();

    assertThat(fetchJavaInfo().getJavaPluginInfo().plugins().processorClasses().toList())
        .containsExactly("com.google.process.stuff");
  }

  @Test
  public void buildHelperCreateJavaInfoWithOutputJarAndStampJar() throws Exception {
    ruleBuilder().withStampJar().build();

    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "my_rule(",
        "  name = 'my_starlark_rule',",
        "  output_jar = 'my_starlark_rule_lib.jar',",
        "  source_jars = ['my_starlark_rule_src.jar']",
        ")");
    assertNoEvents();

    JavaCompilationArgsProvider javaCompilationArgsProvider =
        fetchJavaInfo().getProvider(JavaCompilationArgsProvider.class);
    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectFullCompileTimeJars()))
        .containsExactly("foo/my_starlark_rule_lib.jar");
    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getDirectCompileTimeJars()))
        .containsExactly("foo/my_starlark_rule_lib-stamped.jar");
    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getRuntimeJars()))
        .containsExactly("foo/my_starlark_rule_lib.jar");
    assertThat(prettyArtifactNames(javaCompilationArgsProvider.getTransitiveCompileTimeJars()))
        .containsExactly("foo/my_starlark_rule_lib-stamped.jar");
  }

  @Test
  public void buildHelperCreateJavaInfoWithJdeps_javaRuleOutputJarsProvider() throws Exception {
    ruleBuilder().build();
    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "java_library(name = 'my_java_lib_direct', srcs = ['java/A.java'])",
        "my_rule(",
        "  name = 'my_starlark_rule',",
        "  output_jar = 'my_starlark_rule_lib.jar',",
        "  source_jars = ['my_starlark_rule_src.jar'],",
        "  dep = [':my_java_lib_direct'],",
        "  jdeps = 'my_jdeps.pb',",
        ")");
    assertNoEvents();

    JavaRuleOutputJarsProvider ruleOutputs =
        fetchJavaInfo().getProvider(JavaRuleOutputJarsProvider.class);

    assertThat(prettyArtifactNames(ruleOutputs.getAllClassOutputJars()))
        .containsExactly("foo/my_starlark_rule_lib.jar");
    assertThat(prettyArtifactNames(ruleOutputs.getAllSrcOutputJars()))
        .containsExactly("foo/my_starlark_rule_src.jar");
    assertThat(
            prettyArtifactNames(
                ruleOutputs.getJavaOutputs().stream()
                    .map(JavaOutput::getJdeps)
                    .collect(toImmutableList())))
        .containsExactly("foo/my_jdeps.pb");
  }

  @Test
  public void buildHelperCreateJavaInfoWithGeneratedJars_javaRuleOutputJarsProvider()
      throws Exception {
    ruleBuilder().build();
    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "java_library(name = 'my_java_lib_direct', srcs = ['java/A.java'])",
        "my_rule(",
        "  name = 'my_starlark_rule',",
        "  output_jar = 'my_starlark_rule_lib.jar',",
        "  source_jars = ['my_starlark_rule_src.jar'],",
        "  dep = [':my_java_lib_direct'],",
        "  generated_class_jar = 'generated_class.jar',",
        "  generated_source_jar = 'generated_srcs.jar',",
        ")");
    assertNoEvents();

    JavaRuleOutputJarsProvider ruleOutputs =
        fetchJavaInfo().getProvider(JavaRuleOutputJarsProvider.class);

    assertThat(
            prettyArtifactNames(
                ruleOutputs.getJavaOutputs().stream()
                    .map(JavaOutput::getGeneratedClassJar)
                    .collect(toImmutableList())))
        .containsExactly("foo/generated_class.jar");
    assertThat(
            prettyArtifactNames(
                ruleOutputs.getJavaOutputs().stream()
                    .map(JavaOutput::getGeneratedSourceJar)
                    .collect(toImmutableList())))
        .containsExactly("foo/generated_srcs.jar");
  }

  @Test
  public void buildHelperCreateJavaInfoWithGeneratedJars_javaGenJarsProvider() throws Exception {
    ruleBuilder().build();
    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "java_library(name = 'my_java_lib_direct', srcs = ['java/A.java'])",
        "my_rule(",
        "  name = 'my_starlark_rule',",
        "  output_jar = 'my_starlark_rule_lib.jar',",
        "  source_jars = ['my_starlark_rule_src.jar'],",
        "  dep = [':my_java_lib_direct'],",
        "  generated_class_jar = 'generated_class.jar',",
        "  generated_source_jar = 'generated_srcs.jar',",
        ")");
    assertNoEvents();

    JavaGenJarsProvider ruleOutputs = fetchJavaInfo().getProvider(JavaGenJarsProvider.class);

    assertThat(ruleOutputs.getGenClassJar().prettyPrint()).isEqualTo("foo/generated_class.jar");
    assertThat(ruleOutputs.getGenSourceJar().prettyPrint()).isEqualTo("foo/generated_srcs.jar");
  }

  @Test
  public void buildHelperCreateJavaInfoWithCompileJdeps_javaRuleOutputJarsProvider()
      throws Exception {
    ruleBuilder().build();
    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "java_library(name = 'my_java_lib_direct', srcs = ['java/A.java'])",
        "my_rule(",
        "  name = 'my_starlark_rule',",
        "  output_jar = 'my_starlark_rule_lib.jar',",
        "  source_jars = ['my_starlark_rule_src.jar'],",
        "  dep = [':my_java_lib_direct'],",
        "  compile_jdeps = 'compile.deps',",
        ")");
    assertNoEvents();

    JavaRuleOutputJarsProvider ruleOutputs =
        fetchJavaInfo().getProvider(JavaRuleOutputJarsProvider.class);

    assertThat(
            prettyArtifactNames(
                ruleOutputs.getJavaOutputs().stream()
                    .map(JavaOutput::getCompileJdeps)
                    .collect(toImmutableList())))
        .containsExactly("foo/compile.deps");
  }

  @Test
  public void buildHelperCreateJavaInfoWithNativeHeaders_javaRuleOutputJarsProvider()
      throws Exception {
    ruleBuilder().build();
    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "java_library(name = 'my_java_lib_direct', srcs = ['java/A.java'])",
        "my_rule(",
        "  name = 'my_starlark_rule',",
        "  output_jar = 'my_starlark_rule_lib.jar',",
        "  source_jars = ['my_starlark_rule_src.jar'],",
        "  dep = [':my_java_lib_direct'],",
        "  native_headers_jar = 'nativeheaders.jar',",
        ")");
    assertNoEvents();

    JavaRuleOutputJarsProvider ruleOutputs =
        fetchJavaInfo().getProvider(JavaRuleOutputJarsProvider.class);

    assertThat(
            prettyArtifactNames(
                ruleOutputs.getJavaOutputs().stream()
                    .map(JavaOutput::getNativeHeadersJar)
                    .collect(toImmutableList())))
        .containsExactly("foo/nativeheaders.jar");
  }

  @Test
  public void buildHelperCreateJavaInfoWithManifestProto_javaRuleOutputJarsProvider()
      throws Exception {
    ruleBuilder().build();
    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "java_library(name = 'my_java_lib_direct', srcs = ['java/A.java'])",
        "my_rule(",
        "  name = 'my_starlark_rule',",
        "  output_jar = 'my_starlark_rule_lib.jar',",
        "  source_jars = ['my_starlark_rule_src.jar'],",
        "  dep = [':my_java_lib_direct'],",
        "  manifest_proto = 'manifest.proto',",
        ")");
    assertNoEvents();

    JavaRuleOutputJarsProvider ruleOutputs =
        fetchJavaInfo().getProvider(JavaRuleOutputJarsProvider.class);

    assertThat(
            prettyArtifactNames(
                ruleOutputs.getJavaOutputs().stream()
                    .map(JavaOutput::getManifestProto)
                    .collect(toImmutableList())))
        .containsExactly("foo/manifest.proto");
  }

  @Test
  public void buildHelperCreateJavaInfoWithModuleFlags() throws Exception {
    setBuildLanguageOptions("--noincompatible_java_info_merge_runtime_module_flags");
    ruleBuilder().build();
    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "java_library(",
        "    name = 'my_java_lib_direct',",
        "    srcs = ['java/A.java'],",
        "    add_exports = ['java.base/java.lang'],",
        "    add_opens = ['java.base/java.lang'],",
        ")",
        "java_library(",
        "    name = 'my_java_lib_runtime',",
        "    srcs = ['java/A.java'],",
        "    add_opens = ['java.base/java.util'],",
        ")",
        "java_library(",
        "    name = 'my_java_lib_exports',",
        "    srcs = ['java/A.java'],",
        "    add_opens = ['java.base/java.math'],",
        ")",
        "my_rule(",
        "    name = 'my_starlark_rule',",
        "    dep = [':my_java_lib_direct'],",
        "    dep_runtime = [':my_java_lib_runtime'],",
        "    dep_exports = [':my_java_lib_exports'],",
        "    output_jar = 'my_starlark_rule_lib.jar',",
        "    add_exports = ['java.base/java.lang.invoke'],",
        ")");
    assertNoEvents();

    JavaModuleFlagsProvider ruleOutputs =
        fetchJavaInfo().getProvider(JavaModuleFlagsProvider.class);

    if (analysisMock.isThisBazel()) {
      assertThat(ruleOutputs.toFlags())
          .containsExactly(
              "--add-exports=java.base/java.lang=ALL-UNNAMED",
              "--add-exports=java.base/java.lang.invoke=ALL-UNNAMED",
              // NB: no java.base/java.util as the JavaInfo constructor doesn't
              // look at runtime_deps for module flags.
              "--add-opens=java.base/java.lang=ALL-UNNAMED",
              "--add-opens=java.base/java.math=ALL-UNNAMED")
          .inOrder();
    } else {
      // add_exports/add_opens ignored in JavaInfo constructor in #newJavaInfo below
      assertThat(ruleOutputs.toFlags())
          .containsExactly(
              "--add-exports=java.base/java.lang=ALL-UNNAMED",
              // NB: no java.base/java.util as the JavaInfo constructor doesn't
              // look at runtime_deps for module flags.
              "--add-opens=java.base/java.lang=ALL-UNNAMED",
              "--add-opens=java.base/java.math=ALL-UNNAMED")
          .inOrder();
    }
  }

  @Test
  public void buildHelperCreateJavaInfoWithModuleFlagsIncompatibleMergeRuntime() throws Exception {
    setBuildLanguageOptions("--incompatible_java_info_merge_runtime_module_flags");
    ruleBuilder().build();
    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "java_library(",
        "    name = 'my_java_lib_direct',",
        "    srcs = ['java/A.java'],",
        "    add_exports = ['java.base/java.lang'],",
        "    add_opens = ['java.base/java.lang'],",
        ")",
        "java_library(",
        "    name = 'my_java_lib_runtime',",
        "    srcs = ['java/A.java'],",
        "    add_opens = ['java.base/java.util'],",
        ")",
        "java_library(",
        "    name = 'my_java_lib_exports',",
        "    srcs = ['java/A.java'],",
        "    add_opens = ['java.base/java.math'],",
        ")",
        "my_rule(",
        "    name = 'my_starlark_rule',",
        "    dep = [':my_java_lib_direct'],",
        "    dep_runtime = [':my_java_lib_runtime'],",
        "    dep_exports = [':my_java_lib_exports'],",
        "    output_jar = 'my_starlark_rule_lib.jar',",
        "    add_exports = ['java.base/java.lang.invoke'],",
        ")");
    assertNoEvents();

    JavaModuleFlagsProvider ruleOutputs =
        fetchJavaInfo().getProvider(JavaModuleFlagsProvider.class);

    if (analysisMock.isThisBazel()) {
      assertThat(ruleOutputs.toFlags())
          .containsExactly(
              "--add-exports=java.base/java.lang=ALL-UNNAMED",
              "--add-exports=java.base/java.lang.invoke=ALL-UNNAMED",
              "--add-opens=java.base/java.util=ALL-UNNAMED",
              "--add-opens=java.base/java.math=ALL-UNNAMED",
              "--add-opens=java.base/java.lang=ALL-UNNAMED")
          .inOrder();
    } else {
      // add_exports/add_opens ignored in JavaInfo constructor in #newJavaInfo below
      assertThat(ruleOutputs.toFlags())
          .containsExactly(
              "--add-exports=java.base/java.lang=ALL-UNNAMED",
              "--add-opens=java.base/java.util=ALL-UNNAMED",
              "--add-opens=java.base/java.math=ALL-UNNAMED",
              "--add-opens=java.base/java.lang=ALL-UNNAMED")
          .inOrder();
    }
  }

  @Test
  public void starlarkJavaOutputsCanBeAddedToJavaPluginInfo() throws Exception {
    Artifact classJar = createArtifact("foo.jar");
    StarlarkInfo starlarkJavaOutput =
        makeStruct(ImmutableMap.of("source_jars", Starlark.NONE, "class_jar", classJar));
    StarlarkInfo starlarkPluginInfo =
        makeStruct(
            ImmutableMap.of(
                "java_outputs", StarlarkList.immutableOf(starlarkJavaOutput),
                "plugins", JavaPluginData.empty(),
                "api_generating_plugins", JavaPluginData.empty()));

    JavaPluginInfo pluginInfo = JavaPluginInfo.PROVIDER.wrap(starlarkPluginInfo);

    assertThat(pluginInfo).isNotNull();
    assertThat(pluginInfo.getJavaOutputs()).hasSize(1);
    assertThat(pluginInfo.getJavaOutputs().get(0).getClassJar()).isEqualTo(classJar);
  }

  @Test
  public void javaOutputSourceJarsReturnsListWithIncompatibleFlagDisabled() throws Exception {
    setBuildLanguageOptions("--noincompatible_depset_for_java_output_source_jars");
    scratch.file(
        "foo/extension.bzl",
        "MyInfo = provider()",
        "",
        "def _impl(ctx):",
        "  return MyInfo(source_jars = ctx.attr.dep[JavaInfo].java_outputs[0].source_jars)",
        "",
        "my_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {'dep' : attr.label()}",
        ")");
    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "java_library(name = 'lib')",
        "my_rule(name = 'my_starlark_rule', dep = ':lib')");

    ConfiguredTarget target = getConfiguredTarget("//foo:my_starlark_rule");

    StarlarkInfo info =
        (StarlarkInfo)
            target.get(
                new StarlarkProvider.Key(Label.parseCanonical("//foo:extension.bzl"), "MyInfo"));
    assertThat(info).isNotNull();
    assertThat(info.getValue("source_jars")).isInstanceOf(StarlarkList.class);
  }

  @Test
  public void javaOutputSourceJarsReturnsDepsetWithIncompatibleFlagEnabled() throws Exception {
    setBuildLanguageOptions("--incompatible_depset_for_java_output_source_jars");
    scratch.file(
        "foo/extension.bzl",
        "MyInfo = provider()",
        "",
        "def _impl(ctx):",
        "  return MyInfo(source_jars = ctx.attr.dep[JavaInfo].java_outputs[0].source_jars)",
        "",
        "my_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {'dep' : attr.label()}",
        ")");
    scratch.file(
        "foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "java_library(name = 'lib')",
        "my_rule(name = 'my_starlark_rule', dep = ':lib')");

    ConfiguredTarget target = getConfiguredTarget("//foo:my_starlark_rule");

    StarlarkInfo info =
        (StarlarkInfo)
            target.get(
                new StarlarkProvider.Key(Label.parseCanonical("//foo:extension.bzl"), "MyInfo"));
    assertThat(info).isNotNull();
    assertThat(info.getValue("source_jars")).isInstanceOf(Depset.class);
  }

  @Test
  public void nativeAndStarlarkJavaOutputsCanBeAddedToADepset() throws Exception {
    scratch.file(
        "foo/extension.bzl",
        "def _impl(ctx):",
        "  f = ctx.actions.declare_file(ctx.label.name + '.jar')",
        "  ctx.actions.write(f, '')",
        "  return [JavaInfo(output_jar=f, compile_jar=None)]",
        "",
        "my_rule = rule(implementation = _impl)");
    scratch.file(
        "foo/BUILD",
        //
        "load(':extension.bzl', 'my_rule')",
        "my_rule(name = 'my_starlark_rule')");
    JavaOutput nativeOutput =
        JavaOutput.builder().setClassJar(createArtifact("native.jar")).build();
    StarlarkList<?> starlarkOutputs =
        ((StarlarkInfo)
                getConfiguredTarget("//foo:my_starlark_rule").get(JavaInfo.PROVIDER.getKey()))
            .getValue("java_outputs", StarlarkList.class);

    Depset depset =
        Depset.fromDirectAndTransitive(
            Order.STABLE_ORDER,
            /* direct= */ ImmutableList.builder().add(nativeOutput).addAll(starlarkOutputs).build(),
            /* transitive= */ ImmutableList.of(),
            /* strict= */ true);

    assertThat(depset).isNotNull();
    assertThat(depset.toList()).hasSize(2);
  }

  @Test
  public void translateStarlarkJavaInfo_minimal() throws Exception {
    ImmutableMap<String, Object> fields = getBuilderWithMandataryFields().buildOrThrow();
    StarlarkInfo starlarkInfo = makeStruct(fields);

    JavaInfo javaInfo = JavaInfo.PROVIDER.wrap(starlarkInfo);

    assertThat(javaInfo).isNotNull();
    assertThat(javaInfo.getProvider(JavaCompilationArgsProvider.class)).isNotNull();
    assertThat(javaInfo.getCompilationInfoProvider()).isNull();
    assertThat(javaInfo.getJavaModuleFlagsInfo()).isEqualTo(JavaModuleFlagsProvider.EMPTY);
    assertThat(javaInfo.getJavaPluginInfo()).isEqualTo(JavaPluginInfo.empty());
  }

  @Test
  public void translateStarlarkJavaInfo_binariesDoNotContainCompilationArgs() throws Exception {
    ImmutableMap<String, Object> fields =
        getBuilderWithMandataryFields().put("_is_binary", true).buildOrThrow();
    StarlarkInfo starlarkInfo = makeStruct(fields);

    JavaInfo javaInfo = JavaInfo.PROVIDER.wrap(starlarkInfo);

    assertThat(javaInfo).isNotNull();
    assertThat(javaInfo.getProvider(JavaCompilationArgsProvider.class)).isNull();
  }

  @Test
  public void translateStarlarkJavaInfo_compilationInfo() throws Exception {
    ImmutableMap<String, Object> fields =
        getBuilderWithMandataryFields()
            .put(
                "compilation_info",
                makeStruct(
                    ImmutableMap.of(
                        "javac_options", StarlarkList.immutableOf("opt1", "opt2"),
                        "boot_classpath", StarlarkList.immutableOf(createArtifact("cp.jar")))))
            .buildOrThrow();
    StarlarkInfo starlarkInfo = makeStruct(fields);

    JavaInfo javaInfo = JavaInfo.PROVIDER.wrap(starlarkInfo);

    assertThat(javaInfo).isNotNull();
    assertThat(javaInfo.getCompilationInfoProvider()).isNotNull();
    assertThat(javaInfo.getCompilationInfoProvider().getJavacOpts())
        .containsExactly("opt1", "opt2");
    assertThat(javaInfo.getCompilationInfoProvider().getBootClasspathList()).hasSize(1);
    assertThat(prettyArtifactNames(javaInfo.getCompilationInfoProvider().getBootClasspathList()))
        .containsExactly("cp.jar");
  }

  @Test
  public void translatedStarlarkCompilationInfoEqualsNativeInstance() throws Exception {
    Artifact bootClasspathArtifact = createArtifact("boot.jar");
    NestedSet<Artifact> compilationClasspath =
        NestedSetBuilder.create(Order.NAIVE_LINK_ORDER, createArtifact("compile.jar"));
    NestedSet<Artifact> runtimeClasspath =
        NestedSetBuilder.create(Order.NAIVE_LINK_ORDER, createArtifact("runtime.jar"));
    StarlarkInfo starlarkInfo =
        makeStruct(
            ImmutableMap.of(
                "compilation_classpath", Depset.of(Artifact.class, compilationClasspath),
                "runtime_classpath", Depset.of(Artifact.class, runtimeClasspath),
                "javac_options", StarlarkList.immutableOf("opt1", "opt2"),
                "boot_classpath", StarlarkList.immutableOf(bootClasspathArtifact)));
    JavaCompilationInfoProvider nativeCompilationInfo =
        new JavaCompilationInfoProvider.Builder()
            .setCompilationClasspath(compilationClasspath)
            .setRuntimeClasspath(runtimeClasspath)
            .setJavacOpts(ImmutableList.of("opt1", "opt2"))
            .setBootClasspath(
                NestedSetBuilder.create(Order.NAIVE_LINK_ORDER, bootClasspathArtifact))
            .build();

    JavaCompilationInfoProvider starlarkCompilationInfo =
        JavaCompilationInfoProvider.fromStarlarkCompilationInfo(starlarkInfo);

    assertThat(starlarkCompilationInfo).isNotNull();
    assertThat(starlarkCompilationInfo).isEqualTo(nativeCompilationInfo);
  }

  @Test
  public void translateStarlarkJavaInfo_moduleFlagsInfo() throws Exception {
    ImmutableMap<String, Object> fields =
        getBuilderWithMandataryFields()
            .put(
                "module_flags_info",
                makeStruct(
                    ImmutableMap.of(
                        "add_exports", makeDepset(String.class, "export1", "export2"),
                        "add_opens", makeDepset(String.class, "open1", "open2"))))
            .buildOrThrow();
    StarlarkInfo starlarkInfo = makeStruct(fields);

    JavaInfo javaInfo = JavaInfo.PROVIDER.wrap(starlarkInfo);

    assertThat(javaInfo).isNotNull();
    assertThat(javaInfo.getJavaModuleFlagsInfo()).isNotNull();
    assertThat(javaInfo.getJavaModuleFlagsInfo().getAddExports().toList())
        .containsExactly("export1", "export2");
    assertThat(javaInfo.getJavaModuleFlagsInfo().getAddOpens().toList())
        .containsExactly("open1", "open2");
  }

  @Test
  public void translateStarlarkJavaInfo_pluginInfo() throws Exception {
    ImmutableMap<String, Object> fields =
        getBuilderWithMandataryFields()
            .put(
                "plugins",
                JavaPluginData.create(
                    NestedSetBuilder.create(Order.STABLE_ORDER, "c1", "c2", "c3"),
                    NestedSetBuilder.create(Order.STABLE_ORDER, createArtifact("f1")),
                    NestedSetBuilder.emptySet(Order.STABLE_ORDER)))
            .buildKeepingLast();
    StarlarkInfo starlarkInfo = makeStruct(fields);

    JavaInfo javaInfo = JavaInfo.PROVIDER.wrap(starlarkInfo);

    assertThat(javaInfo).isNotNull();
    assertThat(javaInfo.plugins()).isNotNull();
    assertThat(javaInfo.plugins().processorClasses().toList()).containsExactly("c1", "c2", "c3");
    assertThat(prettyArtifactNames(javaInfo.plugins().processorClasspath())).containsExactly("f1");
  }

  private static ImmutableMap.Builder<String, Object> getBuilderWithMandataryFields() {
    Depset emptyDepset = Depset.of(Artifact.class, NestedSetBuilder.create(Order.STABLE_ORDER));
    return ImmutableMap.<String, Object>builder()
        .put("transitive_native_libraries", emptyDepset)
        .put("compile_jars", emptyDepset)
        .put("full_compile_jars", emptyDepset)
        .put("transitive_compile_time_jars", emptyDepset)
        .put("transitive_runtime_jars", emptyDepset)
        .put("_transitive_full_compile_time_jars", emptyDepset)
        .put("_compile_time_java_dependencies", emptyDepset)
        .put("plugins", JavaPluginData.empty())
        .put("api_generating_plugins", JavaPluginData.empty())
        .put("java_outputs", StarlarkList.empty())
        .put("transitive_source_jars", emptyDepset)
        .put("source_jars", StarlarkList.empty())
        .put("runtime_output_jars", StarlarkList.empty());
  }

  private Artifact createArtifact(String path) throws IOException {
    Path execRoot = scratch.dir("/");
    ArtifactRoot root = ArtifactRoot.asDerivedRoot(execRoot, RootType.Output, "fake-root");
    return ActionsTestUtil.createArtifact(root, path);
  }

  private static <T> Depset makeDepset(Class<T> clazz, T... elems) {
    return Depset.of(clazz, NestedSetBuilder.create(Order.STABLE_ORDER, elems));
  }

  private static StarlarkInfo makeStruct(Map<String, Object> struct) {
    return StructProvider.STRUCT.create(struct, "");
  }

  private RuleBuilder ruleBuilder() {
    return new RuleBuilder();
  }

  private class RuleBuilder {
    private boolean useIJar = false;
    private boolean stampJar;
    private boolean neverLink = false;
    private boolean sourceFiles = false;

    @CanIgnoreReturnValue
    private RuleBuilder withIJar() {
      useIJar = true;
      return this;
    }

    @CanIgnoreReturnValue
    private RuleBuilder withStampJar() {
      stampJar = true;
      return this;
    }

    @CanIgnoreReturnValue
    private RuleBuilder withNeverLink() {
      neverLink = true;
      return this;
    }

    @CanIgnoreReturnValue
    private RuleBuilder withSourceFiles() {
      sourceFiles = true;
      return this;
    }

    private String[] newJavaInfo() {
      assertThat(useIJar && stampJar).isFalse();
      ImmutableList.Builder<String> lines = ImmutableList.builder();
      lines.add(
          "result = provider()",
          "def _impl(ctx):",
          "  ctx.actions.write(ctx.outputs.output_jar, 'JavaInfo API Test', is_executable=False) ",
          "  dp = [dep[java_common.provider] for dep in ctx.attr.dep]",
          "  dp_runtime = [dep[java_common.provider] for dep in ctx.attr.dep_runtime]",
          "  dp_exports = [dep[java_common.provider] for dep in ctx.attr.dep_exports]",
          "  dp_exported_plugins = [dep[JavaPluginInfo] for dep in ctx.attr.dep_exported_plugins]",
          "  dp_libs = [dep[CcInfo] for dep in ctx.attr.cc_dep]");

      if (useIJar) {
        lines.add(
            "  compile_jar = java_common.run_ijar(",
            "    ctx.actions,",
            "    jar = ctx.outputs.output_jar,",
            "    java_toolchain = ctx.attr._toolchain[java_common.JavaToolchainInfo],",
            "  )");
      } else if (stampJar) {
        lines.add(
            "  compile_jar = java_common.stamp_jar(",
            "    ctx.actions,",
            "    jar = ctx.outputs.output_jar,",
            "    target_label = ctx.label,",
            "    java_toolchain = ctx.attr._toolchain[java_common.JavaToolchainInfo],",
            "  )");
      } else {
        lines.add("  compile_jar = ctx.outputs.output_jar");
      }
      if (sourceFiles) {
        lines.add(
            "  source_jar = java_common.pack_sources(",
            "    ctx.actions,",
            "    output_source_jar = ",
            "      ctx.actions.declare_file(ctx.outputs.output_jar.basename[:-4] + '-src.jar'),",
            "    sources = ctx.files.sources,",
            "    source_jars = ctx.files.source_jars,",
            "    java_toolchain = ctx.attr._toolchain[java_common.JavaToolchainInfo],",
            ")");
      } else {
        lines.add(
            "  if ctx.files.source_jars:",
            "    source_jar = list(ctx.files.source_jars)[0]",
            "  else:",
            "    source_jar = None");
      }
      lines.add(
          "  javaInfo = JavaInfo(",
          "    output_jar = ctx.outputs.output_jar,",
          "    compile_jar = compile_jar,",
          "    source_jar = source_jar,",
          neverLink ? "    neverlink = True," : "",
          "    deps = dp,",
          "    runtime_deps = dp_runtime,",
          "    exports = dp_exports,",
          "    exported_plugins = dp_exported_plugins,",
          "    jdeps = ctx.file.jdeps,",
          "    compile_jdeps = ctx.file.compile_jdeps,",
          "    generated_class_jar = ctx.file.generated_class_jar,",
          "    generated_source_jar = ctx.file.generated_source_jar,",
          "    native_headers_jar = ctx.file.native_headers_jar,",
          "    manifest_proto = ctx.file.manifest_proto,",
          "    native_libraries = dp_libs,");
      if (analysisMock.isThisBazel()) {
        lines.add(
            "    add_exports = ctx.attr.add_exports,", //
            "    add_opens = ctx.attr.add_opens,");
      }
      lines.add(
          "  )", //
          "  return [result(property = javaInfo)]");
      return lines.build().toArray(new String[] {});
    }

    private void build() throws Exception {
      if (useIJar || stampJar || sourceFiles) {
        JavaToolchainTestUtil.writeBuildFileForJavaToolchain(scratch);
      }

      ImmutableList.Builder<String> lines = ImmutableList.builder();
      lines.add(newJavaInfo());
      lines.add(
          "my_rule = rule(",
          "  implementation = _impl,",
          "  toolchains = ['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "'],",
          "  attrs = {",
          "    'dep' : attr.label_list(),",
          "    'cc_dep' : attr.label_list(),",
          "    'dep_runtime' : attr.label_list(),",
          "    'dep_exports' : attr.label_list(),",
          "    'dep_exported_plugins' : attr.label_list(),",
          "    'output_jar' : attr.output(mandatory=True),",
          "    'source_jars' : attr.label_list(allow_files=['.jar']),",
          "    'sources' : attr.label_list(allow_files=['.java']),",
          "    'jdeps' : attr.label(allow_single_file=True),",
          "    'compile_jdeps' : attr.label(allow_single_file=True),",
          "    'generated_class_jar' : attr.label(allow_single_file=True),",
          "    'generated_source_jar' : attr.label(allow_single_file=True),",
          "    'native_headers_jar' : attr.label(allow_single_file=True),",
          "    'manifest_proto' : attr.label(allow_single_file=True),",
          "    'add_exports' : attr.string_list(),",
          "    'add_opens' : attr.string_list(),",
          useIJar || stampJar || sourceFiles
              ? "    '_toolchain': attr.label(default = Label('//java/com/google/test:toolchain')),"
              : "",
          "  }",
          ")");

      scratch.file("foo/extension.bzl", lines.build().toArray(new String[] {}));
    }
  }

  private JavaInfo fetchJavaInfo() throws Exception {
    ConfiguredTarget myRuleTarget = getConfiguredTarget("//foo:my_starlark_rule");
    StructImpl info =
        (StructImpl)
            myRuleTarget.get(
                new StarlarkProvider.Key(Label.parseCanonical("//foo:extension.bzl"), "result"));

    return JavaInfo.PROVIDER.wrap(info.getValue("property", Info.class));
  }
}
