// Copyright 2015 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.build.lib.analysis.util;

import static com.google.devtools.build.lib.packages.Attribute.attr;
import static com.google.devtools.build.lib.packages.BuildType.LABEL;
import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST;
import static com.google.devtools.build.lib.packages.Type.STRING;
import static com.google.devtools.build.lib.packages.Type.STRING_LIST;

import com.google.auto.value.AutoValue;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException;
import com.google.devtools.build.lib.analysis.ConfiguredAspect;
import com.google.devtools.build.lib.analysis.ConfiguredAspectFactory;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.PackageSpecificationProvider;
import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder;
import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.Runfiles;
import com.google.devtools.build.lib.analysis.RunfilesProvider;
import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.packages.AspectDefinition;
import com.google.devtools.build.lib.packages.AspectParameters;
import com.google.devtools.build.lib.packages.Attribute.AllowedValueSet;
import com.google.devtools.build.lib.packages.Attribute.ComputedDefault;
import com.google.devtools.build.lib.packages.Attribute.LabelListLateBoundDefault;
import com.google.devtools.build.lib.packages.AttributeMap;
import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.NativeAspectClass;
import com.google.devtools.build.lib.packages.RawAttributeMapper;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.StarlarkNativeAspect;
import com.google.devtools.build.lib.packages.StarlarkProviderIdentifier;
import com.google.devtools.build.lib.packages.Type;
import com.google.devtools.build.lib.rules.java.JavaConfiguration;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetAndData;
import com.google.devtools.build.lib.util.FileTypeSet;
import java.io.Serializable;
import java.util.List;
import javax.annotation.Nullable;

/**
 * Various rule and aspect classes that aid in testing the aspect machinery.
 *
 * <p>These are mostly used in {@link com.google.devtools.build.lib.analysis.DependencyResolverTest}
 * and {@link com.google.devtools.build.lib.analysis.AspectTest}.
 */
public class TestAspects {

  /**
   * A transitive info provider for collecting aspects in the transitive closure. Created by
   * aspects.
   */
  @Immutable
  public static final class AspectInfo implements TransitiveInfoProvider {
    private final NestedSet<String> data;

    public AspectInfo(NestedSet<String> data) {
      this.data = data;
    }

    public NestedSet<String> getData() {
      return data;
    }
  }

  /**
   * A transitive info provider used as sentinel. Created by aspects.
   */
  @Immutable
  public static final class FooProvider implements TransitiveInfoProvider {
  }

  /**
   * A transitive info provider used as sentinel. Created by aspects.
   */
  @Immutable
  public static final class BarProvider implements TransitiveInfoProvider {
  }

  /**
   * A transitive info provider for collecting aspects in the transitive closure. Created by
   * rules.
   */
  @Immutable
  public static final class RuleInfo implements TransitiveInfoProvider {
    private final NestedSet<String> data;

    public RuleInfo(NestedSet<String> data) {
      this.data = data;
    }

    public NestedSet<String> getData() {
      return data;
    }
  }

  /**
   * A very simple provider used in tests that check whether the logic that attaches aspects
   * depending on whether a configured target has a provider works or not.
   */
  @Immutable
  public static final class RequiredProvider implements TransitiveInfoProvider {
  }

  /**
   * Another very simple provider used in tests that check whether the logic that attaches aspects
   * depending on whether a configured target has a provider works or not.
   */
  @Immutable
  public static final class RequiredProvider2 implements TransitiveInfoProvider {
  }

  private static NestedSet<String> collectAspectData(String me, RuleContext ruleContext) {
    NestedSetBuilder<String> result = new NestedSetBuilder<>(Order.STABLE_ORDER);
    result.add(me);

    Iterable<String> attributeNames = ruleContext.attributes().getAttributeNames();
    for (String attributeName : attributeNames) {
      Type<?> attributeType = ruleContext.attributes().getAttributeType(attributeName);
      if (!LABEL.equals(attributeType) && !LABEL_LIST.equals(attributeType)) {
        continue;
      }
      Iterable<AspectInfo> prerequisites =
          ruleContext.getPrerequisites(attributeName, AspectInfo.class);
      for (AspectInfo prerequisite : prerequisites) {
        result.addTransitive(prerequisite.getData());
      }
    }
    return result.build();
  }

  /**
   * A simple rule configured target factory that is used in all the mock rules in this class.
   */
  public static class DummyRuleFactory implements RuleConfiguredTargetFactory {
    @Override
    @Nullable
    public ConfiguredTarget create(RuleContext ruleContext)
        throws InterruptedException, RuleErrorException, ActionConflictException {

      RuleConfiguredTargetBuilder builder =
          new RuleConfiguredTargetBuilder(ruleContext)
              .addProvider(
                  new RuleInfo(collectAspectData("rule " + ruleContext.getLabel(), ruleContext)))
              .setFilesToBuild(NestedSetBuilder.<Artifact>create(Order.STABLE_ORDER))
              .setRunfilesSupport(null, null)
              .add(RunfilesProvider.class, RunfilesProvider.simple(Runfiles.EMPTY));

      if (ruleContext.getRule().getRuleClassObject().getName().equals("honest")) {
        builder.addProvider(new RequiredProvider());
      }

      return builder.build();
    }
  }

