// Copyright 2014 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.starlark;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static com.google.devtools.build.lib.analysis.testing.ExecGroupSubject.assertThat;
import static com.google.devtools.build.lib.analysis.testing.RuleClassSubject.assertThat;
import static com.google.devtools.build.lib.analysis.testing.StarlarkDefinedAspectSubject.assertThat;
import static org.junit.Assert.assertThrows;

import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.testing.EqualsTester;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
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.NoTransition;
import com.google.devtools.build.lib.analysis.starlark.StarlarkAttrModule;
import com.google.devtools.build.lib.analysis.starlark.StarlarkConfig;
import com.google.devtools.build.lib.analysis.starlark.StarlarkGlobalsImpl;
import com.google.devtools.build.lib.analysis.starlark.StarlarkRuleClassFunctions.StarlarkRuleFunction;
import com.google.devtools.build.lib.analysis.starlark.StarlarkRuleContext;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.analysis.util.TestAspects;
import com.google.devtools.build.lib.cmdline.BazelModuleContext;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.cmdline.RepositoryMapping;
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.collect.nestedset.Depset;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.EventKind;
import com.google.devtools.build.lib.events.NullEventHandler;
import com.google.devtools.build.lib.packages.AdvertisedProviderSet;
import com.google.devtools.build.lib.packages.Aspect;
import com.google.devtools.build.lib.packages.AspectClass;
import com.google.devtools.build.lib.packages.AspectParameters;
import com.google.devtools.build.lib.packages.Attribute;
import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.ExecGroup;
import com.google.devtools.build.lib.packages.ImplicitOutputsFunction;
import com.google.devtools.build.lib.packages.PredicateWithMessage;
import com.google.devtools.build.lib.packages.Provider;
import com.google.devtools.build.lib.packages.RequiredProviders;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType;
import com.google.devtools.build.lib.packages.StarlarkAspectClass;
import com.google.devtools.build.lib.packages.StarlarkDefinedAspect;
import com.google.devtools.build.lib.packages.StarlarkInfo;
import com.google.devtools.build.lib.packages.StarlarkProvider;
import com.google.devtools.build.lib.packages.StarlarkProviderIdentifier;
import com.google.devtools.build.lib.packages.StructImpl;
import com.google.devtools.build.lib.packages.StructProvider;
import com.google.devtools.build.lib.packages.Type;
import com.google.devtools.build.lib.starlark.util.BazelEvaluationTestCase;
import com.google.devtools.build.lib.testutil.MoreAsserts;
import com.google.devtools.build.lib.testutil.TestConstants;
import com.google.devtools.build.lib.testutil.TestRuleClassProvider;
import com.google.devtools.build.lib.util.FileTypeSet;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.testing.junit.testparameterinjector.TestParameter;
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import net.starlark.java.eval.Dict;
import net.starlark.java.eval.EvalException;
import net.starlark.java.eval.Module;
import net.starlark.java.eval.Mutability;
import net.starlark.java.eval.Sequence;
import net.starlark.java.eval.Starlark;
import net.starlark.java.eval.StarlarkCallable;
import net.starlark.java.eval.StarlarkInt;
import net.starlark.java.eval.StarlarkList;
import net.starlark.java.eval.StarlarkSemantics;
import net.starlark.java.eval.Structure;
import net.starlark.java.eval.Tuple;
import net.starlark.java.syntax.FileOptions;
import net.starlark.java.syntax.ParserInput;
import org.junit.Before;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
/** Tests for StarlarkRuleClassFunctions. */
@RunWith(TestParameterInjector.class)
public final class StarlarkRuleClassFunctionsTest extends BuildViewTestCase {

  private final BazelEvaluationTestCase ev = new BazelEvaluationTestCase();

  private StarlarkRuleContext createRuleContext(String label) throws Exception {
    return new StarlarkRuleContext(getRuleContextForStarlark(getConfiguredTarget(label)), null);
  }

  @Override
  protected void setBuildLanguageOptions(String... options) throws Exception {
    super.setBuildLanguageOptions(options); // for BuildViewTestCase
    ev.setSemantics(options); // for StarlarkThread
  }

  @Override
  protected ConfiguredRuleClassProvider createRuleClassProvider() {
    ConfiguredRuleClassProvider.Builder builder = new ConfiguredRuleClassProvider.Builder();
    TestRuleClassProvider.addStandardRules(builder);
    builder.addBzlToplevel(
        "parametrized_native_aspect",
        TestAspects.PARAMETRIZED_STARLARK_NATIVE_ASPECT_WITH_PROVIDER);
    builder.addNativeAspectClass(TestAspects.PARAMETRIZED_STARLARK_NATIVE_ASPECT_WITH_PROVIDER);
    return builder.build();
  }

  @org.junit.Rule public ExpectedException thrown = ExpectedException.none();

  @Before
  public void createBuildFile() throws Exception {
    scratch.file(
        "foo/BUILD",
        "genrule(name = 'foo',",
        "  cmd = 'dummy_cmd',",
        "  srcs = ['a.txt', 'b.img'],",
        "  tools = ['t.exe'],",
        "  outs = ['c.txt'])",
        "genrule(name = 'bar',",
        "  cmd = 'dummy_cmd',",
        "  srcs = [':jl', ':gl'],",
        "  outs = ['d.txt'])",
        "java_library(name = 'jl',",
        "  srcs = ['a.java'])",
        "genrule(name = 'gl',",
        "  cmd = 'touch $(OUTS)',",
        "  srcs = ['a.go'],",
        "  outs = [ 'gl.a', 'gl.gcgox', ],",
        "  output_to_bindir = 1,",
        ")");
  }

  @Test
  public void testCannotOverrideBuiltInAttribute() throws Exception {
    ev.setFailFast(false);
    evalAndExport(
        ev,
        "def impl(ctx):", //
        "  return",
        "r = rule(impl, attrs = {'tags': attr.string_list()})");
    ev.assertContainsError(
        "Error in rule: attribute `tags`: built-in attributes cannot be overridden.");
  }

  @Test
  public void testCannotOverrideBuiltInAttributeName() throws Exception {
    ev.setFailFast(false);
    evalAndExport(
        ev,
        "def impl(ctx):", //
        "  return",
        "r = rule(impl, attrs = {'name': attr.string()})");
    ev.assertContainsError(
        "Error in rule: attribute `name`: built-in attributes cannot be overridden.");
  }

  @Test
  public void builtInAttributesAreNotStarlarkDefined() throws Exception {
    ev.setFailFast(false);
    evalAndExport(
        ev,
        "def impl(ctx):", //
        "  return",
        "r = rule(impl, attrs = {'a': attr.string(), 'b': attr.label()})");
    Stream<Attribute> builtInAttributes =
        getRuleClass("r").getAttributes().stream()
            .filter(attr -> !(attr.getName().equals("a") || attr.getName().equals("b")));
    assertThat(builtInAttributes.map(Attribute::starlarkDefined)).doesNotContain(true);
  }

  @Test
  public void testImplicitArgsAttribute() throws Exception {
    ev.setFailFast(false);
    evalAndExport(
        ev,
        "def _impl(ctx):",
        "  pass",
        "exec_rule = rule(implementation = _impl, executable = True)",
        "non_exec_rule = rule(implementation = _impl)");
    assertThat(getRuleClass("exec_rule").hasAttr("args", Type.STRING_LIST)).isTrue();
    assertThat(getRuleClass("non_exec_rule").hasAttr("args", Type.STRING_LIST)).isFalse();
  }

  private RuleClass getRuleClass(String name) throws Exception {
    return ((StarlarkRuleFunction) ev.lookup(name)).getRuleClass();
  }

  private void registerDummyStarlarkFunction() throws Exception {
    ev.exec("def impl():", "  pass");
  }

  @Test
  public void testAttrWithOnlyType() throws Exception {
    Attribute attr = buildAttribute("a1", "attr.string_list()");
    assertThat(attr.starlarkDefined()).isTrue();
    assertThat(attr.getType()).isEqualTo(Type.STRING_LIST);
  }

  private Attribute buildAttribute(String name, String... lines) throws Exception {
    String[] strings = lines.clone();
    strings[strings.length - 1] = String.format("%s = %s", name, strings[strings.length - 1]);
    evalAndExport(ev, strings);
    StarlarkAttrModule.Descriptor lookup = (StarlarkAttrModule.Descriptor) ev.lookup(name);
    return lookup != null ? lookup.build(name) : null;
  }

  @Test
  public void testOutputListAttr() throws Exception {
    Attribute attr = buildAttribute("a1", "attr.output_list()");
    assertThat(attr.starlarkDefined()).isTrue();
    assertThat(attr.getType()).isEqualTo(BuildType.OUTPUT_LIST);
  }

  @Test
  public void testIntListAttr() throws Exception {
    Attribute attr = buildAttribute("a1", "attr.int_list()");
    assertThat(attr.starlarkDefined()).isTrue();
    assertThat(attr.getType()).isEqualTo(Type.INTEGER_LIST);
  }

  @Test
  public void testOutputAttr() throws Exception {
    Attribute attr = buildAttribute("a1", "attr.output()");
    assertThat(attr.starlarkDefined()).isTrue();
    assertThat(attr.getType()).isEqualTo(BuildType.OUTPUT);
  }

  @Test
  public void testStringDictAttr() throws Exception {
    Attribute attr = buildAttribute("a1", "attr.string_dict(default = {'a': 'b'})");
    assertThat(attr.starlarkDefined()).isTrue();
    assertThat(attr.getType()).isEqualTo(Type.STRING_DICT);
  }

  @Test
  public void testStringListDictAttr() throws Exception {
    Attribute attr = buildAttribute("a1", "attr.string_list_dict(default = {'a': ['b', 'c']})");
    assertThat(attr.starlarkDefined()).isTrue();
    assertThat(attr.getType()).isEqualTo(Type.STRING_LIST_DICT);
  }

  @Test
  public void testAttrAllowedFileTypesAnyFile() throws Exception {
    Attribute attr = buildAttribute("a1", "attr.label_list(allow_files = True)");
    assertThat(attr.starlarkDefined()).isTrue();
    assertThat(attr.getAllowedFileTypesPredicate()).isEqualTo(FileTypeSet.ANY_FILE);
  }

  @Test
  public void testAttrAllowedFileTypesWrongType() throws Exception {
    ev.checkEvalErrorContains(
        "got value of type 'int', want 'bool, sequence, or NoneType'",
        "attr.label_list(allow_files = 18)");
  }

  @Test
  public void testAttrNameSpecialCharactersAreForbidden() throws Exception {
    ev.setFailFast(false);
    evalAndExport(ev, "def impl(ctx): return", "r = rule(impl, attrs = {'ab$c': attr.int()})");
    ev.assertContainsError("attribute name `ab$c` is not a valid identifier");
  }

  @Test
  public void testAttrNameCannotStartWithDigit() throws Exception {
    ev.setFailFast(false);
    evalAndExport(ev, "def impl(ctx): return", "r = rule(impl, attrs = {'2_foo': attr.int()})");
    ev.assertContainsError("attribute name `2_foo` is not a valid identifier");
  }

  @Test
  public void testAttrEquality() throws Exception {
    new EqualsTester()
        .addEqualityGroup(
            buildAttribute("foo", "attr.string_list(default = [])"),
            buildAttribute("foo", "attr.string_list(default = [])"))
        .addEqualityGroup(
            buildAttribute("bar", "attr.string_list(default = [])"),
            buildAttribute("bar", "attr.string_list(default = [])"))
        .addEqualityGroup(
            buildAttribute("bar", "attr.label_list(default = [])"),
            buildAttribute("bar", "attr.label_list(default = [])"))
        .addEqualityGroup(
            buildAttribute("foo", "attr.string_list(default = ['hello'])"),
            buildAttribute("foo", "attr.string_list(default = ['hello'])"))
        .addEqualityGroup(
            buildAttribute("foo", "attr.string_list(doc = 'Blah blah blah', default = [])"),
            buildAttribute("foo", "attr.string_list(doc = 'Blah blah blah', default = [])"))
        .addEqualityGroup(
            buildAttribute("foo", "attr.string_list(mandatory = True, default = [])"),
            buildAttribute("foo", "attr.string_list(mandatory = True, default = [])"))
        .addEqualityGroup(
            buildAttribute("foo", "attr.string_list(allow_empty = False, default = [])"),
            buildAttribute("foo", "attr.string_list(allow_empty = False, default = [])"))
        .testEquals();
  }

  @Test
  public void testRuleClassTooManyAttributes() throws Exception {
    ev.setFailFast(false);

    ImmutableList.Builder<String> linesBuilder =
        ImmutableList.<String>builder()
            .add("def impl(ctx): return")
            .add("r = rule(impl, attrs = {");
    for (int i = 0; i < 200; i++) {
      linesBuilder.add("    'attr" + i + "': attr.int(),");
    }
    linesBuilder.add("})");

    evalAndExport(ev, linesBuilder.build().toArray(new String[0]));

    assertThat(ev.getEventCollector()).hasSize(1);
    Event event = ev.getEventCollector().iterator().next();
    assertThat(event.getKind()).isEqualTo(EventKind.ERROR);
    assertThat(event.getMessage()).contains("Rule class r declared too many attributes");
  }

  @Test
  public void testRuleClassTooLongAttributeName() throws Exception {
    ev.setFailFast(false);

    evalAndExport(
        ev,
        "def impl(ctx): return;",
        "r = rule(impl, attrs = { '" + "x".repeat(150) + "': attr.int() })");

    assertThat(ev.getEventCollector()).hasSize(1);
    Event event = ev.getEventCollector().iterator().next();
    assertThat(event.getKind()).isEqualTo(EventKind.ERROR);
    assertThat(event.getLocation().toString()).isEqualTo(":2:9");
    assertThat(event.getMessage())
        .matches("Attribute r\\.x{150}'s name is too long \\(150 > 128\\)");
  }

  @Test
  public void testAttrAllowedSingleFileTypesWrongType() throws Exception {
    ev.checkEvalErrorContains(
        "allow_single_file should be a boolean or a string list",
        "attr.label(allow_single_file = 18)");
  }

  @Test
  public void testAttrWithList() throws Exception {
    Attribute attr = buildAttribute("a1", "attr.label_list(allow_files = ['.xml'])");
    assertThat(attr.starlarkDefined()).isTrue();
    assertThat(attr.getAllowedFileTypesPredicate().apply("a.xml")).isTrue();
    assertThat(attr.getAllowedFileTypesPredicate().apply("a.txt")).isFalse();
    assertThat(attr.isSingleArtifact()).isFalse();
  }

  @Test
  public void testAttrSingleFileWithList() throws Exception {
    Attribute attr = buildAttribute("a1", "attr.label(allow_single_file = ['.xml'])");
    assertThat(attr.starlarkDefined()).isTrue();
    assertThat(attr.getAllowedFileTypesPredicate().apply("a.xml")).isTrue();
    assertThat(attr.getAllowedFileTypesPredicate().apply("a.txt")).isFalse();
    assertThat(attr.isSingleArtifact()).isTrue();
  }

  private static StarlarkProviderIdentifier legacy(String legacyId) {
    return StarlarkProviderIdentifier.forLegacy(legacyId);
  }

  private static StarlarkProviderIdentifier declared(String exportedName) {
    return StarlarkProviderIdentifier.forKey(new StarlarkProvider.Key(FAKE_LABEL, exportedName));
  }

  @Test
  public void testAttrWithProviders() throws Exception {
    Attribute attr =
        buildAttribute(
            "a1", //
            "b = provider()",
            "attr.label_list(allow_files = True, providers = ['a', b])");
    assertThat(attr.starlarkDefined()).isTrue();
    assertThat(attr.getRequiredProviders().isSatisfiedBy(set(legacy("a"), declared("b")))).isTrue();
    assertThat(attr.getRequiredProviders().isSatisfiedBy(set(legacy("a")))).isFalse();
  }

  @Test
  public void testAttrWithProvidersOneEmpty() throws Exception {
    Attribute attr =
        buildAttribute(
            "a1",
            "b = provider()",
            "attr.label_list(allow_files = True, providers = [['a', b],[]])");
    assertThat(attr.starlarkDefined()).isTrue();
    assertThat(attr.getRequiredProviders().acceptsAny()).isTrue();
  }

  @Test
  public void testAttrWithProvidersList() throws Exception {
    Attribute attr =
        buildAttribute(
            "a1",
            "b = provider()",
            "attr.label_list(allow_files = True, providers = [['a', b], ['c']])");
    assertThat(attr.starlarkDefined()).isTrue();
    assertThat(attr.getRequiredProviders().isSatisfiedBy(set(legacy("a"), declared("b")))).isTrue();
    assertThat(attr.getRequiredProviders().isSatisfiedBy(set(legacy("c")))).isTrue();
    assertThat(attr.getRequiredProviders().isSatisfiedBy(set(legacy("a")))).isFalse();
  }

  private static AdvertisedProviderSet set(StarlarkProviderIdentifier... ids) {
    AdvertisedProviderSet.Builder builder = AdvertisedProviderSet.builder();
    for (StarlarkProviderIdentifier id : ids) {
      builder.addStarlark(id);
    }
    return builder.build();
  }

  private void checkAttributeError(String expectedMessage, String... lines) throws Exception {
    ev.setFailFast(false);
    buildAttribute("fakeAttribute", lines);
    MoreAsserts.assertContainsEvent(ev.getEventCollector(), expectedMessage);
  }

  @Test
  public void testAttrWithWrongProvidersList() throws Exception {
    checkAttributeError(
        "element in 'providers' is of unexpected type. Either all elements should be providers,"
            + " or all elements should be lists of providers,"
            + " but got list with an element of type int.",
        "attr.label_list(allow_files = True,  providers = [['a', 1], ['c']])");

    checkAttributeError(
        "element in 'providers' is of unexpected type. Either all elements should be providers,"
            + " or all elements should be lists of providers,"
            + " but got an element of type string.",
        "b = provider()",
        "attr.label_list(allow_files = True,  providers = [['a', b], 'c'])");

    checkAttributeError(
        "element in 'providers' is of unexpected type. Either all elements should be providers,"
            + " or all elements should be lists of providers,"
            + " but got an element of type string.",
        "c = provider()",
        "attr.label_list(allow_files = True,  providers = [['a', b], c])");
  }

  @Test
  public void testLabelListWithAspects() throws Exception {
    evalAndExport(
        ev,
        "def _impl(target, ctx):",
        "   pass",
        "my_aspect = aspect(implementation = _impl)",
        "a = attr.label_list(aspects = [my_aspect])");
    StarlarkAttrModule.Descriptor attr = (StarlarkAttrModule.Descriptor) ev.lookup("a");
    StarlarkDefinedAspect aspect = (StarlarkDefinedAspect) ev.lookup("my_aspect");
    assertThat(aspect).isNotNull();
    assertThat(attr.build("xxx").getAspectClasses()).containsExactly(aspect.getAspectClass());
  }

  @Test
  public void testLabelWithAspects() throws Exception {
    evalAndExport(
        ev,
        "def _impl(target, ctx):",
        "   pass",
        "my_aspect = aspect(implementation = _impl)",
        "a = attr.label(aspects = [my_aspect])");
    StarlarkAttrModule.Descriptor attr = (StarlarkAttrModule.Descriptor) ev.lookup("a");
    StarlarkDefinedAspect aspect = (StarlarkDefinedAspect) ev.lookup("my_aspect");
    assertThat(aspect).isNotNull();
    assertThat(attr.build("xxx").getAspectClasses()).containsExactly(aspect.getAspectClass());
  }

  @Test
  public void testLabelListWithAspectsError() throws Exception {
    ev.checkEvalErrorContains(
        "at index 1 of aspects, got element of type int, want Aspect",
        "def _impl(target, ctx):",
        "   pass",
        "my_aspect = aspect(implementation = _impl)",
        "attr.label_list(aspects = [my_aspect, 123])");
  }

  @Test
  public void testAttrWithAspectRequiringAspects_stackOfRequiredAspects() throws Exception {
    evalAndExport(
        ev,
        "def _impl(target, ctx):",
        "   pass",
        "aspect_c = aspect(implementation = _impl)",
        "aspect_b = aspect(implementation = _impl, requires = [aspect_c])",
        "aspect_a = aspect(implementation = _impl, requires = [aspect_b])",
        "a = attr.label_list(aspects = [aspect_a])");
    StarlarkAttrModule.Descriptor attr = (StarlarkAttrModule.Descriptor) ev.lookup("a");

    StarlarkDefinedAspect aspectA = (StarlarkDefinedAspect) ev.lookup("aspect_a");
    assertThat(aspectA).isNotNull();
    StarlarkDefinedAspect aspectB = (StarlarkDefinedAspect) ev.lookup("aspect_b");
    assertThat(aspectB).isNotNull();
    StarlarkDefinedAspect aspectC = (StarlarkDefinedAspect) ev.lookup("aspect_c");
    assertThat(aspectC).isNotNull();
    List<AspectClass> expectedAspects =
        Arrays.asList(aspectA.getAspectClass(), aspectB.getAspectClass(), aspectC.getAspectClass());
    assertThat(attr.build("xxx").getAspectClasses()).containsExactlyElementsIn(expectedAspects);
  }

  @Test
  public void testAttrWithAspectRequiringAspects_aspectRequiredByMultipleAspects()
      throws Exception {
    evalAndExport(
        ev,
        "def _impl(target, ctx):",
        "   pass",
        "aspect_c = aspect(implementation = _impl)",
        "aspect_b = aspect(implementation = _impl, requires = [aspect_c])",
        "aspect_a = aspect(implementation = _impl, requires = [aspect_c])",
        "a = attr.label_list(aspects = [aspect_a, aspect_b])");
    StarlarkAttrModule.Descriptor attr = (StarlarkAttrModule.Descriptor) ev.lookup("a");

    StarlarkDefinedAspect aspectA = (StarlarkDefinedAspect) ev.lookup("aspect_a");
    assertThat(aspectA).isNotNull();
    StarlarkDefinedAspect aspectB = (StarlarkDefinedAspect) ev.lookup("aspect_b");
    assertThat(aspectB).isNotNull();
    StarlarkDefinedAspect aspectC = (StarlarkDefinedAspect) ev.lookup("aspect_c");
    assertThat(aspectC).isNotNull();
    List<AspectClass> expectedAspects =
        Arrays.asList(aspectA.getAspectClass(), aspectB.getAspectClass(), aspectC.getAspectClass());
    assertThat(attr.build("xxx").getAspectClasses()).containsExactlyElementsIn(expectedAspects);
  }

  @Test
  public void testAttrWithAspectRequiringAspects_aspectRequiredByMultipleAspects2()
      throws Exception {
    evalAndExport(
        ev,
        "def _impl(target, ctx):",
        "   pass",
        "aspect_d = aspect(implementation = _impl)",
        "aspect_c = aspect(implementation = _impl, requires = [aspect_d])",
        "aspect_b = aspect(implementation = _impl, requires = [aspect_d])",
        "aspect_a = aspect(implementation = _impl, requires = [aspect_b, aspect_c])",
        "a = attr.label_list(aspects = [aspect_a])");
    StarlarkAttrModule.Descriptor attr = (StarlarkAttrModule.Descriptor) ev.lookup("a");

    StarlarkDefinedAspect aspectA = (StarlarkDefinedAspect) ev.lookup("aspect_a");
    assertThat(aspectA).isNotNull();
    StarlarkDefinedAspect aspectB = (StarlarkDefinedAspect) ev.lookup("aspect_b");
    assertThat(aspectB).isNotNull();
    StarlarkDefinedAspect aspectC = (StarlarkDefinedAspect) ev.lookup("aspect_c");
    assertThat(aspectC).isNotNull();
    StarlarkDefinedAspect aspectD = (StarlarkDefinedAspect) ev.lookup("aspect_d");
    assertThat(aspectD).isNotNull();
    List<AspectClass> expectedAspects =
        Arrays.asList(
            aspectA.getAspectClass(),
            aspectB.getAspectClass(),
            aspectC.getAspectClass(),
            aspectD.getAspectClass());
    assertThat(attr.build("xxx").getAspectClasses()).containsExactlyElementsIn(expectedAspects);
  }

