Replace Attribute.SplitTransition with config.transitions.SplitTransition.

PiperOrigin-RevId: 179948322
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/DependencyResolver.java b/src/main/java/com/google/devtools/build/lib/analysis/DependencyResolver.java
index 7b9d60d..d268e7d 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/DependencyResolver.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/DependencyResolver.java
@@ -27,6 +27,7 @@
 import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
 import com.google.devtools.build.lib.analysis.config.PatchTransition;
 import com.google.devtools.build.lib.analysis.config.TransitionResolver;
+import com.google.devtools.build.lib.analysis.config.transitions.SplitTransition;
 import com.google.devtools.build.lib.analysis.config.transitions.Transition;
 import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
@@ -422,7 +423,7 @@
    * transition does not apply.
    *
    * <p>Even though the attribute may have a split, splits don't have to apply in every
-   * configuration (see {@link Attribute.SplitTransition#split}).
+   * configuration (see {@link SplitTransition#split}).
    */
   private static Collection<BuildOptions> getSplitOptions(ConfiguredAttributeMapper attributeMap,
       Attribute attribute,
@@ -430,9 +431,7 @@
     if (!attribute.hasSplitConfigurationTransition()) {
       return ImmutableList.<BuildOptions>of();
     }
-    @SuppressWarnings("unchecked") // Attribute.java doesn't have the BuildOptions symbol.
-    Attribute.SplitTransition<BuildOptions> transition =
-        (Attribute.SplitTransition<BuildOptions>) attribute.getSplitTransition(attributeMap);
+    SplitTransition transition = attribute.getSplitTransition(attributeMap);
     return transition.split(ruleConfig.getOptions());
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
index 6abf491..ce2569a 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
@@ -47,6 +47,7 @@
 import com.google.devtools.build.lib.analysis.config.ConfigMatchingProvider;
 import com.google.devtools.build.lib.analysis.config.FragmentCollection;
 import com.google.devtools.build.lib.analysis.config.PatchTransition;
+import com.google.devtools.build.lib.analysis.config.transitions.SplitTransition;
 import com.google.devtools.build.lib.analysis.config.transitions.Transition;
 import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode;
 import com.google.devtools.build.lib.analysis.fileset.FilesetProvider;
@@ -65,7 +66,6 @@
 import com.google.devtools.build.lib.packages.AspectDescriptor;
 import com.google.devtools.build.lib.packages.Attribute;
 import com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition;
-import com.google.devtools.build.lib.packages.Attribute.SplitTransition;
 import com.google.devtools.build.lib.packages.AttributeMap;
 import com.google.devtools.build.lib.packages.BuildType;
 import com.google.devtools.build.lib.packages.ConfigurationFragmentPolicy;
@@ -768,10 +768,8 @@
     checkAttribute(attributeName, Mode.SPLIT);
 
     Attribute attributeDefinition = attributes().getAttributeDefinition(attributeName);
-    @SuppressWarnings("unchecked") // Attribute.java doesn't have the BuildOptions symbol.
-    SplitTransition<BuildOptions> transition =
-        (SplitTransition<BuildOptions>) attributeDefinition.getSplitTransition(
-            ConfiguredAttributeMapper.of(rule, configConditions));
+    SplitTransition transition = attributeDefinition.getSplitTransition(
+        ConfiguredAttributeMapper.of(rule, configConditions));
     List<ConfiguredTarget> deps = targetMap.get(attributeName);
 
     List<BuildOptions> splitOptions = transition.split(getConfiguration().getOptions());
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/ComposingSplitTransition.java b/src/main/java/com/google/devtools/build/lib/analysis/config/ComposingSplitTransition.java
index b984ee4..41cb44d 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/config/ComposingSplitTransition.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/config/ComposingSplitTransition.java
@@ -16,9 +16,9 @@
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.lib.analysis.config.transitions.SplitTransition;
 import com.google.devtools.build.lib.analysis.config.transitions.Transition;
 import com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition;
-import com.google.devtools.build.lib.packages.Attribute.SplitTransition;
 import java.util.List;
 
 /**
@@ -35,7 +35,7 @@
  * combination thereof. We implement this class as a {@link SplitTransition} since that abstraction
  * captures all possible combinations.
  */
-public class ComposingSplitTransition implements SplitTransition<BuildOptions> {
+public class ComposingSplitTransition implements SplitTransition {
   private Transition transition1;
   private Transition transition2;
 
@@ -63,7 +63,7 @@
    */
   private Transition verifySupported(Transition transition) {
     Preconditions.checkArgument(transition instanceof PatchTransition
-        || transition instanceof SplitTransition<?>);
+        || transition instanceof SplitTransition);
     return transition;
   }
 
@@ -77,7 +77,7 @@
     } else if (transition instanceof PatchTransition) {
       return ImmutableList.<BuildOptions>of(((PatchTransition) transition).apply(fromOptions));
     } else if (transition instanceof SplitTransition) {
-      SplitTransition split = (SplitTransition<BuildOptions>) transition;
+      SplitTransition split = (SplitTransition) transition;
       List<BuildOptions> splitOptions = split.split(fromOptions);
       if (splitOptions.isEmpty()) {
         return ImmutableList.<BuildOptions>of(fromOptions);
@@ -91,4 +91,3 @@
     }
   }
 }
-
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/ConfigurationResolver.java b/src/main/java/com/google/devtools/build/lib/analysis/config/ConfigurationResolver.java
index 9a16f0b..d09219e 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/config/ConfigurationResolver.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/config/ConfigurationResolver.java
@@ -26,6 +26,7 @@
 import com.google.common.collect.Sets;
 import com.google.devtools.build.lib.analysis.Dependency;
 import com.google.devtools.build.lib.analysis.TargetAndConfiguration;
+import com.google.devtools.build.lib.analysis.config.transitions.SplitTransition;
 import com.google.devtools.build.lib.analysis.config.transitions.Transition;
 import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.concurrent.ThreadSafety;
@@ -417,10 +418,8 @@
     } else if (transition instanceof PatchTransition) {
       // TODO(bazel-team): safety-check that this never mutates fromOptions.
       result = ImmutableList.<BuildOptions>of(((PatchTransition) transition).apply(fromOptions));
-    } else if (transition instanceof Attribute.SplitTransition) {
-      @SuppressWarnings("unchecked") // Attribute.java doesn't have the BuildOptions symbol.
-      List<BuildOptions> toOptions =
-          ((Attribute.SplitTransition<BuildOptions>) transition).split(fromOptions);
+    } else if (transition instanceof SplitTransition) {
+      List<BuildOptions> toOptions = ((SplitTransition) transition).split(fromOptions);
       if (toOptions.isEmpty()) {
         // When the split returns an empty list, it's signaling it doesn't apply to this instance.
         // So return the original options.
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/DynamicTransitionMapper.java b/src/main/java/com/google/devtools/build/lib/analysis/config/DynamicTransitionMapper.java
index 0ccb19a..4c49201 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/config/DynamicTransitionMapper.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/config/DynamicTransitionMapper.java
@@ -14,6 +14,7 @@
 package com.google.devtools.build.lib.analysis.config;
 
 import com.google.common.collect.ImmutableMap;
+import com.google.devtools.build.lib.analysis.config.transitions.SplitTransition;
 import com.google.devtools.build.lib.analysis.config.transitions.Transition;
 import com.google.devtools.build.lib.packages.Attribute;
 import com.google.devtools.build.lib.packages.RuleClass;
@@ -72,7 +73,7 @@
    */
   public Transition map(Transition fromTransition) {
     if (fromTransition instanceof PatchTransition
-        || fromTransition instanceof Attribute.SplitTransition<?>
+        || fromTransition instanceof SplitTransition
         || fromTransition == null) {
       return fromTransition;
     }
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/TransitionResolver.java b/src/main/java/com/google/devtools/build/lib/analysis/config/TransitionResolver.java
index b84c5db..27c3548 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/config/TransitionResolver.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/config/TransitionResolver.java
@@ -17,10 +17,10 @@
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
 import com.google.devtools.build.lib.analysis.TargetAndConfiguration;
+import com.google.devtools.build.lib.analysis.config.transitions.SplitTransition;
 import com.google.devtools.build.lib.analysis.config.transitions.Transition;
 import com.google.devtools.build.lib.packages.Attribute;
 import com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition;
-import com.google.devtools.build.lib.packages.Attribute.SplitTransition;
 import com.google.devtools.build.lib.packages.ConfiguredAttributeMapper;
 import com.google.devtools.build.lib.packages.InputFile;
 import com.google.devtools.build.lib.packages.PackageGroup;
@@ -112,8 +112,7 @@
     // TODO(gregce): make the below transitions composable (i.e. take away the "else" clauses).
     // The "else" is a legacy restriction from static configurations.
     if (attribute.hasSplitConfigurationTransition()) {
-      currentTransition = split(currentTransition,
-          (SplitTransition<BuildOptions>) attribute.getSplitTransition(attributeMap));
+      currentTransition = split(currentTransition, attribute.getSplitTransition(attributeMap));
     } else {
       // III. Attributes determine configurations. The configuration of a prerequisite is determined
       // by the attribute.
@@ -195,8 +194,7 @@
   /**
    * Applies the given split and composes it after an existing transition.
    */
-  private static Transition split(Transition currentTransition,
-      SplitTransition<BuildOptions> split) {
+  private static Transition split(Transition currentTransition, SplitTransition split) {
     Preconditions.checkState(currentTransition != Attribute.ConfigurationTransition.NULL,
         "cannot apply splits after null transitions (null transitions are expected to be final)");
     Preconditions.checkState(currentTransition != HostTransition.INSTANCE,
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/transitions/SplitTransition.java b/src/main/java/com/google/devtools/build/lib/analysis/config/transitions/SplitTransition.java
index 9dc4eee..dd1cea1 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/config/transitions/SplitTransition.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/config/transitions/SplitTransition.java
@@ -24,6 +24,7 @@
  * handle this.
  */
 @ThreadSafety.Immutable
+@FunctionalInterface
 public interface SplitTransition extends Transition {
   /**
    * Return the list of {@code BuildOptions} after splitting; empty if not applicable.
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttr.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttr.java
index b04a855..78e393f 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttr.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttr.java
@@ -20,13 +20,13 @@
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 import com.google.devtools.build.lib.analysis.config.HostTransition;
+import com.google.devtools.build.lib.analysis.config.transitions.SplitTransition;
 import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.events.Location;
 import com.google.devtools.build.lib.packages.Attribute;
 import com.google.devtools.build.lib.packages.Attribute.AllowedValueSet;
 import com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition;
 import com.google.devtools.build.lib.packages.Attribute.SkylarkComputedDefaultTemplate;
-import com.google.devtools.build.lib.packages.Attribute.SplitTransition;
 import com.google.devtools.build.lib.packages.Attribute.SplitTransitionProvider;
 import com.google.devtools.build.lib.packages.AttributeValueSource;
 import com.google.devtools.build.lib.packages.BuildType;
@@ -298,8 +298,8 @@
         builder.cfg(ConfigurationTransition.DATA);
       } else if (trans.equals("host")) {
         builder.cfg(HostTransition.INSTANCE);
-      } else if (trans instanceof SplitTransition<?>) {
-        builder.cfg((SplitTransition<?>) trans);
+      } else if (trans instanceof SplitTransition) {
+        builder.cfg((SplitTransition) trans);
       } else if (trans instanceof SplitTransitionProvider) {
         builder.cfg((SplitTransitionProvider) trans);
       } else if (!trans.equals("target")) {
diff --git a/src/main/java/com/google/devtools/build/lib/packages/Attribute.java b/src/main/java/com/google/devtools/build/lib/packages/Attribute.java
index b736613..38fdda7 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/Attribute.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/Attribute.java
@@ -29,8 +29,8 @@
 import com.google.common.collect.Ordering;
 import com.google.common.collect.Sets;
 import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
+import com.google.devtools.build.lib.analysis.config.transitions.SplitTransition;
 import com.google.devtools.build.lib.analysis.config.transitions.Transition;
-import com.google.devtools.build.lib.concurrent.ThreadSafety;
 import com.google.devtools.build.lib.events.EventHandler;
 import com.google.devtools.build.lib.events.Location;
 import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassNamePredicate;
@@ -148,23 +148,6 @@
   }
 
   /**
-   * A configuration split transition; this should be used to transition to multiple configurations
-   * simultaneously. Note that the corresponding rule implementations must have special support to
-   * handle this.
-   *
-   * <p>{@code T} must always be {@code BuildOptions}, but it can't be defined that way because
-   * the symbol isn't available here.
-   */
-  // TODO(bazel-team): Serializability constraints?
-  @ThreadSafety.Immutable
-  public interface SplitTransition<T> extends Transition {
-    /**
-     * Return the list of {@code BuildOptions} after splitting; empty if not applicable.
-     */
-    List<T> split(T buildOptions);
-  }
-
-  /**
    * Declaration how the configuration should change when following a label or label list attribute.
    *
    * <p>Do not add to this. Use {@link
@@ -316,7 +299,7 @@
     /**
      * Returns the {@link SplitTransition} given the attribute mapper of the originating rule.
      */
-    SplitTransition<?> apply(AttributeMap attributeMap);
+    SplitTransition apply(AttributeMap attributeMap);
   }
 
   /**
@@ -325,14 +308,14 @@
    */
   private static class BasicSplitTransitionProvider implements SplitTransitionProvider {
 
-    private final SplitTransition<?> splitTransition;
+    private final SplitTransition splitTransition;
 
-    BasicSplitTransitionProvider(SplitTransition<?> splitTransition) {
+    BasicSplitTransitionProvider(SplitTransition splitTransition) {
       this.splitTransition = splitTransition;
     }
 
     @Override
-    public SplitTransition<?> apply(AttributeMap attributeMap) {
+    public SplitTransition apply(AttributeMap attributeMap) {
       return splitTransition;
     }
   }
@@ -533,7 +516,7 @@
      * Defines the configuration transition for this attribute. Defaults to
      * {@code NONE}.
      */
-    public Builder<TYPE> cfg(SplitTransition<?> configTransition) {
+    public Builder<TYPE> cfg(SplitTransition configTransition) {
       return cfg(new BasicSplitTransitionProvider(Preconditions.checkNotNull(configTransition)));
     }
 
@@ -547,7 +530,7 @@
       Preconditions.checkArgument(configTransition != ConfigurationTransition.SPLIT,
           "split transitions must be defined using the SplitTransition object");
       if (configTransition instanceof SplitTransition) {
-        return cfg((SplitTransition<?>) configTransition);
+        return cfg((SplitTransition) configTransition);
       } else {
         this.configTransition = configTransition;
         return this;
@@ -1971,7 +1954,7 @@
    * @return a SplitTransition<BuildOptions> object
    * @throws IllegalStateException if {@link #hasSplitConfigurationTransition} is not true
    */
-  public SplitTransition<?> getSplitTransition(AttributeMap attributeMapper) {
+  public SplitTransition getSplitTransition(AttributeMap attributeMapper) {
     Preconditions.checkState(hasSplitConfigurationTransition());
     return splitTransitionProvider.apply(attributeMapper);
   }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java
index 6a8a0a9..c08da7a 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java
@@ -37,13 +37,13 @@
 import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
 import com.google.devtools.build.lib.analysis.config.BuildOptions;
 import com.google.devtools.build.lib.analysis.config.HostTransition;
+import com.google.devtools.build.lib.analysis.config.transitions.SplitTransition;
 import com.google.devtools.build.lib.analysis.config.transitions.Transition;
 import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.events.EventHandler;
 import com.google.devtools.build.lib.packages.Attribute;
 import com.google.devtools.build.lib.packages.Attribute.AllowedValueSet;
 import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault;
-import com.google.devtools.build.lib.packages.Attribute.SplitTransition;
 import com.google.devtools.build.lib.packages.AttributeMap;
 import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.SafeImplicitOutputsFunction;
 import com.google.devtools.build.lib.packages.Rule;
@@ -206,11 +206,9 @@
         (rule, attributes, configuration) -> configuration.getSdk());
   }
 
-  public static final SplitTransition<BuildOptions> ANDROID_SPLIT_TRANSITION =
-      new AndroidSplitTransition();
+  public static final SplitTransition ANDROID_SPLIT_TRANSITION = new AndroidSplitTransition();
 
-  private static final class AndroidSplitTransition
-      implements SplitTransition<BuildOptions>, SkylarkValue {
+  private static final class AndroidSplitTransition implements SplitTransition, SkylarkValue {
     private static void setCrosstoolToAndroid(BuildOptions output, BuildOptions input) {
       AndroidConfiguration.Options inputAndroidOptions =
           input.get(AndroidConfiguration.Options.class);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSkylarkCommon.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSkylarkCommon.java
index fe8a9dd..be66ad6 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSkylarkCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSkylarkCommon.java
@@ -14,8 +14,7 @@
 package com.google.devtools.build.lib.rules.android;
 
 import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.analysis.config.BuildOptions;
-import com.google.devtools.build.lib.packages.Attribute.SplitTransition;
+import com.google.devtools.build.lib.analysis.config.transitions.SplitTransition;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
 import com.google.devtools.build.lib.vfs.PathFragment;
@@ -47,7 +46,7 @@
             + "the --fat_apk_cpu and --android_crosstool_top flags.",
     structField = true
   )
-  public SplitTransition<BuildOptions> getAndroidSplitTransition() {
+  public SplitTransition getAndroidSplitTransition() {
     return AndroidRuleClasses.ANDROID_SPLIT_TRANSITION;
   }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/MultiArchSplitTransitionProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/MultiArchSplitTransitionProvider.java
index 394c220..8284011 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/MultiArchSplitTransitionProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/MultiArchSplitTransitionProvider.java
@@ -24,7 +24,7 @@
 import com.google.devtools.build.lib.analysis.RuleContext;
 import com.google.devtools.build.lib.analysis.config.BuildConfiguration.Options;
 import com.google.devtools.build.lib.analysis.config.BuildOptions;
-import com.google.devtools.build.lib.packages.Attribute.SplitTransition;
+import com.google.devtools.build.lib.analysis.config.transitions.SplitTransition;
 import com.google.devtools.build.lib.packages.Attribute.SplitTransitionProvider;
 import com.google.devtools.build.lib.packages.AttributeMap;
 import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
@@ -125,7 +125,7 @@
   }
 
   @Override
-  public SplitTransition<?> apply(AttributeMap attrMapper) {
+  public SplitTransition apply(AttributeMap attrMapper) {
     String platformTypeString = attrMapper.get(PlatformRule.PLATFORM_TYPE_ATTR_NAME, STRING);
     String minimumOsVersionString = attrMapper.get(PlatformRule.MINIMUM_OS_VERSION, STRING);
     PlatformType platformType;
@@ -164,7 +164,7 @@
    * platform-specific cpu flag for a particular platform type (for example, --watchos_cpus
    * for watchos platform type).
    */
-  protected static class AppleBinaryTransition implements SplitTransition<BuildOptions> {
+  protected static class AppleBinaryTransition implements SplitTransition {
 
     private final PlatformType platformType;
     // TODO(b/37096178): This should be a mandatory attribute.