  /**
   * A simple rule configured target factory that exports provider {@link RequiredProvider2}.
   */
  public static class DummyRuleFactory2 implements RuleConfiguredTargetFactory {
    @Override
    public ConfiguredTarget create(RuleContext ruleContext)
        throws InterruptedException, RuleErrorException, ActionConflictException {
      return new RuleConfiguredTargetBuilder(ruleContext)
              .addProvider(
                  new RuleInfo(collectAspectData("rule " + ruleContext.getLabel(), ruleContext)))
              .setFilesToBuild(NestedSetBuilder.<Artifact>create(Order.STABLE_ORDER))
              .setRunfilesSupport(null, null)
              .add(RunfilesProvider.class, RunfilesProvider.simple(Runfiles.EMPTY))
              .addProvider(new RequiredProvider())
              .addProvider(new RequiredProvider2())
              .build();
    }
  }

  /**
   * A simple rule configured target factory that expects different providers added through
   * different aspects.
   */
  public static class MultiAspectRuleFactory implements RuleConfiguredTargetFactory {
    @Override
    public ConfiguredTarget create(RuleContext ruleContext)
        throws InterruptedException, RuleErrorException, ActionConflictException {
      TransitiveInfoCollection fooAttribute = ruleContext.getPrerequisite("foo");
      TransitiveInfoCollection barAttribute = ruleContext.getPrerequisite("bar");

      NestedSetBuilder<String> infoBuilder = NestedSetBuilder.<String>stableOrder();

      if (fooAttribute.getProvider(FooProvider.class) != null) {
        infoBuilder.add("foo");
      }
      if (barAttribute.getProvider(BarProvider.class) != null) {
        infoBuilder.add("bar");
      }

      RuleConfiguredTargetBuilder builder =
          new RuleConfiguredTargetBuilder(ruleContext)
              .addProvider(
                  new RuleInfo(infoBuilder.build()))
              .setFilesToBuild(NestedSetBuilder.<Artifact>create(Order.STABLE_ORDER))
              .setRunfilesSupport(null, null)
              .add(RunfilesProvider.class, RunfilesProvider.simple(Runfiles.EMPTY));

      return builder.build();
    }
  }

  /**
   * A base class for mock aspects to reduce boilerplate.
   */
  public abstract static class BaseAspect extends NativeAspectClass
    implements ConfiguredAspectFactory {
    @Override
    public ConfiguredAspect create(
        ConfiguredTargetAndData ctadBase,
        RuleContext ruleContext,
        AspectParameters parameters,
        RepositoryName toolsRepository)
        throws ActionConflictException, InterruptedException {
      String information = parameters.isEmpty()
          ? ""
          : " data " + Iterables.getFirst(parameters.getAttribute("baz"), null);
      return new ConfiguredAspect.Builder(ruleContext)
          .addProvider(
              new AspectInfo(
                  collectAspectData("aspect " + ruleContext.getLabel() + information, ruleContext)))
          .build();
    }
  }

  public static final SimpleAspect SIMPLE_ASPECT = new SimpleAspect();
  public static final FooProviderAspect FOO_PROVIDER_ASPECT = new FooProviderAspect();
  public static final BarProviderAspect BAR_PROVIDER_ASPECT = new BarProviderAspect();
  public static final SimpleStarlarkNativeAspect SIMPLE_STARLARK_NATIVE_ASPECT =
      new SimpleStarlarkNativeAspect();
  public static final ParametrizedAspectWithProvider
      PARAMETRIZED_STARLARK_NATIVE_ASPECT_WITH_PROVIDER = new ParametrizedAspectWithProvider();
  public static final StarlarkNativeAspectWithProvider STARLARK_NATIVE_ASPECT_WITH_PROVIDER =
      new StarlarkNativeAspectWithProvider();

  private static final AspectDefinition SIMPLE_ASPECT_DEFINITION =
      new AspectDefinition.Builder(SIMPLE_ASPECT).build();
  private static final AspectDefinition FOO_PROVIDER_ASPECT_DEFINITION =
      new AspectDefinition.Builder(FOO_PROVIDER_ASPECT).build();
  private static final AspectDefinition BAR_PROVIDER_ASPECT_DEFINITION =
      new AspectDefinition.Builder(BAR_PROVIDER_ASPECT).build();
  private static final AspectDefinition SIMPLE_STARLARK_NATIVE_ASPECT_DEFINITION =
      new AspectDefinition.Builder(SIMPLE_STARLARK_NATIVE_ASPECT).build();

