Add API for aspects to declare they are ready for the toolchain transition migration.

Part of work on toolchain transitions, #10523.

PiperOrigin-RevId: 316752326
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/StarlarkRuleClassFunctions.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/StarlarkRuleClassFunctions.java
index e9a3b8e..763b83c 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/StarlarkRuleClassFunctions.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/StarlarkRuleClassFunctions.java
@@ -491,6 +491,7 @@
       Sequence<?> fragments,
       Sequence<?> hostFragments,
       Sequence<?> toolchains,
+      boolean useToolchainTransition,
       String doc,
       Boolean applyToGeneratingRules,
       StarlarkThread thread)
@@ -591,6 +592,7 @@
         HostTransition.INSTANCE,
         ImmutableSet.copyOf(Sequence.cast(hostFragments, String.class, "host_fragments")),
         parseToolchains(toolchains, thread),
+        useToolchainTransition,
         applyToGeneratingRules);
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/packages/AspectDefinition.java b/src/main/java/com/google/devtools/build/lib/packages/AspectDefinition.java
index 5aa17b3..a65d8ca 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/AspectDefinition.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/AspectDefinition.java
@@ -66,6 +66,7 @@
   private final RequiredProviders requiredProvidersForAspects;
   private final ImmutableMap<String, Attribute> attributes;
   private final ImmutableSet<Label> requiredToolchains;
