Add whitelist flag for --incompatible_disallow_legacy_javainfo.

Progress on #5821

RELNOTES: There is a new flag available `--experimental_java_common_create_provider_enabled_packages` that acts as a whitelist for usages of `java_common.create_provider`. The constructor will be deprecated in Bazel 0.23.
PiperOrigin-RevId: 228164706
diff --git a/src/main/java/com/google/devtools/build/lib/packages/SkylarkSemanticsOptions.java b/src/main/java/com/google/devtools/build/lib/packages/SkylarkSemanticsOptions.java
index 919064f..b389dc4 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/SkylarkSemanticsOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/SkylarkSemanticsOptions.java
@@ -100,6 +100,19 @@
       help = "If set to true, enables the use of the `repo_mapping` attribute in WORKSPACE files.")
   public boolean experimentalEnableRepoMapping;
 
+  // This flag is declared in SkylarkSemanticsOptions instead of JavaOptions because there is no
+  // way to retrieve the java configuration from the Java implementation of
+  // java_common.create_provider.
+  @Option(
+      name = "experimental_java_common_create_provider_enabled_packages",
+      converter = CommaSeparatedOptionListConverter.class,
+      defaultValue = "",
+      documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
+      effectTags = {OptionEffectTag.LOADING_AND_ANALYSIS},
+      metadataTags = {OptionMetadataTag.EXPERIMENTAL},
+      help = "Passes list of packages that can use the java_common.create_provider Starlark API.")
+  public List<String> experimentalJavaCommonCreateProviderEnabledPackages;
+
   @Option(
       name = "experimental_remap_main_repo",
       defaultValue = "false",
@@ -536,6 +549,8 @@
         .experimentalEnableAndroidMigrationApis(experimentalEnableAndroidMigrationApis)
         .experimentalEnableRepoMapping(experimentalEnableRepoMapping)
         .experimentalRemapMainRepo(experimentalRemapMainRepo)
+        .experimentalJavaCommonCreateProviderEnabledPackages(
+            experimentalJavaCommonCreateProviderEnabledPackages)
         .experimentalPlatformsApi(experimentalPlatformsApi)
         .experimentalStarlarkConfigTransitions(experimentalStarlarkConfigTransitions)
         .incompatibleBzlDisallowLoadAfterStatement(incompatibleBzlDisallowLoadAfterStatement)
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/BUILD b/src/main/java/com/google/devtools/build/lib/rules/java/BUILD
index d01553a..4d46d22 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/BUILD
@@ -54,6 +54,7 @@
         "//src/main/java/com/google/devtools/build/lib:packages-internal",
         "//src/main/java/com/google/devtools/build/lib:proto-rules",
         "//src/main/java/com/google/devtools/build/lib:provider-collection",
+        "//src/main/java/com/google/devtools/build/lib:skylark_semantics",
         "//src/main/java/com/google/devtools/build/lib:skylarkinterface",
         "//src/main/java/com/google/devtools/build/lib:util",
         "//src/main/java/com/google/devtools/build/lib/actions",
@@ -129,6 +130,7 @@
         "//src/main/java/com/google/devtools/build/lib:events",
         "//src/main/java/com/google/devtools/build/lib:packages-internal",
         "//src/main/java/com/google/devtools/build/lib:provider-collection",
+        "//src/main/java/com/google/devtools/build/lib:skylark_semantics",
         "//src/main/java/com/google/devtools/build/lib:skylarkinterface",
         "//src/main/java/com/google/devtools/build/lib:util",
         "//src/main/java/com/google/devtools/build/lib/actions",
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java
index 7954c3b..5be43d7 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java
@@ -31,7 +31,9 @@
 import com.google.devtools.build.lib.syntax.Runtime;
 import com.google.devtools.build.lib.syntax.SkylarkList;
 import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
+import com.google.devtools.build.lib.syntax.SkylarkSemantics;
 import com.google.devtools.build.lib.syntax.Type;
+import java.util.List;
 import javax.annotation.Nullable;
 
 /** A module that contains Skylark utilities for Java support. */
@@ -54,11 +56,10 @@
       Environment environment)
       throws EvalException {
     if (environment.getSemantics().incompatibleDisallowLegacyJavaInfo()) {
-      throw new EvalException(
+      checkCallPathInWhitelistedPackages(
+          environment.getSemantics(),
           location,
-          "create_provider is deprecated and cannot be used when "
-              + "--incompatible_disallow_legacy_javainfo is set. "
-              + "Please migrate to the JavaInfo constructor.");
+          environment.getCallerLabel().getPackageFragment().toString());
     }
     return JavaInfoBuildHelper.getInstance()
         .create(
@@ -221,4 +222,21 @@
             .addAll(((SkylarkList<?>) o).getContents(Artifact.class, /*description=*/ null))
             .build();
   }
+
+  /**
+   * Throws an {@link EvalException} if the given {@code callPath} is not listed under the {@code
+   * --experimental_java_common_create_provider_enabled_packages} flag.
+   */
+  private static void checkCallPathInWhitelistedPackages(
+      SkylarkSemantics semantics, Location location, String callPath) throws EvalException {
+    List<String> whitelistedPackagesList =
+        semantics.experimentalJavaCommonCreateProviderEnabledPackages();
+    if (whitelistedPackagesList.stream().noneMatch(path -> callPath.startsWith(path))) {
+      throw new EvalException(
+          location,
+          "java_common.create_provider is deprecated and cannot be used when "
+              + "--incompatible_disallow_legacy_javainfo is set. "
+              + "Please migrate to the JavaInfo constructor.");
+    }
+  }
 }
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 3118c37..a66616f 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
@@ -44,7 +44,11 @@
   @SkylarkCallable(
       name = "create_provider",
       doc =
-          "Creates a JavaInfo from jars. compile_time/runtime_jars represent the outputs of the "
+          "This API is deprecated. It will be disabled by default in Bazel 0.23. Please use "
+              + "<a href ="
+              + "'https://docs.bazel.build/versions/master/skylark/lib/JavaInfo.html#JavaInfo'>"
+              + "JavaInfo()</a> instead."
+              + "Creates a JavaInfo from jars. compile_time/runtime_jars are the outputs of the "
               + "target providing a JavaInfo, while transitive_*_jars represent their dependencies."
               + "<p>Note: compile_time_jars and runtime_jars are not automatically merged into the "
               + "transitive jars (unless the given transitive_*_jars are empty) - if this is the "
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSemantics.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSemantics.java
index 413c818..51961b9 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSemantics.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSemantics.java
@@ -124,6 +124,8 @@
 
   public abstract boolean experimentalEnableRepoMapping();
 
+  public abstract ImmutableList<String> experimentalJavaCommonCreateProviderEnabledPackages();
+
   public abstract boolean experimentalRemapMainRepo();
 
   public abstract boolean experimentalPlatformsApi();
@@ -207,6 +209,7 @@
           .experimentalCcSkylarkApiEnabledPackages(ImmutableList.of())
           .experimentalEnableAndroidMigrationApis(false)
           .experimentalEnableRepoMapping(false)
+          .experimentalJavaCommonCreateProviderEnabledPackages(ImmutableList.of())
           .experimentalRemapMainRepo(false)
           .experimentalPlatformsApi(false)
           .experimentalStarlarkConfigTransitions(false)
@@ -256,6 +259,8 @@
 
     public abstract Builder experimentalRemapMainRepo(boolean value);
 
+    public abstract Builder experimentalJavaCommonCreateProviderEnabledPackages(List<String> value);
+
     public abstract Builder experimentalPlatformsApi(boolean value);
 
     public abstract Builder experimentalStarlarkConfigTransitions(boolean value);