  /** Simple StarlarkNativeAspect */
  public static class SimpleStarlarkNativeAspect extends StarlarkNativeAspect
      implements ConfiguredAspectFactory {
    @Override
    public AspectDefinition getDefinition(AspectParameters aspectParameters) {
      return SIMPLE_STARLARK_NATIVE_ASPECT_DEFINITION;
    }

    @Override
    public ConfiguredAspect create(
        ConfiguredTargetAndData ctadBase,
        RuleContext ruleContext,
        AspectParameters parameters,
        RepositoryName toolsRepository)
        throws ActionConflictException, InterruptedException {
      return new ConfiguredAspect.Builder(ruleContext).addProvider(new FooProvider()).build();
    }
  }

  /**
   * A very simple aspect.
   */
  public static class SimpleAspect extends BaseAspect {
    @Override
    public AspectDefinition getDefinition(AspectParameters aspectParameters) {
      return SIMPLE_ASPECT_DEFINITION;
    }
  }

  /**
   * A simple aspect that propagates a FooProvider provider.
   */
  public static class FooProviderAspect extends NativeAspectClass
      implements ConfiguredAspectFactory {
    @Override
    public AspectDefinition getDefinition(AspectParameters aspectParameters) {
      return FOO_PROVIDER_ASPECT_DEFINITION;
    }

    @Override
    public ConfiguredAspect create(
        ConfiguredTargetAndData ctadBase,
        RuleContext ruleContext,
        AspectParameters parameters,
        RepositoryName toolsRepository)
        throws ActionConflictException, InterruptedException {
      return new ConfiguredAspect.Builder(ruleContext).addProvider(new FooProvider()).build();
    }
  }

  /** A simple aspect that propagates a BarProvider provider. */
  public static class BarProviderAspect extends NativeAspectClass
      implements ConfiguredAspectFactory {
    @Override
    public AspectDefinition getDefinition(AspectParameters aspectParameters) {
      return BAR_PROVIDER_ASPECT_DEFINITION;
    }

    @Override
    public ConfiguredAspect create(
        ConfiguredTargetAndData ctadBase,
        RuleContext ruleContext,
        AspectParameters parameters,
        RepositoryName toolsRepository)
        throws ActionConflictException, InterruptedException {
      return new ConfiguredAspect.Builder(ruleContext).addProvider(new BarProvider()).build();
    }
  }

  public static final ExtraAttributeAspect EXTRA_ATTRIBUTE_ASPECT =
      new ExtraAttributeAspect(/*depLabel=*/ "//extra", /*applyToFiles=*/ false);

  private static final ExtraAttributeAspectRequiringProvider
    EXTRA_ATTRIBUTE_ASPECT_REQUIRING_PROVIDER = new ExtraAttributeAspectRequiringProvider();
  private static final AspectDefinition EXTRA_ATTRIBUTE_ASPECT_REQUIRING_PROVIDER_DEFINITION =
      new AspectDefinition.Builder(EXTRA_ATTRIBUTE_ASPECT_REQUIRING_PROVIDER)
          .add(attr("$dep", LABEL).value(Label.parseAbsoluteUnchecked("//extra:extra")))
          .requireProviders(RequiredProvider.class)
          .build();

  /** An aspect that defines its own implicit attribute. */
  public static class ExtraAttributeAspect extends BaseAspect {

    /** Test provider which includes the {@code dep} label. */
    @AutoValue
    public abstract static class Provider implements TransitiveInfoProvider {
      public abstract String label();

      static Provider create(String label) {
        return new AutoValue_TestAspects_ExtraAttributeAspect_Provider(label);
      }
    }

    private final Label depLabel;
    private final boolean applyToFiles;
    private final Class<? extends TransitiveInfoProvider>[] requiredAspectProviders;

    public ExtraAttributeAspect(
        String depLabel,
        boolean applyToFiles,
        Class<? extends TransitiveInfoProvider>... requiredAspectProviders) {
      this.depLabel = Label.parseAbsoluteUnchecked(depLabel);
      this.applyToFiles = applyToFiles;
      this.requiredAspectProviders = requiredAspectProviders;
    }

    @Override
    public ConfiguredAspect create(
        ConfiguredTargetAndData ctadBase,
        RuleContext ruleContext,
        AspectParameters parameters,
        RepositoryName toolsRepository)
        throws ActionConflictException, InterruptedException {
      TransitiveInfoCollection dep = ruleContext.getPrerequisite("$dep");
      if (dep == null) {
        ruleContext.attributeError("$dep", "$dep attribute not resolved");
        return ConfiguredAspect.builder(ruleContext).build();
      }
      return ConfiguredAspect.builder(ruleContext)
          .addProvider(Provider.create(dep.getLabel().getCanonicalForm()))
          .build();
    }

    @Override
    public String getName() {
      return String.format("%s_%s_%s", super.getName(), depLabel.getCanonicalForm(), applyToFiles);
    }