+  private final boolean useToolchainTransition;
 
   /**
    * Which attributes aspect should propagate along:
@@ -91,6 +92,7 @@
       RequiredProviders requiredProvidersForAspects,
       ImmutableMap<String, Attribute> attributes,
       ImmutableSet<Label> requiredToolchains,
+      boolean useToolchainTransition,
       @Nullable ImmutableSet<String> restrictToAttributes,
       @Nullable ConfigurationFragmentPolicy configurationFragmentPolicy,
       boolean applyToFiles,
@@ -102,6 +104,7 @@
 
     this.attributes = attributes;
     this.requiredToolchains = requiredToolchains;
+    this.useToolchainTransition = useToolchainTransition;
     this.restrictToAttributes = restrictToAttributes;
     this.configurationFragmentPolicy = configurationFragmentPolicy;
     this.applyToFiles = applyToFiles;
@@ -130,6 +133,10 @@
     return requiredToolchains;
   }
 
+  public boolean useToolchainTransition() {
+    return useToolchainTransition;
+  }
+
   /**
    * Returns {@link RequiredProviders} that a configured target must have so that
    * this aspect can be applied to it.
@@ -249,6 +256,7 @@
     private boolean applyToFiles = false;
     private boolean applyToGeneratingRules = false;
     private final List<Label> requiredToolchains = new ArrayList<>();
+    private boolean useToolchainTransition = false;
 
     public Builder(AspectClass aspectClass) {
       this.aspectClass = aspectClass;
@@ -518,6 +526,12 @@
       this.requiredToolchains.addAll(requiredToolchains);
       return this;
     }
+
+    public Builder useToolchainTransition(boolean useToolchainTransition) {
+      this.useToolchainTransition = useToolchainTransition;
+      return this;
+    }
+
     /**
      * Builds the aspect definition.
      *
@@ -538,6 +552,7 @@
           requiredAspectProviders.build(),
           ImmutableMap.copyOf(attributes),
           ImmutableSet.copyOf(requiredToolchains),
+          useToolchainTransition,
           propagateAlongAttributes == null ? null : ImmutableSet.copyOf(propagateAlongAttributes),
           configurationFragmentPolicy.build(),
           applyToFiles,
diff --git a/src/main/java/com/google/devtools/build/lib/packages/StarlarkDefinedAspect.java b/src/main/java/com/google/devtools/build/lib/packages/StarlarkDefinedAspect.java
index 2e3df58..dba23a8 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/StarlarkDefinedAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/StarlarkDefinedAspect.java
@@ -43,6 +43,7 @@
   private final ConfigurationTransition hostTransition;
   private final ImmutableSet<String> hostFragments;
   private final ImmutableList<Label> requiredToolchains;
+  private final boolean useToolchainTransition;
   private final boolean applyToGeneratingRules;
 
   private StarlarkAspectClass aspectClass;
@@ -59,6 +60,7 @@
       ConfigurationTransition hostTransition,
       ImmutableSet<String> hostFragments,
       ImmutableList<Label> requiredToolchains,
+      boolean useToolchainTransition,
       boolean applyToGeneratingRules) {
     this.implementation = implementation;
     this.attributeAspects = attributeAspects;
@@ -70,6 +72,7 @@
     this.hostTransition = hostTransition;
     this.hostFragments = hostFragments;
     this.requiredToolchains = requiredToolchains;
+    this.useToolchainTransition = useToolchainTransition;
     this.applyToGeneratingRules = applyToGeneratingRules;
   }
 
@@ -88,6 +91,7 @@
       ConfigurationTransition hostTransition,
       ImmutableSet<String> hostFragments,
       ImmutableList<Label> requiredToolchains,
+      boolean useToolchainTransition,
       boolean applyToGeneratingRules,
       StarlarkAspectClass aspectClass) {
     this(
@@ -101,6 +105,7 @@
         hostTransition,
         hostFragments,
         requiredToolchains,
+        useToolchainTransition,
         applyToGeneratingRules);
     this.aspectClass = aspectClass;
   }
@@ -186,6 +191,7 @@
     builder.requiresConfigurationFragmentsByStarlarkBuiltinName(fragments);
     builder.requiresConfigurationFragmentsByStarlarkBuiltinName(hostTransition, hostFragments);
     builder.addRequiredToolchains(requiredToolchains);
+    builder.useToolchainTransition(useToolchainTransition);
     builder.applyToGeneratingRules(applyToGeneratingRules);
     return builder.build();
   }
@@ -234,6 +240,10 @@
     return requiredToolchains;
   }
 
+  public boolean useToolchainTransition() {
+    return useToolchainTransition;
+  }
+
   @Override
   public void attachToAttribute(Attribute.Builder<?> attrBuilder) throws EvalException {
     if (!isExported()) {
@@ -262,6 +272,7 @@
         && Objects.equals(hostTransition, that.hostTransition)
         && Objects.equals(hostFragments, that.hostFragments)
         && Objects.equals(requiredToolchains, that.requiredToolchains)
+        && Objects.equals(useToolchainTransition, that.useToolchainTransition)
         && Objects.equals(aspectClass, that.aspectClass);
   }
 
@@ -278,6 +289,7 @@
         hostTransition,
         hostFragments,
         requiredToolchains,
+        useToolchainTransition,
         aspectClass);
   }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java
index 200b703..e4bf47b 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java
@@ -30,6 +30,7 @@
 import com.google.devtools.build.lib.analysis.DependencyKind;
 import com.google.devtools.build.lib.analysis.DuplicateException;
 import com.google.devtools.build.lib.analysis.InconsistentAspectOrderException;
+import com.google.devtools.build.lib.analysis.PlatformOptions;
 import com.google.devtools.build.lib.analysis.ResolvedToolchainContext;
 import com.google.devtools.build.lib.analysis.RuleContext.InvalidExecGroupException;
 import com.google.devtools.build.lib.analysis.TargetAndConfiguration;
@@ -48,6 +49,7 @@
 import com.google.devtools.build.lib.events.Event;
 import com.google.devtools.build.lib.events.StoredEventHandler;
 import com.google.devtools.build.lib.packages.Aspect;
+import com.google.devtools.build.lib.packages.AspectDefinition;
 import com.google.devtools.build.lib.packages.AspectDescriptor;
 import com.google.devtools.build.lib.packages.BuildFileContainsErrorsException;
 import com.google.devtools.build.lib.packages.NativeAspectClass;
@@ -424,7 +426,7 @@
                     : ToolchainCollection.builder()
                         .addDefaultContext(unloadedToolchainContext)
                         .build(),
-                /* useToolchainTransition= */ false,
+                shouldUseToolchainTransition(configuration, aspect.getDefinition()),
                 ruleClassProvider,
                 view.getHostConfiguration(originalTargetAndAspectConfiguration.getConfiguration()),
                 transitivePackagesForPackageRootResolution,