  @Test
  public void testAttrWithAspectRequiringAspects_requireExistingAspect_passed() throws Exception {
    evalAndExport(
        ev,
        "def _impl(target, ctx):",
        "   pass",
        "aspect_b = aspect(implementation = _impl)",
        "aspect_a = aspect(implementation = _impl, requires = [aspect_b])",
        "a = attr.label_list(aspects = [aspect_b, aspect_a])");
    StarlarkAttrModule.Descriptor attr = (StarlarkAttrModule.Descriptor) ev.lookup("a");

    StarlarkDefinedAspect aspectA = (StarlarkDefinedAspect) ev.lookup("aspect_a");
    assertThat(aspectA).isNotNull();
    StarlarkDefinedAspect aspectB = (StarlarkDefinedAspect) ev.lookup("aspect_b");
    assertThat(aspectB).isNotNull();
    List<AspectClass> expectedAspects =
        Arrays.asList(aspectA.getAspectClass(), aspectB.getAspectClass());
    assertThat(attr.build("xxx").getAspectClasses()).containsExactlyElementsIn(expectedAspects);
  }

  @Test
  public void testAttrWithAspectRequiringAspects_requireExistingAspect_failed() throws Exception {
    ev.setFailFast(false);

    evalAndExport(
        ev,
        "def _impl(target, ctx):",
        "   pass",
        "aspect_b = aspect(implementation = _impl)",
        "aspect_a = aspect(implementation = _impl, requires = [aspect_b])",
        "attr.label_list(aspects = [aspect_a, aspect_b])");

    ev.assertContainsError(
        String.format(
            "aspect %s%%aspect_b was added before as a required aspect of aspect %s%%aspect_a",
            FAKE_LABEL, FAKE_LABEL));
  }

  @Test
  public void testAspectExtraDeps() throws Exception {
    evalAndExport(
        ev,
        "def _impl(target, ctx):",
        "   pass",
        "my_aspect = aspect(_impl,",
        "   attrs = { '_extra_deps' : attr.label(default = Label('//foo/bar:baz')) }",
        ")");
    StarlarkDefinedAspect aspect = (StarlarkDefinedAspect) ev.lookup("my_aspect");
    Attribute attribute = Iterables.getOnlyElement(aspect.getAttributes());
    assertThat(attribute.getName()).isEqualTo("$extra_deps");
    assertThat(attribute.getDefaultValue(null))
        .isEqualTo(Label.parseCanonicalUnchecked("//foo/bar:baz"));
  }

  @Test
  public void testAspectParameter() throws Exception {
    evalAndExport(
        ev,
        "def _impl(target, ctx):",
        "   pass",
        "my_aspect = aspect(_impl,",
        "   attrs = { 'param' : attr.string(values=['a', 'b']) }",
        ")");
    StarlarkDefinedAspect aspect = (StarlarkDefinedAspect) ev.lookup("my_aspect");
    Attribute attribute = Iterables.getOnlyElement(aspect.getAttributes());
    assertThat(attribute.getName()).isEqualTo("param");
  }

  @Test
  public void testAspectParameterWithDefaultValue() throws Exception {
    evalAndExport(
        ev,
        "def _impl(target, ctx):",
        "   pass",
        "my_aspect = aspect(_impl,",
        "   attrs = { 'param' : attr.string(default = 'a', values=['a', 'b']) }",
        ")");
    StarlarkDefinedAspect aspect = (StarlarkDefinedAspect) ev.lookup("my_aspect");
    Attribute attribute = Iterables.getOnlyElement(aspect.getAttributes());
    assertThat(attribute.getName()).isEqualTo("param");
    assertThat(((String) attribute.getDefaultValueUnchecked())).isEqualTo("a");
  }

  @Test
  public void testAspectParameterBadDefaultValue() throws Exception {
    ev.checkEvalErrorContains(
        "Aspect parameter attribute 'param' has a bad default value: has to be"
            + " one of 'b' instead of 'a'",
        "def _impl(target, ctx):",
        "   pass",
        "my_aspect = aspect(_impl,",
        "   attrs = { 'param' : attr.string(default = 'a', values = ['b']) }",
        ")");
  }

  @Test
  public void testAspectParameterNotRequireValues() throws Exception {
    evalAndExport(
        ev,
        "def _impl(target, ctx):",
        "   pass",
        "my_aspect = aspect(_impl,",
        "   attrs = { 'param' : attr.string(default = 'val') }",
        ")");
    StarlarkDefinedAspect aspect = (StarlarkDefinedAspect) ev.lookup("my_aspect");
    Attribute attribute = Iterables.getOnlyElement(aspect.getAttributes());
    assertThat(attribute.getName()).isEqualTo("param");
    assertThat(((String) attribute.getDefaultValueUnchecked())).isEqualTo("val");
  }

  @Test
  public void testAspectParameterBadType() throws Exception {
    ev.checkEvalErrorContains(
        "Aspect parameter attribute 'param' must have type 'bool', 'int' or 'string'.",
        "def _impl(target, ctx):",
        "   pass",
        "my_aspect = aspect(_impl,",
        "   attrs = { 'param' : attr.label(default = Label('//foo/bar:baz')) }",
        ")");
  }

  @Test
  public void testAspectParameterAndExtraDeps() throws Exception {
    evalAndExport(
        ev,
        "def _impl(target, ctx):",
        "   pass",
        "my_aspect = aspect(_impl,",
        "   attrs = { 'param' : attr.string(values=['a', 'b']),",
        "             '_extra' : attr.label(default = Label('//foo/bar:baz')) }",
        ")");
    StarlarkDefinedAspect aspect = (StarlarkDefinedAspect) ev.lookup("my_aspect");
    assertThat(aspect.getAttributes()).hasSize(2);
    assertThat(aspect.getParamAttributes()).containsExactly("param");
  }

  @Test
  public void testAspectNoDefaultValueAttribute() throws Exception {
    ev.checkEvalErrorContains(
        "Aspect attribute '_extra_deps' has no default value",
        "def _impl(target, ctx):",
        "   pass",
        "my_aspect = aspect(_impl,",
        "   attrs = { '_extra_deps' : attr.label() }",
        ")");
  }

  @Test
  public void testAspectAddToolchain() throws Exception {
    evalAndExport(
        ev,
        "def _impl(ctx): pass",
        "a1 = aspect(_impl,",
        "    toolchains=[",
        "        '//test:my_toolchain_type1',",
        "        config_common.toolchain_type('//test:my_toolchain_type2'),",
        "        config_common.toolchain_type('//test:my_toolchain_type3', mandatory=False),",
        "        config_common.toolchain_type('//test:my_toolchain_type4', mandatory=True),",
        "    ],",
        ")");
    StarlarkDefinedAspect a = (StarlarkDefinedAspect) ev.lookup("a1");
    assertThat(a).hasToolchainType("//test:my_toolchain_type1");
    assertThat(a).toolchainType("//test:my_toolchain_type1").isMandatory();
    assertThat(a).hasToolchainType("//test:my_toolchain_type2");
    assertThat(a).toolchainType("//test:my_toolchain_type2").isMandatory();
    assertThat(a).hasToolchainType("//test:my_toolchain_type3");
    assertThat(a).toolchainType("//test:my_toolchain_type3").isOptional();
    assertThat(a).hasToolchainType("//test:my_toolchain_type4");
    assertThat(a).toolchainType("//test:my_toolchain_type4").isMandatory();
  }

  @Test
  public void testNonLabelAttrWithProviders() throws Exception {
    ev.checkEvalErrorContains(
        "unexpected keyword argument 'providers'", "attr.string(providers = ['a'])");
  }

  private static final RuleClass.ConfiguredTargetFactory<Object, Object, Exception>
      DUMMY_CONFIGURED_TARGET_FACTORY =
          ruleContext -> {
            throw new IllegalStateException();
          };

  private static RuleClass ruleClass(String name) {
    return new RuleClass.Builder(name, RuleClassType.NORMAL, false)
        .factory(DUMMY_CONFIGURED_TARGET_FACTORY)
        .add(Attribute.attr("tags", Type.STRING_LIST))
        .build();
  }

  @Test
  public void testAttrAllowedRuleClassesSpecificRuleClasses() throws Exception {
    Attribute attr =
        buildAttribute(
            "a", //
            "attr.label_list(allow_rules = ['java_binary'], allow_files = True)");
    assertThat(attr.getAllowedRuleClassObjectPredicate().apply(ruleClass("java_binary"))).isTrue();
    assertThat(attr.getAllowedRuleClassObjectPredicate().apply(ruleClass("genrule"))).isFalse();
  }

  @Test
  public void testAttrDefaultValue() throws Exception {
    Attribute attr = buildAttribute("a1", "attr.string(default = 'some value')");
    assertThat(attr.getDefaultValueUnchecked()).isEqualTo("some value");
  }

  @Test
  public void testLabelAttrDefaultValueAsString() throws Exception {
    Attribute sligleAttr = buildAttribute("a1", "attr.label(default = '//foo:bar')");
    assertThat(sligleAttr.getDefaultValueUnchecked())
        .isEqualTo(Label.parseCanonicalUnchecked("//foo:bar"));

    Attribute listAttr =
        buildAttribute("a2", "attr.label_list(default = ['//foo:bar', '//bar:foo'])");
    assertThat(listAttr.getDefaultValueUnchecked())
        .isEqualTo(
            ImmutableList.of(
                Label.parseCanonicalUnchecked("//foo:bar"),
                Label.parseCanonicalUnchecked("//bar:foo")));

    Attribute dictAttr =
        buildAttribute("a3", "attr.label_keyed_string_dict(default = {'//foo:bar': 'my value'})");
    assertThat(dictAttr.getDefaultValueUnchecked())
        .isEqualTo(ImmutableMap.of(Label.parseCanonicalUnchecked("//foo:bar"), "my value"));
  }

  @Test
  public void testLabelAttrDefaultValueAsStringBadValue() throws Exception {
    ev.checkEvalErrorContains(
        "invalid label '/foo:bar' in parameter 'default' of attribute 'label': "
            + "invalid package name '/foo': package names may not start with '/'",
        "attr.label(default = '/foo:bar')");

    ev.checkEvalErrorContains(
        "invalid label '/bar:foo' in element 1 of parameter 'default' of attribute "
            + "'label_list': invalid package name '/bar': package names may not start with '/'",
        "attr.label_list(default = ['//foo:bar', '/bar:foo'])");

    ev.checkEvalErrorContains(
        "invalid label '/bar:foo' in dict key element: invalid package name '/bar': "
            + "package names may not start with '/'",
        "attr.label_keyed_string_dict(default = {'//foo:bar': 'a', '/bar:foo': 'b'})");
  }

  @Test
  public void testAttrDefaultValueBadType() throws Exception {
    ev.checkEvalErrorContains("got value of type 'int', want 'string'", "attr.string(default = 1)");
  }

  @Test
  public void testAttrMandatory() throws Exception {
    Attribute attr = buildAttribute("a1", "attr.string(mandatory=True)");
    assertThat(attr.isMandatory()).isTrue();
    assertThat(attr.isNonEmpty()).isFalse();
  }

  @Test
  public void testAttrAllowEmpty() throws Exception {
    Attribute attr = buildAttribute("a1", "attr.string_list(allow_empty=False)");
    assertThat(attr.isNonEmpty()).isTrue();
    assertThat(attr.isMandatory()).isFalse();
  }

  @Test
  public void testAttrBadKeywordArguments() throws Exception {
    ev.checkEvalErrorContains(
        "string() got unexpected keyword argument 'bad_keyword'", "attr.string(bad_keyword = '')");
  }

  @Test
  public void testAttrCfgHostDisabled() throws Exception {
    setBuildLanguageOptions("--incompatible_disable_starlark_host_transitions");

    EvalException ex = assertThrows(EvalException.class, () -> ev.eval("attr.label(cfg = 'host')"));
    assertThat(ex).hasMessageThat().contains("Please use 'cfg = \"exec\"' instead");
  }

  @Test
  public void testAttrCfgTarget() throws Exception {
    Attribute attr = buildAttribute("a1", "attr.label(cfg = 'target', allow_files = True)");
    assertThat(NoTransition.isInstance(attr.getTransitionFactory())).isTrue();
  }

  @Test
  public void incompatibleDataTransition() {
    EvalException expected =
        assertThrows(EvalException.class, () -> ev.eval("attr.label(cfg = 'data')"));
    assertThat(expected).hasMessageThat().contains("cfg must be either 'target', 'exec'");
  }

  @Test
  public void testAttrValues() throws Exception {
    Attribute attr = buildAttribute("a1", "attr.string(values = ['ab', 'cd'])");
    PredicateWithMessage<Object> predicate = attr.getAllowedValues();
    assertThat(predicate.apply("ab")).isTrue();
    assertThat(predicate.apply("xy")).isFalse();
  }

  @Test
  public void testAttrIntValues() throws Exception {
    Attribute attr = buildAttribute("a1", "attr.int(values = [1, 2])");
    PredicateWithMessage<Object> predicate = attr.getAllowedValues();
    assertThat(predicate.apply(StarlarkInt.of(2))).isTrue();
    assertThat(predicate.apply(StarlarkInt.of(3))).isFalse();
  }

  @Test
  public void testAttrDoc(
      @TestParameter({
            "bool",
            "int",
            "int_list",
            "label",
            "label_keyed_string_dict",
            "label_list",
            "output",
            "output_list",
            "string",
            "string_dict",
            "string_list",
            "string_list_dict"
          })
          String attrType)
      throws Exception {
    Attribute documented =
        buildAttribute("documented", String.format("attr.%s(doc='foo')", attrType));
    assertThat(documented.getDoc()).isEqualTo("foo");
    Attribute documentedNeedingDedent =
        buildAttribute(
            "documented",
            String.format("attr.%s(doc='''foo\n\n    More details.\n    ''')", attrType));
    assertThat(documentedNeedingDedent.getDoc()).isEqualTo("foo\n\nMore details.");
    Attribute undocumented = buildAttribute("undocumented", String.format("attr.%s()", attrType));
    assertThat(undocumented.getDoc()).isNull();
  }

  @Test
  public void testNoAttrLicense() {
    EvalException expected = assertThrows(EvalException.class, () -> ev.eval("attr.license()"));
    assertThat(expected).hasMessageThat().contains("'attr' value has no field or method 'license'");
  }

  @Test
  public void testAttrDocValueBadType() throws Exception {
    ev.checkEvalErrorContains(
        "got value of type 'int', want 'string or NoneType'", "attr.string(doc = 1)");
  }

  @Test
  public void testRuleImplementation() throws Exception {
    evalAndExport(ev, "def impl(ctx): return None", "rule1 = rule(impl)");
    RuleClass c = ((StarlarkRuleFunction) ev.lookup("rule1")).getRuleClass();
    assertThat(c.getConfiguredTargetFunction().getName()).isEqualTo("impl");
  }

  @Test
  public void testRuleDoc() throws Exception {
    evalAndExport(
        ev,
        "def impl(ctx):",
        "    return None",
        "documented_rule = rule(impl, doc = 'My doc string')",
        "long_documented_rule = rule(",
        "    impl,",
        "    doc = '''Long doc",
        "",
        "             With details",
        "''',",
        ")",
        "undocumented_rule = rule(impl)");
    StarlarkRuleFunction documentedRule = (StarlarkRuleFunction) ev.lookup("documented_rule");
    StarlarkRuleFunction longDocumentedRule =
        (StarlarkRuleFunction) ev.lookup("long_documented_rule");
    StarlarkRuleFunction undocumentedRule = (StarlarkRuleFunction) ev.lookup("undocumented_rule");
    assertThat(documentedRule.getDocumentation()).hasValue("My doc string");
    assertThat(longDocumentedRule.getDocumentation()).hasValue("Long doc\n\nWith details");
    assertThat(undocumentedRule.getDocumentation()).isEmpty();
  }

  @Test
  public void testFunctionAsAttrDefault() throws Exception {
    ev.exec("def f(): pass");

    // Late-bound attributes, which are computed during analysis as a function
    // of the configuration, are only available for attributes involving labels:
    //   attr.label
    //   attr.label_list
    //   attr.label_keyed_string_dict
    //   attr.output,
    //   attr.output_list
    // (See testRuleClassImplicitOutputFunctionDependingOnComputedAttribute
    // for a more detailed positive test.)
    evalAndExport(
        ev,
        "attr.label(default=f)",
        "attr.label_list(default=f)",
        "attr.label_keyed_string_dict(default=f)");
    // For all other attribute types, the default value may not be a function.
    //
    // (This is a regression test for github.com/bazelbuild/bazel/issues/9463.
    // The loading-phase feature of "computed attribute defaults" is not exposed
    // to Starlark; the bug was that the @StarlarkMethod
    // annotation was more permissive than the method declaration.)
    ev.checkEvalErrorContains(
        "got value of type 'function', want 'string'", "attr.string(default=f)");
    ev.checkEvalErrorContains(
        "got value of type 'function', want 'sequence'", "attr.string_list(default=f)");
    ev.checkEvalErrorContains("got value of type 'function', want 'int'", "attr.int(default=f)");
    ev.checkEvalErrorContains(
        "got value of type 'function', want 'sequence'", "attr.int_list(default=f)");
    ev.checkEvalErrorContains("got value of type 'function', want 'bool'", "attr.bool(default=f)");
    ev.checkEvalErrorContains(
        "got value of type 'function', want 'dict'", "attr.string_dict(default=f)");
    ev.checkEvalErrorContains(
        "got value of type 'function', want 'dict'", "attr.string_list_dict(default=f)");
    // Note: attr.license appears to be disabled already.
    // (see --incompatible_no_attr_license)
  }

  private static final Label FAKE_LABEL = Label.parseCanonicalUnchecked("//fake/label.bzl");

  @Test
  public void testRuleAddAttribute() throws Exception {
    evalAndExport(ev, "def impl(ctx): return None", "r1 = rule(impl, attrs={'a1': attr.string()})");
    RuleClass c = ((StarlarkRuleFunction) ev.lookup("r1")).getRuleClass();
    assertThat(c.hasAttr("a1", Type.STRING)).isTrue();
  }

  private static void evalAndExport(BazelEvaluationTestCase ev, String... lines) throws Exception {
    ev.execAndExport(FAKE_LABEL, lines);
  }

  @Test
  public void testExportAliasedName() throws Exception {
    // When there are multiple names aliasing the same StarlarkExportable, the first one to be
    // declared should be used. Make sure we're not using lexicographical order, hash order,
    // non-deterministic order, or anything else.
    evalAndExport(
        ev,
        "def _impl(ctx): pass",
        "d = rule(implementation = _impl)",
        "a = d",
        // Having more names improves the chance that non-determinism will be caught.
        "b = d",
        "c = d",
        "e = d",
        "f = d",
        "foo = d",
        "bar = d",
        "baz = d",
        "x = d",
        "y = d",
        "z = d");
    String dName = ((StarlarkRuleFunction) ev.lookup("d")).getRuleClass().getName();
    String fooName = ((StarlarkRuleFunction) ev.lookup("foo")).getRuleClass().getName();
    assertThat(dName).isEqualTo("d");
    assertThat(fooName).isEqualTo("d");
  }

  @Test
  public void testOutputToGenfiles() throws Exception {
    evalAndExport(ev, "def impl(ctx): pass", "r1 = rule(impl, output_to_genfiles=True)");
    RuleClass c = ((StarlarkRuleFunction) ev.lookup("r1")).getRuleClass();
    assertThat(c.outputsToBindir()).isFalse();
  }

  @Test
  public void testRuleAddMultipleAttributes() throws Exception {
    evalAndExport(
        ev,
        "def impl(ctx): return None",
        "r1 = rule(impl,",
        "     attrs = {",
        "            'a1': attr.label_list(allow_files=True),",
        "            'a2': attr.int()",
        "})");
    RuleClass c = ((StarlarkRuleFunction) ev.lookup("r1")).getRuleClass();
    assertThat(c.hasAttr("a1", BuildType.LABEL_LIST)).isTrue();
    assertThat(c.hasAttr("a2", Type.INTEGER)).isTrue();
  }

  @Test
  public void testRuleAttributeFlag() throws Exception {
    evalAndExport(
        ev,
        "def impl(ctx): return None",
        "r1 = rule(impl, attrs = {'a1': attr.string(mandatory=True)})");
    RuleClass c = ((StarlarkRuleFunction) ev.lookup("r1")).getRuleClass();
    assertThat(c.getAttributeByName("a1").isMandatory()).isTrue();
  }

  @Test
  public void unknownRuleAttributeFlags_forbidden() throws Exception {
    ev.setFailFast(false);
    evalAndExport(
        ev,
        "def _impl(ctx): return None",
        "r1 = rule(_impl, attrs = { 'srcs': attr.label_list(flags = ['NO-SUCH-FLAG']) })");
    ev.assertContainsError("unknown attribute flag 'NO-SUCH-FLAG'");
  }

  @Test
  public void duplicateRuleAttributeFlags_forbidden() throws Exception {
    ev.setFailFast(false);
    evalAndExport(
        ev,
        "def _impl(ctx): return None",
        "r1 = rule(_impl, attrs = { 'srcs': attr.label_list(mandatory = True,",
        "                                                   flags = ['MANDATORY']) })");
    ev.assertContainsError("'MANDATORY' flag is already set");
  }

  @Test
  public void testRuleOutputs() throws Exception {
    evalAndExport(
        ev,
        "def impl(ctx): return None", //
        "r1 = rule(impl, outputs = {'a': 'a.txt'})");
    RuleClass c = ((StarlarkRuleFunction) ev.lookup("r1")).getRuleClass();
    ImplicitOutputsFunction function = c.getDefaultImplicitOutputsFunction();
    assertThat(function.getImplicitOutputs(ev.getEventHandler(), null)).containsExactly("a.txt");
  }

  @Test
  public void testRuleUnknownKeyword() throws Exception {
    registerDummyStarlarkFunction();
    ev.checkEvalErrorContains(
        "unexpected keyword argument 'bad_keyword'", "rule(impl, bad_keyword = 'some text')");
  }

  @Test
  public void testRuleImplementationMissing() throws Exception {
    ev.checkEvalErrorContains(
        "rule() missing 1 required positional argument: implementation", "rule(attrs = {})");
  }

  @Test
  public void testRuleBadTypeForAdd() throws Exception {
    registerDummyStarlarkFunction();
    ev.checkEvalErrorContains(
        "in call to rule(), parameter 'attrs' got value of type 'string', want 'dict'",
        "rule(impl, attrs = 'some text')");
  }

  @Test
  public void testRuleBadTypeInAdd() throws Exception {
    registerDummyStarlarkFunction();
    ev.checkEvalErrorContains(
        "got dict<string, string> for 'attrs', want dict<string, Attribute>",
        "rule(impl, attrs = {'a1': 'some text'})");
  }

  @Test
  public void testRuleBadTypeForDoc() throws Exception {
    registerDummyStarlarkFunction();
    ev.checkEvalErrorContains(
        "got value of type 'int', want 'string or NoneType'", "rule(impl, doc = 1)");
  }

  @Test
  public void testLabel() throws Exception {
    Object result = ev.eval("Label('//foo/foo:foo')");
    assertThat(result).isInstanceOf(Label.class);
    assertThat(result.toString()).isEqualTo("//foo/foo:foo");
  }