    @Override
    public AspectDefinition getDefinition(AspectParameters aspectParameters) {
      AspectDefinition.Builder aspectDefinition =
          new AspectDefinition.Builder(this)
              .add(attr("$dep", LABEL).value(depLabel))
              .applyToFiles(applyToFiles)
              .advertiseProvider(Provider.class);

      if (requiredAspectProviders.length > 0) {
        aspectDefinition.requireAspectsWithBuiltinProviders(requiredAspectProviders);
      }

      return aspectDefinition.build();
    }
  }

  /** An aspect that defines its own implicit attribute, requiring PackageSpecificationProvider. */
  public static class PackageGroupAttributeAspect extends BaseAspect {
    @Override
    public AspectDefinition getDefinition(AspectParameters aspectParameters) {
      return PACKAGE_GROUP_ATTRIBUTE_ASPECT_DEFINITION;
    }
  }

  public static final PackageGroupAttributeAspect PACKAGE_GROUP_ATTRIBUTE_ASPECT =
      new PackageGroupAttributeAspect();
  private static final AspectDefinition PACKAGE_GROUP_ATTRIBUTE_ASPECT_DEFINITION =
      new AspectDefinition.Builder(PACKAGE_GROUP_ATTRIBUTE_ASPECT)
          .add(
              attr("$dep", LABEL)
                  .value(Label.parseAbsoluteUnchecked("//extra:extra"))
                  .mandatoryBuiltinProviders(ImmutableList.of(PackageSpecificationProvider.class)))
          .build();

  public static final ComputedAttributeAspect COMPUTED_ATTRIBUTE_ASPECT =
      new ComputedAttributeAspect();
  private static final AspectDefinition COMPUTED_ATTRIBUTE_ASPECT_DEFINITION =
      new AspectDefinition.Builder(COMPUTED_ATTRIBUTE_ASPECT)
          .add(
              attr("$default_copts", STRING_LIST)
                  .value(
                      new ComputedDefault() {
                        @Override
                        public Object getDefault(AttributeMap rule) {
                          return rule.getPackageDefaultCopts();
                        }
                      }))
          .build();

  /** An aspect that defines its own computed default attribute. */
  public static class ComputedAttributeAspect extends BaseAspect {
    @Override
    public AspectDefinition getDefinition(AspectParameters aspectParameters) {
      return COMPUTED_ATTRIBUTE_ASPECT_DEFINITION;
    }
  }

  public static final AttributeAspect ATTRIBUTE_ASPECT = new AttributeAspect();
  private static final AspectDefinition ATTRIBUTE_ASPECT_DEFINITION =
      new AspectDefinition.Builder(ATTRIBUTE_ASPECT)
      .propagateAlongAttribute("foo")
      .build();

  /**
   * An aspect that propagates along all attributes.
   */
  public static class AllAttributesAspect extends BaseAspect {

    @Override
    public AspectDefinition getDefinition(AspectParameters aspectParameters) {
      return ALL_ATTRIBUTES_ASPECT_DEFINITION;
    }
  }
  public static final NativeAspectClass ALL_ATTRIBUTES_ASPECT = new AllAttributesAspect();
  private static final AspectDefinition ALL_ATTRIBUTES_ASPECT_DEFINITION =
      new AspectDefinition.Builder(ALL_ATTRIBUTES_ASPECT)
          .propagateAlongAllAttributes()
          .build();

  /** An aspect that propagates along all attributes and has a tool dependency. */
  public static class AllAttributesWithToolAspect extends BaseAspect {

    @Override
    public AspectDefinition getDefinition(AspectParameters aspectParameters) {
      return ALL_ATTRIBUTES_WITH_TOOL_ASPECT_DEFINITION;
    }
  }

  public static final NativeAspectClass ALL_ATTRIBUTES_WITH_TOOL_ASPECT =
      new AllAttributesWithToolAspect();
  private static final AspectDefinition ALL_ATTRIBUTES_WITH_TOOL_ASPECT_DEFINITION =
      new AspectDefinition.Builder(ALL_ATTRIBUTES_WITH_TOOL_ASPECT)
          .propagateAlongAllAttributes()
          .add(
              attr("$tool", BuildType.LABEL)
                  .allowedFileTypes(FileTypeSet.ANY_FILE)
                  .value(Label.parseAbsoluteUnchecked("//a:tool")))
          .build();

  /**
   * An aspect that requires aspects on the attributes of rules it attaches to.
   */
  public static class AttributeAspect extends BaseAspect {
    @Override
    public AspectDefinition getDefinition(AspectParameters aspectParameters) {
      return ATTRIBUTE_ASPECT_DEFINITION;
    }
  }

  /**
   * An aspect that defines its own implicit attribute and requires provider.
   */
  public static class ExtraAttributeAspectRequiringProvider extends BaseAspect {
    @Override
    public AspectDefinition getDefinition(AspectParameters aspectParameters) {
      return EXTRA_ATTRIBUTE_ASPECT_REQUIRING_PROVIDER_DEFINITION;
    }
  }

