// 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.Map;
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(name, 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_nameUnchanged() throws Exception {
    scratch.file(
        "initializer_testing/b.bzl",
        "def initializer(name, **kwargs):",
        "  if name != 'my_target':",
        "     fail()",
        "  return {'name': name} | kwargs",
        "MyInfo = provider()",
        "def impl(ctx): ",
        "  pass",
        "my_rule = rule(impl, initializer = initializer)");
    scratch.file(
        "initializer_testing/BUILD", //
        "load(':b.bzl','my_rule')",
        "my_rule(name = 'my_target')");

    getConfiguredTarget("//initializer_testing:my_target");

    assertNoEvents();
  }

  @Test
  public void initializer_nameChanged() throws Exception {
    scratch.file(
        "initializer_testing/b.bzl",
        "def initializer(name, **kwargs):",
        "  return {'name': 'my_new_name'}",
        "def impl(ctx): ",
        "  pass",
        "my_rule = rule(impl, initializer = initializer)");
    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");

    ev.assertContainsError("Error in my_rule: Initializer can't change the name of the target");
  }

  @Test
  @SuppressWarnings("unchecked")
  public void initializer_stringListDict() throws Exception {
    scratch.file(
        "initializer_testing/b.bzl",
        "def initializer(**kwargs):",
        "  return {}",
        "MyInfo = provider()",
        "def impl(ctx): ",
        "  return [MyInfo(dict = ctx.attr.dict)]",
        "my_rule = rule(impl,",
        "  initializer = initializer,",
        "  attrs = {",
        "    'dict': attr.string_list_dict(),",
        "  })");
    scratch.file(
        "initializer_testing/BUILD", //
        "load(':b.bzl','my_rule')",
        "my_rule(name = 'my_target', dict = {'k': ['val']})");

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

    assertThat(((Map<String, List<String>>) info.getValue("dict")).keySet()).containsExactly("k");
    assertThat(((Map<String, List<String>>) info.getValue("dict")).get("k")).containsExactly("val");
  }

  @Test
  @SuppressWarnings("unchecked")
  public void initializer_labelKeyedStringDict() throws Exception {
    scratch.file(
        "BUILD", //
        "filegroup(name = 'key')");
    scratch.file(
        "initializer_testing/b.bzl",
        "def initializer(**kwargs):",
        "  return {}",
        "MyInfo = provider()",
        "def impl(ctx): ",
        "  return [MyInfo(dict = ctx.attr.dict)]",
        "my_rule = rule(impl,",
        "  initializer = initializer,",
        "  attrs = {",
        "    'dict': attr.label_keyed_string_dict(),",
        "  })");
    scratch.file(
        "initializer_testing/BUILD", //
        "load(':b.bzl','my_rule')",
        "my_rule(name = 'my_target', dict = {'//:key': 'val'})");

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

    assertThat(((Map<ConfiguredTarget, String>) info.getValue("dict")).keySet())
        .containsExactly(key);
    assertThat(((Map<ConfiguredTarget, String>) info.getValue("dict")).get(key)).isEqualTo("val");
  }

  @Test
  public void initializer_legacyAnyType() throws Exception {
    scratch.file(
        "initializer_testing/b.bzl",
        "MyInfo = provider()",
        "def initializer(name, 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(name, 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(name, 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(name, 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(name, 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(name, 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(name, 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(name, 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(name, 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(name, 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(name, 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(name, 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(name, 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(name, 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(name, 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(name, 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(name, 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");
  }
}