  @Test
  public void testLabelIdempotence() throws Exception {
    Object result = ev.eval("Label(Label('//foo/foo:foo'))");
    assertThat(result).isInstanceOf(Label.class);
    assertThat(result.toString()).isEqualTo("//foo/foo:foo");
  }

  @Test
  public void testLabelSameInstance() throws Exception {
    Object l1 = ev.eval("Label('//foo/foo:foo')");
    // Implicitly creates a new pkgContext and environment, yet labels should be the same.
    Object l2 = ev.eval("Label('//foo/foo:foo')");
    assertThat(l1).isSameInstanceAs(l2);
  }

  @Test
  public void testLabelNameAndPackage() throws Exception {
    Object result = ev.eval("Label('//foo/bar:baz').name");
    assertThat(result).isEqualTo("baz");
    // NB: implicitly creates a new pkgContext and environments, yet labels should be the same.
    result = ev.eval("Label('//foo/bar:baz').package");
    assertThat(result).isEqualTo("foo/bar");
  }

  @Test
  public void testRuleLabelDefaultValue() throws Exception {
    evalAndExport(
        ev,
        "def impl(ctx): return None\n"
            + "r1 = rule(impl, attrs = {'a1': "
            + "attr.label(default = Label('//foo:foo'), allow_files=True)})");
    RuleClass c = ((StarlarkRuleFunction) ev.lookup("r1")).getRuleClass();
    Attribute a = c.getAttributeByName("a1");
    assertThat(a.getDefaultValueUnchecked()).isInstanceOf(Label.class);
    assertThat(a.getDefaultValueUnchecked().toString()).isEqualTo("//foo:foo");
  }

  @Test
  public void testIntDefaultValue() throws Exception {
    evalAndExport(
        ev,
        "def impl(ctx): return None",
        "r1 = rule(impl, attrs = {'a1': attr.int(default = 40+2)})");
    RuleClass c = ((StarlarkRuleFunction) ev.lookup("r1")).getRuleClass();
    Attribute a = c.getAttributeByName("a1");
    assertThat(a.getDefaultValueUnchecked()).isEqualTo(StarlarkInt.of(42));
  }

  @Test
  public void testIntDefaultValueMustBeInt32() throws Exception {
    // This is a test of the loading phase. Move somewhere more appropriate.
    ev.checkEvalErrorContains(
        "for parameter 'default' of attribute '', got 4294967296, want value in signed 32-bit"
            + " range",
        "attr.int(default = 0x10000 * 0x10000)");
    ev.checkEvalErrorContains(
        "for element 0 of parameter 'default' of attribute '', got 4294967296, want value in"
            + " signed 32-bit range",
        "attr.int_list(default = [0x10000 * 0x10000])");
  }

  @Test
  public void testIntAttributeValueMustBeInt32() throws Exception {
    // This is a test of the loading phase. Move somewhere more appropriate.
    scratch.file(
        "p/inc.bzl", //
        "def _impl(ctx): pass",
        "r = rule(_impl, attrs = dict(i=attr.int()))");
    scratch.file(
        "p/BUILD", //
        "load('inc.bzl', 'r')",
        "r(name = 'p', i = 0x10000 * 0x10000)");
    AssertionError expected = assertThrows(AssertionError.class, () -> createRuleContext("//p"));
    assertThat(expected)
        .hasMessageThat()
        .contains(
            "for attribute 'i' in 'r' rule, got 4294967296, want value in signed 32-bit range");
  }

  @Test
  public void testIntegerConcatTruncates() throws Exception {
    // The Type.INTEGER.concat operator, as used to resolve select(int)+select(int)
    // after rule construction, has a range of int32.
    scratch.file(
        "p/BUILD", //
        "s = select({'//conditions:default': -0x7fffffff})", // -0x7fffffff + -0x7fffffff = 2
        "cc_test(name='c', shard_count = s+s)");
    StarlarkRuleContext context = createRuleContext("//p:c");
    assertThat(context.getAttr().getValue("shard_count")).isEqualTo(StarlarkInt.of(2));
  }

  @Test
  public void testRuleInheritsBaseRuleAttributes() throws Exception {
    evalAndExport(ev, "def impl(ctx): return None", "r1 = rule(impl)");
    RuleClass c = ((StarlarkRuleFunction) ev.lookup("r1")).getRuleClass();
    assertThat(c.hasAttr("tags", Type.STRING_LIST)).isTrue();
    assertThat(c.hasAttr("visibility", BuildType.NODEP_LABEL_LIST)).isTrue();
    assertThat(c.hasAttr("deprecation", Type.STRING)).isTrue();
    assertThat(c.hasAttr(":action_listener", BuildType.LABEL_LIST))
        .isTrue(); // required for extra actions
  }

  private void checkTextMessage(String from, String... lines) throws Exception {
    Object result = ev.eval(from);
    String expect = "";
    if (lines.length > 0) {
      expect = Joiner.on("\n").join(lines) + "\n";
    }
    assertThat(result).isEqualTo(expect);
  }

  @Test
  public void testSimpleTextMessagesBooleanFields() throws Exception {
    checkTextMessage("struct(name=True).to_proto()", "name: true");
    checkTextMessage("struct(name=False).to_proto()", "name: false");
  }

  @Test
  public void testStructRestrictedOverrides() throws Exception {
    ev.checkEvalErrorContains(
        "cannot override built-in struct function 'to_json'", "struct(to_json='foo')");

    ev.checkEvalErrorContains(
        "cannot override built-in struct function 'to_proto'", "struct(to_proto='foo')");
  }

  @Test
  public void testSimpleTextMessages() throws Exception {
    checkTextMessage("struct(name='value').to_proto()", "name: \"value\"");
    checkTextMessage("struct(name=[]).to_proto()"); // empty lines
    checkTextMessage("struct(name=['a', 'b']).to_proto()", "name: \"a\"", "name: \"b\"");
    checkTextMessage("struct(name=123).to_proto()", "name: 123");
    checkTextMessage(
        "struct(a=1.2e34, b=float('nan'), c=float('-inf'), d=float('+inf')).to_proto()",
        "a: 1.2e+34",
        "b: nan",
        "c: -inf",
        // Caution! textproto requires +inf be encoded as "inf" rather than "+inf"
        "d: inf");
    checkTextMessage("struct(name=123).to_proto()", "name: 123");
    checkTextMessage("struct(name=[1, 2, 3]).to_proto()", "name: 1", "name: 2", "name: 3");
    checkTextMessage("struct(a=struct(b='b')).to_proto()", "a {", "  b: \"b\"", "}");
    checkTextMessage(
        "struct(a=[struct(b='x'), struct(b='y')]).to_proto()",
        "a {",
        "  b: \"x\"",
        "}",
        "a {",
        "  b: \"y\"",
        "}");
    checkTextMessage(
        "struct(a=struct(b=struct(c='c'))).to_proto()", "a {", "  b {", "    c: \"c\"", "  }", "}");
    // dict to_proto tests
    checkTextMessage("struct(name={}).to_proto()"); // empty lines
    checkTextMessage(
        "struct(name={'a': 'b'}).to_proto()", "name {", "  key: \"a\"", "  value: \"b\"", "}");
    checkTextMessage(
        "struct(name={'c': 'd', 'a': 'b'}).to_proto()",
        "name {",
        "  key: \"c\"",
        "  value: \"d\"",
        "}",
        "name {",
        "  key: \"a\"",
        "  value: \"b\"",
        "}");
    checkTextMessage(
        "struct(x=struct(y={'a': 1})).to_proto()",
        "x {",
        "  y {",
        "    key: \"a\"",
        "    value: 1",
        "  }",
        "}");
    checkTextMessage(
        "struct(name={'a': struct(b=1, c=2)}).to_proto()",
        "name {",
        "  key: \"a\"",
        "  value {",
        "    b: 1",
        "    c: 2",
        "  }",
        "}");
    checkTextMessage(
        "struct(name={'a': struct(b={4: 'z', 3: 'y'}, c=2)}).to_proto()",
        "name {",
        "  key: \"a\"",
        "  value {",
        "    b {",
        "      key: 4",
        "      value: \"z\"",
        "    }",
        "    b {",
        "      key: 3",
        "      value: \"y\"",
        "    }",
        "    c: 2",
        "  }",
        "}");
  }

  @Test
  public void testNoneStructValue() throws Exception {
    checkTextMessage(
        "proto.encode_text(struct(a=1, b=None, nested=struct(c=2, d=None)))",
        "a: 1",
        "nested {",
        "  c: 2",
        "}");
  }

  @Test
  public void testProtoFieldsOrder() throws Exception {
    checkTextMessage("struct(d=4, b=2, c=3, a=1).to_proto()", "a: 1", "b: 2", "c: 3", "d: 4");
  }

  @Test
  public void testTextMessageEscapes() throws Exception {
    checkTextMessage("struct(name='a\"b').to_proto()", "name: \"a\\\"b\"");
    checkTextMessage("struct(name='a\\'b').to_proto()", "name: \"a'b\"");
    checkTextMessage("struct(name='a\\nb').to_proto()", "name: \"a\\nb\"");

    // struct(name="a\\\"b") -> name: "a\\\"b"
    checkTextMessage("struct(name='a\\\\\\\"b').to_proto()", "name: \"a\\\\\\\"b\"");
  }

  @Test
  public void testTextMessageInvalidStructure() throws Exception {
    // list in list
    ev.checkEvalErrorContains(
        "in struct field .a: at list index 0: got list, want string, int, float, bool, or struct",
        "struct(a=[['b']]).to_proto()");

    // dict in list
    ev.checkEvalErrorContains(
        "in struct field .a: at list index 0: got dict, want string, int, float, bool, or struct",
        "struct(a=[{'b': 1}]).to_proto()");

    // tuple as dict key
    ev.checkEvalErrorContains(
        "in struct field .a: invalid dict key: got tuple, want int or string",
        "struct(a={(1, 2): 3}).to_proto()");

    // dict in dict
    ev.checkEvalErrorContains(
        "in struct field .name: in value for dict key \"a\": got dict, want string, int, float,"
            + " bool, or struct",
        "struct(name={'a': {'b': [1, 2]}}).to_proto()");

    // callable in field
    ev.checkEvalErrorContains(
        "in struct field .a: got builtin_function_or_method, want string, int, float, bool, or"
            + " struct",
        "struct(a=rule).to_proto()");
  }

  private void checkJson(String from, String expected) throws Exception {
    Object result = ev.eval(from);
    assertThat(result).isEqualTo(expected);
  }

  @Test
  public void testStarlarkJsonModule() throws Exception {
    // struct.to_json is deprecated.
    // java.starlark.net's json module is its replacement.
    setBuildLanguageOptions("--incompatible_struct_has_no_methods=false");
    checkJson("json.encode(struct(name=True))", "{\"name\":true}");
    checkJson("json.encode([1, 2])", "[1,2]"); // works for non-structs too
    checkJson("str(dir(struct()))", "[\"to_json\", \"to_proto\"]");

    setBuildLanguageOptions("--incompatible_struct_has_no_methods=true");
    ev.checkEvalErrorContains("no field or method 'to_json'", "struct(name=True).to_json()");
    checkJson("str(dir(struct()))", "[]"); // no to_{json,proto}
  }

  @Test
  public void testJsonBooleanFields() throws Exception {
    checkJson("struct(name=True).to_json()", "{\"name\":true}");
    checkJson("struct(name=False).to_json()", "{\"name\":false}");
  }

  @Test
  public void testJsonDictFields() throws Exception {
    checkJson("struct(config={}).to_json()", "{\"config\":{}}");
    checkJson("struct(config={'key': 'value'}).to_json()", "{\"config\":{\"key\":\"value\"}}");
    ev.checkEvalErrorContains(
        "Keys must be a string but got a int for struct field 'config'",
        "struct(config={1:2}).to_json()");
    ev.checkEvalErrorContains(
        "Keys must be a string but got a int for dict value 'foo'",
        "struct(config={'foo':{1:2}}).to_json()");
    ev.checkEvalErrorContains(
        "Keys must be a string but got a bool for struct field 'config'",
        "struct(config={True: False}).to_json()");
  }

  @Test
  public void testJsonEncoding() throws Exception {
    checkJson("struct(name='value').to_json()", "{\"name\":\"value\"}");
    checkJson("struct(name=['a', 'b']).to_json()", "{\"name\":[\"a\",\"b\"]}");
    checkJson("struct(name=123).to_json()", "{\"name\":123}");
    checkJson("struct(name=[1, 2, 3]).to_json()", "{\"name\":[1,2,3]}");
    checkJson("struct(a=struct(b='b')).to_json()", "{\"a\":{\"b\":\"b\"}}");
    checkJson(
        "struct(a=[struct(b='x'), struct(b='y')]).to_json()",
        "{\"a\":[{\"b\":\"x\"},{\"b\":\"y\"}]}");
    checkJson("struct(a=struct(b=struct(c='c'))).to_json()", "{\"a\":{\"b\":{\"c\":\"c\"}}}");
  }

  @Test
  public void testJsonEscapes() throws Exception {
    checkJson("struct(name='a\"b').to_json()", "{\"name\":\"a\\\"b\"}");
    checkJson("struct(name='a\\'b').to_json()", "{\"name\":\"a'b\"}");
    checkJson("struct(name='a\\\\b').to_json()", "{\"name\":\"a\\\\b\"}");
    checkJson("struct(name='a\\nb').to_json()", "{\"name\":\"a\\nb\"}");
    checkJson("struct(name='a\\rb').to_json()", "{\"name\":\"a\\rb\"}");
    checkJson("struct(name='a\\tb').to_json()", "{\"name\":\"a\\tb\"}");
  }

  @Test
  public void testJsonNestedListStructure() throws Exception {
    checkJson("struct(a=[['b']]).to_json()", "{\"a\":[[\"b\"]]}");
  }

  @Test
  public void testJsonInvalidStructure() throws Exception {
    ev.checkEvalErrorContains(
        "Invalid text format, expected a struct, a string, a bool, or an int but got a "
            + "builtin_function_or_method for struct field 'a'",
        "struct(a=rule).to_json()");
  }

  @Test
  public void testLabelAttrWrongDefault() throws Exception {
    ev.checkEvalErrorContains(
        "got value of type 'int', want 'Label, string, LateBoundDefault, function, or NoneType'",
        "attr.label(default = 123)");
  }

  @Test
  public void testLabelGetRelative() throws Exception {
    assertThat(ev.eval("Label('//foo:bar').relative('baz')").toString()).isEqualTo("//foo:baz");
    assertThat(ev.eval("Label('//foo:bar').relative('//baz:qux')").toString())
        .isEqualTo("//baz:qux");
  }

  @Test
  public void testLabelGetRelativeSyntaxError() throws Exception {
    ev.checkEvalErrorContains(
        "invalid target name 'bad//syntax': target names may not contain '//' path separators",
        "Label('//foo:bar').relative('bad//syntax')");
  }

  @Test
  public void testStructCreation() throws Exception {
    // TODO(fwe): cannot be handled by current testing suite
    ev.exec("x = struct(a = 1, b = 2)");
    assertThat(ev.lookup("x")).isInstanceOf(Structure.class);
  }

  @Test
  public void testStructFields() throws Exception {
    // TODO(fwe): cannot be handled by current testing suite
    ev.exec("x = struct(a = 1, b = 2)");
    Structure x = (Structure) ev.lookup("x");
    assertThat(x.getValue("a")).isEqualTo(StarlarkInt.of(1));
    assertThat(x.getValue("b")).isEqualTo(StarlarkInt.of(2));

    // Update is prohibited.
    ev.checkEvalErrorContains(
        "struct value does not support field assignment", "x = struct(a = 1); x.a = 2");
  }

  @Test
  public void testStructEquality() throws Exception {
    assertThat((Boolean) ev.eval("struct(a = 1, b = 2) == struct(b = 2, a = 1)")).isTrue();
    assertThat((Boolean) ev.eval("struct(a = 1) == struct(a = 1, b = 2)")).isFalse();
    assertThat((Boolean) ev.eval("struct(a = 1, b = 2) == struct(a = 1)")).isFalse();
    // Compare a recursive object to itself to make sure reference equality is checked
    ev.exec("s = struct(a = 1, b = []); s.b.append(s)");
    assertThat((Boolean) ev.eval("s == s")).isTrue();
    assertThat((Boolean) ev.eval("struct(a = 1, b = 2) == struct(a = 1, b = 3)")).isFalse();
    assertThat((Boolean) ev.eval("struct(a = 1) == [1]")).isFalse();
    assertThat((Boolean) ev.eval("[1] == struct(a = 1)")).isFalse();
    assertThat((Boolean) ev.eval("struct() == struct()")).isTrue();
    assertThat((Boolean) ev.eval("struct() == struct(a = 1)")).isFalse();

    ev.exec("foo = provider(); bar = provider()");
    assertThat((Boolean) ev.eval("struct(a = 1) == foo(a = 1)")).isFalse();
    assertThat((Boolean) ev.eval("foo(a = 1) == struct(a = 1)")).isFalse();
    assertThat((Boolean) ev.eval("foo(a = 1) == bar(a = 1)")).isFalse();
    assertThat((Boolean) ev.eval("foo(a = 1) == foo(a = 1)")).isTrue();
  }

  @Test
  public void testStructIncomparability() throws Exception {
    ev.checkEvalErrorContains(
        "unsupported comparison: struct <=> struct", "struct(a = 1) < struct(a = 2)");
    ev.checkEvalErrorContains(
        "unsupported comparison: struct <=> struct", "struct(a = 1) > struct(a = 2)");
    ev.checkEvalErrorContains(
        "unsupported comparison: struct <=> struct", "struct(a = 1) <= struct(a = 2)");
    ev.checkEvalErrorContains(
        "unsupported comparison: struct <=> struct", "struct(a = 1) >= struct(a = 2)");
  }

  @Test
  public void testStructAccessingFieldsFromStarlark() throws Exception {
    ev.exec("x = struct(a = 1, b = 2)", "x1 = x.a", "x2 = x.b");
    assertThat(ev.lookup("x1")).isEqualTo(StarlarkInt.of(1));
    assertThat(ev.lookup("x2")).isEqualTo(StarlarkInt.of(2));
  }

  @Test
  public void testStructAccessingUnknownField() throws Exception {
    ev.checkEvalErrorContains(
        "'struct' value has no field or method 'c'\n" + "Available attributes: a, b",
        "x = struct(a = 1, b = 2)",
        "y = x.c");
  }

  @Test
  public void testStructAccessingUnknownFieldWithArgs() throws Exception {
    ev.checkEvalErrorContains(
        "'struct' value has no field or method 'c'", "x = struct(a = 1, b = 2)", "y = x.c()");
  }

  @Test
  public void testStructAccessingNonFunctionFieldWithArgs() throws Exception {
    ev.checkEvalErrorContains(
        "'int' object is not callable", "x = struct(a = 1, b = 2)", "x1 = x.a(1)");
  }

  @Test
  public void testStructAccessingFunctionFieldWithArgs() throws Exception {
    ev.exec("def f(x): return x+5", "x = struct(a = f, b = 2)", "x1 = x.a(1)");
    assertThat(ev.lookup("x1")).isEqualTo(StarlarkInt.of(6));
  }

  @Test
  public void testStructPosArgs() throws Exception {
    ev.checkEvalErrorContains(
        "struct() got unexpected positional argument", "x = struct(1, b = 2)");
  }

  @Test
  public void testStructConcatenationFieldNames() throws Exception {
    // TODO(fwe): cannot be handled by current testing suite
    ev.exec(
        "x = struct(a = 1, b = 2)", //
        "y = struct(c = 1, d = 2)",
        "z = x + y\n");
    StructImpl z = (StructImpl) ev.lookup("z");
    assertThat(z.getFieldNames()).containsExactly("a", "b", "c", "d");
  }

  @Test
  public void testStructConcatenationFieldValues() throws Exception {
    // TODO(fwe): cannot be handled by current testing suite
    ev.exec(
        "x = struct(a = 1, b = 2)", //
        "y = struct(c = 1, d = 2)",
        "z = x + y\n");
    StructImpl z = (StructImpl) ev.lookup("z");
    assertThat(z.getValue("a")).isEqualTo(StarlarkInt.of(1));
    assertThat(z.getValue("b")).isEqualTo(StarlarkInt.of(2));
    assertThat(z.getValue("c")).isEqualTo(StarlarkInt.of(1));
    assertThat(z.getValue("d")).isEqualTo(StarlarkInt.of(2));
  }

  @Test
  public void testStructConcatenationCommonFields() throws Exception {
    ev.checkEvalErrorContains(
        "cannot add struct instances with common field 'a'",
        "x = struct(a = 1, b = 2)",
        "y = struct(c = 1, a = 2)",
        "z = x + y\n");
  }

  @Test
  public void testConditionalStructConcatenation() throws Exception {
    // TODO(fwe): cannot be handled by current testing suite
    ev.exec(
        "def func():",
        "  x = struct(a = 1, b = 2)",
        "  if True:",
        "    x += struct(c = 1, d = 2)",
        "  return x",
        "x = func()");
    StructImpl x = (StructImpl) ev.lookup("x");
    assertThat(x.getValue("a")).isEqualTo(StarlarkInt.of(1));
    assertThat(x.getValue("b")).isEqualTo(StarlarkInt.of(2));
    assertThat(x.getValue("c")).isEqualTo(StarlarkInt.of(1));
    assertThat(x.getValue("d")).isEqualTo(StarlarkInt.of(2));
  }

  @Test
  public void testGetattrNoAttr() throws Exception {
    ev.checkEvalErrorContains(
        "'struct' value has no field or method 'b'\nAvailable attributes: a",
        "s = struct(a='val')",
        "getattr(s, 'b')");
  }

  @Test
  public void testGetattr() throws Exception {
    ev.exec("s = struct(a='val')", "x = getattr(s, 'a')", "y = getattr(s, 'b', 'def')");
    assertThat(ev.lookup("x")).isEqualTo("val");
    assertThat(ev.lookup("y")).isEqualTo("def");
  }

  @Test
  public void testHasattr() throws Exception {
    ev.exec(
        "s = struct(a=1)", //
        "x = hasattr(s, 'a')",
        "y = hasattr(s, 'b')\n");
    assertThat(ev.lookup("x")).isEqualTo(true);
    assertThat(ev.lookup("y")).isEqualTo(false);
  }

  @Test
  public void testStructStr() throws Exception {
    assertThat(ev.eval("str(struct(x = 2, y = 3, z = 4))"))
        .isEqualTo("struct(x = 2, y = 3, z = 4)");
  }

  @Test
  public void testStructsInSets() throws Exception {
    ev.exec("depset([struct(a='a')])");
  }

  @Test
  public void testStructsInDicts() throws Exception {
    ev.exec("d = {struct(a = 1): 'aa', struct(b = 2): 'bb'}");
    assertThat(ev.eval("d[struct(a = 1)]")).isEqualTo("aa");
    assertThat(ev.eval("d[struct(b = 2)]")).isEqualTo("bb");
    assertThat(ev.eval("str([d[k] for k in d])")).isEqualTo("[\"aa\", \"bb\"]");

    ev.checkEvalErrorContains("unhashable type: 'struct'", "{struct(a = []): 'foo'}");
  }

  @Test
  public void testStructDictMembersAreMutable() throws Exception {
    ev.exec(
        "s = struct(x = {'a' : 1})", //
        "s.x['b'] = 2\n");
    assertThat(((StructImpl) ev.lookup("s")).getValue("x"))
        .isEqualTo(ImmutableMap.of("a", StarlarkInt.of(1), "b", StarlarkInt.of(2)));
  }

  @Test
  public void testDepsetGoodCompositeItem() throws Exception {
    ev.exec("def func():", "  return depset([struct(a='a')])", "s = func()");
    ImmutableList<?> result = ((Depset) ev.lookup("s")).toList();
    assertThat(result).hasSize(1);
    assertThat(result.get(0)).isInstanceOf(StructImpl.class);
  }