  public static class AspectRequiringProvider extends BaseAspect {
    @Override
    public AspectDefinition getDefinition(AspectParameters aspectParameters) {
      return ASPECT_REQUIRING_PROVIDER_DEFINITION;
    }
  }

  /**
   * An aspect that requires provider sets {{@link RequiredProvider}} and
   * {{@link RequiredProvider2}}.
   */
  public static class AspectRequiringProviderSets extends BaseAspect {
    @Override
    public AspectDefinition getDefinition(AspectParameters aspectParameters) {
      return ASPECT_REQUIRING_PROVIDER_SETS_DEFINITION;
    }
  }

  /** A native aspect exposed to Starlark and advertises a simple provider. */
  public static class StarlarkNativeAspectWithProvider extends StarlarkNativeAspect
      implements ConfiguredAspectFactory {

    @Override
    public AspectDefinition getDefinition(AspectParameters aspectParameters) {
      AspectDefinition.Builder builder =
          new AspectDefinition.Builder(STARLARK_NATIVE_ASPECT_WITH_PROVIDER);
      builder.requireProviders(RequiredProvider.class);
      return builder.build();
    }

    @Override
    public ConfiguredAspect create(
        ConfiguredTargetAndData ctadBase,
        RuleContext ruleContext,
        AspectParameters parameters,
        RepositoryName toolsRepository)
        throws ActionConflictException, InterruptedException {
      return new ConfiguredAspect.Builder(ruleContext)
          .addStarlarkTransitiveInfo("native_aspect_prov", "native_aspect_val")
          .build();
    }
  }

  /**
   * An aspect that has a definition depending on parameters provided by originating rule and
   * advertises a simple provider.
   */
  public static class ParametrizedAspectWithProvider extends StarlarkNativeAspect
      implements ConfiguredAspectFactory {

    @Override
    public AspectDefinition getDefinition(AspectParameters aspectParameters) {
      AspectDefinition.Builder builder =
          new AspectDefinition.Builder(PARAMETRIZED_STARLARK_NATIVE_ASPECT_WITH_PROVIDER);
      ImmutableCollection<String> aspectAttr = aspectParameters.getAttribute("aspect_attr");
      if (aspectAttr != null) {
        builder.add(
            attr("aspect_attr", Type.STRING)
                .allowedValues(new AllowedValueSet("v1", "v2"))
                .value(aspectAttr.iterator().next()));
      }
      return builder.build();
    }

    @Override
    public ConfiguredAspect create(
        ConfiguredTargetAndData ctadBase,
        RuleContext ruleContext,
        AspectParameters parameters,
        RepositoryName toolsRepository)
        throws ActionConflictException, InterruptedException {
      return new ConfiguredAspect.Builder(ruleContext).addProvider(new FooProvider()).build();
    }

    @Override
    public Function<Rule, AspectParameters> getDefaultParametersExtractor() {
      return (Function<Rule, AspectParameters> & Serializable)
          (@Nullable Rule rule) -> {
            AttributeMap attributes = RawAttributeMapper.of(rule);
            return new AspectParameters.Builder()
                .addAttribute("aspect_attr", attributes.get("aspect_attr", Type.STRING))
                .build();
          };
    }

    @Override
    public ImmutableSet<String> getParamAttributes() {
      return ImmutableSet.of("aspect_attr");
    }
  }

  /**
   * An aspect that has a definition depending on parameters provided by originating rule.
   */
  public static class ParametrizedDefinitionAspect extends NativeAspectClass
    implements ConfiguredAspectFactory {

    @Override
    public AspectDefinition getDefinition(AspectParameters aspectParameters) {
      AspectDefinition.Builder builder =
          new AspectDefinition.Builder(PARAMETRIZED_DEFINITION_ASPECT)
              .propagateAlongAttribute("foo");
      ImmutableCollection<String> baz = aspectParameters.getAttribute("baz");
      if (baz != null) {
        try {
          builder.add(attr("$dep", LABEL).value(Label.parseCanonical(baz.iterator().next())));
        } catch (LabelSyntaxException e) {
          throw new IllegalStateException(e);
        }
      }
      return builder.build();
    }

    @Override
    public ConfiguredAspect create(
        ConfiguredTargetAndData ctadBase,
        RuleContext ruleContext,
        AspectParameters parameters,
        RepositoryName toolsRepository)
        throws ActionConflictException, InterruptedException {
      StringBuilder information = new StringBuilder("aspect " + ruleContext.getLabel());
      if (!parameters.isEmpty()) {
        information.append(" data " + Iterables.getFirst(parameters.getAttribute("baz"), null));
        information.append(" ");
      }
      List<? extends TransitiveInfoCollection> deps = ruleContext.getPrerequisites("$dep");
      information.append("$dep:[");
      for (TransitiveInfoCollection dep : deps) {
        information.append(" ");
        information.append(dep.getLabel());
      }
      information.append("]");
      return new ConfiguredAspect.Builder(ruleContext)
          .addProvider(new AspectInfo(collectAspectData(information.toString(), ruleContext)))
          .build();
    }
  }

