Add `required_providers` attribute to Starlark defined aspects.

`required_providers` attribute allows the aspect to limit its propagation to only the targets whose rules advertise the required providers. It accepts a list of either providers or providers lists. To make some rule targets visible to an aspect, the rule must advertise all providers from at least one of the lists specified in the aspect `required_providers`.

This CL also adds incompatible flag `incompatible_top_level_aspects_require_providers` which when set allows the top level aspects to only run on top level targets that advertise its required providers. It is needed to avoid breaking existing usages on command line aspects on targets not advertising its required providers.

PiperOrigin-RevId: 373738497
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 44ab8a7..aead10e 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
@@ -58,12 +58,14 @@
 import com.google.devtools.build.lib.packages.NoSuchThingException;
 import com.google.devtools.build.lib.packages.OutputFile;
 import com.google.devtools.build.lib.packages.Package;
+import com.google.devtools.build.lib.packages.Rule;
 import com.google.devtools.build.lib.packages.RuleClassProvider;
 import com.google.devtools.build.lib.packages.StarlarkAspect;
 import com.google.devtools.build.lib.packages.StarlarkAspectClass;
 import com.google.devtools.build.lib.packages.StarlarkDefinedAspect;
 import com.google.devtools.build.lib.packages.Target;
 import com.google.devtools.build.lib.packages.Type.ConversionException;
+import com.google.devtools.build.lib.packages.semantics.BuildLanguageOptions;
 import com.google.devtools.build.lib.profiler.memory.CurrentRuleTracker;
 import com.google.devtools.build.lib.skyframe.AspectValueKey.AspectKey;
 import com.google.devtools.build.lib.skyframe.BzlLoadFunction.BzlLoadFailedException;
@@ -78,6 +80,7 @@
 import java.util.HashMap;
 import java.util.Map;
 import javax.annotation.Nullable;
+import net.starlark.java.eval.StarlarkSemantics;
 
 /**
  * The Skyframe function that generates aspects.
@@ -314,6 +317,34 @@
           baseConfiguredTargetValue.getConfiguredTarget());
     }
 
+    // If the incompatible flag is set, the top-level aspect should not be applied on top-level
+    // targets whose rules do not advertise the aspect's required providers. The aspect should not
+    // also propagate to these targets dependencies.
+    StarlarkSemantics starlarkSemantics = PrecomputedValue.STARLARK_SEMANTICS.get(env);
+    if (starlarkSemantics == null) {
+      return null;
+    }
+    boolean checkRuleAdvertisedProviders =
+        starlarkSemantics.getBool(
+            BuildLanguageOptions.INCOMPATIBLE_TOP_LEVEL_ASPECTS_REQUIRE_PROVIDERS);
+    if (checkRuleAdvertisedProviders) {
+      Target target = associatedConfiguredTargetAndData.getTarget();
+      if (target instanceof Rule) {
+        if (!aspect
+            .getDefinition()
+            .getRequiredProviders()
+            .isSatisfiedBy(((Rule) target).getRuleClassObject().getAdvertisedProviders())) {
+          return new AspectValue(
+              key,
+              aspect,
+              target.getLocation(),
+              ConfiguredAspect.forNonapplicableTarget(),
+              /*transitivePackagesForPackageRootResolution=*/ NestedSetBuilder
+                  .<Package>stableOrder()
+                  .build());
+        }
+      }
+    }
 
     ImmutableList.Builder<Aspect> aspectPathBuilder = ImmutableList.builder();