  private static StructImpl makeStruct(String field, Object value) {
    return StructProvider.STRUCT.create(ImmutableMap.of(field, value), "no field '%'");
  }

  private static StructImpl makeBigStruct(@Nullable Mutability mu) {
    // struct(a=[struct(x={1:1}), ()], b=(), c={2:2})
    return StructProvider.STRUCT.create(
        ImmutableMap.of(
            "a",
                StarlarkList.<Object>of(
                    mu,
                    StructProvider.STRUCT.create(
                        ImmutableMap.of("x", dictOf(mu, 1, 1)), "no field '%s'"),
                    Tuple.of()),
            "b", Tuple.of(),
            "c", dictOf(mu, 2, 2)),
        "no field '%s'");
  }

  private static Dict<Object, Object> dictOf(@Nullable Mutability mu, int k, int v) {
    return Dict.builder().put(StarlarkInt.of(k), StarlarkInt.of(v)).build(mu);
  }

  @Test
  public void testStructMutabilityShallow() {
    assertThat(Starlark.isImmutable(makeStruct("a", StarlarkInt.of(1)))).isTrue();
  }

  private static StarlarkList<Object> makeList(@Nullable Mutability mu) {
    return StarlarkList.of(mu, StarlarkInt.of(1), StarlarkInt.of(2), StarlarkInt.of(3));
  }

  @Test
  public void testStructMutabilityDeep() {
    assertThat(Starlark.isImmutable(Tuple.of(makeList(null)))).isTrue();
    assertThat(Starlark.isImmutable(makeStruct("a", makeList(null)))).isTrue();
    assertThat(Starlark.isImmutable(makeBigStruct(null))).isTrue();

    Mutability mu = Mutability.create("test");
    assertThat(Starlark.isImmutable(Tuple.of(makeList(mu)))).isFalse();
    assertThat(Starlark.isImmutable(makeStruct("a", makeList(mu)))).isFalse();
    assertThat(Starlark.isImmutable(makeBigStruct(mu))).isFalse();
  }

  @Test
  public void declaredProviders() throws Exception {
    evalAndExport(ev, "data = provider()", "d = data(x = 1, y ='abc')", "d_x = d.x", "d_y = d.y");
    assertThat(ev.lookup("d_x")).isEqualTo(StarlarkInt.of(1));
    assertThat(ev.lookup("d_y")).isEqualTo("abc");
    StarlarkProvider dataConstructor = (StarlarkProvider) ev.lookup("data");
    StructImpl data = (StructImpl) ev.lookup("d");
    assertThat(data.getProvider()).isEqualTo(dataConstructor);
    assertThat(dataConstructor.isExported()).isTrue();
    assertThat(dataConstructor.getPrintableName()).isEqualTo("data");
    assertThat(dataConstructor.getKey()).isEqualTo(new StarlarkProvider.Key(FAKE_LABEL, "data"));
  }

  @Test
  public void declaredProviderDocumentation() throws Exception {
    evalAndExport(
        ev,
        "UndocumentedInfo = provider()",
        "DocumentedInfo = provider(doc = '''",
        "    My documented provider",
        "",
        "    Details''')",
        // Note fields below are not alphabetized
        "SchemafulWithoutDocsInfo = provider(fields = ['b', 'a'])",
        "SchemafulWithDocsInfo = provider(fields = {'b': 'Field b', 'a': 'Field\\n    a'})");

    StarlarkProvider undocumentedInfo = (StarlarkProvider) ev.lookup("UndocumentedInfo");
    StarlarkProvider documentedInfo = (StarlarkProvider) ev.lookup("DocumentedInfo");
    StarlarkProvider schemafulWithoutDocsInfo =
        (StarlarkProvider) ev.lookup("SchemafulWithoutDocsInfo");
    StarlarkProvider schemafulWithDocsInfo = (StarlarkProvider) ev.lookup("SchemafulWithDocsInfo");

    assertThat(undocumentedInfo.getDocumentation()).isEmpty();
    assertThat(documentedInfo.getDocumentation()).hasValue("My documented provider\n\nDetails");
    assertThat(schemafulWithoutDocsInfo.getSchema())
        .containsExactly("b", Optional.empty(), "a", Optional.empty());
    assertThat(schemafulWithDocsInfo.getSchema())
        .containsExactly("b", Optional.of("Field b"), "a", Optional.of("Field\na"));
  }

  @Test
  public void declaredProvidersWithInit() throws Exception {
    evalAndExport(
        ev,
        "def _data_init(x, y = 'abc'):", //
        "    return {'x': x, 'y': y}",
        "data, _new_data = provider(init = _data_init)",
        "d1 = data(x = 1)  # normal provider constructor",
        "d1_x = d1.x",
        "d1_y = d1.y",
        "d2 = data(1, 'def')  # normal provider constructor invoked with positional arguments",
        "d2_x = d2.x",
        "d2_y = d2.y",
        "d3 = _new_data(x = 2, y = 'xyz')  # raw constructor",
        "d3_x = d3.x",
        "d3_y = d3.y");

    assertThat(ev.lookup("d1_x")).isEqualTo(StarlarkInt.of(1));
    assertThat(ev.lookup("d1_y")).isEqualTo("abc");
    assertThat(ev.lookup("d2_x")).isEqualTo(StarlarkInt.of(1));
    assertThat(ev.lookup("d2_y")).isEqualTo("def");
    assertThat(ev.lookup("d3_x")).isEqualTo(StarlarkInt.of(2));
    assertThat(ev.lookup("d3_y")).isEqualTo("xyz");
    StarlarkProvider dataConstructor = (StarlarkProvider) ev.lookup("data");
    StarlarkCallable rawConstructor = (StarlarkCallable) ev.lookup("_new_data");
    assertThat(rawConstructor).isNotInstanceOf(Provider.class);
    assertThat(dataConstructor.getInit().getName()).isEqualTo("_data_init");

    StructImpl data1 = (StructImpl) ev.lookup("d1");
    StructImpl data2 = (StructImpl) ev.lookup("d2");
    StructImpl data3 = (StructImpl) ev.lookup("d3");
    assertThat(data1.getProvider()).isEqualTo(dataConstructor);
    assertThat(data2.getProvider()).isEqualTo(dataConstructor);
    assertThat(data3.getProvider()).isEqualTo(dataConstructor);
    assertThat(dataConstructor.isExported()).isTrue();
    assertThat(dataConstructor.getPrintableName()).isEqualTo("data");
    assertThat(dataConstructor.getKey()).isEqualTo(new StarlarkProvider.Key(FAKE_LABEL, "data"));
  }

  @Test
  public void declaredProvidersWithFailingInit_rawConstructorSucceeds() throws Exception {
    evalAndExport(
        ev,
        "def _data_failing_init(x):", //
        "    fail('_data_failing_init fails')",
        "data, _new_data = provider(init = _data_failing_init)");

    StarlarkProvider dataConstructor = (StarlarkProvider) ev.lookup("data");

    evalAndExport(ev, "d = _new_data(x = 1)  # raw constructor");
    StructImpl data = (StructImpl) ev.lookup("d");
    assertThat(data.getProvider()).isEqualTo(dataConstructor);
  }

  @Test
  public void declaredProvidersWithFailingInit_normalConstructorFails() throws Exception {
    evalAndExport(
        ev,
        "def _data_failing_init(x):", //
        "    fail('_data_failing_init fails')",
        "data, _new_data = provider(init = _data_failing_init)");

    ev.checkEvalErrorContains("_data_failing_init fails", "d = data(x = 1)  # normal constructor");
    assertThat(ev.lookup("d")).isNull();
  }

  @Test
  public void declaredProvidersWithInitReturningInvalidType_normalConstructorFails()
      throws Exception {
    evalAndExport(
        ev,
        "def _data_invalid_init(x):", //
        "    return 'INVALID'",
        "data, _new_data = provider(init = _data_invalid_init)");

    ev.checkEvalErrorContains(
        "got string for 'return value of provider init()', want dict",
        "d = data(x = 1)  # normal constructor");
    assertThat(ev.lookup("d")).isNull();
  }

  @Test
  public void declaredProvidersWithInitReturningInvalidDict_normalConstructorFails()
      throws Exception {
    evalAndExport(
        ev,
        "def _data_invalid_init(x):", //
        "    return {('x', 'x', 'x'): x}",
        "data, _new_data = provider(init = _data_invalid_init)");

    ev.checkEvalErrorContains(
        "got dict<tuple, int> for 'return value of provider init()'",
        "d = data(x = 1)  # normal constructor");
    assertThat(ev.lookup("d")).isNull();
  }

  @Test
  public void declaredProvidersWithInitReturningUnexpectedFields_normalConstructorFails()
      throws Exception {
    evalAndExport(
        ev,
        "def _data_unexpected_fields_init(x):", //
        "    return {'x': x, 'y': x * 2}",
        "data, _new_data = provider(fields = ['x'], init = _data_unexpected_fields_init)");

    ev.checkEvalErrorContains(
        "got unexpected field 'y' in call to instantiate provider data",
        "d = data(x = 1)  # normal constructor");
    assertThat(ev.lookup("d")).isNull();
  }

  @Test
  public void declaredProvidersConcatSuccess() throws Exception {
    evalAndExport(
        ev,
        "data = provider()",
        "dx = data(x = 1)",
        "dy = data(y = 'abc')",
        "dxy = dx + dy",
        "x = dxy.x",
        "y = dxy.y");
    assertThat(ev.lookup("x")).isEqualTo(StarlarkInt.of(1));
    assertThat(ev.lookup("y")).isEqualTo("abc");
    StarlarkProvider dataConstructor = (StarlarkProvider) ev.lookup("data");
    StructImpl dx = (StructImpl) ev.lookup("dx");
    assertThat(dx.getProvider()).isEqualTo(dataConstructor);
    StructImpl dy = (StructImpl) ev.lookup("dy");
    assertThat(dy.getProvider()).isEqualTo(dataConstructor);
  }

  @Test
  public void declaredProvidersWithInitConcatSuccess() throws Exception {
    evalAndExport(
        ev,
        "def _data_init(x):",
        "    return {'x': x}",
        "data, _new_data = provider(init = _data_init)",
        "dx = data(x = 1)  # normal constructor",
        "dy = _new_data(y = 'abc')  # raw constructor",
        "dxy = dx + dy",
        "x = dxy.x",
        "y = dxy.y");
    assertThat(ev.lookup("x")).isEqualTo(StarlarkInt.of(1));
    assertThat(ev.lookup("y")).isEqualTo("abc");
    StarlarkProvider dataConstructor = (StarlarkProvider) ev.lookup("data");
    StructImpl dx = (StructImpl) ev.lookup("dx");
    assertThat(dx.getProvider()).isEqualTo(dataConstructor);
    StructImpl dy = (StructImpl) ev.lookup("dy");
    assertThat(dy.getProvider()).isEqualTo(dataConstructor);
  }

  @Test
  public void declaredProvidersConcatError() throws Exception {
    evalAndExport(ev, "data1 = provider()", "data2 = provider()");

    ev.checkEvalErrorContains(
        "Cannot use '+' operator on instances of different providers (data1 and data2)",
        "d1 = data1(x = 1)",
        "d2 = data2(y = 2)",
        "d = d1 + d2");
  }

  @Test
  public void declaredProvidersWithFieldsConcatSuccess() throws Exception {
    evalAndExport(
        ev,
        "data = provider(fields=['f1', 'f2'])",
        "d1 = data(f1 = 4)",
        "d2 = data(f2 = 5)",
        "d3 = d1 + d2",
        "f1 = d3.f1",
        "f2 = d3.f2");
    assertThat(ev.lookup("f1")).isEqualTo(StarlarkInt.of(4));
    assertThat(ev.lookup("f2")).isEqualTo(StarlarkInt.of(5));
  }

  @Test
  public void declaredProvidersWithFieldsConcatError() throws Exception {
    evalAndExport(ev, "data1 = provider(fields=['f1', 'f2'])", "data2 = provider(fields=['f3'])");
    ev.checkEvalErrorContains(
        "Cannot use '+' operator on instances of different providers (data1 and data2)",
        "d1 = data1(f1=1, f2=2)",
        "d2 = data2(f3=3)",
        "d = d1 + d2");
  }

  @Test
  public void declaredProvidersWithOverlappingFieldsConcatError() throws Exception {
    evalAndExport(ev, "data = provider(fields=['f1', 'f2'])");
    ev.checkEvalErrorContains(
        "cannot add struct instances with common field 'f1'",
        "d1 = data(f1 = 4)",
        "d2 = data(f1 = 5)",
        "d1 + d2");
  }

  @Test
  public void structsAsDeclaredProvidersTest() throws Exception {
    evalAndExport(ev, "data = struct(x = 1)");
    StructImpl data = (StructImpl) ev.lookup("data");
    assertThat(StructProvider.STRUCT.isExported()).isTrue();
    assertThat(data.getProvider()).isEqualTo(StructProvider.STRUCT);
    assertThat(data.getProvider().getKey()).isEqualTo(StructProvider.STRUCT.getKey());
  }

  @Test
  public void declaredProvidersDoc() throws Exception {
    evalAndExport(ev, "data1 = provider(doc='foo')");
  }

  @Test
  public void declaredProvidersBadTypeForDoc() throws Exception {
    ev.checkEvalErrorContains(
        "got value of type 'int', want 'string or NoneType'", "provider(doc = 1)");
  }

  @Test
  public void aspectAttrs() throws Exception {
    evalAndExport(
        ev,
        "def _impl(target, ctx):", //
        "   pass",
        "my_aspect = aspect(_impl, attr_aspects=['srcs', 'data'])");

    StarlarkDefinedAspect myAspect = (StarlarkDefinedAspect) ev.lookup("my_aspect");
    assertThat(myAspect.getAttributeAspects()).containsExactly("srcs", "data");
    assertThat(myAspect.getDefinition(AspectParameters.EMPTY).propagateAlong("srcs")).isTrue();
    assertThat(myAspect.getDefinition(AspectParameters.EMPTY).propagateAlong("data")).isTrue();
    assertThat(myAspect.getDefinition(AspectParameters.EMPTY).propagateAlong("other")).isFalse();
  }

  @Test
  public void aspectAllAttrs() throws Exception {
    evalAndExport(
        ev,
        "def _impl(target, ctx):", //
        "   pass",
        "my_aspect = aspect(_impl, attr_aspects=['*'])");

    StarlarkDefinedAspect myAspect = (StarlarkDefinedAspect) ev.lookup("my_aspect");
    assertThat(myAspect.getAttributeAspects()).containsExactly("*");
    assertThat(myAspect.getDefinition(AspectParameters.EMPTY).propagateAlong("foo")).isTrue();
  }

  @Test
  public void aspectRequiredAspectProvidersSingle() throws Exception {
    evalAndExport(
        ev,
        "def _impl(target, ctx):",
        "   pass",
        "cc = provider()",
        "my_aspect = aspect(_impl, required_aspect_providers=['java', cc])");
    StarlarkDefinedAspect myAspect = (StarlarkDefinedAspect) ev.lookup("my_aspect");
    RequiredProviders requiredProviders =
        myAspect.getDefinition(AspectParameters.EMPTY).getRequiredProvidersForAspects();
    assertThat(requiredProviders.isSatisfiedBy(AdvertisedProviderSet.ANY)).isTrue();
    assertThat(requiredProviders.isSatisfiedBy(AdvertisedProviderSet.EMPTY)).isFalse();
    assertThat(
            requiredProviders.isSatisfiedBy(
                AdvertisedProviderSet.builder()
                    .addStarlark(declared("cc"))
                    .addStarlark("java")
                    .build()))
        .isTrue();
    assertThat(
            requiredProviders.isSatisfiedBy(
                AdvertisedProviderSet.builder().addStarlark("cc").build()))
        .isFalse();
  }

  @Test
  public void aspectRequiredAspectProvidersAlternatives() throws Exception {
    evalAndExport(
        ev,
        "def _impl(target, ctx):",
        "   pass",
        "cc = provider()",
        "my_aspect = aspect(_impl, required_aspect_providers=[['java'], [cc]])");
    StarlarkDefinedAspect myAspect = (StarlarkDefinedAspect) ev.lookup("my_aspect");
    RequiredProviders requiredProviders =
        myAspect.getDefinition(AspectParameters.EMPTY).getRequiredProvidersForAspects();
    assertThat(requiredProviders.isSatisfiedBy(AdvertisedProviderSet.ANY)).isTrue();
    assertThat(requiredProviders.isSatisfiedBy(AdvertisedProviderSet.EMPTY)).isFalse();
    assertThat(
            requiredProviders.isSatisfiedBy(
                AdvertisedProviderSet.builder().addStarlark("java").build()))
        .isTrue();
    assertThat(
            requiredProviders.isSatisfiedBy(
                AdvertisedProviderSet.builder().addStarlark(declared("cc")).build()))
        .isTrue();
    assertThat(
            requiredProviders.isSatisfiedBy(
                AdvertisedProviderSet.builder().addStarlark("prolog").build()))
        .isFalse();
  }

  @Test
  public void aspectRequiredAspectProvidersEmpty() throws Exception {
    evalAndExport(
        ev,
        "def _impl(target, ctx):",
        "   pass",
        "my_aspect = aspect(_impl, required_aspect_providers=[])");
    StarlarkDefinedAspect myAspect = (StarlarkDefinedAspect) ev.lookup("my_aspect");
    RequiredProviders requiredProviders =
        myAspect.getDefinition(AspectParameters.EMPTY).getRequiredProvidersForAspects();
    assertThat(requiredProviders.isSatisfiedBy(AdvertisedProviderSet.ANY)).isFalse();
    assertThat(requiredProviders.isSatisfiedBy(AdvertisedProviderSet.EMPTY)).isFalse();
  }

  @Test
  public void aspectRequiredAspectProvidersDefault() throws Exception {
    evalAndExport(
        ev,
        "def _impl(target, ctx):", //
        "   pass",
        "my_aspect = aspect(_impl)");
    StarlarkDefinedAspect myAspect = (StarlarkDefinedAspect) ev.lookup("my_aspect");
    RequiredProviders requiredProviders =
        myAspect.getDefinition(AspectParameters.EMPTY).getRequiredProvidersForAspects();
    assertThat(requiredProviders.isSatisfiedBy(AdvertisedProviderSet.ANY)).isFalse();
    assertThat(requiredProviders.isSatisfiedBy(AdvertisedProviderSet.EMPTY)).isFalse();
  }

  @Test
  public void aspectRequiredProvidersNotAllowedWithApplyToGeneratingRules() throws Exception {
    ev.checkEvalErrorContains(
        "An aspect cannot simultaneously have required providers and apply to generating rules.",
        "prov = provider()",
        "def _impl(target, ctx):",
        "   pass",
        "my_aspect = aspect(_impl,",
        "   required_providers = [prov],",
        "   apply_to_generating_rules = True",
        ")");
  }

  @Test
  public void aspectRequiredProvidersSingle() throws Exception {
    evalAndExport(
        ev,
        "def _impl(target, ctx):",
        "   pass",
        "cc = provider()",
        "my_aspect = aspect(_impl, required_providers=['java', cc])");
    StarlarkDefinedAspect myAspect = (StarlarkDefinedAspect) ev.lookup("my_aspect");
    RequiredProviders requiredProviders =
        myAspect.getDefinition(AspectParameters.EMPTY).getRequiredProviders();

    assertThat(requiredProviders.isSatisfiedBy(AdvertisedProviderSet.ANY)).isTrue();
    assertThat(requiredProviders.isSatisfiedBy(AdvertisedProviderSet.EMPTY)).isFalse();
    assertThat(
            requiredProviders.isSatisfiedBy(
                AdvertisedProviderSet.builder()
                    .addStarlark(declared("cc"))
                    .addStarlark("java")
                    .build()))
        .isTrue();
    assertThat(
            requiredProviders.isSatisfiedBy(
                AdvertisedProviderSet.builder().addStarlark(declared("cc")).build()))
        .isFalse();
  }

  @Test
  public void aspectRequiredProvidersAlternatives() throws Exception {
    evalAndExport(
        ev,
        "def _impl(target, ctx):",
        "   pass",
        "cc = provider()",
        "my_aspect = aspect(_impl, required_providers=[['java'], [cc]])");
    StarlarkDefinedAspect myAspect = (StarlarkDefinedAspect) ev.lookup("my_aspect");
    RequiredProviders requiredProviders =
        myAspect.getDefinition(AspectParameters.EMPTY).getRequiredProviders();

    assertThat(requiredProviders.isSatisfiedBy(AdvertisedProviderSet.ANY)).isTrue();
    assertThat(requiredProviders.isSatisfiedBy(AdvertisedProviderSet.EMPTY)).isFalse();
    assertThat(
            requiredProviders.isSatisfiedBy(
                AdvertisedProviderSet.builder().addStarlark("java").build()))
        .isTrue();
    assertThat(
            requiredProviders.isSatisfiedBy(
                AdvertisedProviderSet.builder().addStarlark(declared("cc")).build()))
        .isTrue();
    assertThat(
            requiredProviders.isSatisfiedBy(
                AdvertisedProviderSet.builder().addStarlark("prolog").build()))
        .isFalse();
  }

  @Test
  public void aspectRequiredProvidersEmpty() throws Exception {
    evalAndExport(
        ev,
        "def _impl(target, ctx):",
        "   pass",
        "my_aspect = aspect(_impl, required_providers=[])");
    StarlarkDefinedAspect myAspect = (StarlarkDefinedAspect) ev.lookup("my_aspect");
    RequiredProviders requiredProviders =
        myAspect.getDefinition(AspectParameters.EMPTY).getRequiredProviders();

    assertThat(requiredProviders.isSatisfiedBy(AdvertisedProviderSet.ANY)).isTrue();
    assertThat(requiredProviders.isSatisfiedBy(AdvertisedProviderSet.EMPTY)).isTrue();
  }

  @Test
  public void aspectRequiredProvidersDefault() throws Exception {
    evalAndExport(
        ev,
        "def _impl(target, ctx):", //
        "   pass",
        "my_aspect = aspect(_impl)");
    StarlarkDefinedAspect myAspect = (StarlarkDefinedAspect) ev.lookup("my_aspect");
    RequiredProviders requiredProviders =
        myAspect.getDefinition(AspectParameters.EMPTY).getRequiredProviders();

    assertThat(requiredProviders.isSatisfiedBy(AdvertisedProviderSet.ANY)).isTrue();
    assertThat(requiredProviders.isSatisfiedBy(AdvertisedProviderSet.EMPTY)).isTrue();
  }

  @Test
  public void aspectProvides() throws Exception {
    evalAndExport(
        ev,
        "def _impl(target, ctx):",
        "   pass",
        "y = provider()",
        "my_aspect = aspect(_impl, provides = ['x', y])");
    StarlarkDefinedAspect myAspect = (StarlarkDefinedAspect) ev.lookup("my_aspect");
    AdvertisedProviderSet advertisedProviders =
        myAspect.getDefinition(AspectParameters.EMPTY).getAdvertisedProviders();
    assertThat(advertisedProviders.canHaveAnyProvider()).isFalse();
    assertThat(advertisedProviders.getStarlarkProviders())
        .containsExactly(legacy("x"), declared("y"));
  }

  @Test
  public void aspectProvidesError() throws Exception {
    ev.setFailFast(false);
    evalAndExport(
        ev,
        "def _impl(target, ctx):",
        "   pass",
        "y = provider()",
        "my_aspect = aspect(_impl, provides = ['x', 1])");
    MoreAsserts.assertContainsEvent(
        ev.getEventCollector(),
        " Illegal argument: element in 'provides' is of unexpected type."
            + " Should be list of providers, but got item of type int. ");
  }