  static final ParametrizedDefinitionAspect PARAMETRIZED_DEFINITION_ASPECT =
      new ParametrizedDefinitionAspect();

  static final AspectRequiringProvider ASPECT_REQUIRING_PROVIDER = new AspectRequiringProvider();
  static final AspectRequiringProviderSets ASPECT_REQUIRING_PROVIDER_SETS =
      new AspectRequiringProviderSets();
  private static final AspectDefinition ASPECT_REQUIRING_PROVIDER_DEFINITION =
      new AspectDefinition.Builder(ASPECT_REQUIRING_PROVIDER)
          .requireProviders(RequiredProvider.class)
          .propagateAlongAttribute("foo")
          .build();
  private static final AspectDefinition ASPECT_REQUIRING_PROVIDER_SETS_DEFINITION =
      new AspectDefinition.Builder(ASPECT_REQUIRING_PROVIDER_SETS)
          .requireProviderSets(
              ImmutableList.of(
                  ImmutableSet.of(RequiredProvider.class),
                  ImmutableSet.of(RequiredProvider2.class)))
          .build();

  /**
   * An aspect that prints a warning.
   */
  public static class WarningAspect extends NativeAspectClass
    implements ConfiguredAspectFactory {

    @Override
    public ConfiguredAspect create(
        ConfiguredTargetAndData ctadBase,
        RuleContext ruleContext,
        AspectParameters parameters,
        RepositoryName toolsRepository)
        throws ActionConflictException, InterruptedException {
      ruleContext.ruleWarning("Aspect warning on " + ctadBase.getTarget().getLabel());
      return new ConfiguredAspect.Builder(ruleContext).build();
    }

    @Override
    public AspectDefinition getDefinition(AspectParameters aspectParameters) {
      return WARNING_ASPECT_DEFINITION;
    }
  }

  public static final WarningAspect WARNING_ASPECT = new WarningAspect();
  private static final AspectDefinition WARNING_ASPECT_DEFINITION =
      new AspectDefinition.Builder(WARNING_ASPECT)
      .propagateAlongAttribute("bar")
      .build();

  /**
   * An aspect that raises an error.
   */
  public static class ErrorAspect extends NativeAspectClass
    implements ConfiguredAspectFactory {

    @Override
    public ConfiguredAspect create(
        ConfiguredTargetAndData ctadBase,
        RuleContext ruleContext,
        AspectParameters parameters,
        RepositoryName toolsRepository) {
      ruleContext.ruleError("Aspect error");
      return null;
    }

    @Override
    public AspectDefinition getDefinition(AspectParameters aspectParameters) {
      return ERROR_ASPECT_DEFINITION;
    }
  }

  public static final ErrorAspect ERROR_ASPECT = new ErrorAspect();
  private static final AspectDefinition ERROR_ASPECT_DEFINITION =
      new AspectDefinition.Builder(ERROR_ASPECT)
      .propagateAlongAttribute("bar")
      .build();

  /**
   * An aspect that advertises but fails to provide providers.
   */
  public static class FalseAdvertisementAspect extends NativeAspectClass
    implements ConfiguredAspectFactory {

    @Override
    public AspectDefinition getDefinition(AspectParameters aspectParameters) {
      return FALSE_ADVERTISEMENT_DEFINITION;
    }

    @Override
    public ConfiguredAspect create(
        ConfiguredTargetAndData ctadBase,
        RuleContext context,
        AspectParameters parameters,
        RepositoryName toolsRepository)
        throws InterruptedException, ActionConflictException {
      return new ConfiguredAspect.Builder(context).build();
    }
  }
  public static final FalseAdvertisementAspect FALSE_ADVERTISEMENT_ASPECT
      = new FalseAdvertisementAspect();
  private static final AspectDefinition FALSE_ADVERTISEMENT_DEFINITION =
      new AspectDefinition.Builder(FALSE_ADVERTISEMENT_ASPECT)
          .advertiseProvider(RequiredProvider.class)
          .advertiseProvider(
              ImmutableList.of(StarlarkProviderIdentifier.forLegacy("advertised_provider")))
          .build();

  /**
   * A common base rule for mock rules in this class to reduce boilerplate.
   *
   * <p>It has a few common attributes because internal Blaze machinery assumes the presence of
   * these.
   */
  public static final MockRule BASE_RULE = () ->
      MockRule.factory(DummyRuleFactory.class).define("base");

  /**
   * A rule that defines an aspect on one of its attributes.
   */
  public static final MockRule ASPECT_REQUIRING_RULE = () ->
      MockRule.ancestor(BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
          "aspect",
          attr("foo", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE)
              .aspect(SIMPLE_ASPECT),
          attr("bar", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE)
              .aspect(SIMPLE_ASPECT));

