Propagate JavaGenJarsProvider through Starlark-constructed JavaInfo

PiperOrigin-RevId: 318303229
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaGenJarsProvider.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaGenJarsProvider.java
index 6c78f07..acf4dc3 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaGenJarsProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaGenJarsProvider.java
@@ -14,6 +14,8 @@
 
 package com.google.devtools.build.lib.rules.java;
 
+import static com.google.common.base.Preconditions.checkState;
+
 import com.google.common.collect.ImmutableList;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
@@ -42,7 +44,7 @@
   private final NestedSet<Artifact> transitiveGenClassJars;
   private final NestedSet<Artifact> transitiveGenSourceJars;
 
-  static JavaGenJarsProvider create(
+  public static JavaGenJarsProvider create(
       boolean usesAnnotationProcessing,
       @Nullable Artifact genClassJar,
       @Nullable Artifact genSourceJar,
@@ -71,6 +73,33 @@
         sourceJarsBuilder.build());
   }
 
+  /** Returns a copy with the given details, preserving transitiveXxx sets. */
+  public JavaGenJarsProvider withDirectInfo(
+      boolean usesAnnotationProcessing,
+      @Nullable Artifact genClassJar,
+      @Nullable Artifact genSourceJar,
+      NestedSet<Artifact> processorClasspath,
+      NestedSet<String> processorClassNames) {
+    // Existing Jars would be a problem b/c we can't remove them from transitiveXxx sets
+    checkState(this.genClassJar == null, "Existing genClassJar: %s", this.genClassJar);
+    checkState(this.genSourceJar == null, "Existing genSrcJar: %s", this.genSourceJar);
+    return new JavaGenJarsProvider(
+        usesAnnotationProcessing,
+        genClassJar,
+        genSourceJar,
+        processorClasspath,
+        processorClassNames,
+        addIf(transitiveGenClassJars, genClassJar),
+        addIf(transitiveGenSourceJars, genSourceJar));
+  }
+
+  private static <T> NestedSet<T> addIf(NestedSet<T> set, @Nullable T element) {
+    if (element == null) {
+      return set;
+    }
+    return NestedSetBuilder.<T>stableOrder().add(element).addTransitive(set).build();
+  }
+
   // Package-private for @AutoCodec
   JavaGenJarsProvider(
       boolean usesAnnotationProcessing,
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaInfoBuildHelper.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaInfoBuildHelper.java
index 444ee49..a7d50cb 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaInfoBuildHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaInfoBuildHelper.java
@@ -130,6 +130,16 @@
         JavaSourceJarsProvider.class,
         createJavaSourceJarsProvider(sourceJars, concat(compileTimeDeps, runtimeDeps, exports)));
 
+    javaInfoBuilder.addProvider(
+        JavaGenJarsProvider.class,
+        JavaGenJarsProvider.create(
+            false,
+            null,
+            null,
+            JavaPluginInfoProvider.empty(),
+            JavaInfo.fetchProvidersFromList(
+                concat(compileTimeDeps, exports), JavaGenJarsProvider.class)));
+
     javaInfoBuilder.setRuntimeJars(ImmutableList.of(outputJar));
 
     return javaInfoBuilder.build();
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaStarlarkCommon.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaStarlarkCommon.java
index dc3b78d..69b782b 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaStarlarkCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaStarlarkCommon.java
@@ -221,6 +221,20 @@
   }
 
   @Override
+  public JavaInfo setAnnotationProcessing(
+      JavaInfo javaInfo,
+      boolean enabled,
+      Sequence<?> processorClassnames,
+      Object processorClasspath,
+      Object classJar,
+      Object sourceJar)
+      throws EvalException {
+    // No implementation in Bazel. This method not callable in Starlark except through
+    // (discouraged) use of --experimental_google_legacy_api.
+    return null;
+  }
+
+  @Override
   public Depset /*<Artifact>*/ getCompileTimeJavaDependencyArtifacts(JavaInfo javaInfo) {
     // No implementation in Bazel. This method not callable in Starlark except through
     // (discouraged) use of --experimental_google_legacy_api.
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/java/JavaCommonApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/java/JavaCommonApi.java
index c639c24..7e48cdf 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/java/JavaCommonApi.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/java/JavaCommonApi.java
@@ -511,6 +511,66 @@
   JavaInfoT removeAnnotationProcessors(JavaInfoT javaInfo);
 
   @StarlarkMethod(
+      name = "set_annotation_processing",
+      doc = "Returns a copy of the given JavaInfo with the given annotation_processing info.",
+      parameters = {
+        @Param(
+            name = "java_info",
+            positional = true,
+            named = false,
+            type = JavaInfoApi.class,
+            doc = "The JavaInfo to enhance."),
+        @Param(
+            name = "enabled",
+            type = Boolean.class,
+            named = true,
+            positional = false,
+            defaultValue = "False",
+            doc = "Returns true if the rule uses annotation processing."),
+        @Param(
+            name = "processor_classnames",
+            type = Sequence.class,
+            generic1 = String.class,
+            named = true,
+            positional = false,
+            defaultValue = "[]",
+            doc = "Class names of annotation processors applied to this rule."),
+        @Param(
+            name = "processor_classpath",
+            type = Depset.class,
+            named = true,
+            noneable = true,
+            positional = false,
+            defaultValue = "None",
+            doc = "Class names of annotation processors applied to this rule."),
+        @Param(
+            name = "class_jar",
+            type = FileApi.class,
+            named = true,
+            noneable = true,
+            positional = false,
+            defaultValue = "None",
+            doc = "Jar file that is the result of annotation processing for this rule, or None."),
+        @Param(
+            name = "source_jar",
+            type = FileApi.class,
+            named = true,
+            noneable = true,
+            positional = false,
+            defaultValue = "None",
+            doc = "Source archive resulting from annotation processing of this rule, or None."),
+      },
+      enableOnlyWithFlag = FlagIdentifier.EXPERIMENTAL_GOOGLE_LEGACY_API)
+  JavaInfoT setAnnotationProcessing(
+      JavaInfoT javaInfo,
+      boolean enabled,
+      Sequence<?> processorClassnames /* <String> expected. */,
+      Object processorClasspath,
+      Object classJar,
+      Object sourceJar)
+      throws EvalException;
+
+  @StarlarkMethod(
       name = "compile_time_jdeps",
       doc = "Returns a depset of the given JavaInfo's compile-time jdeps files.",
       parameters = {
diff --git a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/java/FakeJavaCommon.java b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/java/FakeJavaCommon.java
index 3ffafbf..d4fce25 100644
--- a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/java/FakeJavaCommon.java
+++ b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/java/FakeJavaCommon.java
@@ -147,6 +147,17 @@
   }
 
   @Override
+  public FakeJavaInfo setAnnotationProcessing(
+      FakeJavaInfo javaInfo,
+      boolean enabled,
+      Sequence<?> processorClassnames,
+      Object processorClasspath,
+      Object classJar,
+      Object sourceJar) {
+    return new FakeJavaInfo();
+  }
+
+  @Override
   public Depset /*<FileApi>*/ getCompileTimeJavaDependencyArtifacts(FakeJavaInfo javaInfo) {
     return null;
   }