  @Test
  public void aspectDoc() throws Exception {
    evalAndExport(
        ev,
        "def _impl(target, ctx):", //
        "   pass",
        "documented_aspect = aspect(_impl, doc='My doc string')",
        "long_documented_aspect = aspect(",
        "    implementation = _impl,",
        "    doc='''",
        "           My doc string",
        "           ",
        "           With details''',",
        ")",
        "undocumented_aspect = aspect(_impl)");

    StarlarkDefinedAspect documentedAspect = (StarlarkDefinedAspect) ev.lookup("documented_aspect");
    assertThat(documentedAspect.getDocumentation()).hasValue("My doc string");
    StarlarkDefinedAspect longDocumentedAspect =
        (StarlarkDefinedAspect) ev.lookup("long_documented_aspect");
    assertThat(longDocumentedAspect.getDocumentation()).hasValue("My doc string\n\nWith details");
    StarlarkDefinedAspect undocumentedAspect =
        (StarlarkDefinedAspect) ev.lookup("undocumented_aspect");
    assertThat(undocumentedAspect.getDocumentation()).isEmpty();
  }

  @Test
  public void aspectBadTypeForDoc() throws Exception {
    registerDummyStarlarkFunction();
    ev.checkEvalErrorContains(
        "got value of type 'int', want 'string or NoneType'", "aspect(impl, doc = 1)");
  }

  @Test
  public void fancyExports() throws Exception {
    evalAndExport(
        ev,
        "def _impla(target, ctx): pass",
        "p, (a, p1) = [",
        "   provider(),",
        "   [ aspect(_impla),",
        "     provider() ]",
        "]");
    StarlarkProvider p = (StarlarkProvider) ev.lookup("p");
    StarlarkDefinedAspect a = (StarlarkDefinedAspect) ev.lookup("a");
    StarlarkProvider p1 = (StarlarkProvider) ev.lookup("p1");
    assertThat(p.getPrintableName()).isEqualTo("p");
    assertThat(p.getKey()).isEqualTo(new StarlarkProvider.Key(FAKE_LABEL, "p"));
    assertThat(p1.getPrintableName()).isEqualTo("p1");
    assertThat(p1.getKey()).isEqualTo(new StarlarkProvider.Key(FAKE_LABEL, "p1"));
    assertThat(a.getAspectClass()).isEqualTo(new StarlarkAspectClass(FAKE_LABEL, "a"));
  }

  @Test
  public void multipleTopLevels() throws Exception {
    evalAndExport(
        ev,
        "p = provider()", //
        "p1 = p");
    StarlarkProvider p = (StarlarkProvider) ev.lookup("p");
    StarlarkProvider p1 = (StarlarkProvider) ev.lookup("p1");
    assertThat(p).isEqualTo(p1);
    assertThat(p.getKey()).isEqualTo(new StarlarkProvider.Key(FAKE_LABEL, "p"));
    assertThat(p1.getKey()).isEqualTo(new StarlarkProvider.Key(FAKE_LABEL, "p"));
  }

  @Test
  public void providerWithFields() throws Exception {
    evalAndExport(
        ev,
        "p = provider(fields = ['x', 'y'])", //
        "p1 = p(x = 1, y = 2)",
        "x = p1.x",
        "y = p1.y");
    StarlarkProvider p = (StarlarkProvider) ev.lookup("p");
    StarlarkInfo p1 = (StarlarkInfo) ev.lookup("p1");

    assertThat(p1.getProvider()).isEqualTo(p);
    assertThat(ev.lookup("x")).isEqualTo(StarlarkInt.of(1));
    assertThat(ev.lookup("y")).isEqualTo(StarlarkInt.of(2));
  }

  @Test
  public void providerWithFieldsDict() throws Exception {
    evalAndExport(
        ev,
        "p = provider(fields = { 'x' : 'I am x', 'y' : 'I am y'})",
        "p1 = p(x = 1, y = 2)",
        "x = p1.x",
        "y = p1.y");
    StarlarkProvider p = (StarlarkProvider) ev.lookup("p");
    StarlarkInfo p1 = (StarlarkInfo) ev.lookup("p1");

    assertThat(p1.getProvider()).isEqualTo(p);
    assertThat(ev.lookup("x")).isEqualTo(StarlarkInt.of(1));
    assertThat(ev.lookup("y")).isEqualTo(StarlarkInt.of(2));
  }

  @Test
  public void providerWithFieldsOptional() throws Exception {
    evalAndExport(
        ev,
        "p = provider(fields = ['x', 'y'])", //
        "p1 = p(y = 2)",
        "y = p1.y");
    StarlarkProvider p = (StarlarkProvider) ev.lookup("p");
    StarlarkInfo p1 = (StarlarkInfo) ev.lookup("p1");

    assertThat(p1.getProvider()).isEqualTo(p);
    assertThat(ev.lookup("y")).isEqualTo(StarlarkInt.of(2));
  }

  @Test
  public void providerWithFieldsOptionalError() throws Exception {
    ev.setFailFast(false);
    evalAndExport(
        ev,
        "p = provider(fields = ['x', 'y'])", //
        "p1 = p(y = 2)",
        "x = p1.x");
    MoreAsserts.assertContainsEvent(
        ev.getEventCollector(), " 'p' value has no field or method 'x'");
  }

  @Test
  public void providerWithExtraFieldsError() throws Exception {
    ev.setFailFast(false);
    evalAndExport(ev, "p = provider(fields = ['x', 'y'])", "p1 = p(x = 1, y = 2, z = 3)");
    MoreAsserts.assertContainsEvent(
        ev.getEventCollector(), "got unexpected field 'z' in call to instantiate provider p");
  }

  @Test
  public void providerWithEmptyFieldsError() throws Exception {
    ev.setFailFast(false);
    evalAndExport(
        ev,
        "p = provider(fields = [])", //
        "p1 = p(x = 1, y = 2, z = 3)");
    MoreAsserts.assertContainsEvent(
        ev.getEventCollector(),
        "got unexpected fields 'x', 'y', 'z' in call to instantiate provider p");
  }

  @Test
  public void providerWithDuplicateFieldsError() throws Exception {
    ev.setFailFast(false);
    evalAndExport(
        ev,
        "p = provider(fields = ['a', 'b'])", //
        "p(a = 1, b = 2, **dict(b = 3))");
    MoreAsserts.assertContainsEvent(
        ev.getEventCollector(),
        "got multiple values for parameter b in call to instantiate provider p");
  }

  @Test
  public void starTheOnlyAspectArg() throws Exception {
    ev.checkEvalErrorContains(
        "'*' must be the only string in 'attr_aspects' list",
        "def _impl(target, ctx):",
        "   pass",
        "aspect(_impl, attr_aspects=['*', 'foo'])");
  }

  @Test
  public void testMandatoryConfigParameterForExecutableLabels() throws Exception {
    scratch.file(
        "third_party/foo/extension.bzl",
        "def _main_rule_impl(ctx):",
        "    pass",
        "my_rule = rule(_main_rule_impl,",
        "    attrs = { ",
        "        'exe' : attr.label(executable = True, allow_files = True),",
        "    },",
        ")");
    scratch.file(
        "third_party/foo/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "my_rule(name = 'main', exe = ':tool.sh')");

    AssertionError expected =
        assertThrows(AssertionError.class, () -> createRuleContext("//third_party/foo:main"));
    assertThat(expected)
        .hasMessageThat()
        .contains("cfg parameter is mandatory when executable=True is provided.");
  }

  @Test
  public void testRuleAddToolchain() throws Exception {
    evalAndExport(
        ev,
        "def impl(ctx): return None",
        "r1 = rule(impl,",
        "    toolchains=[",
        "        '//test:my_toolchain_type1',",
        "        config_common.toolchain_type('//test:my_toolchain_type2'),",
        "        config_common.toolchain_type('//test:my_toolchain_type3', mandatory=False),",
        "        config_common.toolchain_type('//test:my_toolchain_type4', mandatory=True),",
        "    ],",
        ")");
    RuleClass c = ((StarlarkRuleFunction) ev.lookup("r1")).getRuleClass();
    assertThat(c).hasToolchainType("//test:my_toolchain_type1");
    assertThat(c).toolchainType("//test:my_toolchain_type1").isMandatory();
    assertThat(c).hasToolchainType("//test:my_toolchain_type2");
    assertThat(c).toolchainType("//test:my_toolchain_type2").isMandatory();
    assertThat(c).hasToolchainType("//test:my_toolchain_type3");
    assertThat(c).toolchainType("//test:my_toolchain_type3").isOptional();
    assertThat(c).hasToolchainType("//test:my_toolchain_type4");
    assertThat(c).toolchainType("//test:my_toolchain_type4").isMandatory();
  }

  @Test
  public void testRuleAddToolchain_duplicate() throws Exception {
    evalAndExport(
        ev,
        "def impl(ctx): return None",
        "r1 = rule(impl,",
        "    toolchains=[",
        "        '//test:my_toolchain_type1',",
        "        config_common.toolchain_type('//test:my_toolchain_type1'),",
        "        config_common.toolchain_type('//test:my_toolchain_type2', mandatory = False),",
        "        config_common.toolchain_type('//test:my_toolchain_type2', mandatory = True),",
        "        config_common.toolchain_type('//test:my_toolchain_type3', mandatory = False),",
        "        config_common.toolchain_type('//test:my_toolchain_type3', mandatory = False),",
        "    ],",
        ")");

    RuleClass c = ((StarlarkRuleFunction) ev.lookup("r1")).getRuleClass();
    assertThat(c).hasToolchainType("//test:my_toolchain_type1");
    assertThat(c).toolchainType("//test:my_toolchain_type1").isMandatory();
    assertThat(c).hasToolchainType("//test:my_toolchain_type2");
    assertThat(c).toolchainType("//test:my_toolchain_type2").isMandatory();
    assertThat(c).hasToolchainType("//test:my_toolchain_type3");
    assertThat(c).toolchainType("//test:my_toolchain_type3").isOptional();
  }

  @Test
  public void testRuleAddExecutionConstraints() throws Exception {
    registerDummyStarlarkFunction();
    evalAndExport(
        ev,
        "r1 = rule(",
        "  implementation = impl,",
        "  exec_compatible_with=['//constraint:cv1', '//constraint:cv2'],",
        ")");
    RuleClass c = ((StarlarkRuleFunction) ev.lookup("r1")).getRuleClass();
    assertThat(c.getExecutionPlatformConstraints())
        .containsExactly(
            Label.parseCanonicalUnchecked("//constraint:cv1"),
            Label.parseCanonicalUnchecked("//constraint:cv2"));
  }

  @Test
  public void testRuleAddExecGroup() throws Exception {
    registerDummyStarlarkFunction();
    evalAndExport(
        ev,
        "plum = rule(",
        "  implementation = impl,",
        "  exec_groups = {",
        "    'group': exec_group(",
        "      toolchains=[",
        "        '//test:my_toolchain_type1',",
        "        config_common.toolchain_type('//test:my_toolchain_type2'),",
        "        config_common.toolchain_type('//test:my_toolchain_type3', mandatory=False),",
        "        config_common.toolchain_type('//test:my_toolchain_type4', mandatory=True),",
        "      ],",
        "      exec_compatible_with=['//constraint:cv1', '//constraint:cv2'],",
        "    ),",
        "  },",
        ")");
    RuleClass plum = ((StarlarkRuleFunction) ev.lookup("plum")).getRuleClass();
    assertThat(plum.getToolchainTypes()).isEmpty();
    ExecGroup execGroup = plum.getExecGroups().get("group");
    assertThat(execGroup).hasToolchainType("//test:my_toolchain_type1");
    assertThat(execGroup).toolchainType("//test:my_toolchain_type1").isMandatory();
    assertThat(execGroup).hasToolchainType("//test:my_toolchain_type2");
    assertThat(execGroup).toolchainType("//test:my_toolchain_type2").isMandatory();
    assertThat(execGroup).hasToolchainType("//test:my_toolchain_type3");
    assertThat(execGroup).toolchainType("//test:my_toolchain_type3").isOptional();
    assertThat(execGroup).hasToolchainType("//test:my_toolchain_type4");
    assertThat(execGroup).toolchainType("//test:my_toolchain_type4").isMandatory();

    assertThat(plum.getExecutionPlatformConstraints()).isEmpty();
    assertThat(execGroup).hasExecCompatibleWith("//constraint:cv1");
    assertThat(execGroup).hasExecCompatibleWith("//constraint:cv2");
  }

  @Test
  public void testRuleFunctionReturnsNone() throws Exception {
    scratch.file(
        "test/rule.bzl",
        "def _impl(ctx):",
        "  pass",
        "foo_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {'params': attr.string_list()},",
        ")");
    scratch.file(
        "test/BUILD",
        "load(':rule.bzl', 'foo_rule')",
        "r = foo_rule(name='foo')", // Custom rule should return None
        "c = cc_library(name='cc')", // Native rule should return None
        "",
        "foo_rule(",
        "    name='check',",
        "    params = [type(r), type(c)]",
        ")");
    invalidatePackages();
    StarlarkRuleContext context = createRuleContext("//test:check");
    @SuppressWarnings("unchecked")
    StarlarkList<Object> params = (StarlarkList<Object>) context.getAttr().getValue("params");
    assertThat(params.get(0)).isEqualTo("NoneType");
    assertThat(params.get(1)).isEqualTo("NoneType");
  }

  @Test
  public void testTypeOfStruct() throws Exception {
    ev.exec("p = type(struct)", "s = type(struct())");

    assertThat(ev.lookup("p")).isEqualTo("Provider");
    assertThat(ev.lookup("s")).isEqualTo("struct");
  }

  @Test
  public void testCreateExecGroup() throws Exception {
    evalAndExport(
        ev,
        "group = exec_group(",
        "  toolchains=[",
        "    '//test:my_toolchain_type1',",
        "    config_common.toolchain_type('//test:my_toolchain_type2'),",
        "    config_common.toolchain_type('//test:my_toolchain_type3', mandatory=False),",
        "    config_common.toolchain_type('//test:my_toolchain_type4', mandatory=True),",
        "  ],",
        "  exec_compatible_with=['//constraint:cv1', '//constraint:cv2'],",
        ")");
    ExecGroup group = ((ExecGroup) ev.lookup("group"));
    assertThat(group).hasToolchainType("//test:my_toolchain_type1");
    assertThat(group).toolchainType("//test:my_toolchain_type1").isMandatory();
    assertThat(group).hasToolchainType("//test:my_toolchain_type2");
    assertThat(group).toolchainType("//test:my_toolchain_type2").isMandatory();
    assertThat(group).hasToolchainType("//test:my_toolchain_type3");
    assertThat(group).toolchainType("//test:my_toolchain_type3").isOptional();
    assertThat(group).hasToolchainType("//test:my_toolchain_type4");
    assertThat(group).toolchainType("//test:my_toolchain_type4").isMandatory();

    assertThat(group).hasExecCompatibleWith("//constraint:cv1");
    assertThat(group).hasExecCompatibleWith("//constraint:cv2");
  }

  @Test
  public void ruleDefinitionEnvironmentDigest_unaffectedByTargetAttrValueChange() throws Exception {
    scratch.file(
        "r/def.bzl",
        "def _r(ctx): return struct(value=ctx.attr.text)",
        "r = rule(implementation=_r, attrs={'text': attr.string()})");
    scratch.file("r/BUILD", "load(':def.bzl', 'r')", "r(name='r', text='old')");
    byte[] oldDigest =
        createRuleContext("//r:r")
            .getRuleContext()
            .getRule()
            .getRuleClassObject()
            .getRuleDefinitionEnvironmentDigest();

    scratch.deleteFile("r/BUILD");
    scratch.file("r/BUILD", "load(':def.bzl', 'r')", "r(name='r', text='new')");
    // Signal SkyFrame to discover changed files.
    skyframeExecutor.handleDiffsForTesting(NullEventHandler.INSTANCE);
    byte[] newDigest =
        createRuleContext("//r:r")
            .getRuleContext()
            .getRule()
            .getRuleClassObject()
            .getRuleDefinitionEnvironmentDigest();

    assertThat(newDigest).isEqualTo(oldDigest);
  }

  @Test
  public void ruleDefinitionEnvironmentDigest_accountsForFunctionWhenCreatingRuleWithAMacro()
      throws Exception {
    scratch.file("r/create.bzl", "def create(impl): return rule(implementation=impl)");
    scratch.file(
        "r/def.bzl",
        "load(':create.bzl', 'create')",
        "def f(ctx): return struct(value='OLD')",
        "r = create(f)");
    scratch.file("r/BUILD", "load(':def.bzl', 'r')", "r(name='r')");
    byte[] oldDigest =
        createRuleContext("//r:r")
            .getRuleContext()
            .getRule()
            .getRuleClassObject()
            .getRuleDefinitionEnvironmentDigest();

    scratch.deleteFile("r/def.bzl");
    scratch.file(
        "r/def.bzl",
        "load(':create.bzl', 'create')",
        "def f(ctx): return struct(value='NEW')",
        "r = create(f)");
    // Signal SkyFrame to discover changed files.
    skyframeExecutor.handleDiffsForTesting(NullEventHandler.INSTANCE);
    byte[] newDigest =
        createRuleContext("//r:r")
            .getRuleContext()
            .getRule()
            .getRuleClassObject()
            .getRuleDefinitionEnvironmentDigest();

    assertThat(newDigest).isNotEqualTo(oldDigest);
  }

  @Test
  public void ruleDefinitionEnvironmentDigest_accountsForAttrsWhenCreatingRuleWithMacro()
      throws Exception {
    scratch.file(
        "r/create.bzl",
        "def f(ctx): return struct(value=ctx.attr.to_json())",
        "def create(attrs): return rule(implementation=f, attrs=attrs)");
    scratch.file("r/def.bzl", "load(':create.bzl', 'create')", "r = create({})");
    scratch.file("r/BUILD", "load(':def.bzl', 'r')", "r(name='r')");
    byte[] oldDigest =
        createRuleContext("//r:r")
            .getRuleContext()
            .getRule()
            .getRuleClassObject()
            .getRuleDefinitionEnvironmentDigest();

    scratch.deleteFile("r/def.bzl");
    scratch.file(
        "r/def.bzl",
        "load(':create.bzl', 'create')",
        "r = create({'value': attr.string(default='')})");
    // Signal SkyFrame to discover changed files.
    skyframeExecutor.handleDiffsForTesting(NullEventHandler.INSTANCE);
    byte[] newDigest =
        createRuleContext("//r:r")
            .getRuleContext()
            .getRule()
            .getRuleClassObject()
            .getRuleDefinitionEnvironmentDigest();

    assertThat(newDigest).isNotEqualTo(oldDigest);
  }

  /**
   * This test is crucial for correctness of {@link RuleClass#getRuleDefinitionEnvironmentDigest}
   * since we use a dummy bzl transitive digest in that case. It is correct to do that only because
   * a rule class created by a BUILD thread cannot be instantiated.
   */
  @Test
  public void ruleClassDefinedInBuildFile_fails() throws Exception {
    reporter.removeHandler(failFastHandler);
    reporter.addHandler(ev.getEventCollector());
    scratch.file("r/create.bzl", "def create(impl): return rule(implementation=impl)");
    scratch.file("r/def.bzl", "load(':create.bzl', 'create')", "r = create({})");
    scratch.file("r/impl.bzl", "def make_struct(ctx): return struct(value='hello')");
    scratch.file(
        "r/BUILD",
        "load(':create.bzl', 'create')",
        "load(':impl.bzl', 'make_struct')",
        "r = create(make_struct)",
        "r(name='r')");

    getConfiguredTarget("//r:r");

    ev.assertContainsError(
        "rule() can only be used during .bzl initialization (top-level evaluation)");
  }

  @Test
  public void testAttrWithAspectRequiringAspects_requiredNativeAspect_getsParamsFromBaseRules()
      throws Exception {
    scratch.file(
        "lib.bzl",
        "rule_prov = provider()",
        "def _impl(target, ctx):",
        "   pass",
        "aspect_a = aspect(implementation = _impl,",
        "                  requires = [parametrized_native_aspect],",
        "                  attr_aspects = ['deps'],",
        "                  required_providers = [rule_prov])",
        "def impl(ctx):",
        "   return None",
        "my_rule = rule(impl,",
        "               attrs={'deps': attr.label_list(aspects = [aspect_a]),",
        "                      'aspect_attr': attr.string()})");
    scratch.file(
        "BUILD", "load(':lib.bzl', 'my_rule')", "my_rule(name = 'main', aspect_attr = 'v1')");

    RuleContext ruleContext = createRuleContext("//:main").getRuleContext();

    Rule rule = ruleContext.getRule();
    Attribute attr = rule.getRuleClassObject().getAttributeByName("deps");
    ImmutableList<Aspect> aspects = attr.getAspects(rule);
    Aspect requiredNativeAspect = aspects.get(0);
    assertThat(requiredNativeAspect.getAspectClass().getName())
        .isEqualTo("ParametrizedAspectWithProvider");
    assertThat(
            requiredNativeAspect
                .getDefinition()
                .getAttributes()
                .get("aspect_attr")
                .getDefaultValueUnchecked())
        .isEqualTo("v1");
  }

  @Test
  public void initializer_onlyAllowedInBuiltins() throws Exception {
    scratch.file(
        "p/b.bzl",
        "def initializer(**kwargs):",
        "  return kwargs",
        "def impl(ctx): ",
        "  pass",
        "my_rule = rule(impl, initializer = initializer)");
    scratch.file(
        "p/BUILD", //
        "load(':b.bzl','my_rule')",
        "my_rule(name = 'my_target')");

    reporter.removeHandler(failFastHandler);
    reporter.addHandler(ev.getEventCollector());
    getConfiguredTarget("//p:my_target");

    ev.assertContainsError("file '//p:b.bzl' cannot use private API");
  }

  // TODO b/298561048 - move the initializers tests below into a separate file

  /**
   * Verifies that precisely returned attributes are modified.
   *
   * <p>When an attribute is not returned it's unaffected.
   *
   * <p>It also verifies that the keyword arguments passed to the initializer are exactly the values
   * of the declared attributes.".
   */
  @Test
  @SuppressWarnings("unchecked")
  public void initializer_basic() throws Exception {
    scratch.file(
        "BUILD", //
        "filegroup(name = 'initial')",
        "filegroup(name = 'added')");
    scratch.file(
        "initializer_testing/b.bzl",
        "MyInfo = provider()",
        "def initializer(srcs = [], deps = []):",
        "  return {'deps': deps + ['//:added']}",
        "def impl(ctx): ",
        "  return [MyInfo(",
        "    srcs = [s.short_path for s in ctx.files.srcs],",
        "    deps = [str(d.label) for d in ctx.attr.deps])]",
        "my_rule = rule(impl,",
        "  initializer = initializer,",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files = ['ml']),",
        "    'deps': attr.label_list(),",
        "  })");
    scratch.file(
        "initializer_testing/BUILD", //
        "load(':b.bzl','my_rule')",
        "my_rule(name = 'my_target', srcs = ['a.ml'], deps = ['//:initial'])");

    ConfiguredTarget myTarget = getConfiguredTarget("//initializer_testing:my_target");
    StructImpl info =
        (StructImpl)
            myTarget.get(
                new StarlarkProvider.Key(
                    Label.parseCanonical("//initializer_testing:b.bzl"), "MyInfo"));

    assertThat((List<String>) info.getValue("srcs")).containsExactly("initializer_testing/a.ml");
    assertThat((List<String>) info.getValue("deps")).containsExactly("@@//:initial", "@@//:added");
  }