  /**
   * A rule that defines different aspects on different attributes.
   */
  public static final MockRule MULTI_ASPECT_RULE = () ->
      MockRule.ancestor(BASE_RULE.getClass()).factory(MultiAspectRuleFactory.class).define(
          "multi_aspect",
          attr("foo", LABEL).allowedFileTypes(FileTypeSet.ANY_FILE)
              .mandatory()
              .aspect(FOO_PROVIDER_ASPECT),
          attr("bar", LABEL).allowedFileTypes(FileTypeSet.ANY_FILE)
              .mandatory()
              .aspect(BAR_PROVIDER_ASPECT));

  private static final Function<Rule, AspectParameters> TEST_ASPECT_PARAMETERS_EXTRACTOR =
      (rule) -> {
        if (rule.isAttrDefined("baz", STRING)) {
          String value = rule.getAttr("baz").toString();
          if (!value.equals("")) {
            return new AspectParameters.Builder().addAttribute("baz", value).build();
          }
        }
        return AspectParameters.EMPTY;
      };

  /**
   * A rule that defines an {@link AspectRequiringProvider} on one of its attributes.
   */
  public static final MockRule ASPECT_REQUIRING_PROVIDER_RULE = () ->
      MockRule.ancestor(BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
          "aspect_requiring_provider",
          (builder, env) ->
              builder
                  .add(
                      attr("foo", LABEL_LIST)
                          .allowedFileTypes(FileTypeSet.ANY_FILE)
                          .aspect(ASPECT_REQUIRING_PROVIDER, TEST_ASPECT_PARAMETERS_EXTRACTOR))
                  .add(attr("baz", STRING)));

  /**
   * A rule that defines an {@link AspectRequiringProviderSets} on one of its attributes.
   */
  public static final MockRule ASPECT_REQUIRING_PROVIDER_SETS_RULE = () ->
      MockRule.ancestor(BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
          "aspect_requiring_provider_sets",
          attr("foo", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE)
              .aspect(ASPECT_REQUIRING_PROVIDER_SETS),
          attr("baz", STRING));

  /**
   * A rule that defines an {@link ExtraAttributeAspect} on one of its attributes.
   */
  public static final MockRule EXTRA_ATTRIBUTE_ASPECT_RULE = () ->
      MockRule.ancestor(BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
          "rule_with_extra_deps_aspect",
          attr("foo", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE)
              .aspect(EXTRA_ATTRIBUTE_ASPECT));

  /** A rule that defines an {@link PackageGroupAttributeAspect} on one of its attributes. */
  public static final MockRule PACKAGE_GROUP_ATTRIBUTE_ASPECT_RULE =
      () ->
          MockRule.ancestor(BASE_RULE.getClass())
              .factory(DummyRuleFactory.class)
              .define(
                  "rule_with_package_group_deps_aspect",
                  attr("foo", LABEL_LIST)
                      .allowedFileTypes(FileTypeSet.ANY_FILE)
                      .aspect(PACKAGE_GROUP_ATTRIBUTE_ASPECT));

  /** A rule that defines an {@link ComputedAttributeAspect} on one of its attributes. */
  public static final MockRule COMPUTED_ATTRIBUTE_ASPECT_RULE =
      () ->
          MockRule.ancestor(BASE_RULE.getClass())
              .factory(DummyRuleFactory.class)
              .define(
                  "rule_with_computed_deps_aspect",
                  attr("foo", LABEL_LIST)
                      .allowedFileTypes(FileTypeSet.ANY_FILE)
                      .aspect(COMPUTED_ATTRIBUTE_ASPECT));

  /**
   * A rule that defines an {@link ParametrizedDefinitionAspect} on one of its attributes.
   */
  public static final MockRule PARAMETERIZED_DEFINITION_ASPECT_RULE = () ->
      MockRule.ancestor(BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
          "parametrized_definition_aspect",
          (builder, env) ->
              builder
                  .add(
                      attr("foo", LABEL_LIST)
                          .allowedFileTypes(FileTypeSet.ANY_FILE)
                          .aspect(PARAMETRIZED_DEFINITION_ASPECT, TEST_ASPECT_PARAMETERS_EXTRACTOR))
                  .add(attr("baz", STRING)));


  /**
   * A rule that defines an {@link ExtraAttributeAspectRequiringProvider} on one of its attributes.
   */
  public static final MockRule EXTRA_ATTRIBUTE_ASPECT_REQUIRING_PROVIDER_RULE = () ->
      MockRule.ancestor(BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
          "extra_attribute_aspect_requiring_provider",
          attr("foo", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE)
              .aspect(EXTRA_ATTRIBUTE_ASPECT_REQUIRING_PROVIDER));

