Expose `config.no_config` to Starlark.

This allows Starlark rules to create data-only non-configured dependencies, to reduce fan-out across configurations.

RELNOTES: A no-config transition is now available as `config.no_config()`.
PiperOrigin-RevId: 689926488
Change-Id: I37625596642a825c745276db29309ec11a2ac998
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/BUILD b/src/main/java/com/google/devtools/build/lib/analysis/BUILD
index b6bd784..76d8d05 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/analysis/BUILD
@@ -2221,6 +2221,7 @@
         ":config/transitions/transition_factory",
         "//src/main/java/com/google/devtools/build/lib/events",
         "//src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec:serialization-constant",
+        "//src/main/java/com/google/devtools/build/lib/starlarkbuildapi/config:configuration_transition_api",
         "//third_party:auto_value",
         "//third_party:guava",
     ],
@@ -2642,6 +2643,7 @@
     srcs = ["starlark/StarlarkConfig.java"],
     deps = [
         ":config/execution_transition_factory",
+        ":config/transitions/no_config_transition",
         ":config/transitions/no_transition",
         "//src/main/java/com/google/devtools/build/lib/packages",
         "//src/main/java/com/google/devtools/build/lib/starlarkbuildapi/config",
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/transitions/NoConfigTransition.java b/src/main/java/com/google/devtools/build/lib/analysis/config/transitions/NoConfigTransition.java
index ea645bb..b3927f0 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/config/transitions/NoConfigTransition.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/config/transitions/NoConfigTransition.java
@@ -22,6 +22,7 @@
 import com.google.devtools.build.lib.analysis.config.FragmentOptions;
 import com.google.devtools.build.lib.events.EventHandler;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.SerializationConstant;
+import com.google.devtools.build.lib.starlarkbuildapi.config.ConfigurationTransitionApi;
 
 /**
  * Transitions to a stable, empty configuration for rules that don't rely on configuration.
@@ -46,6 +47,15 @@
   private static final TransitionFactory<? extends TransitionFactory.Data> FACTORY_INSTANCE =
       new AutoValue_NoConfigTransition_Factory<>();
 
+  /**
+   * Returns {@code true} if the given {@link TransitionFactory} is an instance of the no
+   * transition.
+   */
+  public static <T extends TransitionFactory.Data> boolean isInstance(
+      TransitionFactory<T> instance) {
+    return instance instanceof Factory;
+  }
+
   private NoConfigTransition() {}
 
   @Override
@@ -67,7 +77,8 @@
 
   /** A {@link TransitionFactory} implementation that generates the transition. */
   @AutoValue
-  abstract static class Factory<T extends TransitionFactory.Data> implements TransitionFactory<T> {
+  abstract static class Factory<T extends TransitionFactory.Data>
+      implements TransitionFactory<T>, ConfigurationTransitionApi {
     @Override
     public PatchTransition create(T unused) {
       return INSTANCE;
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/starlark/StarlarkConfig.java b/src/main/java/com/google/devtools/build/lib/analysis/starlark/StarlarkConfig.java
index 0cb8297..da73017 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/starlark/StarlarkConfig.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/starlark/StarlarkConfig.java
@@ -20,6 +20,7 @@
 import static com.google.devtools.build.lib.packages.Types.STRING_LIST;
 
 import com.google.devtools.build.lib.analysis.config.ExecutionTransitionFactory;
+import com.google.devtools.build.lib.analysis.config.transitions.NoConfigTransition;
 import com.google.devtools.build.lib.analysis.config.transitions.NoTransition;
 import com.google.devtools.build.lib.packages.BuildSetting;
 import com.google.devtools.build.lib.starlarkbuildapi.config.ConfigurationTransitionApi;
@@ -67,6 +68,11 @@
   }
 
   @Override
+  public ConfigurationTransitionApi none() {
+    return (ConfigurationTransitionApi) NoConfigTransition.getFactory();
+  }
+
+  @Override
   public void repr(Printer printer) {
     printer.append("<config>");
   }
diff --git a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/config/StarlarkConfigApi.java b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/config/StarlarkConfigApi.java
index 6975234..2117740 100644
--- a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/config/StarlarkConfigApi.java
+++ b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/config/StarlarkConfigApi.java
@@ -166,6 +166,14 @@
               + " Equivalent to <code>cfg = \"target\"</code> in <code>attr.label()</code>.")
   ConfigurationTransitionApi target();
 
+  @StarlarkMethod(
+      name = "none",
+      doc =
+          "Creates a no_config transition. This is a transition that unsets all flags, intended for"
+              + " the case where a dependency is data-only and contains no code that needs to be"
+              + " built, but should only be analyzed once.")
+  ConfigurationTransitionApi none();
+
   /** The api for exec transitions. */
   @StarlarkBuiltin(
       name = "ExecTransitionFactory",
diff --git a/src/test/java/com/google/devtools/build/lib/starlark/BUILD b/src/test/java/com/google/devtools/build/lib/starlark/BUILD
index 03d5145..bd2c7c7 100644
--- a/src/test/java/com/google/devtools/build/lib/starlark/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/starlark/BUILD
@@ -129,6 +129,7 @@
         "//src/main/java/com/google/devtools/build/lib/analysis:analysis_cluster",
         "//src/main/java/com/google/devtools/build/lib/analysis:config/build_configuration",
         "//src/main/java/com/google/devtools/build/lib/analysis:config/toolchain_type_requirement",
+        "//src/main/java/com/google/devtools/build/lib/analysis:config/transitions/no_config_transition",
         "//src/main/java/com/google/devtools/build/lib/analysis:config/transitions/no_transition",
         "//src/main/java/com/google/devtools/build/lib/analysis:configured_target",
         "//src/main/java/com/google/devtools/build/lib/analysis:starlark/starlark_config",
diff --git a/src/test/java/com/google/devtools/build/lib/starlark/StarlarkRuleClassFunctionsTest.java b/src/test/java/com/google/devtools/build/lib/starlark/StarlarkRuleClassFunctionsTest.java
index 1ecdefc..c538bbf 100644
--- a/src/test/java/com/google/devtools/build/lib/starlark/StarlarkRuleClassFunctionsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/starlark/StarlarkRuleClassFunctionsTest.java
@@ -33,6 +33,7 @@
 import com.google.devtools.build.lib.analysis.RuleContext;
 import com.google.devtools.build.lib.analysis.config.BuildConfigurationValue;
 import com.google.devtools.build.lib.analysis.config.ToolchainTypeRequirement;
+import com.google.devtools.build.lib.analysis.config.transitions.NoConfigTransition;
 import com.google.devtools.build.lib.analysis.config.transitions.NoTransition;
 import com.google.devtools.build.lib.analysis.starlark.StarlarkAttrModule;
 import com.google.devtools.build.lib.analysis.starlark.StarlarkConfig;
@@ -1377,6 +1378,12 @@
     assertThat(NoTransition.isInstance(attr.getTransitionFactory())).isTrue();
   }
 
+  @Test
+  public void testAttrCfgNone() throws Exception {
+    Attribute attr = buildAttribute("a1", "attr.label(cfg = config.none(), allow_files = True)");
+    assertThat(NoConfigTransition.isInstance(attr.getTransitionFactory())).isTrue();
+  }
+
   private void writeRuleCfgTestRule(String cfg) throws Exception {
     scratch.file(
         "rule_testing/rule.bzl",