  @Test
  public void initializer_legacyAnyType() throws Exception {
    scratch.file(
        "initializer_testing/b.bzl",
        "MyInfo = provider()",
        "def initializer(tristate = -1):",
        "  return {'tristate': int(tristate)}",
        "def impl(ctx): ",
        "  return [MyInfo(tristate = ctx.attr.tristate)]",
        "my_rule = rule(impl,",
        "  initializer = initializer,",
        "  attrs = {",
        "    'tristate': attr.int(),",
        "    '_legacy_any_type_attrs': attr.string_list(default = ['tristate']),",
        "  })");
    scratch.file(
        "initializer_testing/BUILD", //
        "load(':b.bzl','my_rule')",
        "my_rule(name = 'my_target', tristate = True)");

    ConfiguredTarget myTarget = getConfiguredTarget("//initializer_testing:my_target");
    StructImpl info =
        (StructImpl)
            myTarget.get(
                new StarlarkProvider.Key(
                    Label.parseCanonical("//initializer_testing:b.bzl"), "MyInfo"));

    assertThat((StarlarkInt) info.getValue("tristate")).isEqualTo(StarlarkInt.of(1));
  }

  @Test
  public void initializer_wrongType() throws Exception {
    scratch.file(
        "initializer_testing/b.bzl",
        "MyInfo = provider()",
        "def initializer(srcs = []):",
        "  return {'srcs': ['a.ml']}",
        "def impl(ctx): ",
        "  return [MyInfo(",
        "    srcs = [s.short_path for s in ctx.files.srcs])]",
        "my_rule = rule(impl,",
        "  initializer = initializer,",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files = ['ml']),",
        "  })");
    scratch.file(
        "initializer_testing/BUILD", //
        "load(':b.bzl','my_rule')",
        "my_rule(name = 'my_target', srcs = 'default_files')");

    reporter.removeHandler(failFastHandler);
    reporter.addHandler(ev.getEventCollector());
    getConfiguredTarget("//initializer_testing:my_target");