  /**
   * A rule that defines an {@link AllAttributesAspect} on one of its attributes.
   */
  public static final MockRule ALL_ATTRIBUTES_ASPECT_RULE = () ->
      MockRule.ancestor(BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
          "all_attributes_aspect",
          attr("foo", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE)
              .aspect(ALL_ATTRIBUTES_ASPECT));

  /** A rule that defines an {@link AllAttributesWithToolAspect} on one of its attributes. */
  public static final MockRule ALL_ATTRIBUTES_WITH_TOOL_ASPECT_RULE = () ->
      MockRule.ancestor(BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
          "all_attributes_with_tool_aspect",
           attr("foo", LABEL_LIST)
               .allowedFileTypes(FileTypeSet.ANY_FILE)
               .aspect(ALL_ATTRIBUTES_WITH_TOOL_ASPECT));

  /**
   * A rule that defines a {@link WarningAspect} on one of its attributes.
   */
  public static final MockRule WARNING_ASPECT_RULE = () ->
      MockRule.ancestor(BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
          "warning_aspect",
          attr("foo", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE)
              .aspect(WARNING_ASPECT),
          attr("bar", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE));

  /**
   * A rule that defines an {@link ErrorAspect} on one of its attributes.
   */
  public static final MockRule ERROR_ASPECT_RULE = () ->
      MockRule.ancestor(BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
          "error_aspect",
          attr("foo", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE)
              .aspect(ERROR_ASPECT),
          attr("bar", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE));

  /**
   * A simple rule that has an attribute.
   */
  public static final MockRule SIMPLE_RULE = () ->
      MockRule.ancestor(BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
          "simple",
          attr("foo", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE),
          attr("foo1", LABEL).allowedFileTypes(FileTypeSet.ANY_FILE),
          attr("txt", STRING));

  /**
   * A rule that advertises a provider but doesn't implement it.
   */
  public static final MockRule LIAR_RULE = () ->
      MockRule.ancestor(BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
          "liar",
          (builder, env) ->
              builder
                  .add(attr("foo", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE))
                  .advertiseProvider(RequiredProvider.class));

  /**
   * A rule that advertises a provider and implements it.
   */
  public static final MockRule HONEST_RULE = () ->
      MockRule.ancestor(BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
          "honest",
          (builder, env) ->
              builder
              .add(attr("foo", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE))
              .advertiseProvider(RequiredProvider.class));

  /**
   * A rule that advertises another, different provider and implements it.
   */
  public static final MockRule HONEST_RULE_2 = () ->
      MockRule.ancestor(BASE_RULE.getClass()).factory(DummyRuleFactory2.class).define(
          "honest2",
          (builder, env) ->
              builder
                  .add(attr("foo", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE))
                  .advertiseProvider(RequiredProvider2.class));

  /**
   * Rule with an implcit dependency.
   */
  public static final MockRule IMPLICIT_DEP_RULE = () ->
      MockRule.ancestor(BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
          "implicit_dep",
          attr("$dep", LABEL).value(Label.parseAbsoluteUnchecked("//extra:extra")));

  // TODO(b/65746853): provide a way to do this without passing the entire configuration
  private static final LabelListLateBoundDefault<?> PLUGINS_LABEL_LIST =
      LabelListLateBoundDefault.fromTargetConfiguration(
          JavaConfiguration.class, (rule, attributes, javaConfig) -> javaConfig.getPlugins());

  public static final MockRule LATE_BOUND_DEP_RULE = () ->
      MockRule.ancestor(BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
          "late_bound_dep",
          attr(":plugins", LABEL_LIST).value(PLUGINS_LABEL_LIST));

  /**
   * Rule with {@link FalseAdvertisementAspect}
   */
  public static final MockRule FALSE_ADVERTISEMENT_ASPECT_RULE = () ->
      MockRule.ancestor(BASE_RULE.getClass()).factory(DummyRuleFactory.class).define(
          "false_advertisement_aspect",
          attr("deps", LABEL_LIST).allowedFileTypes().aspect(FALSE_ADVERTISEMENT_ASPECT));

  /** Aspect that propagates over rule outputs. */
  public static class AspectApplyingToFiles extends NativeAspectClass
      implements ConfiguredAspectFactory {

    /** Simple provider for testing */
    @Immutable
    public static final class Provider implements TransitiveInfoProvider {
      private final Label label;

      private Provider(Label label) {
        this.label = label;
      }

      public Label getLabel() {
        return label;
      }
    }

    @Override
    public AspectDefinition getDefinition(AspectParameters aspectParameters) {
      return AspectDefinition.builder(this).applyToFiles(true).build();
    }

    @Override
    public ConfiguredAspect create(
        ConfiguredTargetAndData ctadBase,
        RuleContext context,
        AspectParameters parameters,
        RepositoryName toolsRepository)
        throws InterruptedException, ActionConflictException {
      return ConfiguredAspect.builder(context)
          .addProvider(Provider.class, new Provider(ctadBase.getConfiguredTarget().getLabel()))
          .build();
    }
  }
}