@@ -495,15 +497,33 @@
   }
 
   /**
-   * Merges aspects defined by {@code aspectKeys} into the {@code target} using
-   * previously computed {@code values}.
+   * Returns whether or not to use the new toolchain transition. Checks the global incompatible
+   * change flag and the aspect's toolchain transition readiness attribute.
+   */
+  // TODO(#10523): Remove this when the migration period for toolchain transitions has ended.
+  private static boolean shouldUseToolchainTransition(
+      @Nullable BuildConfiguration configuration, AspectDefinition definition) {
+    // Check whether the global incompatible change flag is set.
+    if (configuration != null) {
+      PlatformOptions platformOptions = configuration.getOptions().get(PlatformOptions.class);
+      if (platformOptions != null && platformOptions.overrideToolchainTransition) {
+        return true;
+      }
+    }
+
+    // Check the aspect definition to see if it is ready.
+    return definition.useToolchainTransition();
+  }
+
+  /**
+   * Merges aspects defined by {@code aspectKeys} into the {@code target} using previously computed
+   * {@code values}.
    *
    * @return A {@link ConfiguredTarget} that is a result of a merge.
    * @throws DuplicateException if there is a duplicate provider provided by aspects.
    */
-  private ConfiguredTarget getBaseTarget(ConfiguredTarget target,
-      ImmutableList<AspectKey> aspectKeys,
-      Map<SkyKey, SkyValue> values)
+  private static ConfiguredTarget getBaseTarget(
+      ConfiguredTarget target, ImmutableList<AspectKey> aspectKeys, Map<SkyKey, SkyValue> values)
       throws DuplicateException {
     ArrayList<ConfiguredAspect> aspectValues = new ArrayList<>();
     for (AspectKey aspectKey : aspectKeys) {
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/StarlarkRuleFunctionsApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/StarlarkRuleFunctionsApi.java
index 28fca45..f29e965 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/StarlarkRuleFunctionsApi.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/StarlarkRuleFunctionsApi.java
@@ -484,6 +484,15 @@
                     + "found by checking the current platform, and provided to the rule "
                     + "implementation via <code>ctx.toolchain</code>."),
         @Param(
+            name = "incompatible_use_toolchain_transition",
+            type = Boolean.class,
+            defaultValue = "False",
+            named = true,
+            doc =
+                "If set, this aspect will use the toolchain transition for toolchain dependencies."
+                    + " This is ignored if the --incompatible_use_toolchain_transition flag is"
+                    + " set."),
+        @Param(
             name = "doc",
             type = String.class,
             named = true,
@@ -518,6 +527,7 @@
       Sequence<?> fragments,
       Sequence<?> hostFragments,
       Sequence<?> toolchains,
+      boolean useToolchainTransition,
       String doc,
       Boolean applyToGeneratingRules,
       StarlarkThread thread)
diff --git a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeStarlarkRuleFunctionsApi.java b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeStarlarkRuleFunctionsApi.java
index ef3c0ec..51e8eb0 100644
--- a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeStarlarkRuleFunctionsApi.java
+++ b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeStarlarkRuleFunctionsApi.java
@@ -185,6 +185,7 @@
       Sequence<?> fragments,
       Sequence<?> hostFragments,
       Sequence<?> toolchains,
+      boolean useToolchainTransition,
       String doc,
       Boolean applyToFiles,
       StarlarkThread thread)