    ev.assertContainsError(
        "expected value of type 'list(label)' for attribute 'srcs' in 'my_rule' rule, but got"
            + " \"default_files\" (string)");
  }

  @Test
  @SuppressWarnings("unchecked")
  public void initializer_withSelect() throws Exception {
    scratch.file(
        "initializer_testing/b.bzl",
        "MyInfo = provider()",
        "def initializer(srcs = []):",
        "  return {'srcs': srcs + ['b.ml']}",
        "def impl(ctx): ",
        "  return [MyInfo(",
        "    srcs = [s.short_path for s in ctx.files.srcs])]",
        "my_rule = rule(impl,",
        "  initializer = initializer,",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files = ['ml']),",
        "  })");
    scratch.file(
        "initializer_testing/BUILD", //
        "load(':b.bzl','my_rule')",
        "my_rule(name = 'my_target', srcs = select({'//conditions:default': ['a.ml']}))");

    ConfiguredTarget myTarget = getConfiguredTarget("//initializer_testing:my_target");
    StructImpl info =
        (StructImpl)
            myTarget.get(
                new StarlarkProvider.Key(
                    Label.parseCanonical("//initializer_testing:b.bzl"), "MyInfo"));

    assertThat((List<String>) info.getValue("srcs"))
        .containsExactly("initializer_testing/a.ml", "initializer_testing/b.ml");
  }

  @Test
  public void initializer_passThrough() throws Exception {
    scratch.file(
        "initializer_testing/b.bzl",
        "def initializer(**kwargs):",
        "  pass",
        "def impl(ctx): ",
        "  pass",
        "my_rule = rule(impl,",
        "  initializer = initializer,",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files = ['ml']),",
        "    'deps': attr.label_list(),",
        "  })");
    scratch.file(
        "initializer_testing/BUILD", //
        "load(':b.bzl','my_rule')",
        "my_rule(name = 'my_target', srcs = ['a.ml'])");

    getConfiguredTarget("//initializer_testing:my_target");

    assertNoEvents();
  }

  @Test
  @SuppressWarnings("unchecked")
  public void initializer_overridesAttributeDefault() throws Exception {
    scratch.file(
        "BUILD", //
        "filegroup(name = 'initializer_default')",
        "filegroup(name = 'attr_default')");
    scratch.file(
        "initializer_testing/b.bzl",
        "MyInfo = provider()",
        "def initializer(deps = ['//:initializer_default']):",
        "  return {'deps': deps}",
        "def impl(ctx): ",
        "  return [MyInfo(",
        "    deps = [str(d.label) for d in ctx.attr.deps])]",
        "my_rule = rule(impl,",
        "  initializer = initializer,",
        "  attrs = {",
        "    'deps': attr.label_list(default = ['//:attr_default']),",
        "  })");
    scratch.file(
        "initializer_testing/BUILD", //
        "load(':b.bzl','my_rule')",
        "my_rule(name = 'my_target')");

    ConfiguredTarget myTarget = getConfiguredTarget("//initializer_testing:my_target");
    StructImpl info =
        (StructImpl)
            myTarget.get(
                new StarlarkProvider.Key(
                    Label.parseCanonical("//initializer_testing:b.bzl"), "MyInfo"));

    assertThat((List<String>) info.getValue("deps")).containsExactly("@@//:initializer_default");
  }

  @Test
  @SuppressWarnings("unchecked")
  public void initializer_returningNoneSetsDefault() throws Exception {
    scratch.file(
        "BUILD", //
        "filegroup(name = 'initializer_default')",
        "filegroup(name = 'attr_default')");
    scratch.file(
        "initializer_testing/b.bzl",
        "MyInfo = provider()",
        "def initializer(deps = ['//:initializer_default']):",
        "  return {'deps': None}",
        "def impl(ctx): ",
        "  return [MyInfo(",
        "    deps = [str(d.label) for d in ctx.attr.deps])]",
        "my_rule = rule(impl,",
        "  initializer = initializer,",
        "  attrs = {",
        "    'deps': attr.label_list(default = ['//:attr_default']),",
        "  })");
    scratch.file(
        "initializer_testing/BUILD", //
        "load(':b.bzl','my_rule')",
        "my_rule(name = 'my_target')");

    ConfiguredTarget myTarget = getConfiguredTarget("//initializer_testing:my_target");
    StructImpl info =
        (StructImpl)
            myTarget.get(
                new StarlarkProvider.Key(
                    Label.parseCanonical("//initializer_testing:b.bzl"), "MyInfo"));

    assertThat((List<String>) info.getValue("deps")).containsExactly("@@//:attr_default");
  }

  @Test
  public void initializer_omittedValueIsNotPassed() throws Exception {
    scratch.file(
        "initializer_testing/b.bzl",
        "MyInfo = provider()",
        "def initializer(srcs):",
        "  return {'srcs': srcs}",
        "def impl(ctx): ",
        "  pass",
        "my_rule = rule(impl,",
        "  initializer = initializer,",
        "  attrs = {",
        "    'srcs': attr.label_list(),",
        "  })");
    scratch.file(
        "initializer_testing/BUILD", //
        "load(':b.bzl','my_rule')",
        "my_rule(name = 'my_target')");

    reporter.removeHandler(failFastHandler);
    reporter.addHandler(ev.getEventCollector());
    getConfiguredTarget("//initializer_testing:my_target");

    // TODO: b/298561048 - Fix error messages to match a rule without initializer
    ev.assertContainsError("initializer() missing 1 required positional argument: srcs");
  }

  @Test
  public void initializer_noneValueIsNotPassed() throws Exception {
    scratch.file(
        "initializer_testing/b.bzl",
        "MyInfo = provider()",
        "def initializer(srcs):",
        "  return {'srcs': srcs}",
        "def impl(ctx): ",
        "  pass",
        "my_rule = rule(impl,",
        "  initializer = initializer,",
        "  attrs = {",
        "    'srcs': attr.label_list(),",
        "  })");
    scratch.file(
        "initializer_testing/BUILD", //
        "load(':b.bzl','my_rule')",
        "my_rule(name = 'my_target', srcs = None)");

    reporter.removeHandler(failFastHandler);
    reporter.addHandler(ev.getEventCollector());
    getConfiguredTarget("//initializer_testing:my_target");

    ev.assertContainsError("initializer() missing 1 required positional argument: srcs");
  }

  @Test
  public void initializer_incorrectReturnType() throws Exception {
    scratch.file(
        "initializer_testing/b.bzl",
        "def initializer(srcs = []):",
        "  return [srcs]",
        "def impl(ctx): ",
        "  pass",
        "my_rule = rule(impl,",
        "  initializer = initializer,",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files = ['ml']),",
        "  })");
    scratch.file(
        "initializer_testing/BUILD", //
        "load(':b.bzl','my_rule')",
        "my_rule(name = 'my_target', srcs = ['a.ml'])");

    reporter.removeHandler(failFastHandler);
    reporter.addHandler(ev.getEventCollector());
    getConfiguredTarget("//initializer_testing:my_target");

    ev.assertContainsError("got list for 'rule's initializer return value', want dict");
  }

  @Test
  public void initializer_incorrectReturnDicts() throws Exception {
    scratch.file(
        "initializer_testing/b.bzl",
        "def initializer(srcs = []):",
        "  return {True: srcs}",
        "def impl(ctx): ",
        "  pass",
        "my_rule = rule(impl,",
        "  initializer = initializer,",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files = ['ml']),",
        "  })");
    scratch.file(
        "initializer_testing/BUILD", //
        "load(':b.bzl','my_rule')",
        "my_rule(name = 'my_target', srcs = ['a.ml'])");

    reporter.removeHandler(failFastHandler);
    reporter.addHandler(ev.getEventCollector());
    getConfiguredTarget("//initializer_testing:my_target");

    ev.assertContainsError("got dict<bool, list> for 'rule's initializer return value', want dict");
  }

  @Test
  public void initializer_failsSettingBaseAttribute() throws Exception {
    // 'args' is an attribute defined for all executable rules
    scratch.file(
        "initializer_testing/b.bzl",
        "def initializer(srcs = [], deps = []):",
        "  return {'srcs': srcs, 'deps': deps, 'args': ['a']}",
        "def impl(ctx): ",
        "  pass",
        "my_rule = rule(impl,",
        "  initializer = initializer,",
        "  executable = True,",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files = ['ml']),",
        "    'deps': attr.label_list(),",
        "  })");
    scratch.file(
        "initializer_testing/BUILD", //
        "load(':b.bzl','my_rule')",
        "my_rule(name = 'my_target', srcs = ['a.ml'])");

    reporter.removeHandler(failFastHandler);
    reporter.addHandler(ev.getEventCollector());
    getConfiguredTarget("//initializer_testing:my_target");

    ev.assertContainsError("Initializer can only set Starlark defined attributes, not 'args'");
  }

  @Test
  public void initializer_failsSettingPrivateAttribute_outsideBuiltins() throws Exception {
    scratch.file(
        "initializer_testing/b.bzl",
        "def initializer(srcs = [], deps = []):",
        "  return {'srcs': srcs, '_tool': ':my_tool'}",
        "def impl(ctx): ",
        "  pass",
        "my_rule = rule(impl,",
        "  initializer = initializer,",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files = ['ml']),",
        "    '_tool': attr.label(),",
        "  })");
    scratch.file(
        "initializer_testing/BUILD", //
        "load(':b.bzl','my_rule')",
        "filegroup(name='my_tool')",
        "my_rule(name = 'my_target', srcs = ['a.ml'])");

    reporter.removeHandler(failFastHandler);
    reporter.addHandler(ev.getEventCollector());
    getConfiguredTarget("//initializer_testing:my_target");

    ev.assertContainsError("file '//initializer_testing:b.bzl' cannot use private API");
  }

  @Test
  public void initializer_settingPrivateAttribute_insideBuiltins() throws Exception {
    // Because it's hard to test something that needs to be in builtins,
    // this is also allowed in a special testing location: {@link
    // StarlarkRuleClassFunctions.ALLOWLIST_RULE_EXTENSION_API_EXPERIMENTAL}
    scratch.file("initializer_testing/builtins/BUILD", "filegroup(name='my_tool')");
    scratch.file(
        "initializer_testing/builtins/b.bzl",
        "def initializer(srcs = [], deps = []):",
        "  return {'srcs': srcs, '_tool': ':my_tool'}",
        "MyInfo = provider()",
        "def impl(ctx): ",
        "  return MyInfo(_tool = str(ctx.attr._tool.label))",
        "my_rule = rule(impl,",
        "  initializer = initializer,",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files = ['ml']),",
        "    '_tool': attr.label(),",
        "  })");
    scratch.file(
        "initializer_testing/BUILD", //
        "load('//initializer_testing/builtins:b.bzl','my_rule')",
        "my_rule(name = 'my_target', srcs = ['a.ml'])");

    ConfiguredTarget myTarget = getConfiguredTarget("//initializer_testing:my_target");
    StructImpl info =
        (StructImpl)
            myTarget.get(
                new StarlarkProvider.Key(
                    Label.parseCanonical("//initializer_testing/builtins:b.bzl"), "MyInfo"));

    assertThat(info.getValue("_tool").toString())
        .isEqualTo("@@//initializer_testing/builtins:my_tool");
  }

  @Test
  public void initializer_failsSettingUnknownAttr() throws Exception {
    scratch.file(
        "initializer_testing/b.bzl",
        "def initializer(srcs = [], deps = []):",
        "  return {'srcs': srcs, 'my_deps': deps}",
        "def impl(ctx): ",
        "  pass",
        "my_rule = rule(impl,",
        "  initializer = initializer,",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files = ['ml']),",
        "    'deps': attr.label_list(),",
        "  })");
    scratch.file(
        "initializer_testing/BUILD", //
        "load(':b.bzl','my_rule')",
        "my_rule(name = 'my_target', srcs = ['a.ml'])");

    reporter.removeHandler(failFastHandler);
    reporter.addHandler(ev.getEventCollector());
    getConfiguredTarget("//initializer_testing:my_target");

    ev.assertContainsError("no such attribute 'my_deps' in 'my_rule' rule (did you mean 'deps'?)");
  }

  @Test
  public void initializer_failsCreatingAnotherRule() throws Exception {
    scratch.file(
        "initializer_testing/b.bzl",
        "def initializer(srcs = [], deps = []):",
        "  native.java_library(name = 'jl', srcs = ['a.java'])",
        "  return {'srcs': srcs, 'deps': deps}",
        "def impl(ctx): ",
        "  pass",
        "my_rule = rule(impl,",
        "  initializer = initializer,",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files = ['ml']),",
        "    'deps': attr.label_list(),",
        "  })");
    scratch.file(
        "initializer_testing/BUILD", //
        "load(':b.bzl','my_rule')",
        "my_rule(name = 'my_target', srcs = ['a.ml'])");

    reporter.removeHandler(failFastHandler);
    reporter.addHandler(ev.getEventCollector());
    getConfiguredTarget("//initializer_testing:my_target");

    ev.assertContainsError(
        "A rule can only be instantiated in a BUILD file, or a macro invoked from a BUILD file");
  }

  @Test
  public void initializer_failsWithExistingRules() throws Exception {
    scratch.file(
        "initializer_testing/b.bzl",
        "def initializer(srcs = [], deps = []):",
        "  native.existing_rules()",
        "  return {'srcs': srcs, 'deps': deps}",
        "def impl(ctx): ",
        "  pass",
        "my_rule = rule(impl,",
        "  initializer = initializer,",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files = ['ml']),",
        "    'deps': attr.label_list(),",
        "  })");
    scratch.file(
        "initializer_testing/BUILD", //
        "load(':b.bzl','my_rule')",
        "my_rule(name = 'my_target', srcs = ['a.ml'])");

    reporter.removeHandler(failFastHandler);
    reporter.addHandler(ev.getEventCollector());
    getConfiguredTarget("//initializer_testing:my_target");

    ev.assertContainsError("'native.existing_rules' cannot be called from an initializer");
  }

  @Test
  public void initializer_withFails() throws Exception {
    scratch.file(
        "initializer_testing/b.bzl",
        "def initializer(srcs = [], deps = []):",
        "  fail('Fail called in initializer')",
        "  return {'srcs': srcs, 'deps': deps}",
        "def impl(ctx): ",
        "  pass",
        "my_rule = rule(impl,",
        "  initializer = initializer,",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files = ['ml']),",
        "    'deps': attr.label_list(),",
        "  })");
    scratch.file(
        "initializer_testing/BUILD", //
        "load(':b.bzl','my_rule')",
        "my_rule(name = 'my_target', srcs = ['a.ml'])");

    reporter.removeHandler(failFastHandler);
    reporter.addHandler(ev.getEventCollector());
    getConfiguredTarget("//initializer_testing:my_target");

    ev.assertContainsError("Fail called in initializer");
    // TODO: b/298561048 - fix that the whole package doesn't fail if possible
    ev.assertContainsError("target 'my_target' not declared in package 'initializer_testing'");
  }

  private void scratchParentRule(String rule, String... ruleArgs) throws IOException {
    scratch.file("extend_rule_testing/parent/BUILD");
    scratch.file(
        "extend_rule_testing/parent/parent.bzl",
        "ParentInfo = provider()",
        "def _impl(ctx):",
        "  return [ParentInfo()]",
        rule + " = rule(",
        "  implementation = _impl,",
        "  extendable = True,",
        "  attrs = { ",
        "    'srcs': attr.label_list(allow_files = ['.parent']),",
        "    'deps': attr.label_list(providers = [ParentInfo]),",
        "  },",
        String.join("\n", ruleArgs),
        ")");
  }

  @Test
  public void extendRule_onlyAllowedInBuiltins() throws Exception {
    scratchParentRule("parent_library");
    scratch.file(
        "bar/child.bzl",
        "load('//extend_rule_testing/parent:parent.bzl', 'parent_library')",
        "def _impl(ctx):",
        "  pass",
        "my_library = rule(",
        "  implementation = _impl,",
        "  parent = parent_library,",
        ")");
    scratch.file(
        "bar/BUILD", //
        "load(':child.bzl','my_library')",
        "my_library(name = 'my_target', srcs = ['a.proto'])");

    reporter.removeHandler(failFastHandler);
    reporter.addHandler(ev.getEventCollector());
    getConfiguredTarget("//bar:my_target");

    ev.assertContainsError("file '//bar:child.bzl' cannot use private API");
  }

  @Test
  public void extendRule_basicUse() throws Exception {
    scratchParentRule("parent_library"); // parent has srcs and deps attribute
    scratch.file(
        "extend_rule_testing/child.bzl",
        "load('//extend_rule_testing/parent:parent.bzl', 'parent_library')",
        "MyInfo = provider()",
        "def _impl(ctx):",
        "  return ctx.super() + [MyInfo(",
        "    srcs = ctx.files.srcs,",
        "    deps = ctx.attr.deps,",
        "    runtime_deps = ctx.attr.runtime_deps)]",
        "my_library = rule(",
        "  implementation = _impl,",
        "  parent = parent_library,",
        "  attrs = {",
        "    'runtime_deps': attr.label_list(),",
        "  }",
        ")");
    scratch.file(
        "extend_rule_testing/BUILD",
        "load(':child.bzl', 'my_library')",
        "my_library(name = 'my_target', srcs = ['a.parent'], runtime_deps = [':dep'])",
        "filegroup(name = 'dep')");

    ConfiguredTarget myTarget = getConfiguredTarget("//extend_rule_testing:my_target");
    Rule rule = getRuleContext(myTarget).getRule();
    StarlarkProvider.Key myInfoKey =
        new StarlarkProvider.Key(
            Label.parseCanonicalUnchecked("//extend_rule_testing:child.bzl"), "MyInfo");
    StarlarkInfo myInfo = (StarlarkInfo) myTarget.get(myInfoKey);

    assertNoEvents();
    assertThat(rule.getRuleClassObject().isExecutableStarlark()).isFalse();
    assertThat(rule.getRuleClassObject().getRuleClassType()).isEqualTo(RuleClassType.NORMAL);
    assertThat(
            Sequence.cast(myInfo.getValue("srcs"), Artifact.class, "srcs").stream()
                .map(Artifact::getFilename))
        .containsExactly("a.parent");
    assertThat(
            Sequence.cast(myInfo.getValue("deps"), ConfiguredTarget.class, "deps").stream()
                .map(ConfiguredTarget::getLabel)
                .map(Label::getName))
        .containsExactly();
    assertThat(
            Sequence.cast(myInfo.getValue("runtime_deps"), ConfiguredTarget.class, "runtime_deps")
                .stream()
                .map(ConfiguredTarget::getLabel)
                .map(Label::getName))
        .containsExactly("dep");
    StarlarkProvider.Key parentInfoKey =
        new StarlarkProvider.Key(
            Label.parseCanonicalUnchecked("//extend_rule_testing/parent:parent.bzl"), "ParentInfo");
    assertThat(myTarget.get(parentInfoKey)).isNotNull();
  }

  @Test
  public void extendRule_withInitializers() throws Exception {
    scratch.file("extend_rule_testing/parent/BUILD");
    scratch.file(
        "extend_rule_testing/parent/parent.bzl",
        "ParentInfo = provider()",
        "def _parent_initializer(srcs, deps):", // only parents attributes
        "  return {'deps': deps + ['//extend_rule_testing:parent_dep']}",
        "def _impl(ctx):",
        "  return [ParentInfo()]",
        "parent_library = rule(",
        "  implementation = _impl,",
        "  initializer = _parent_initializer,",
        "  extendable = True,",
        "  attrs = { ",
        "    'srcs': attr.label_list(allow_files = ['.parent']),",
        "    'deps': attr.label_list(),",
        "  },",
        ")");
    scratch.file(
        "extend_rule_testing/child.bzl",
        "load('//extend_rule_testing/parent:parent.bzl', 'parent_library')",
        "ChildInfo = provider()",
        "def _child_initializer(srcs, deps, runtime_deps = []):",
        "  return {'deps': deps + [':child_dep'], 'runtime_deps': runtime_deps + [':runtime_dep']}",
        "def _impl(ctx):",
        "  return ctx.super() + [ChildInfo(",
        "    srcs = ctx.files.srcs,",
        "    deps = ctx.attr.deps,",
        "    runtime_deps = ctx.attr.runtime_deps)]",
        "child_library = rule(",
        "  implementation = _impl,",
        "  initializer = _child_initializer,",
        "  parent = parent_library,",
        "  attrs = {",
        "    'runtime_deps': attr.label_list(),",
        "  }",
        ")");
    scratch.file(
        "extend_rule_testing/BUILD",
        "load(':child.bzl', 'child_library')",
        "child_library(name = 'my_target', srcs = ['a.parent'], deps = [':dep'])",
        "filegroup(name = 'dep')",
        "filegroup(name = 'child_dep')",
        "filegroup(name = 'parent_dep')",
        "filegroup(name = 'runtime_dep')");

    ConfiguredTarget myTarget = getConfiguredTarget("//extend_rule_testing:my_target");
    Rule rule = getRuleContext(myTarget).getRule();
    StarlarkProvider.Key myInfoKey =
        new StarlarkProvider.Key(
            Label.parseCanonicalUnchecked("//extend_rule_testing:child.bzl"), "ChildInfo");
    StarlarkInfo myInfo = (StarlarkInfo) myTarget.get(myInfoKey);

    assertNoEvents();
    assertThat(rule.getRuleClassObject().isExecutableStarlark()).isFalse();
    assertThat(rule.getRuleClassObject().getRuleClassType()).isEqualTo(RuleClassType.NORMAL);
    assertThat(
            Sequence.cast(myInfo.getValue("srcs"), Artifact.class, "srcs").stream()
                .map(Artifact::getFilename))
        .containsExactly("a.parent");
    assertThat(
            Sequence.cast(myInfo.getValue("deps"), ConfiguredTarget.class, "deps").stream()
                .map(ConfiguredTarget::getLabel)
                .map(Label::getName))
        .containsExactly("dep", "child_dep", "parent_dep")
        .inOrder();
    assertThat(
            Sequence.cast(myInfo.getValue("runtime_deps"), ConfiguredTarget.class, "runtime_deps")
                .stream()
                .map(ConfiguredTarget::getLabel)
                .map(Label::getName))
        .containsExactly("runtime_dep");
    StarlarkProvider.Key parentInfoKey =
        new StarlarkProvider.Key(
            Label.parseCanonicalUnchecked("//extend_rule_testing/parent:parent.bzl"), "ParentInfo");
    assertThat(myTarget.get(parentInfoKey)).isNotNull();
  }

  @Test
  public void extendRule_superNotCalled() throws Exception {
    scratchParentRule("parent_library"); // parent has srcs and deps attribute
    scratch.file(
        "extend_rule_testing/child.bzl",
        "load('//extend_rule_testing/parent:parent.bzl', 'parent_library')",
        "def _impl(ctx):",
        "  return []",
        "my_library = rule(",
        "  implementation = _impl,",
        "  parent = parent_library,",
        ")");
    scratch.file(
        "extend_rule_testing/BUILD",
        "load(':child.bzl', 'my_library')",
        "my_library(name = 'my_target', srcs = ['a.parent'])");

    reporter.removeHandler(failFastHandler);
    reporter.addHandler(ev.getEventCollector());
    getConfiguredTarget("//extend_rule_testing:my_target");

    ev.assertContainsError(
        "in my_library rule //extend_rule_testing:my_target: 'super' was not called.");
  }

  @Test
  public void extendRule_superCalledTwice() throws Exception {
    scratchParentRule("parent_library"); // parent has srcs and deps attribute
    scratch.file(
        "extend_rule_testing/child.bzl",
        "load('//extend_rule_testing/parent:parent.bzl', 'parent_library')",
        "def _impl(ctx):",
        "  ctx.super()",
        "  ctx.super()",
        "  return []",
        "my_library = rule(",
        "  implementation = _impl,",
        "  parent = parent_library,",
        ")");
    scratch.file(
        "extend_rule_testing/BUILD",
        "load(':child.bzl', 'my_library')",
        "my_library(name = 'my_target', srcs = ['a.parent'])");

    reporter.removeHandler(failFastHandler);
    reporter.addHandler(ev.getEventCollector());
    getConfiguredTarget("//extend_rule_testing:my_target");

    ev.assertContainsError("Error in super: 'super' called the second time.");
  }

  @Test
  public void extendRule_noParent_superCalled() throws Exception {
    scratchParentRule("parent_library"); // parent has srcs and deps attribute
    scratch.file(
        "extend_rule_testing/child.bzl",
        "def _impl(ctx):",
        "  ctx.super()",
        "  return []",
        "my_library = rule(",
        "  implementation = _impl,",
        ")");
    scratch.file(
        "extend_rule_testing/BUILD",
        "load(':child.bzl', 'my_library')",
        "my_library(name = 'my_target')");

    reporter.removeHandler(failFastHandler);
    reporter.addHandler(ev.getEventCollector());
    getConfiguredTarget("//extend_rule_testing:my_target");

    ev.assertContainsError("Error in super: Can't use 'super' call, the rule has no parent.");
  }

  @Test
  public void extendRule_extendRuleTwice() throws Exception {
    scratchParentRule("parent_library"); // parent has srcs and deps attribute
    scratch.file(
        "extend_rule_testing/first_extension.bzl",
        "load('//extend_rule_testing/parent:parent.bzl', 'parent_library')",
        "MyInfo1 = provider()",
        "def _impl(ctx):",
        "  return ctx.super() + [MyInfo1()]",
        "library_extended_once = rule(",
        "  implementation = _impl,",
        "  parent = parent_library,",
        "  extendable = True",
        ")");
    scratch.file(
        "extend_rule_testing/second_extension.bzl",
        "load('//extend_rule_testing:first_extension.bzl', 'library_extended_once')",
        "MyInfo2 = provider()",
        "def _impl(ctx):",
        "  return ctx.super() + [MyInfo2()]",
        "library_extended_twice = rule(",
        "  implementation = _impl,",
        "  parent = library_extended_once,",
        ")");
    scratch.file(
        "extend_rule_testing/BUILD",
        "load(':second_extension.bzl', 'library_extended_twice')",
        "library_extended_twice(name = 'my_target')");

    ConfiguredTarget myTarget = getConfiguredTarget("//extend_rule_testing:my_target");
    StarlarkProvider.Key myInfo1Key =
        new StarlarkProvider.Key(
            Label.parseCanonicalUnchecked("//extend_rule_testing:first_extension.bzl"), "MyInfo1");
    StarlarkProvider.Key myInfo2Key =
        new StarlarkProvider.Key(
            Label.parseCanonicalUnchecked("//extend_rule_testing:second_extension.bzl"), "MyInfo2");
    StarlarkProvider.Key parentInfoKey =
        new StarlarkProvider.Key(
            Label.parseCanonicalUnchecked("//extend_rule_testing/parent:parent.bzl"), "ParentInfo");

    assertThat(myTarget.get(myInfo1Key)).isNotNull();
    assertThat(myTarget.get(myInfo2Key)).isNotNull();
    assertThat(myTarget.get(parentInfoKey)).isNotNull();
  }

  @Test
  public void extendRule_extendRuleTwice_superNotCalled() throws Exception {
    scratchParentRule("parent_library"); // parent has srcs and deps attribute
    scratch.file(
        "extend_rule_testing/first_extension.bzl",
        "load('//extend_rule_testing/parent:parent.bzl', 'parent_library')",
        "def _impl(ctx):",
        "  return []", // <- here we didn't call ctx.super()
        "library_extended_once = rule(",
        "  implementation = _impl,",
        "  parent = parent_library,",
        "  extendable = True",
        ")");
    scratch.file(
        "extend_rule_testing/second_extension.bzl",
        "load('//extend_rule_testing:first_extension.bzl', 'library_extended_once')",
        "def _impl(ctx):",
        "  return ctx.super()",
        "library_extended_twice = rule(",
        "  implementation = _impl,",
        "  parent = library_extended_once,",
        ")");
    scratch.file(
        "extend_rule_testing/BUILD",
        "load(':second_extension.bzl', 'library_extended_twice')",
        "library_extended_twice(name = 'my_target')");

    reporter.removeHandler(failFastHandler);
    reporter.addHandler(ev.getEventCollector());
    getConfiguredTarget("//extend_rule_testing:my_target");

    ev.assertContainsError(
        "in library_extended_twice rule //extend_rule_testing:my_target: in library_extended_once"
            + " rule: 'super' was not called.");
  }

  @Test
  public void ctxSuper_calledFromAspect() throws Exception {
    scratch.file(
        "extend_rule_testing/child.bzl",
        "def _aspect_impl(target, ctx):",
        "  ctx.super()",
        "  return []",
        "my_aspect = aspect(_aspect_impl)",
        "def _impl(ctx):",
        "  pass",
        "my_library = rule(",
        "  implementation = _impl,",
        "  attrs = {'deps': attr.label_list(aspects = [my_aspect])},",
        ")");
    scratch.file(
        "extend_rule_testing/BUILD",
        "load(':child.bzl', 'my_library')",
        "my_library(name = 'my_target', deps = [':dep'])",
        "filegroup(name = 'dep')");

    reporter.removeHandler(failFastHandler);
    reporter.addHandler(ev.getEventCollector());
    getConfiguredTarget("//extend_rule_testing:my_target");

    ev.assertContainsError("Error in super: Can't use 'super' call in an aspect.");
  }

  @Test
  public void extendRule_attributeAdditionalAspects() throws Exception {
    scratch.file("extend_rule_testing/parent/BUILD");
    scratch.file(
        "extend_rule_testing/parent/parent.bzl",
        "ParentInfo = provider()",
        "def _aspect_impl(ctx, target):",
        "  return []",
        "parent_aspect = aspect(_aspect_impl)",
        "def _impl(ctx):",
        "  return [ParentInfo()]",
        "parent_library = rule(",
        "  implementation = _impl,",
        "  extendable = True,",
        "  attrs = { ",
        "    'srcs': attr.label_list(allow_files = ['.parent']),",
        "    'deps': attr.label_list(aspects = [parent_aspect]),",
        "    'tool': attr.label(providers = [ParentInfo]),",
        "  },",
        ")");
    scratch.file(
        "extend_rule_testing/child.bzl",
        "load('//extend_rule_testing/parent:parent.bzl', 'parent_library')",
        "def _aspect_impl(ctx, target):",
        "  return []",
        "my_aspect = aspect(_aspect_impl)",
        "def _impl(ctx):",
        "  return ctx.super()",
        "my_library = rule(",
        "  implementation = _impl,",
        "  parent = parent_library,",
        "  attrs = {",
        "    'deps': attr.label_list(aspects = [my_aspect]),",
        "    'tool': attr.label(aspects = [my_aspect]),",
        "  }",
        ")");
    scratch.file(
        "extend_rule_testing/BUILD",
        "load(':child.bzl', 'my_library')",
        "my_library(name = 'my_target', deps = [':dep'])",
        "filegroup(name = 'dep')");

    ConfiguredTarget myTarget = getConfiguredTarget("//extend_rule_testing:my_target");
    Rule rule = getRuleContext(myTarget).getRule();
    assertNoEvents();

    assertThat(rule.getRuleClassObject().isExecutableStarlark()).isFalse();
    assertThat(rule.getRuleClassObject().getRuleClassType()).isEqualTo(RuleClassType.NORMAL);
    assertThat(
            rule.getRuleClassObject().getAttributeByName("deps").getAspectClasses().stream()
                .map(AspectClass::toString))
        .containsExactly(
            "//extend_rule_testing/parent:parent.bzl%parent_aspect",
            "//extend_rule_testing:child.bzl%my_aspect");
    assertThat(
            rule.getRuleClassObject().getAttributeByName("tool").getAspectClasses().stream()
                .map(AspectClass::toString))
        .containsExactly("//extend_rule_testing:child.bzl%my_aspect");
  }

  @Test
  public void extendRule_overridePrivateAttribute_fails() throws Exception {
    scratch.file(
        "extend_rule_testing/parent/BUILD", //
        "filegroup(name = 'parent_tool')");
    scratch.file(
        "extend_rule_testing/parent/parent.bzl",
        "def _impl(ctx):",
        "  return []",
        "parent_library = rule(",
        "  implementation = _impl,",
        "  attrs = { ",
        "    '_tool': attr.label(default = ':parent_tool'),",
        "  },",
        ")");
    scratch.file(
        "extend_rule_testing/child.bzl",
        "load('//extend_rule_testing/parent:parent.bzl', 'parent_library')",
        "def _impl(ctx):",
        "  return ctx.super()",
        "my_library = rule(",
        "  implementation = _impl,",
        "  parent = parent_library,",
        "  attrs = {",
        "    '_tool': attr.label(default = ':child_tool'),",
        "  }",
        ")");
    scratch.file(
        "extend_rule_testing/BUILD",
        "load(':child.bzl', 'my_library')",
        "my_library(name = 'my_target')",
        "filegroup(name = 'child_tool')");

    reporter.removeHandler(failFastHandler);
    reporter.addHandler(ev.getEventCollector());
    getConfiguredTarget("//extend_rule_testing:BUILD");

    ev.assertContainsError(
        "Error in rule: attribute `_tool`: private attributes cannot be overridden.");
  }

  @Test
  public void extendRule_attributeOverrideDefault() throws Exception {
    scratch.file("extend_rule_testing/parent/BUILD");
    scratch.file(
        "extend_rule_testing/parent/parent.bzl",
        "ParentInfo = provider()",
        "def _impl(ctx):",
        "  return [ParentInfo(deps = ctx.attr.deps, tools = [ctx.attr.tool])]",
        "parent_library = rule(",
        "  implementation = _impl,",
        "  extendable = True,",
        "  attrs = { ",
        "    'srcs': attr.label_list(allow_files = ['.parent']),",
        "    'deps': attr.label_list(),",
        "    'tool': attr.label(default = ':tool_parent'),",
        "  },",
        ")");
    scratch.file(
        "extend_rule_testing/child.bzl",
        "load('//extend_rule_testing/parent:parent.bzl', 'parent_library')",
        "def _impl(ctx):",
        "  return ctx.super()",
        "my_library = rule(",
        "  implementation = _impl,",
        "  parent = parent_library,",
        "  attrs = {",
        "    'deps': attr.label_list(default = [':dep']),",
        "    'tool': attr.label(default = ':tool_child'),",
        "  }",
        ")");
    scratch.file(
        "extend_rule_testing/BUILD",
        "load(':child.bzl', 'my_library')",
        "my_library(name = 'my_target')",
        "filegroup(name = 'dep')",
        "filegroup(name = 'tool_child')");

    ConfiguredTarget myTarget = getConfiguredTarget("//extend_rule_testing:my_target");
    StarlarkProvider.Key parentInfoKey =
        new StarlarkProvider.Key(
            Label.parseCanonicalUnchecked("//extend_rule_testing/parent:parent.bzl"), "ParentInfo");
    StarlarkInfo parentInfo = (StarlarkInfo) myTarget.get(parentInfoKey);

    assertNoEvents();
    assertThat(
            Sequence.cast(parentInfo.getValue("deps"), ConfiguredTarget.class, "deps").stream()
                .map(ConfiguredTarget::getLabel)
                .map(Label::getName))
        .containsExactly("dep");
    assertThat(
            Sequence.cast(parentInfo.getValue("tools"), ConfiguredTarget.class, "tools").stream()
                .map(ConfiguredTarget::getLabel)
                .map(Label::getName))
        .containsExactly("tool_child");
  }

  @Test
  public void extendRule_attributeCollision() throws Exception {
    // TODO b/300201845 - encapsulate parents and childs private attributes
    scratchParentRule("parent_library");
    scratch.file(
        "extend_rule_testing/child.bzl",
        "load('//extend_rule_testing/parent:parent.bzl', 'parent_library')",
        "def _impl(ctx):",
        "  pass",
        "my_library = rule(",
        "  implementation = _impl,",
        "  parent = parent_library,",
        "  attrs = {",
        "    'srcs': attr.string(),", // srcs already defined as label_list in parent
        "  }",
        ")");
    scratch.file("extend_rule_testing/BUILD", "load(':child.bzl', 'my_library')");

    reporter.removeHandler(failFastHandler);
    reporter.addHandler(ev.getEventCollector());
    getConfiguredTarget("//extend_rule_testing:BUILD");

    ev.assertContainsError(
        "Error in rule: attribute `srcs`: Types of parent and child's attributes mismatch.");
  }

  @Test
  public void extendRule_executableMatches() throws Exception {
    scratchParentRule("parent_binary", "executable = True,");
    scratch.file(
        "extend_rule_testing/child.bzl",
        "load('//extend_rule_testing/parent:parent.bzl', 'parent_binary')",
        "MyInfo = provider()",
        "def _impl(ctx):",
        "  exec = ctx.actions.declare_file('my_exec')",
        "  ctx.actions.write(exec, '')",
        "  ctx.super()",
        "  return DefaultInfo(executable = exec)",
        "my_binary = rule(",
        "  implementation = _impl,",
        "  parent = parent_binary,",
        ")");
    scratch.file(
        "extend_rule_testing/BUILD",
        "load(':child.bzl', 'my_binary')",
        "my_binary(name = 'my_target', srcs = ['a.parent'])");

    ConfiguredTarget myTarget = getConfiguredTarget("//extend_rule_testing:my_target");
    Rule rule = getRuleContext(myTarget).getRule();

    assertNoEvents();
    assertThat(rule.getRuleClassObject().isExecutableStarlark()).isTrue();
    assertThat(rule.getRuleClassObject().getRuleClassType()).isEqualTo(RuleClassType.NORMAL);
  }

  @Test
  public void extendRule_testMatches() throws Exception {
    scratchParentRule("parent_test", "test = True,");
    scratch.file(
        "extend_rule_testing/child.bzl",
        "load('//extend_rule_testing/parent:parent.bzl', 'parent_test')",
        "MyInfo = provider()",
        "def _impl(ctx):",
        "  exec = ctx.actions.declare_file('my_exec')",
        "  ctx.actions.write(exec, '')",
        "  ctx.super()",
        "  return DefaultInfo(executable = exec)",
        "my_test = rule(",
        "  implementation = _impl,",
        "  parent = parent_test,",
        ")");
    scratch.file(
        "extend_rule_testing/BUILD",
        "load(':child.bzl', 'my_test')",
        "my_test(name = 'my_target', srcs = ['a.parent'])");

    ConfiguredTarget myTarget = getConfiguredTarget("//extend_rule_testing:my_target");
    Rule rule = getRuleContext(myTarget).getRule();

    assertNoEvents();
    assertThat(rule.getRuleClassObject().isExecutableStarlark()).isTrue();
    assertThat(rule.getRuleClassObject().getRuleClassType()).isEqualTo(RuleClassType.TEST);
  }

  @Test
  public void extendRule_controlledParameters_fail() throws Exception {
    BazelEvaluationTestCase ev = new BazelEvaluationTestCase("//extend_rule_testing:child.bzl");
    ev.exec(
        "def impl():", //
        "  pass");
    ev.execAndExport("parent_library = rule(impl)");

    ev.checkEvalError(
        "Omit test parameter when extending rules.",
        "rule(impl, test = False, parent = parent_library)");
    ev.checkEvalError(
        "Omit executable parameter when extending rules.",
        "rule(impl, executable = False, parent = parent_library)");
    ev.checkEvalError(
        "output_to_genfiles are not supported when extending rules (deprecated).",
        "rule(impl, output_to_genfiles = True, parent = parent_library)");
    ev.checkEvalError(
        "host_fragments are not supported when extending rules (deprecated).",
        "rule(impl, host_fragments = ['a'], parent = parent_library)");
    ev.checkEvalError(
        "_skylark_testable is not supported when extending rules.",
        "rule(impl, _skylark_testable = True, parent = parent_library)");
    ev.checkEvalError(
        "analysis_test is not supported when extending rules.",
        "rule(impl, analysis_test = True, parent = parent_library)");

    ev.update("config", new StarlarkConfig());
    ev.checkEvalError(
        "build_setting is not supported when extending rules.",
        "rule(impl, build_setting = config.int(), parent = parent_library)");
  }

  @Test
  public void extendRule_fragments_merged() throws Exception {
    scratchParentRule(
        "parent_library", //
        "fragments = ['java']");
    scratch.file(
        "extend_rule_testing/child.bzl",
        "load('//extend_rule_testing/parent:parent.bzl', 'parent_library')",
        "MyInfo = provider()",
        "def _impl(ctx):",
        "  ctx.super()",
        "my_library = rule(",
        "  implementation = _impl,",
        "  parent = parent_library,",
        "  fragments = ['cc']",
        ")");
    scratch.file(
        "extend_rule_testing/BUILD",
        "load(':child.bzl', 'my_library')",
        "my_library(name = 'my_target')");

    ConfiguredTarget myTarget = getConfiguredTarget("//extend_rule_testing:my_target");
    Rule rule = getRuleContext(myTarget).getRule();

    assertNoEvents();
    assertThat(
            rule.getRuleClassObject()
                .getConfigurationFragmentPolicy()
                .getRequiredStarlarkFragments())
        .containsExactly("java", "cc");
  }

  private String notExtendableError(String rule) {
    return String.format(
        "The rule '%s' is not extendable. Only Starlark rules not using deprecated features (like"
            + " implicit outputs, output to genfiles) may be extended. Special rules like"
            + " analysis tests or rules using build_settings cannot be extended.",
        rule);
  }

  @Test
  public void extendRule_notExtendable() throws Exception {
    BazelEvaluationTestCase ev = new BazelEvaluationTestCase("//extend_rule_testing:child.bzl");
    ev.exec(
        "def impl():", //
        "  pass");

    ev.execAndExport("parent_library = rule(impl, output_to_genfiles = True)");
    ev.checkEvalError(notExtendableError("parent_library"), "rule(impl, parent = parent_library)");

    ev.execAndExport("parent_library = rule(impl, _skylark_testable = True)");
    ev.checkEvalError(notExtendableError("parent_library"), "rule(impl, parent = parent_library)");

    ev.execAndExport("parent_test = rule(impl, analysis_test = True)");
    ev.checkEvalError(notExtendableError("parent_test"), "rule(impl, parent = parent_test)");

    ev.update("config", new StarlarkConfig());
    ev.execAndExport("parent_library = rule(impl, build_setting = config.int())");
    ev.checkEvalError(notExtendableError("parent_library"), "rule(impl, parent = parent_library)");

    ev.execAndExport("parent_library = rule(impl, outputs = {'deploy': '%{name}_deploy.jar'})");
    ev.checkEvalError(notExtendableError("parent_library"), "rule(impl, parent = parent_library)");
  }

  @Test
  public void extendRule_nativeRule_notExtendable() throws Exception {
    scratch.file(
        "extend_rule_testing/child.bzl",
        "def _impl(ctx):",
        "  ctx.super()",
        "my_library = rule(",
        "  implementation = _impl,",
        "  parent = native.alias,",
        "  fragments = ['cc']",
        ")");
    scratch.file(
        "extend_rule_testing/BUILD",
        "load(':child.bzl', 'my_library')",
        "my_library(name = 'my_target')");

    reporter.removeHandler(failFastHandler);
    reporter.addHandler(ev.getEventCollector());
    getConfiguredTarget("//extend_rule_testing:my_target");

    ev.assertContainsError("Parent needs to be a Starlark rule");
  }

  @Test
  public void extendRule_extendableAllowed() throws Exception {
    scratch.file("extend_rule_testing/parent/BUILD");
    scratch.file(
        "extend_rule_testing/parent/parent.bzl",
        "ParentInfo = provider()",
        "def _impl(ctx):",
        "  return [ParentInfo()]",
        "parent_library = rule(",
        "  implementation = _impl,",
        "  extendable = True,",
        ")");
    scratch.file(
        "extend_rule_testing/child.bzl",
        "load('//extend_rule_testing/parent:parent.bzl', 'parent_library')",
        "def _impl(ctx):",
        "  ctx.super()",
        "my_library = rule(",
        "  implementation = _impl,",
        "  parent = parent_library,",
        ")");
    scratch.file(
        "extend_rule_testing/BUILD",
        "load(':child.bzl', 'my_library')",
        "my_library(name = 'my_target')");

    getConfiguredTarget("//extend_rule_testing:my_target");

    assertNoEvents();
  }

  @Test
  public void extendRule_extendableDisallowed() throws Exception {
    scratch.file("extend_rule_testing/parent/BUILD");
    scratch.file(
        "extend_rule_testing/parent/parent.bzl",
        "ParentInfo = provider()",
        "def _impl(ctx):",
        "  return [ParentInfo()]",
        "parent_library = rule(",
        "  implementation = _impl,",
        "  extendable = False,",
        ")");
    scratch.file(
        "extend_rule_testing/child.bzl",
        "load('//extend_rule_testing/parent:parent.bzl', 'parent_library')",
        "def _impl(ctx):",
        "  ctx.super()",
        "my_library = rule(",
        "  implementation = _impl,",
        "  parent = parent_library,",
        ")");
    scratch.file(
        "extend_rule_testing/BUILD",
        "load(':child.bzl', 'my_library')",
        "my_library(name = 'my_target')");

    reporter.removeHandler(failFastHandler);
    reporter.addHandler(ev.getEventCollector());
    getConfiguredTarget("//extend_rule_testing:my_target");

    ev.assertContainsError("The rule 'parent_library' is not extendable.");
  }

  @Test
  public void extendRule_extendableAllowlisted() throws Exception {
    scratch.file(
        "extend_rule_testing/parent/BUILD",
        "package_group(",
        "  name = 'allowlist',",
        "  packages = ['//extend_rule_testing']",
        ")");
    scratch.file(
        "extend_rule_testing/parent/parent.bzl",
        "ParentInfo = provider()",
        "def _impl(ctx):",
        "  return [ParentInfo()]",
        "parent_library = rule(",
        "  implementation = _impl,",
        "  extendable = '//extend_rule_testing/parent:allowlist',",
        ")");
    scratch.file(
        "extend_rule_testing/child.bzl",
        "load('//extend_rule_testing/parent:parent.bzl', 'parent_library')",
        "def _impl(ctx):",
        "  ctx.super()",
        "my_library = rule(",
        "  implementation = _impl,",
        "  parent = parent_library,",
        ")");
    scratch.file(
        "extend_rule_testing/BUILD",
        "load(':child.bzl', 'my_library')",
        "my_library(name = 'my_target')");
    scratch.file(
        "not_on_allowlist/BUILD",
        "load('//extend_rule_testing:child.bzl', 'my_library')",
        "my_library(name = 'my_target')");

    getConfiguredTarget("//extend_rule_testing:my_target");
    getConfiguredTarget("//not_on_allowlist:my_target");

    assertNoEvents();
  }

  @Test
  public void extendRule_extendableAllowlistDenied() throws Exception {
    scratch.file(
        "extend_rule_testing/parent/BUILD",
        "package_group(",
        "  name = 'allowlist',",
        "  packages = []",
        ")");
    scratch.file(
        "extend_rule_testing/parent/parent.bzl",
        "ParentInfo = provider()",
        "def _impl(ctx):",
        "  return [ParentInfo()]",
        "parent_library = rule(",
        "  implementation = _impl,",
        "  extendable = '//extend_rule_testing/parent:allowlist',",
        ")");
    scratch.file(
        "extend_rule_testing/child.bzl",
        "load('//extend_rule_testing/parent:parent.bzl', 'parent_library')",
        "def _impl(ctx):",
        "  ctx.super()",
        "my_library = rule(",
        "  implementation = _impl,",
        "  parent = parent_library,",
        ")");
    scratch.file(
        "extend_rule_testing/BUILD",
        "load(':child.bzl', 'my_library')",
        "my_library(name = 'my_target')");

    reporter.removeHandler(failFastHandler);
    reporter.addHandler(ev.getEventCollector());
    getConfiguredTarget("//extend_rule_testing:my_target");

    ev.assertContainsError("Non-allowlisted attempt to extend a rule.");
  }

  @Test
  public void extendRule_extendableDefault() throws Exception {
    scratch.file("extend_rule_testing/parent/BUILD");
    scratch.file(
        "extend_rule_testing/parent/parent.bzl",
        "ParentInfo = provider()",
        "def _impl(ctx):",
        "  return [ParentInfo()]",
        "parent_library = rule(",
        "  implementation = _impl,",
        ")");
    scratch.file(
        "extend_rule_testing/child.bzl",
        "load('//extend_rule_testing/parent:parent.bzl', 'parent_library')",
        "def _impl(ctx):",
        "  ctx.super()",
        "my_library = rule(",
        "  implementation = _impl,",
        "  parent = parent_library,",
        ")");
    scratch.file(
        "extend_rule_testing/BUILD",
        "load(':child.bzl', 'my_library')",
        "my_library(name = 'my_target')");

    if (!analysisMock.isThisBazel()) {
      reporter.removeHandler(failFastHandler);
      reporter.addHandler(ev.getEventCollector());
    }

    getConfiguredTarget("//extend_rule_testing:my_target");

    if (analysisMock.isThisBazel()) {
      assertNoEvents();
    } else {
      ev.assertContainsError("Non-allowlisted attempt to extend a rule.");
    }
  }

  @Test
  public void extendRule_toolchains_merged() throws Exception {
    scratchParentRule(
        "parent_library", //
        "toolchains = ['" + TestConstants.CPP_TOOLCHAIN_TYPE + "']");
    scratch.file(
        "extend_rule_testing/child.bzl",
        "load('//extend_rule_testing/parent:parent.bzl', 'parent_library')",
        "MyInfo = provider()",
        "def _impl(ctx):",
        "  ctx.super()",
        "my_library = rule(",
        "  implementation = _impl,",
        "  parent = parent_library,",
        "  toolchains = ['" + TestConstants.JAVA_TOOLCHAIN_TYPE + "']",
        ")");
    scratch.file(
        "extend_rule_testing/BUILD",
        "load(':child.bzl', 'my_library')",
        "my_library(name = 'my_target')");

    ConfiguredTarget myTarget = getConfiguredTarget("//extend_rule_testing:my_target");
    Rule rule = getRuleContext(myTarget).getRule();

    assertNoEvents();
    assertThat(
            rule.getRuleClassObject().getToolchainTypes().stream()
                .map(ToolchainTypeRequirement::toolchainType)
                .map(Label::toString))
        .containsExactly(TestConstants.JAVA_TOOLCHAIN_TYPE, TestConstants.CPP_TOOLCHAIN_TYPE);
  }

  @Test
  public void extendRule_advertisedProviders_merged() throws Exception {
    scratchParentRule(
        "parent_library", //
        "provides = [ParentInfo]");
    scratch.file(
        "extend_rule_testing/child.bzl",
        "load('//extend_rule_testing/parent:parent.bzl', 'parent_library', 'ParentInfo')",
        "MyInfo = provider()",
        "def _impl(ctx):",
        "  ctx.super()",
        "  return [MyInfo(), ParentInfo()]",
        "my_library = rule(",
        "  implementation = _impl,",
        "  parent = parent_library,",
        "  provides = [MyInfo]",
        ")");
    scratch.file(
        "extend_rule_testing/BUILD",
        "load(':child.bzl', 'my_library')",
        "my_library(name = 'my_target')");

    ConfiguredTarget myTarget = getConfiguredTarget("//extend_rule_testing:my_target");
    Rule rule = getRuleContext(myTarget).getRule();

    assertNoEvents();
    assertThat(
            rule.getRuleClassObject().getAdvertisedProviders().getStarlarkProviders().stream()
                .map(StarlarkProviderIdentifier::getKey)
                .map(key -> ((StarlarkProvider.Key) key).getExportedName()))
        .containsExactly("MyInfo", "ParentInfo");
  }

  @Test
  public void extendRule_execCompatibleWith_merged() throws Exception {
    String constr1 = TestConstants.CONSTRAINTS_PACKAGE_ROOT + "cpu:x86_64";
    String constr2 = TestConstants.CONSTRAINTS_PACKAGE_ROOT + "os:linux";
    scratchParentRule(
        "parent_library", //
        "exec_compatible_with = ['" + constr1 + "']");
    scratch.file(
        "extend_rule_testing/child.bzl",
        "load('//extend_rule_testing/parent:parent.bzl', 'parent_library', 'ParentInfo')",
        "MyInfo = provider()",
        "def _impl(ctx):",
        "  ctx.super()",
        "  return [MyInfo(), ParentInfo()]",
        "my_library = rule(",
        "  implementation = _impl,",
        "  parent = parent_library,",
        "  exec_compatible_with = ['" + constr2 + "']",
        ")");
    scratch.file(
        "extend_rule_testing/BUILD",
        "load(':child.bzl', 'my_library')",
        "my_library(name = 'my_target')");

    ConfiguredTarget myTarget = getConfiguredTarget("//extend_rule_testing:my_target");
    Rule rule = getRuleContext(myTarget).getRule();

    assertNoEvents();
    assertThat(rule.getRuleClassObject().getExecutionPlatformConstraints())
        .containsExactly(
            Label.parseCanonicalUnchecked(constr1), Label.parseCanonicalUnchecked(constr2));
  }

  @Test
  public void extendRule_execGroups_merged() throws Exception {
    scratchParentRule(
        "parent_library", //
        "exec_groups = {'parent_exec_group': exec_group()}");
    scratch.file(
        "extend_rule_testing/child.bzl",
        "load('//extend_rule_testing/parent:parent.bzl', 'parent_library', 'ParentInfo')",
        "MyInfo = provider()",
        "def _impl(ctx):",
        "  ctx.super()",
        "  return [MyInfo(), ParentInfo()]",
        "my_library = rule(",
        "  implementation = _impl,",
        "  parent = parent_library,",
        "  exec_groups = {'child_exec_group': exec_group()}",
        ")");
    scratch.file(
        "extend_rule_testing/BUILD",
        "load(':child.bzl', 'my_library')",
        "my_library(name = 'my_target')");

    ConfiguredTarget myTarget = getConfiguredTarget("//extend_rule_testing:my_target");
    Rule rule = getRuleContext(myTarget).getRule();

    assertNoEvents();
    assertThat(rule.getRuleClassObject().getExecGroups().keySet())
        .containsExactly("parent_exec_group", "child_exec_group");
  }

  private void scratchStarlarkTransition() throws IOException {
    scratch.overwriteFile(
        TestConstants.TOOLS_REPOSITORY_SCRATCH
            + "tools/allowlists/function_transition_allowlist/BUILD",
        "package_group(",
        "    name = 'function_transition_allowlist',",
        "    packages = [",
        "        'public',",
        "    ],",
        ")");
    scratch.file(
        "test/build_settings.bzl",
        "def _impl(ctx):",
        "  return []",
        "string_flag = rule(implementation = _impl, build_setting = config.string(flag=True))");
    scratch.file(
        "test/BUILD",
        "load('//test:build_settings.bzl', 'string_flag')",
        "string_flag(",
        "  name = 'parent-flag',",
        "  build_setting_default = 'default-parent'",
        ")",
        "string_flag(",
        "  name = 'parent-child-flag',",
        "  build_setting_default = 'default-parent-child'",
        ")",
        "string_flag(",
        "  name = 'child-flag',",
        "  build_setting_default = 'child-default'",
        ")");
    scratch.file(
        "test/transitions.bzl",
        "def _parent_trans_impl(settings, attr):",
        "  return {'//test:parent-flag': 'parent-changed',",
        "          '//test:parent-child-flag': 'parent-child-changed-in-parent'}",
        "parent_transition = transition(",
        "  implementation = _parent_trans_impl,",
        "  inputs = [],",
        "  outputs = ['//test:parent-flag', '//test:parent-child-flag']",
        ")",
        "def _child_trans_impl(settings, attr):",
        "  return {'//test:child-flag': 'child-changed',",
        "          '//test:parent-child-flag': 'parent-child-changed-in-child'}",
        "child_transition = transition(",
        "  implementation = _child_trans_impl,",
        "  inputs = [],",
        "  outputs = ['//test:child-flag', '//test:parent-child-flag']",
        ")");
  }

  @Test
  public void extendRule_cfg_fromParent() throws Exception {
    scratchStarlarkTransition();
    scratch.file("extend_rule_testing/parent/BUILD");
    scratch.file(
        "extend_rule_testing/parent/parent.bzl",
        "load('//test:transitions.bzl', 'parent_transition')",
        "def _impl(ctx):",
        "  pass",
        "parent_rule = rule(",
        "  implementation = _impl,",
        "  extendable = True,",
        "  cfg = parent_transition",
        ")");
    scratch.file(
        "extend_rule_testing/child.bzl",
        "load('//extend_rule_testing/parent:parent.bzl', 'parent_rule')",
        "def _impl(ctx):",
        "  ctx.super()",
        "my_library = rule(",
        "  implementation = _impl,",
        "  parent = parent_rule,",
        ")");
    scratch.file(
        "extend_rule_testing/BUILD",
        "load(':child.bzl', 'my_library')",
        "my_library(name = 'my_target')");

    BuildConfigurationValue configuration =
        getConfiguration(getConfiguredTarget("//extend_rule_testing:my_target"));

    var options = configuration.getOptions().getStarlarkOptions();
    assertThat(options.get(Label.parseCanonicalUnchecked("//test:parent-flag")))
        .isEqualTo("parent-changed");
    assertThat(options.get(Label.parseCanonicalUnchecked("//test:parent-child-flag")))
        .isEqualTo("parent-child-changed-in-parent");
    assertThat(options.get(Label.parseCanonicalUnchecked("//test:child-flag"))).isNull();
  }

  @Test
  public void extendRule_cfg_onChild() throws Exception {
    scratchStarlarkTransition();
    scratch.file("extend_rule_testing/parent/BUILD");
    scratch.file(
        "extend_rule_testing/parent/parent.bzl",
        "def _impl(ctx):",
        "  pass",
        "parent_rule = rule(",
        "  implementation = _impl,",
        "  extendable = True,",
        ")");
    scratch.file(
        "extend_rule_testing/child.bzl",
        "load('//extend_rule_testing/parent:parent.bzl', 'parent_rule')",
        "load('//test:transitions.bzl', 'child_transition')",
        "def _impl(ctx):",
        "  ctx.super()",
        "my_library = rule(",
        "  implementation = _impl,",
        "  parent = parent_rule,",
        "  cfg = child_transition",
        ")");
    scratch.file(
        "extend_rule_testing/BUILD",
        "load(':child.bzl', 'my_library')",
        "my_library(name = 'my_target')");

    BuildConfigurationValue configuration =
        getConfiguration(getConfiguredTarget("//extend_rule_testing:my_target"));

    var options = configuration.getOptions().getStarlarkOptions();
    assertThat(options.get(Label.parseCanonicalUnchecked("//test:parent-flag"))).isNull();
    assertThat(options.get(Label.parseCanonicalUnchecked("//test:parent-child-flag")))
        .isEqualTo("parent-child-changed-in-child");
    assertThat(options.get(Label.parseCanonicalUnchecked("//test:child-flag")))
        .isEqualTo("child-changed");
  }

  @Test
  public void extendRule_cfg_onChildAndFromParent() throws Exception {
    scratchStarlarkTransition();
    scratch.file("extend_rule_testing/parent/BUILD");
    scratch.file(
        "extend_rule_testing/parent/parent.bzl",
        "load('//test:transitions.bzl', 'parent_transition')",
        "def _impl(ctx):",
        "  pass",
        "parent_rule = rule(",
        "  implementation = _impl,",
        "  extendable = True,",
        "  cfg = parent_transition",
        ")");
    scratch.file(
        "extend_rule_testing/child.bzl",
        "load('//extend_rule_testing/parent:parent.bzl', 'parent_rule')",
        "load('//test:transitions.bzl', 'child_transition')",
        "def _impl(ctx):",
        "  ctx.super()",
        "my_library = rule(",
        "  implementation = _impl,",
        "  parent = parent_rule,",
        "  cfg = child_transition",
        ")");
    scratch.file(
        "extend_rule_testing/BUILD",
        "load(':child.bzl', 'my_library')",
        "my_library(name = 'my_target')");

    BuildConfigurationValue configuration =
        getConfiguration(getConfiguredTarget("//extend_rule_testing:my_target"));

    var options = configuration.getOptions().getStarlarkOptions();
    assertThat(options.get(Label.parseCanonicalUnchecked("//test:parent-flag")))
        .isEqualTo("parent-changed");
    assertThat(options.get(Label.parseCanonicalUnchecked("//test:parent-child-flag")))
        .isEqualTo("parent-child-changed-in-parent");
    assertThat(options.get(Label.parseCanonicalUnchecked("//test:child-flag")))
        .isEqualTo("child-changed");
  }

  @Test
  public void testAnalysisTest() throws Exception {
    scratch.file(
        "p/b.bzl",
        "def impl(ctx): ",
        "  return  [AnalysisTestResultInfo(",
        "    success = True,",
        "    message = ''",
        "  )]",
        "def my_test_macro(name):",
        "  testing.analysis_test(name = name, implementation = impl)");
    scratch.file(
        "p/BUILD", //
        "load(':b.bzl','my_test_macro')",
        "my_test_macro(name = 'my_test_target')");

    getConfiguredTarget("//p:my_test_target");

    assertNoEvents();
  }

  @Test
  public void testAnalysisTestAttrs() throws Exception {
    scratch.file(
        "p/b.bzl",
        "def impl(ctx): ",
        "  ctx.attr.target_under_test",
        "  return  [AnalysisTestResultInfo(",
        "    success = True,",
        "    message = ''",
        "  )]",
        "def my_test_macro(name):",
        "  native.filegroup(name = 'my_subject', srcs = [])",
        "  testing.analysis_test(name = name,",
        "    implementation = impl,",
        "    attrs = {'target_under_test': attr.label_list()},",
        "    attr_values = {'target_under_test': [':my_subject']},",
        "  )");
    scratch.file(
        "p/BUILD", //
        "load(':b.bzl','my_test_macro')",
        "my_test_macro(name = 'my_test_target')");

    getConfiguredTarget("//p:my_test_target");

    assertNoEvents();
  }

  /** Tests two analysis_test calls with same name. */
  @Test
  public void testAnalysisTestDuplicateName() throws Exception {
    scratch.file(
        "p/a.bzl",
        "def impl(ctx): ",
        "  return  [AnalysisTestResultInfo(",
        "    success = True,",
        "    message = ''",
        "  )]",
        "def my_test_macro1(name):",
        "  testing.analysis_test(name = name, implementation = impl)");
    scratch.file(
        "p/b.bzl",
        "def impl(ctx): ",
        "  return  [AnalysisTestResultInfo(",
        "    success = True,",
        "    message = ''",
        "  )]",
        "def my_test_macro2(name):",
        "  testing.analysis_test(name = name, implementation = impl)");
    scratch.file(
        "p/BUILD", //
        "load(':a.bzl','my_test_macro1')",
        "load(':b.bzl','my_test_macro2')",
        "my_test_macro1(name = 'my_test_target')",
        "my_test_macro2(name = 'my_test_target')");

    reporter.removeHandler(failFastHandler);
    reporter.addHandler(ev.getEventCollector());
    getConfiguredTarget("//p:my_test_target");

    ev.assertContainsError(
        "Error in analysis_test: my_test_target_test rule 'my_test_target' in package 'p' conflicts"
            + " with existing my_test_target_test rule");
  }

  /**
   * Tests analysis_test call with a name that is not Starlark identifier (but still a good target
   * name).
   */
  @Test
  public void testAnalysisTestBadName() throws Exception {
    scratch.file(
        "p/b.bzl",
        "def impl(ctx): ",
        "  return  [AnalysisTestResultInfo(",
        "    success = True,",
        "    message = ''",
        "  )]",
        "def my_test_macro(name):",
        "  testing.analysis_test(name = name, implementation = impl)");
    scratch.file(
        "p/BUILD", //
        "load(':b.bzl','my_test_macro')",
        "my_test_macro(name = 'my+test+target')");

    reporter.removeHandler(failFastHandler);
    reporter.addHandler(ev.getEventCollector());
    getConfiguredTarget("//p:my+test+target");

    ev.assertContainsError(
        "Error in analysis_test: 'name' is limited to Starlark identifiers, got my+test+target");
  }

  @Test
  public void testAnalysisTestBadArgs() throws Exception {
    scratch.file(
        "p/b.bzl",
        "def impl(ctx): ",
        "  return  [AnalysisTestResultInfo(",
        "    success = True,",
        "    message = ''",
        "  )]",
        "def my_test_macro(name):",
        "  testing.analysis_test(",
        "    name = name, implementation = impl, attr_values = {'notthere':[]})");
    scratch.file(
        "p/BUILD", //
        "load(':b.bzl','my_test_macro')",
        "my_test_macro(name = 'my_test_target')");

    reporter.removeHandler(failFastHandler);
    reporter.addHandler(ev.getEventCollector());
    getConfiguredTarget("//p:my_test_target");

    ev.assertContainsError("no such attribute 'notthere' in 'my_test_target_test' rule");
  }

  @Test
  public void testAnalysisTestErrorOnExport() throws Exception {
    scratch.file(
        "p/b.bzl",
        "def impl(ctx): ",
        "  return  [AnalysisTestResultInfo(",
        "    success = True,",
        "    message = ''",
        "  )]",
        "def my_test_macro(name):",
        "  testing.analysis_test(name = name, implementation = impl, attrs = {'name':"
            + " attr.string()})");
    scratch.file(
        "p/BUILD", //
        "load(':b.bzl','my_test_macro')",
        "my_test_macro(name = 'my_test_target')");

    reporter.removeHandler(failFastHandler);
    reporter.addHandler(ev.getEventCollector());
    getConfiguredTarget("//p:my_test_target");

    ev.assertContainsError(
        "Error in analysis_test: attribute `name`: built-in attributes cannot be overridden");
  }

  @Test
  public void testAnalysisTestErrorOverridingName() throws Exception {
    scratch.file(
        "p/b.bzl",
        "def impl(ctx): ",
        "  return  [AnalysisTestResultInfo(",
        "    success = True,",
        "    message = ''",
        "  )]",
        "def my_test_macro(name):",
        "  testing.analysis_test(name = name, implementation = impl, attr_values = {'name':"
            + " 'override'})");
    scratch.file(
        "p/BUILD", //
        "load(':b.bzl','my_test_macro')",
        "my_test_macro(name = 'my_test_target')");

    reporter.removeHandler(failFastHandler);
    reporter.addHandler(ev.getEventCollector());
    getConfiguredTarget("//p:override");

    ev.assertContainsError(
        "Error in analysis_test: 'name' cannot be set or overridden in 'attr_values'");
  }

  private Object eval(Module module, String... lines) throws Exception {
    ParserInput input = ParserInput.fromLines(lines);
    return Starlark.eval(input, FileOptions.DEFAULT, module, ev.getStarlarkThread());
  }

  @Test
  public void testLabelWithStrictVisibility() throws Exception {
    RepositoryName currentRepo = RepositoryName.createUnvalidated("module~1.2.3");
    RepositoryName otherRepo = RepositoryName.createUnvalidated("dep~4.5");
    Label bzlLabel =
        Label.create(
            PackageIdentifier.create(currentRepo, PathFragment.create("lib")), "label.bzl");
    Object clientData =
        BazelModuleContext.create(
            bzlLabel,
            RepositoryMapping.create(
                ImmutableMap.of("my_module", currentRepo, "dep", otherRepo), currentRepo),
            "lib/label.bzl",
            /* loads= */ ImmutableList.of(),
            /* bzlTransitiveDigest= */ new byte[0]);
    Module module =
        Module.withPredeclaredAndData(
            StarlarkSemantics.DEFAULT,
            StarlarkGlobalsImpl.INSTANCE.getFixedBzlToplevels(),
            clientData);

    assertThat(eval(module, "Label('//foo:bar').workspace_root"))
        .isEqualTo("external/module~1.2.3");
    assertThat(eval(module, "Label('@my_module//foo:bar').workspace_root"))
        .isEqualTo("external/module~1.2.3");
    assertThat(eval(module, "Label('@@module~1.2.3//foo:bar').workspace_root"))
        .isEqualTo("external/module~1.2.3");
    assertThat(eval(module, "Label('@dep//foo:bar').workspace_root")).isEqualTo("external/dep~4.5");
    assertThat(eval(module, "Label('@@dep~4.5//foo:bar').workspace_root"))
        .isEqualTo("external/dep~4.5");
    assertThat(eval(module, "Label('@@//foo:bar').workspace_root")).isEqualTo("");

    assertThat(eval(module, "str(Label('@@//foo:bar'))")).isEqualTo("@@//foo:bar");
    assertThat(
            assertThrows(
                EvalException.class, () -> eval(module, "Label('@//foo:bar').workspace_name")))
        .hasMessageThat()
        .isEqualTo(
            "'workspace_name' is not allowed on invalid Label @@[unknown repo '' requested from"
                + " @@module~1.2.3]//foo:bar");
    assertThat(
            assertThrows(
                EvalException.class, () -> eval(module, "Label('@//foo:bar').workspace_root")))
        .hasMessageThat()
        .isEqualTo(
            "'workspace_root' is not allowed on invalid Label @@[unknown repo '' requested from"
                + " @@module~1.2.3]//foo:bar");
  }
}
