// Copyright 2018 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.rules.cpp;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static com.google.devtools.build.lib.actions.util.ActionsTestUtil.baseArtifactNames;
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.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.CommandLineExpansionException;
import com.google.devtools.build.lib.actions.util.ActionsTestUtil;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.DefaultInfo;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.util.AnalysisMock;
import com.google.devtools.build.lib.analysis.util.AnalysisTestUtil;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
import com.google.devtools.build.lib.collect.nestedset.Depset;
import com.google.devtools.build.lib.packages.Provider;
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.util.Crosstool.CcToolchainConfig;
import com.google.devtools.build.lib.packages.util.MockCcSupport;
import com.google.devtools.build.lib.packages.util.ResourceLoader;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.ActionConfig;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.ArtifactNamePattern;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.EnvEntry;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.EnvSet;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.Feature;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.Flag.SingleChunkFlag;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FlagGroup;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FlagSet;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.Tool;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.VariableWithValue;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.WithFeatureSet;
import com.google.devtools.build.lib.rules.cpp.CcToolchainVariables.StringValueParser;
import com.google.devtools.build.lib.testutil.Scratch;
import com.google.devtools.build.lib.testutil.TestConstants;
import com.google.devtools.build.lib.util.Pair;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CToolchain;
import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.MakeVariable;
import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.ToolPath;
import com.google.protobuf.TextFormat;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import net.starlark.java.eval.EvalException;
import net.starlark.java.eval.Sequence;
import net.starlark.java.eval.Starlark;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Unit tests for the {@code cc_common} Starlark module. */
@RunWith(JUnit4.class)
public class StarlarkCcCommonTest extends BuildViewTestCase {

  @Before
  public void setBuildLanguageOptions() throws Exception {
    this.setBuildLanguageOptions(StarlarkCcCommonTestHelper.CC_STARLARK_WHITELIST_FLAG);
    invalidatePackages();

    scratch.file("myinfo/myinfo.bzl", "MyInfo = provider()");

    scratch.file("myinfo/BUILD");
  }

  private static StructImpl getMyInfoFromTarget(ConfiguredTarget configuredTarget)
      throws LabelSyntaxException {
    Provider.Key key =
        new StarlarkProvider.Key(
            Label.parseAbsolute("//myinfo:myinfo.bzl", ImmutableMap.of()), "MyInfo");
    return (StructImpl) configuredTarget.get(key);
  }

  private static Iterable<Artifact> getArtifactsFromMyInfo(ConfiguredTarget target, String field)
      throws Exception {
    StructImpl myInfo = getMyInfoFromTarget(target);
    @SuppressWarnings("unchecked")
    Iterable<Artifact> artifacts = (Iterable<Artifact>) myInfo.getValue(field);
    return artifacts;
  }

  @Test
  public void testAllFiles() throws Exception {
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'crule')",
        "cc_toolchain_alias(name='alias')",
        "crule(name='r')");

    scratch.file(
        "a/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  return [MyInfo(all_files = toolchain.all_files)]",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
        "  },",
        ");");

    ConfiguredTarget r = getConfiguredTarget("//a:r");
    Depset allFiles = (Depset) getMyInfoFromTarget(r).getValue("all_files");
    RuleContext ruleContext = getRuleContext(r);
    CcToolchainProvider toolchain =
        CppHelper.getToolchain(ruleContext, ruleContext.getPrerequisite("$cc_toolchain"));
    assertThat(allFiles.getSet(Artifact.class)).isEqualTo(toolchain.getAllFiles());
  }

  @Test
  public void testRuntimeLib() throws Exception {
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'crule')",
        "cc_toolchain_alias(name='alias')",
        "crule(name='r')");

    scratch.file(
        "a/rule.bzl",
        "CruleInfo = provider(fields=['static', 'dynamic'])",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "    ctx = ctx,",
        "    cc_toolchain = toolchain,",
        "  )",
        "  return [CruleInfo(",
        "    static = toolchain.static_runtime_lib(feature_configuration = feature_configuration),",
        "    dynamic = toolchain.dynamic_runtime_lib(",
        "      feature_configuration = feature_configuration),",
        "  )]",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
        "  },",
        "  fragments = ['cpp'],",
        ");");

    // 1. Build without static_link_cpp_runtimes
    ConfiguredTarget r = getConfiguredTarget("//a:r");
    Provider.Key key =
        new StarlarkProvider.Key(
            Label.create(r.getLabel().getPackageIdentifier(), "rule.bzl"), "CruleInfo");
    StarlarkInfo cruleInfo = (StarlarkInfo) r.get(key);
    Depset staticRuntimeLib = (Depset) cruleInfo.getValue("static");
    Depset dynamicRuntimeLib = (Depset) cruleInfo.getValue("dynamic");

    assertThat(staticRuntimeLib.getSet(Artifact.class).toList()).isEmpty();
    assertThat(dynamicRuntimeLib.getSet(Artifact.class).toList()).isEmpty();

    // 2. Build with static_link_cpp_runtimes
    getAnalysisMock()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder().withFeatures(CppRuleClasses.STATIC_LINK_CPP_RUNTIMES));
    invalidatePackages();
    r = getConfiguredTarget("//a:r");
    cruleInfo = (StarlarkInfo) r.get(key);
    staticRuntimeLib = (Depset) cruleInfo.getValue("static");
    dynamicRuntimeLib = (Depset) cruleInfo.getValue("dynamic");

    RuleContext ruleContext = getRuleContext(r);
    CcToolchainProvider toolchain =
        CppHelper.getToolchain(ruleContext, ruleContext.getPrerequisite("$cc_toolchain"));
    assertThat(staticRuntimeLib.getSet(Artifact.class))
        .isEqualTo(toolchain.getStaticRuntimeLibForTesting());
    assertThat(dynamicRuntimeLib.getSet(Artifact.class))
        .isEqualTo(toolchain.getDynamicRuntimeLibForTesting());
  }

  @Test
  public void testGetToolForAction() throws Exception {
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'crule')",
        "cc_toolchain_alias(name='alias')",
        "crule(name='r')");

    scratch.file(
        "a/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "    ctx = ctx,",
        "    cc_toolchain = toolchain,",
        "  )",
        "  return [MyInfo(",
        "    action_tool_path = cc_common.get_tool_for_action(",
        "        feature_configuration = feature_configuration,",
        "        action_name = 'c++-compile'))]",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
        "  },",
        "  fragments = ['cpp'],",
        ");");

    ConfiguredTarget r = getConfiguredTarget("//a:r");
    String actionToolPath = (String) getMyInfoFromTarget(r).getValue("action_tool_path");
    RuleContext ruleContext = getRuleContext(r);
    CcToolchainProvider toolchain =
        CppHelper.getToolchain(ruleContext, ruleContext.getPrerequisite("$cc_toolchain"));
    FeatureConfiguration featureConfiguration =
        CcCommon.configureFeaturesOrThrowEvalException(
            ImmutableSet.of(),
            ImmutableSet.of(),
            toolchain,
            ruleContext.getFragment(CppConfiguration.class));
    assertThat(actionToolPath)
        .isEqualTo(featureConfiguration.getToolPathForAction(CppActionNames.CPP_COMPILE));
  }

  @Test
  public void testExecutionRequirements() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder()
                .withFeatures(MockCcSupport.CPP_COMPILE_ACTION_WITH_REQUIREMENTS));
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'crule')",
        "cc_toolchain_alias(name='alias')",
        "crule(name='r')");

    scratch.file(
        "a/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "    ctx = ctx,",
        "    cc_toolchain = toolchain,",
        "  )",
        "  return [MyInfo(",
        "    requirements = cc_common.get_execution_requirements(",
        "        feature_configuration = feature_configuration,",
        "        action_name = 'yolo_action_with_requirements'))]",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
        "  },",
        "  fragments = ['cpp'],",
        ");");

    ConfiguredTarget r = getConfiguredTarget("//a:r");
    @SuppressWarnings("unchecked")
    Sequence<String> requirements =
        (Sequence<String>) getMyInfoFromTarget(r).getValue("requirements");
    assertThat(requirements).containsExactly("requires-yolo");
  }

  @Test
  public void testFeatureConfigurationWithAdditionalEnabledFeature() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig, CcToolchainConfig.builder().withFeatures("foo_feature"));
    useConfiguration();
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'crule')",
        "cc_toolchain_alias(name='alias')",
        "crule(name='r')");

    scratch.file(
        "a/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "      ctx = ctx,",
        "      cc_toolchain = toolchain,",
        "      requested_features = ['foo_feature'])",
        "  return [MyInfo(",
        "    foo_feature_enabled = cc_common.is_enabled(",
        "        feature_configuration = feature_configuration,",
        "        feature_name = 'foo_feature'))]",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
        "  },",
        "  fragments = ['cpp'],",
        ");");

    ConfiguredTarget r = getConfiguredTarget("//a:r");
    boolean fooFeatureEnabled = (boolean) getMyInfoFromTarget(r).getValue("foo_feature_enabled");
    assertThat(fooFeatureEnabled).isTrue();
  }

  @Test
  public void testFeatureConfigurationWithAdditionalUnsupportedFeature() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig, CcToolchainConfig.builder().withFeatures("foo_feature"));
    useConfiguration("--features=foo_feature");
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'crule')",
        "cc_toolchain_alias(name='alias')",
        "crule(name='r')");

    scratch.file(
        "a/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "      ctx = ctx,",
        "      cc_toolchain = toolchain,",
        "      unsupported_features = ['foo_feature'])",
        "  return [MyInfo(",
        "    foo_feature_enabled = cc_common.is_enabled(",
        "        feature_configuration = feature_configuration,",
        "        feature_name = 'foo_feature'))]",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
        "  },",
        "  fragments = ['cpp'],",
        ");");

    ConfiguredTarget r = getConfiguredTarget("//a:r");
    boolean fooFeatureEnabled = (boolean) getMyInfoFromTarget(r).getValue("foo_feature_enabled");
    assertThat(fooFeatureEnabled).isFalse();
  }

  @Test
  public void testGetCommandLine() throws Exception {
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'crule')",
        "cc_toolchain_alias(name='alias')",
        "crule(name='r')");

    scratch.file(
        "a/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "    ctx = ctx,",
        "    cc_toolchain = toolchain,",
        "  )",
        "  return [MyInfo(",
        "    command_line = cc_common.get_memory_inefficient_command_line(",
        "        feature_configuration = feature_configuration,",
        "        action_name = 'c++-link-executable',",
        "        variables = cc_common.empty_variables()))]",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
        "  },",
        "  fragments = ['cpp'],",
        ");");

    ConfiguredTarget r = getConfiguredTarget("//a:r");
    @SuppressWarnings("unchecked")
    Sequence<String> commandLine =
        (Sequence<String>) getMyInfoFromTarget(r).getValue("command_line");
    RuleContext ruleContext = getRuleContext(r);
    CcToolchainProvider toolchain =
        CppHelper.getToolchain(ruleContext, ruleContext.getPrerequisite("$cc_toolchain"));
    FeatureConfiguration featureConfiguration =
        CcCommon.configureFeaturesOrThrowEvalException(
            ImmutableSet.of(),
            ImmutableSet.of(),
            toolchain,
            ruleContext.getFragment(CppConfiguration.class));
    assertThat(commandLine)
        .containsExactlyElementsIn(
            featureConfiguration.getCommandLine("c++-link-executable", CcToolchainVariables.EMPTY));
  }

  @Test
  public void testGetEnvironment() throws Exception {
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'crule')",
        "cc_toolchain_alias(name='alias')",
        "crule(name='r')");

    scratch.file(
        "a/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "    ctx = ctx,",
        "    cc_toolchain = toolchain,",
        "  )",
        "  return [MyInfo(",
        "    environment_variables = cc_common.get_environment_variables(",
        "        feature_configuration = feature_configuration,",
        "        action_name = 'c++-compile',",
        "        variables = cc_common.empty_variables()))]",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
        "  },",
        "  fragments = ['cpp'],",
        ");");

    ConfiguredTarget r = getConfiguredTarget("//a:r");
    @SuppressWarnings("unchecked")
    Map<String, String> environmentVariables =
        (Map<String, String>) getMyInfoFromTarget(r).getValue("environment_variables");
    RuleContext ruleContext = getRuleContext(r);
    CcToolchainProvider toolchain =
        CppHelper.getToolchain(ruleContext, ruleContext.getPrerequisite("$cc_toolchain"));
    FeatureConfiguration featureConfiguration =
        CcCommon.configureFeaturesOrThrowEvalException(
            ImmutableSet.of(),
            ImmutableSet.of(),
            toolchain,
            ruleContext.getFragment(CppConfiguration.class));
    assertThat(environmentVariables)
        .containsExactlyEntriesIn(
            featureConfiguration.getEnvironmentVariables(
                CppActionNames.CPP_COMPILE, CcToolchainVariables.EMPTY));
  }

  @Test
  public void testActionIsEnabled() throws Exception {
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'crule')",
        "cc_toolchain_alias(name='alias')",
        "crule(name='r')");

    scratch.file(
        "a/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "    ctx = ctx,",
        "    cc_toolchain = toolchain,",
        "  )",
        "  return [MyInfo(",
        "    enabled_action = cc_common.action_is_enabled(",
        "        feature_configuration = feature_configuration,",
        "        action_name = 'c-compile'),",
        "    disabled_action = cc_common.action_is_enabled(",
        "        feature_configuration = feature_configuration,",
        "        action_name = 'wololoo'))]",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
        "  },",
        "  fragments = ['cpp'],",
        ");");

    StructImpl myInfo = getMyInfoFromTarget(getConfiguredTarget("//a:r"));
    boolean enabledActionIsEnabled = (boolean) myInfo.getValue("enabled_action");
    boolean disabledActionIsDisabled = (boolean) myInfo.getValue("disabled_action");
    assertThat(enabledActionIsEnabled).isTrue();
    assertThat(disabledActionIsDisabled).isFalse();
  }

  @Test
  public void testIsEnabled() throws Exception {
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'crule')",
        "cc_toolchain_alias(name='alias')",
        "crule(name='r')");

    scratch.file(
        "a/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "    ctx = ctx,",
        "    cc_toolchain = toolchain,",
        "  )",
        "  return [MyInfo(",
        "    enabled_feature = cc_common.is_enabled(",
        "        feature_configuration = feature_configuration,",
        "        feature_name = 'libraries_to_link'),",
        "    disabled_feature = cc_common.is_enabled(",
        "        feature_configuration = feature_configuration,",
        "        feature_name = 'wololoo'))]",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
        "  },",
        "  fragments = ['cpp'],",
        ");");

    StructImpl myInfo = getMyInfoFromTarget(getConfiguredTarget("//a:r"));

    boolean enabledFeatureIsEnabled = (boolean) myInfo.getValue("enabled_feature");
    boolean disabledFeatureIsDisabled = (boolean) myInfo.getValue("disabled_feature");
    assertThat(enabledFeatureIsEnabled).isTrue();
    assertThat(disabledFeatureIsDisabled).isFalse();
  }

  @Test
  public void testFeatureConfigurationRequiresCtx() throws Exception {
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'crule')",
        "cc_toolchain_alias(name='alias')",
        "crule(name='r')");

    scratch.file(
        "a/rule.bzl",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(cc_toolchain = toolchain)",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
        "  },",
        "  fragments = ['cpp'],",
        ");");
    useConfiguration("--incompatible_require_ctx_in_configure_features");
    reporter.removeHandler(failFastHandler);

    getConfiguredTarget("//a:r");
    assertContainsEvent("mandatory parameter 'ctx' of cc_common.configure_features is missing");
  }

  @Test
  public void testActionNames() throws Exception {
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'crule')",
        "cc_toolchain_alias(name='alias')",
        "crule(name='r')");
    scratch.overwriteFile("tools/build_defs/cc/BUILD");
    scratch.overwriteFile(
        "tools/build_defs/cc/action_names.bzl",
        ResourceLoader.readFromResources(
            TestConstants.RULES_CC_REPOSITORY_EXECROOT + "cc/action_names.bzl"));

    scratch.file(
        "a/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "load('//tools/build_defs/cc:action_names.bzl',",
        "    'C_COMPILE_ACTION_NAME',",
        "    'CPP_COMPILE_ACTION_NAME',",
        "    'LINKSTAMP_COMPILE_ACTION_NAME',",
        "    'CC_FLAGS_MAKE_VARIABLE_ACTION_NAME',",
        "    'CPP_MODULE_CODEGEN_ACTION_NAME',",
        "    'CPP_HEADER_PARSING_ACTION_NAME',",
        "    'CPP_MODULE_COMPILE_ACTION_NAME',",
        "    'ASSEMBLE_ACTION_NAME',",
        "    'PREPROCESS_ASSEMBLE_ACTION_NAME',",
        "    'LTO_INDEXING_ACTION_NAME',",
        "    'LTO_BACKEND_ACTION_NAME',",
        "    'CPP_LINK_EXECUTABLE_ACTION_NAME',",
        "    'CPP_LINK_DYNAMIC_LIBRARY_ACTION_NAME',",
        "    'CPP_LINK_NODEPS_DYNAMIC_LIBRARY_ACTION_NAME',",
        "    'CPP_LINK_STATIC_LIBRARY_ACTION_NAME',",
        "    'STRIP_ACTION_NAME')",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "    ctx = ctx,",
        "    cc_toolchain = toolchain,",
        "  )",
        "  return [MyInfo(",
        "      c_compile_action_name=C_COMPILE_ACTION_NAME,",
        "      cpp_compile_action_name=CPP_COMPILE_ACTION_NAME,",
        "      linkstamp_compile_action_name=LINKSTAMP_COMPILE_ACTION_NAME,",
        "      cc_flags_make_variable_action_name_action_name=CC_FLAGS_MAKE_VARIABLE_ACTION_NAME,",
        "      cpp_module_codegen_action_name=CPP_MODULE_CODEGEN_ACTION_NAME,",
        "      cpp_header_parsing_action_name=CPP_HEADER_PARSING_ACTION_NAME,",
        "      cpp_module_compile_action_name=CPP_MODULE_COMPILE_ACTION_NAME,",
        "      assemble_action_name=ASSEMBLE_ACTION_NAME,",
        "      preprocess_assemble_action_name=PREPROCESS_ASSEMBLE_ACTION_NAME,",
        "      lto_indexing_action_name=LTO_INDEXING_ACTION_NAME,",
        "      lto_backend_action_name=LTO_BACKEND_ACTION_NAME,",
        "      cpp_link_executable_action_name=CPP_LINK_EXECUTABLE_ACTION_NAME,",
        "      cpp_link_dynamic_library_action_name=CPP_LINK_DYNAMIC_LIBRARY_ACTION_NAME,",
        "     "
            + " cpp_link_nodeps_dynamic_library_action_name=CPP_LINK_NODEPS_DYNAMIC_LIBRARY_ACTION_NAME,",
        "      cpp_link_static_library_action_name=CPP_LINK_STATIC_LIBRARY_ACTION_NAME,",
        "      strip_action_name=STRIP_ACTION_NAME)]",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
        "  },",
        "  fragments = ['cpp'],",
        ")");

    assertThat(getTarget("//a:r")).isNotNull();

    StructImpl myInfo = getMyInfoFromTarget(getConfiguredTarget("//a:r"));

    assertThat(myInfo.getValue("c_compile_action_name")).isEqualTo(CppActionNames.C_COMPILE);
    assertThat(myInfo.getValue("cpp_compile_action_name")).isEqualTo(CppActionNames.CPP_COMPILE);
    assertThat(myInfo.getValue("linkstamp_compile_action_name"))
        .isEqualTo(CppActionNames.LINKSTAMP_COMPILE);
    assertThat(myInfo.getValue("cc_flags_make_variable_action_name_action_name"))
        .isEqualTo(CppActionNames.CC_FLAGS_MAKE_VARIABLE);
    assertThat(myInfo.getValue("cpp_module_codegen_action_name"))
        .isEqualTo(CppActionNames.CPP_MODULE_CODEGEN);
    assertThat(myInfo.getValue("cpp_header_parsing_action_name"))
        .isEqualTo(CppActionNames.CPP_HEADER_PARSING);
    assertThat(myInfo.getValue("cpp_module_compile_action_name"))
        .isEqualTo(CppActionNames.CPP_MODULE_COMPILE);
    assertThat(myInfo.getValue("assemble_action_name")).isEqualTo(CppActionNames.ASSEMBLE);
    assertThat(myInfo.getValue("preprocess_assemble_action_name"))
        .isEqualTo(CppActionNames.PREPROCESS_ASSEMBLE);
    assertThat(myInfo.getValue("lto_indexing_action_name")).isEqualTo(CppActionNames.LTO_INDEXING);
    assertThat(myInfo.getValue("lto_backend_action_name")).isEqualTo(CppActionNames.LTO_BACKEND);
    assertThat(myInfo.getValue("cpp_link_executable_action_name"))
        .isEqualTo(CppActionNames.CPP_LINK_EXECUTABLE);
    assertThat(myInfo.getValue("cpp_link_dynamic_library_action_name"))
        .isEqualTo(CppActionNames.CPP_LINK_DYNAMIC_LIBRARY);
    assertThat(myInfo.getValue("cpp_link_nodeps_dynamic_library_action_name"))
        .isEqualTo(CppActionNames.CPP_LINK_NODEPS_DYNAMIC_LIBRARY);
    assertThat(myInfo.getValue("cpp_link_static_library_action_name"))
        .isEqualTo(CppActionNames.CPP_LINK_STATIC_LIBRARY);
    assertThat(myInfo.getValue("strip_action_name")).isEqualTo(CppActionNames.STRIP);
  }

  @Test
  public void testCompileBuildVariablesWithSourceFile() throws Exception {
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_COMPILE,
                "cc_common.create_compile_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "source_file = 'foo/bar/hello'",
                ")"))
        .containsAtLeast("-c", "foo/bar/hello")
        .inOrder();
  }

  @Test
  public void testCompileBuildVariablesWithOutputFile() throws Exception {
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_COMPILE,
                "cc_common.create_compile_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "output_file = 'foo/bar/hello.o'",
                ")"))
        .containsAtLeast("-o", "foo/bar/hello.o")
        .inOrder();
  }

  @Test
  public void testCompileBuildVariablesForIncludes() throws Exception {
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_COMPILE,
                "cc_common.create_compile_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "include_directories = depset(['foo/bar/include'])",
                ")"))
        .contains("-Ifoo/bar/include");
  }

  @Test
  public void testCompileBuildVariablesForFrameworkIncludes() throws Exception {
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_COMPILE,
                "cc_common.create_compile_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "framework_include_directories = depset(['foo/bar'])",
                ")"))
        .contains("-Ffoo/bar");
  }

  @Test
  public void testCompileBuildVariablesForDefines() throws Exception {
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_COMPILE,
                "cc_common.create_compile_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "preprocessor_defines = depset(['DEBUG_FOO'])",
                ")"))
        .contains("-DDEBUG_FOO");
  }

  @Test
  public void testCompileBuildVariablesForPic() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder()
                .withFeatures(CppRuleClasses.SUPPORTS_PIC, CppRuleClasses.PIC));
    useConfiguration();
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_COMPILE,
                "cc_common.create_compile_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "use_pic = True",
                ")"))
        .contains("-fPIC");
  }

  @Test
  public void testUserCompileFlags() throws Exception {
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_COMPILE,
                "cc_common.create_compile_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "user_compile_flags = ['-foo']",
                ")"))
        .contains("-foo");
  }

  @Test
  public void testCompileBuildVariablesForDummyLtoBackendAction() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig, CcToolchainConfig.builder().withFeatures(CppRuleClasses.THIN_LTO));
    useConfiguration("--features=thin_lto");
    Sequence<String> commandLine =
        commandLineForVariables(
            CppActionNames.LTO_BACKEND,
            "cc_common.create_compile_variables(",
            "feature_configuration = feature_configuration,",
            "cc_toolchain = toolchain,",
            "thinlto_input_bitcode_file = 'path/to/input',",
            "thinlto_output_object_file = 'path/to/output',",
            "thinlto_index = '/dev/null'",
            ")");

    assertThat(commandLine)
        .containsAtLeast(
            "thinlto_index=/dev/null",
            "thinlto_output_object_file=path/to/output",
            "thinlto_input_bitcode_file=path/to/input");
  }

  @Test
  public void testEmptyLinkVariables() throws Exception {
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_LINK_EXECUTABLE,
                "cc_common.create_link_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "user_link_flags = [ '-foo' ],",
                ")"))
        .contains("-foo");
  }

  @Test
  public void testEmptyLinkVariablesContainSysroot() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig, CcToolchainConfig.builder().withSysroot("/foo/bar/sysroot"));
    useConfiguration();
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_LINK_EXECUTABLE,
                "cc_common.create_link_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                ")"))
        .contains("--sysroot=/foo/bar/sysroot");
  }

  @Test
  public void testLibrarySearchDirectoriesLinkVariables() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder().withFeatures("library_search_directories"));
    useConfiguration();
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_LINK_EXECUTABLE,
                "cc_common.create_link_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "library_search_directories = depset([ 'a', 'b', 'c' ]),",
                ")"))
        .containsAtLeast("--library=a", "--library=b", "--library=c")
        .inOrder();
  }

  @Test
  public void testRuntimeLibrarySearchDirectoriesLinkVariables() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder().withFeatures("runtime_library_search_directories"));
    useConfiguration();
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_LINK_EXECUTABLE,
                "cc_common.create_link_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "runtime_library_search_directories = depset([ 'a', 'b', 'c' ]),",
                ")"))
        .containsAtLeast("--runtime_library=a", "--runtime_library=b", "--runtime_library=c")
        .inOrder();
  }

  @Test
  public void testUserLinkFlagsLinkVariables() throws Exception {
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_LINK_EXECUTABLE,
                "cc_common.create_link_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "user_link_flags = [ '-avocado' ],",
                ")"))
        .contains("-avocado");
  }

  @Test
  public void testIfsoRelatedVariablesAreNotExposed() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig, CcToolchainConfig.builder().withFeatures("uses_ifso_variables"));
    useConfiguration();
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_LINK_DYNAMIC_LIBRARY,
                "cc_common.create_link_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                ")"))
        .doesNotContain("--generate_interface_library_was_available");
  }

  @Test
  public void testOutputFileLinkVariables() throws Exception {
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_LINK_EXECUTABLE,
                "cc_common.create_link_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "output_file = 'foo/bar/executable',",
                ")"))
        .contains("foo/bar/executable");
  }

  @Test
  public void testParamFileLinkVariables() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder().withFeatures(CppRuleClasses.DO_NOT_SPLIT_LINKING_CMDLINE));
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_LINK_EXECUTABLE,
                "cc_common.create_link_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "param_file = 'foo/bar/params',",
                ")"))
        .contains("@foo/bar/params");
  }

  @Test
  public void testDefFileLinkVariables() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(mockToolsConfig, CcToolchainConfig.builder().withFeatures("def"));
    useConfiguration();
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_LINK_EXECUTABLE,
                "cc_common.create_link_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "def_file = 'foo/bar/def',",
                ")"))
        .contains("-qux_foo/bar/def");
  }

  @Test
  public void testMustKeepDebugLinkVariables() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig, CcToolchainConfig.builder().withFeatures("strip_debug_symbols"));

    useConfiguration();
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_LINK_EXECUTABLE,
                0,
                "cc_common.create_link_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "must_keep_debug = False,",
                ")"))
        .contains("-strip_stuff");
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_LINK_EXECUTABLE,
                1,
                "cc_common.create_link_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "must_keep_debug = True,",
                ")"))
        .doesNotContain("-strip_stuff");
  }

  @Test
  public void testIsLinkingDynamicLibraryLinkVariables() throws Exception {
    useConfiguration("--linkopt=-pie");
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_LINK_EXECUTABLE,
                0,
                "cc_common.create_link_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "is_linking_dynamic_library = True,",
                "user_link_flags = [ '-pie' ],",
                ")"))
        .doesNotContain("-pie");
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_LINK_EXECUTABLE,
                1,
                "cc_common.create_link_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "is_linking_dynamic_library = False,",
                "user_link_flags = [ '-pie' ],",
                ")"))
        .contains("-pie");
  }

  @Test
  public void testIsUsingLinkerLinkVariables() throws Exception {
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_LINK_EXECUTABLE,
                0,
                "cc_common.create_link_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "is_using_linker = True,",
                "user_link_flags = [ '-i_dont_want_to_see_this_on_archiver_command_line' ],",
                ")"))
        .contains("-i_dont_want_to_see_this_on_archiver_command_line");
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_LINK_EXECUTABLE,
                1,
                "cc_common.create_link_variables(",
                "feature_configuration = feature_configuration,",
                "cc_toolchain = toolchain,",
                "is_using_linker = False,",
                "user_link_flags = [ '-i_dont_want_to_see_this_on_archiver_command_line' ],",
                ")"))
        .doesNotContain("-i_dont_want_to_see_this_on_archiver_command_line");
  }

  private Sequence<String> commandLineForVariables(String actionName, String... variables)
      throws Exception {
    return commandLineForVariables(actionName, 0, variables);
  }

  // This method is only there to change the package to fix multiple runs of this method in a single
  // test.
  // TODO(b/109917616): Remove pkgSuffix argument when bzl files are not cached within single test
  private Sequence<String> commandLineForVariables(
      String actionName, int pkgSuffix, String... variables) throws Exception {
    scratch.file(
        "a" + pkgSuffix + "/BUILD",
        "load(':rule.bzl', 'crule')",
        "cc_toolchain_alias(name='alias')",
        "crule(name='r')");

    scratch.file(
        "a" + pkgSuffix + "/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "    ctx = ctx,",
        "    cc_toolchain = toolchain,",
        "    requested_features = ctx.features,",
        "  )",
        "  variables = " + Joiner.on("\n").join(variables),
        "  return [MyInfo(",
        "    command_line = cc_common.get_memory_inefficient_command_line(",
        "        feature_configuration = feature_configuration,",
        "        action_name = '" + actionName + "',",
        "        variables = variables))]",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "    '_cc_toolchain': attr.label(default=Label('//a" + pkgSuffix + ":alias'))",
        "  },",
        "  fragments = ['cpp'],",
        ");");

    /** Calling {@link #getTarget} to get loading errors */
    getTarget("//a" + pkgSuffix + ":r");
    ConfiguredTarget r = getConfiguredTarget("//a" + pkgSuffix + ":r");
    if (r == null) {
      return null;
    }
    @SuppressWarnings("unchecked")
    Sequence<String> result = (Sequence<String>) getMyInfoFromTarget(r).getValue("command_line");
    return result;
  }

  @Test
  public void testCcCompilationProvider() throws Exception {
    scratch.file(
        "a/BUILD",
        "load('//tools/build_defs/cc:rule.bzl', 'crule')",
        "licenses(['notice'])",
        "cc_library(",
        "    name='lib',",
        "    hdrs = ['lib.h'],",
        "    srcs = ['lib.cc'],",
        "    deps = ['r']",
        ")",
        "cc_library(",
        "    name = 'dep1',",
        "    srcs = ['dep1.cc'],",
        "    hdrs = ['dep1.h'],",
        "    includes = ['dep1/baz'],",
        "    defines = ['DEP1'],",
        "    local_defines = ['LOCALDEP1'],",
        ")",
        "cc_library(",
        "    name = 'dep2',",
        "    srcs = ['dep2.cc'],",
        "    hdrs = ['dep2.h'],",
        "    includes = ['dep2/qux'],",
        "    defines = ['DEP2'],",
        ")",
        "crule(name='r')");
    scratch.overwriteFile("tools/build_defs/cc/BUILD", "");
    scratch.file(
        "tools/build_defs/cc/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  compilation_context = cc_common.create_compilation_context(",
        "    headers=depset([ctx.file._header]),",
        "    system_includes=depset([ctx.attr._system_include]),",
        "    includes=depset([ctx.attr._include]),",
        "    quote_includes=depset([ctx.attr._quote_include]),",
        "    framework_includes=depset([ctx.attr._framework_include]),",
        "    defines=depset([ctx.attr._define]))",
        "  cc_infos = [CcInfo(compilation_context=compilation_context)]",
        "  for dep in ctx.attr._deps:",
        "      cc_infos.append(dep[CcInfo])",
        "  merged_cc_info=cc_common.merge_cc_infos(cc_infos=cc_infos)",
        "  return [",
        "      merged_cc_info,",
        "      MyInfo(",
        "          merged_headers=merged_cc_info.compilation_context.headers,",
        "          merged_system_includes=merged_cc_info.compilation_context.system_includes,",
        "          merged_includes=merged_cc_info.compilation_context.includes,",
        "          merged_quote_includes=merged_cc_info.compilation_context.quote_includes,",
        "         "
            + " merged_framework_includes=merged_cc_info.compilation_context.framework_includes,",
        "          merged_defines=merged_cc_info.compilation_context.defines",
        "      )]",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "    '_header': attr.label(allow_single_file=True,",
        "        default=Label('//a:header.h')),",
        "    '_system_include': attr.string(default='foo/bar'),",
        "    '_include': attr.string(default='baz/qux'),",
        "    '_quote_include': attr.string(default='quux/abc'),",
        "    '_framework_include': attr.string(default='fuux/fgh'),",
        "    '_define': attr.string(default='MYDEFINE'),",
        "    '_local_define': attr.string(default='MYLOCALDEFINE'),",
        "    '_deps': attr.label_list(default=['//a:dep1', '//a:dep2'])",
        "  },",
        "  fragments = ['cpp'],",
        ");");

    ConfiguredTarget lib = getConfiguredTarget("//a:lib");
    CcCompilationContext ccCompilationContext = lib.get(CcInfo.PROVIDER).getCcCompilationContext();
    assertThat(
            ccCompilationContext.getDeclaredIncludeSrcs().toList().stream()
                .map(Artifact::getFilename)
                .collect(ImmutableList.toImmutableList()))
        .containsExactly("lib.h", "header.h", "dep1.h", "dep2.h");

    StructImpl myInfo = getMyInfoFromTarget(getConfiguredTarget("//a:r"));

    List<Artifact> mergedHeaders =
        ((Depset) myInfo.getValue("merged_headers")).getSet(Artifact.class).toList();
    assertThat(
            mergedHeaders.stream()
                .map(Artifact::getFilename)
                .collect(ImmutableList.toImmutableList()))
        .containsAtLeast("header.h", "dep1.h", "dep2.h");

    List<String> mergedDefines =
        ((Depset) myInfo.getValue("merged_defines")).getSet(String.class).toList();
    assertThat(mergedDefines).containsAtLeast("MYDEFINE", "DEP1", "DEP2");
    assertThat(mergedDefines).doesNotContain("LOCALDEP1");

    List<String> mergedSystemIncludes =
        ((Depset) myInfo.getValue("merged_system_includes")).getSet(String.class).toList();
    assertThat(mergedSystemIncludes).containsAtLeast("foo/bar", "a/dep1/baz", "a/dep2/qux");

    List<String> mergedIncludes =
        ((Depset) myInfo.getValue("merged_includes")).getSet(String.class).toList();
    assertThat(mergedIncludes).contains("baz/qux");

    List<String> mergedQuoteIncludes =
        ((Depset) myInfo.getValue("merged_quote_includes")).getSet(String.class).toList();
    assertThat(mergedQuoteIncludes).contains("quux/abc");

    List<String> mergedFrameworkIncludes =
        ((Depset) myInfo.getValue("merged_framework_includes")).getSet(String.class).toList();
    assertThat(mergedFrameworkIncludes).contains("fuux/fgh");
  }

  @Test
  public void testCcCompilationProviderDefaultValues() throws Exception {
    scratch.file(
        "a/BUILD",
        "load('//tools/build_defs/cc:rule.bzl', 'crule')",
        "licenses(['notice'])",
        "crule(name='r')");
    scratch.overwriteFile("tools/build_defs/cc/BUILD", "");
    scratch.file(
        "tools/build_defs/cc/rule.bzl",
        "def _impl(ctx):",
        "  compilation_context = cc_common.create_compilation_context()",
        "crule = rule(",
        "  _impl,",
        "  fragments = ['cpp'],",
        ");");

    assertThat(getConfiguredTarget("//a:r")).isNotNull();
  }

  @Test
  public void testCcCompilationProviderInvalidValues() throws Exception {
    reporter.removeHandler(failFastHandler);
    scratch.file(
        "a/BUILD",
        "load('//tools/build_defs/cc:rule.bzl', 'crule')",
        "licenses(['notice'])",
        "crule(name='r')");
    scratch.overwriteFile("tools/build_defs/cc/BUILD", "");
    scratch.file(
        "tools/build_defs/cc/rule.bzl",
        "def _impl(ctx):",
        "  compilation_context = cc_common.create_compilation_context(headers=[])",
        "crule = rule(",
        "  _impl,",
        "  fragments = ['cpp'],",
        ");");

    getConfiguredTarget("//a:r");
    assertContainsEvent("for headers, got list, want a depset of File");
  }

  @Test
  public void testCreateCompilationOutputs_invalidDepset() throws Exception {
    reporter.removeHandler(failFastHandler);
    scratch.file("test/BUILD", "load(':my_rule.bzl', 'my_rule')", "my_rule(name='x')");
    scratch.file(
        "test/my_rule.bzl",
        "def _impl(ctx):",
        "  cc_common.create_compilation_outputs(",
        "      objects = depset([1, 2]), pic_objects = depset([1, 2]))",
        "my_rule = rule(",
        "  _impl,",
        ");");

    assertThat(getConfiguredTarget("//test:x")).isNull();
    assertContainsEvent("for 'objects', got a depset of 'int', expected a depset of 'File'");
  }

  @Test
  public void testCreateCompilationOutputs_empty() throws Exception {
    scratch.file("test/BUILD", "load(':my_rule.bzl', 'my_rule')", "my_rule(name='x')");
    scratch.file(
        "test/my_rule.bzl",
        "def _impl(ctx):",
        "  cc_common.create_compilation_outputs()",
        "my_rule = rule(",
        "  _impl,",
        ");");

    assertThat(getConfiguredTarget("//test:x")).isNotNull();
  }

  @Test
  public void testCcLinkingContextOnWindows() throws Exception {
    if (!AnalysisMock.get().isThisBazel()) {
      return;
    }
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder()
                .withFeatures(
                    CppRuleClasses.COPY_DYNAMIC_LIBRARIES_TO_BINARY,
                    CppRuleClasses.TARGETS_WINDOWS,
                    CppRuleClasses.SUPPORTS_DYNAMIC_LINKER));
    doTestCcLinkingContext(
        ImmutableList.of("a.a", "libdep2.a", "b.a", "c.a", "d.a", "libdep1.a"),
        ImmutableList.of("a.pic.a", "b.pic.a", "c.pic.a", "e.pic.a"),
        // The suffix of dynamic library is caculated based on repository name and package path
        // to avoid conflicts with dynamic library from other packages.
        ImmutableList.of("a.so", "libdep2_c092dd9ce2.so", "b.so", "e.so", "libdep1_c092dd9ce2.so"));
  }

  @Test
  public void testCcLinkingContext() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder()
                .withFeatures(
                    CppRuleClasses.PIC,
                    CppRuleClasses.SUPPORTS_PIC,
                    CppRuleClasses.SUPPORTS_DYNAMIC_LINKER));
    doTestCcLinkingContext(
        ImmutableList.of("a.a", "b.a", "c.a", "d.a"),
        ImmutableList.of("a.pic.a", "libdep2.a", "b.pic.a", "c.pic.a", "e.pic.a", "libdep1.a"),
        ImmutableList.of("a.so", "liba_Slibdep2.so", "b.so", "e.so", "liba_Slibdep1.so"));
  }

  @Test
  public void testCcLinkingContextForExperimentalCcSharedLibrary() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder()
                .withFeatures(
                    CppRuleClasses.PIC,
                    CppRuleClasses.SUPPORTS_PIC,
                    CppRuleClasses.SUPPORTS_DYNAMIC_LINKER));
    doTestCcLinkingContext(
        ImmutableList.of("a.a", "b.a", "c.a", "d.a"),
        ImmutableList.of("a.pic.a", "libdep2.a", "b.pic.a", "c.pic.a", "e.pic.a", "libdep1.a"),
        ImmutableList.of("a.so", "liba_Slibdep2.so", "b.so", "e.so", "liba_Slibdep1.so"));
  }

  /** TODO(#8118): This test can go away once flag is flipped. */
  @Test
  public void testIncompatibleDepsetForLibrariesToLinkGetter() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder()
                .withFeatures(
                    CppRuleClasses.PIC,
                    CppRuleClasses.SUPPORTS_PIC,
                    CppRuleClasses.SUPPORTS_DYNAMIC_LINKER));
    this.setBuildLanguageOptions("--incompatible_depset_for_libraries_to_link_getter");
    setUpCcLinkingContextTest(false);
    ConfiguredTarget a = getConfiguredTarget("//a:a");
    StructImpl info = ((StructImpl) getMyInfoFromTarget(a).getValue("info"));

    Depset librariesToLink = info.getValue("libraries_to_link", Depset.class);
    assertThat(
            librariesToLink.toList(LibraryToLink.class).stream()
                .filter(x -> x.getStaticLibrary() != null)
                .map(x -> x.getStaticLibrary().getFilename())
                .collect(ImmutableList.toImmutableList()))
        .containsExactly("a.a", "b.a", "c.a", "d.a");
    assertThat(
            librariesToLink.toList(LibraryToLink.class).stream()
                .filter(x -> x.getPicStaticLibrary() != null)
                .map(x -> x.getPicStaticLibrary().getFilename())
                .collect(ImmutableList.toImmutableList()))
        .containsExactly("a.pic.a", "libdep2.a", "b.pic.a", "c.pic.a", "e.pic.a", "libdep1.a");
    assertThat(
            librariesToLink.toList(LibraryToLink.class).stream()
                .filter(x -> x.getDynamicLibrary() != null)
                .map(x -> x.getDynamicLibrary().getFilename())
                .collect(ImmutableList.toImmutableList()))
        .containsExactly("a.so", "liba_Slibdep2.so", "b.so", "e.so", "liba_Slibdep1.so");
  }

  private static String getSolibRelativePath(Artifact library, CcToolchainProvider toolchain) {
    return library.getRootRelativePath().relativeTo(toolchain.getSolibDirectory()).toString();
  }

  @Test
  public void testSolibLinkDefault() throws Exception {
    setUpCcLinkingContextTest(false);
    scratch.file(
        "foo/BUILD",
        "load('//tools/build_defs/cc:rule.bzl', 'crule')",
        "cc_binary(name='bin',",
        "   deps = [':a'],",
        ")",
        "crule(name='a',",
        "   dynamic_library = 'a.so',",
        "   interface_library = 'a.ifso',",
        ")");
    ConfiguredTarget a = getConfiguredTarget("//foo:a");
    RuleContext ruleContext = getRuleContext(a);
    CcToolchainProvider toolchain =
        CppHelper.getToolchain(ruleContext, ruleContext.getPrerequisite("$cc_toolchain"));
    StructImpl info = ((StructImpl) getMyInfoFromTarget(a).getValue("info"));
    Depset librariesToLink = info.getValue("libraries_to_link", Depset.class);
    assertThat(
            librariesToLink.toList(LibraryToLink.class).stream()
                .filter(x -> x.getDynamicLibrary() != null)
                .map(x -> getSolibRelativePath(x.getDynamicLibrary(), toolchain))
                .collect(ImmutableList.toImmutableList()))
        .containsExactly("_U_S_Sfoo_Ca___Ufoo/a.so");
    assertThat(
            librariesToLink.toList(LibraryToLink.class).stream()
                .filter(x -> x.getInterfaceLibrary() != null)
                .map(x -> getSolibRelativePath(x.getInterfaceLibrary(), toolchain))
                .collect(ImmutableList.toImmutableList()))
        .containsExactly("_U_S_Sfoo_Ca___Ufoo/a.ifso");
  }

  @Test
  public void testSolibLinkCustom() throws Exception {
    setUpCcLinkingContextTest(false);
    scratch.file(
        "foo/BUILD",
        "load('//tools/build_defs/cc:rule.bzl', 'crule')",
        "cc_binary(name='bin',",
        "   deps = [':a'],",
        ")",
        "crule(name='a',",
        "   dynamic_library = 'a.so',",
        "   interface_library = 'a.ifso',",
        "   dynamic_library_symlink_path = 'custom/libcustom.so',",
        "   interface_library_symlink_path = 'libcustom.ifso',",
        ")");
    ConfiguredTarget a = getConfiguredTarget("//foo:a");
    RuleContext ruleContext = getRuleContext(a);
    CcToolchainProvider toolchain =
        CppHelper.getToolchain(ruleContext, ruleContext.getPrerequisite("$cc_toolchain"));
    StructImpl info = ((StructImpl) getMyInfoFromTarget(a).getValue("info"));
    Depset librariesToLink = info.getValue("libraries_to_link", Depset.class);
    assertThat(
            librariesToLink.toList(LibraryToLink.class).stream()
                .filter(x -> x.getDynamicLibrary() != null)
                .map(
                    x ->
                        x.getDynamicLibrary()
                            .getRootRelativePath()
                            .relativeTo(toolchain.getSolibDirectory())
                            .toString())
                .collect(ImmutableList.toImmutableList()))
        .containsExactly("custom/libcustom.so");
    assertThat(
            librariesToLink.toList(LibraryToLink.class).stream()
                .filter(x -> x.getInterfaceLibrary() != null)
                .map(
                    x ->
                        x.getInterfaceLibrary()
                            .getRootRelativePath()
                            .relativeTo(toolchain.getSolibDirectory())
                            .toString())
                .collect(ImmutableList.toImmutableList()))
        .containsExactly("libcustom.ifso");
  }

  private void doTestCcLinkingContext(
      List<String> staticLibraryList,
      List<String> picStaticLibraryList,
      List<String> dynamicLibraryList)
      throws Exception {
    useConfiguration("--features=-supports_interface_shared_libraries");
    this.setBuildLanguageOptions("--incompatible_depset_for_libraries_to_link_getter");
    setUpCcLinkingContextTest(false);
    ConfiguredTarget a = getConfiguredTarget("//a:a");

    StructImpl info = ((StructImpl) getMyInfoFromTarget(a).getValue("info"));
    @SuppressWarnings("unchecked")
    Sequence<String> userLinkFlags =
        (Sequence<String>) info.getValue("user_link_flags", Sequence.class);
    assertThat(userLinkFlags.getImmutableList())
        .containsExactly("-la", "-lc2", "-DEP2_LINKOPT", "-lc1", "-lc2", "-DEP1_LINKOPT");
    Depset additionalInputs = info.getValue("additional_inputs", Depset.class);
    assertThat(
            additionalInputs.toList(Artifact.class).stream()
                .map(x -> x.getFilename())
                .collect(ImmutableList.toImmutableList()))
        .containsExactly("b.lds", "d.lds");
    Collection<LibraryToLink> librariesToLink =
        info.getValue("libraries_to_link", Depset.class).toList(LibraryToLink.class);
    assertThat(
            librariesToLink.stream()
                .filter(x -> x.getStaticLibrary() != null)
                .map(x -> x.getStaticLibrary().getFilename())
                .collect(ImmutableList.toImmutableList()))
        .containsExactlyElementsIn(staticLibraryList);
    assertThat(
            librariesToLink.stream()
                .filter(x -> x.getPicStaticLibrary() != null)
                .map(x -> x.getPicStaticLibrary().getFilename())
                .collect(ImmutableList.toImmutableList()))
        .containsExactlyElementsIn(picStaticLibraryList);
    assertThat(
            librariesToLink.stream()
                .filter(x -> x.getDynamicLibrary() != null)
                .map(x -> x.getDynamicLibrary().getFilename())
                .collect(ImmutableList.toImmutableList()))
        .containsExactlyElementsIn(dynamicLibraryList);
    assertThat(
            librariesToLink.stream()
                .filter(x -> x.getInterfaceLibrary() != null)
                .map(x -> x.getInterfaceLibrary().getFilename())
                .collect(ImmutableList.toImmutableList()))
        .containsExactly("a.ifso");
    Artifact staticLibrary = info.getValue("static_library", Artifact.class);
    assertThat(staticLibrary.getFilename()).isEqualTo("a.a");
    Artifact picStaticLibrary = info.getValue("pic_static_library", Artifact.class);
    assertThat(picStaticLibrary.getFilename()).isEqualTo("a.pic.a");
    Artifact dynamicLibrary = info.getValue("dynamic_library", Artifact.class);
    assertThat(dynamicLibrary.getFilename()).isEqualTo("a.so");
    Artifact interfaceLibrary = info.getValue("interface_library", Artifact.class);
    assertThat(interfaceLibrary.getFilename()).isEqualTo("a.ifso");
    boolean alwayslink = info.getValue("alwayslink", Boolean.class);
    assertThat(alwayslink).isTrue();

    ConfiguredTarget bin = getConfiguredTarget("//a:bin");
    assertThat(bin).isNotNull();
  }

  private void setUpCcLinkingContextTest(boolean enableExperimentalCcImport) throws Exception {
    if (enableExperimentalCcImport) {
      useConfiguration("--experimental_starlark_cc_import");
    }
    scratch.file(
        "a/BUILD",
        "load('//tools/build_defs/cc:rule.bzl', 'crule')",
        "cc_binary(name='bin',",
        "   deps = [':a'],",
        ")",
        "crule(name='a',",
        "   static_library = 'a.a',",
        "   pic_static_library = 'a.pic.a',",
        "   dynamic_library = 'a.so',",
        "   interface_library = 'a.ifso',",
        "   user_link_flags = ['-la', '-lc2'],",
        "   alwayslink = True,",
        "   deps = [':c', ':dep2', ':b'],",
        ")",
        "crule(name='b',",
        "   static_library = 'b.a',",
        "   pic_static_library = 'b.pic.a',",
        "   dynamic_library = 'b.so',",
        "   deps = [':c', ':d'],",
        "   additional_inputs = ['b.lds'],",
        ")",
        "crule(name='c',",
        "   static_library = 'c.a',",
        "   pic_static_library = 'c.pic.a',",
        "   user_link_flags = ['-lc1', '-lc2'],",
        ")",
        "crule(name='d',",
        "   static_library = 'd.a',",
        "   alwayslink = True,",
        "   deps = [':e'],",
        "   additional_inputs = ['d.lds'],",
        ")",
        "crule(name='e',",
        "   pic_static_library = 'e.pic.a',",
        "   dynamic_library = 'e.so',",
        "   deps = [':dep1'],",
        ")",
        "cc_toolchain_alias(name='alias')",
        "cc_library(",
        "    name = 'dep1',",
        "    srcs = ['dep1.cc'],",
        "    hdrs = ['dep1.h'],",
        "    linkopts = ['-DEP1_LINKOPT'],",
        ")",
        "cc_library(",
        "    name = 'dep2',",
        "    srcs = ['dep2.cc'],",
        "    hdrs = ['dep2.h'],",
        "    linkopts = ['-DEP2_LINKOPT'],",
        ")");
    scratch.file("a/lib.a", "");
    scratch.file("a/lib.so", "");
    scratch.overwriteFile("tools/build_defs/cc/BUILD", "");
    scratch.file(
        "tools/build_defs/cc/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "linker_input = cc_common.create_linker_input(",
        "                 owner=Label('//toplevel'),",
        "                 user_link_flags=depset(['-first_flag', '-second_flag']))",
        "top_linking_context_smoke = cc_common.create_linking_context(",
        "   linker_inputs=depset([linker_input]))",
        "def _create(ctx, feature_configuration, static_library, pic_static_library,",
        "  dynamic_library,",
        "  interface_library, dynamic_library_symlink_path, interface_library_symlink_path,",
        "  alwayslink, objects, pic_objects):",
        "  return cc_common.create_library_to_link(",
        "    actions=ctx.actions, feature_configuration=feature_configuration, ",
        "    cc_toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo], ",
        "    static_library=static_library, pic_static_library=pic_static_library,",
        "    dynamic_library=dynamic_library, interface_library=interface_library,",
        "    dynamic_library_symlink_path=dynamic_library_symlink_path,",
        "    interface_library_symlink_path=interface_library_symlink_path,",
        "    alwayslink=alwayslink, ",
        enableExperimentalCcImport ? "    objects=objects, " : "",
        enableExperimentalCcImport ? "    pic_objects=pic_objects" : "",
        "    )",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "    ctx = ctx,",
        "    cc_toolchain = toolchain,",
        "  )",
        "  library_to_link = _create(ctx, feature_configuration, ctx.file.static_library, ",
        "     ctx.file.pic_static_library, ctx.file.dynamic_library, ctx.file.interface_library,",
        "     ctx.attr.dynamic_library_symlink_path,",
        "     ctx.attr.interface_library_symlink_path,",
        "     ctx.attr.alwayslink, ctx.files.objects, ctx.files.pic_objects)",
        "  linker_input = cc_common.create_linker_input(",
        "                   owner=ctx.label,",
        "                   libraries=depset([library_to_link]),",
        "                   user_link_flags=depset(ctx.attr.user_link_flags),",
        "                   additional_inputs=depset(ctx.files.additional_inputs))",
        "  linking_context = cc_common.create_linking_context(",
        "     linker_inputs=depset([linker_input]))",
        "  cc_infos = [CcInfo(linking_context=linking_context)]",
        "  for dep in ctx.attr.deps:",
        "      cc_infos.append(dep[CcInfo])",
        "  merged_cc_info = cc_common.merge_cc_infos(cc_infos=cc_infos)",
        "  merged_libraries = []",
        "  merged_additional_inputs = []",
        "  merged_user_link_flags = []",
        "  for l in merged_cc_info.linking_context.linker_inputs.to_list():",
        "      merged_libraries.extend(l.libraries)",
        "      merged_additional_inputs.extend(l.additional_inputs)",
        "      merged_user_link_flags.extend(l.user_link_flags)",
        "  return [",
        "     MyInfo(",
        "         info = struct(",
        "             cc_info = merged_cc_info,",
        "             user_link_flags = merged_user_link_flags,",
        "             additional_inputs = depset(merged_additional_inputs),",
        "             libraries_to_link = depset(merged_libraries),",
        "             static_library = library_to_link.static_library,",
        "             pic_static_library = library_to_link.pic_static_library,",
        "             dynamic_library = library_to_link.dynamic_library,",
        "             interface_library = library_to_link.interface_library,",
        "             alwayslink = library_to_link.alwayslink,",
        "             objects = library_to_link.objects,",
        "             pic_objects = library_to_link.pic_objects),",
        "      ),",
        "      merged_cc_info]",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "    'user_link_flags' : attr.string_list(),",
        "    'additional_inputs': attr.label_list(allow_files=True),",
        "    'static_library': attr.label(allow_single_file=True),",
        "    'pic_static_library': attr.label(allow_single_file=True),",
        "    'dynamic_library': attr.label(allow_single_file=True),",
        "    'dynamic_library_symlink_path': attr.string(),",
        "    'interface_library': attr.label(allow_single_file=True),",
        "    'interface_library_symlink_path': attr.string(),",
        "    'objects': attr.label_list(allow_files=True),",
        "    'pic_objects': attr.label_list(allow_files=True),",
        "    'alwayslink': attr.bool(),",
        "    '_cc_toolchain': attr.label(default=Label('//a:alias')),",
        "    'deps': attr.label_list(),",
        "  },",
        "  fragments = ['cpp'],",
        ");");
  }

  private void loadCcToolchainConfigLib() throws IOException {
    scratch.appendFile("tools/cpp/BUILD", "");
    scratch.overwriteFile(
        "tools/cpp/cc_toolchain_config_lib.bzl",
        ResourceLoader.readFromResources(
            TestConstants.RULES_CC_REPOSITORY_EXECROOT + "cc/cc_toolchain_config_lib.bzl"));
  }

  @Test
  public void testVariableWithValue() throws Exception {
    loadCcToolchainConfigLib();
    createVariableWithValueRule("one", /* name= */ "None", /* value= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//one:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("name parameter of variable_with_value should be a string, found NoneType");

    createVariableWithValueRule("two", /* name= */ "'abc'", /* value= */ "None");

    e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//two:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("value parameter of variable_with_value should be a string, found NoneType");

    createVariableWithValueRule("three", /* name= */ "''", /* value= */ "None");

    e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//three:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("name parameter of variable_with_value must be a nonempty string");

    createVariableWithValueRule("four", /* name= */ "'abc'", /* value= */ "''");

    e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//four:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("value parameter of variable_with_value must be a nonempty string");

    createVariableWithValueRule("five", /* name= */ "'abc'", /* value= */ "'def'");

    ConfiguredTarget t = getConfiguredTarget("//five:a");
    StarlarkInfo variable = (StarlarkInfo) getMyInfoFromTarget(t).getValue("variable");
    assertThat(variable).isNotNull();
    VariableWithValue v = CcModule.variableWithValueFromStarlark(variable);
    assertThat(v).isNotNull();
    assertThat(v.variable).isEqualTo("abc");
    assertThat(v.value).isEqualTo("def");

    createEnvEntryRule("six", /* key= */ "'abc'", /* value= */ "'def'");
    t = getConfiguredTarget("//six:a");
    StarlarkInfo envEntry = (StarlarkInfo) getMyInfoFromTarget(t).getValue("entry");
    EvalException ee =
        assertThrows(EvalException.class, () -> CcModule.variableWithValueFromStarlark(envEntry));
    assertThat(ee)
        .hasMessageThat()
        .contains("Expected object of type 'variable_with_value', received 'env_entry");
  }

  private void createVariableWithValueRule(String pkg, String name, String value)
      throws IOException {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl', 'variable_with_value')",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(variable = variable_with_value(",
        "       name = " + name + ",",
        "       value = " + value + "))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testCustomVariableWithValue_none_none() throws Exception {
    loadCcToolchainConfigLib();
    createCustomVariableWithValueRule("one", /* name= */ "None", /* value= */ "None");
    ConfiguredTarget t = getConfiguredTarget("//one:a");
    StarlarkInfo variable = (StarlarkInfo) getMyInfoFromTarget(t).getValue("variable");
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.variableWithValueFromStarlark(variable));
    assertThat(e)
        .hasMessageThat()
        .contains("'name' parameter of variable_with_value must be a nonempty string.");
  }

  @Test
  public void testCustomVariableWithValue_string_none() throws Exception {
    loadCcToolchainConfigLib();
    createCustomVariableWithValueRule("two", /* name= */ "'abc'", /* value= */ "None");

    ConfiguredTarget t = getConfiguredTarget("//two:a");
    StarlarkInfo variable = (StarlarkInfo) getMyInfoFromTarget(t).getValue("variable");
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.variableWithValueFromStarlark(variable));
    assertThat(e)
        .hasMessageThat()
        .contains("'value' parameter of variable_with_value must be a nonempty string.");
  }

  @Test
  public void testCustomVariableWithValue_string_struct() throws Exception {
    loadCcToolchainConfigLib();
    createCustomVariableWithValueRule("three", /* name= */ "'abc'", /* value= */ "struct()");

    ConfiguredTarget t = getConfiguredTarget("//three:a");
    StarlarkInfo variable = (StarlarkInfo) getMyInfoFromTarget(t).getValue("variable");
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.variableWithValueFromStarlark(variable));
    assertThat(e).hasMessageThat().contains("Field 'value' is not of 'java.lang.String' type.");
  }

  @Test
  public void testCustomVariableWithValue_boolean_string() throws Exception {
    loadCcToolchainConfigLib();
    createCustomVariableWithValueRule("four", /* name= */ "True", /* value= */ "'abc'");

    ConfiguredTarget t = getConfiguredTarget("//four:a");
    StarlarkInfo variable = (StarlarkInfo) getMyInfoFromTarget(t).getValue("variable");
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.variableWithValueFromStarlark(variable));
    assertThat(e).hasMessageThat().contains("Field 'name' is not of 'java.lang.String' type.");
  }

  private void createCustomVariableWithValueRule(String pkg, String name, String value)
      throws IOException {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(variable = struct(",
        "       name = " + name + ",",
        "       value = " + value + ",",
        "       type_name = 'variable_with_value'))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testEnvEntry_none_none() throws Exception {
    loadCcToolchainConfigLib();
    createEnvEntryRule("one", "None", /* value= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//one:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("key parameter of env_entry should be a string, found NoneType");
  }

  @Test
  public void testEnvEntry_string_none() throws Exception {
    loadCcToolchainConfigLib();
    createEnvEntryRule("two", "'abc'", /* value= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//two:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("value parameter of env_entry should be a string, found NoneType");
  }

  @Test
  public void testEnvEntry_emptyString_none() throws Exception {
    loadCcToolchainConfigLib();
    createEnvEntryRule("three", "''", /* value= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//three:a"));
    assertThat(e).hasMessageThat().contains("key parameter of env_entry must be a nonempty string");
  }

  @Test
  public void testEnvEntry_string_emptyString() throws Exception {
    loadCcToolchainConfigLib();
    createEnvEntryRule("four", "'abc'", /* value= */ "''");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//four:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("value parameter of env_entry must be a nonempty string");
  }

  @Test
  public void testEnvEntry_string_string() throws Exception {
    loadCcToolchainConfigLib();
    createEnvEntryRule("five", "'abc'", /* value= */ "'def'");

    ConfiguredTarget t = getConfiguredTarget("//five:a");
    StarlarkInfo entryProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("entry");
    assertThat(entryProvider).isNotNull();
    EnvEntry entry = CcModule.envEntryFromStarlark(entryProvider);
    assertThat(entry).isNotNull();
    StringValueParser parser = new StringValueParser("def");
    assertThat(entry).isEqualTo(new EnvEntry("abc", parser.getChunks()));
  }

  @Test
  public void testEnvEntryVariable_string_string() throws Exception {
    loadCcToolchainConfigLib();
    createVariableWithValueRule("six", /* name= */ "'abc'", /* value= */ "'def'");
    ConfiguredTarget t = getConfiguredTarget("//six:a");
    StarlarkInfo variable = (StarlarkInfo) getMyInfoFromTarget(t).getValue("variable");
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.envEntryFromStarlark(variable));
    assertThat(e)
        .hasMessageThat()
        .contains("Expected object of type 'env_entry', received 'variable_with_value");
  }

  private void createEnvEntryRule(String pkg, String key, String value) throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl', 'env_entry')",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(entry = env_entry(",
        "       key = " + key + ",",
        "       value = " + value + "))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testCustomEnvEntry_none_none() throws Exception {
    loadCcToolchainConfigLib();
    createCustomEnvEntryRule("one", /* key= */ "None", /* value= */ "None");

    ConfiguredTarget t = getConfiguredTarget("//one:a");
    StarlarkInfo entry = (StarlarkInfo) getMyInfoFromTarget(t).getValue("entry");
    EvalException e = assertThrows(EvalException.class, () -> CcModule.envEntryFromStarlark(entry));
    assertThat(e)
        .hasMessageThat()
        .contains("'key' parameter of env_entry must be a nonempty string.");
  }

  @Test
  public void testCustomEnvEntry_string_none() throws Exception {
    loadCcToolchainConfigLib();
    createCustomEnvEntryRule("two", /* key= */ "'abc'", /* value= */ "None");

    ConfiguredTarget t = getConfiguredTarget("//two:a");
    StarlarkInfo entry = (StarlarkInfo) getMyInfoFromTarget(t).getValue("entry");
    EvalException e =
        assertThrows(
            "Should have failed because of empty string.",
            EvalException.class,
            () -> CcModule.envEntryFromStarlark(entry));
    assertThat(e)
        .hasMessageThat()
        .contains("'value' parameter of env_entry must be a nonempty string.");
  }

  @Test
  public void testCustomEnvEntry_string_struct() throws Exception {
    loadCcToolchainConfigLib();
    createCustomEnvEntryRule("three", /* key= */ "'abc'", /* value= */ "struct()");

    ConfiguredTarget t = getConfiguredTarget("//three:a");
    StarlarkInfo entry = (StarlarkInfo) getMyInfoFromTarget(t).getValue("entry");
    EvalException e = assertThrows(EvalException.class, () -> CcModule.envEntryFromStarlark(entry));
    assertThat(e).hasMessageThat().contains("Field 'value' is not of 'java.lang.String' type.");
  }

  @Test
  public void testCustomEnvEntry_boolean_string() throws Exception {
    loadCcToolchainConfigLib();
    createCustomEnvEntryRule("four", /* key= */ "True", /* value= */ "'abc'");

    ConfiguredTarget t = getConfiguredTarget("//four:a");
    StarlarkInfo entry = (StarlarkInfo) getMyInfoFromTarget(t).getValue("entry");
    EvalException e = assertThrows(EvalException.class, () -> CcModule.envEntryFromStarlark(entry));
    assertThat(e).hasMessageThat().contains("Field 'key' is not of 'java.lang.String' type.");
  }

  private void createCustomEnvEntryRule(String pkg, String key, String value) throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(entry = struct(",
        "       key = " + key + ",",
        "       value = " + value + ",",
        "       type_name = 'env_entry'))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testToolPath_none_none() throws Exception {
    loadCcToolchainConfigLib();
    createToolPathRule("one", /* name= */ "None", "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//one:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("name parameter of tool_path should be a string, found NoneType");
  }

  @Test
  public void testToolPath_string_none() throws Exception {
    loadCcToolchainConfigLib();
    createToolPathRule("two", /* name= */ "'abc'", "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//two:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("path parameter of tool_path should be a string, found NoneType");
  }

  @Test
  public void testToolPath_emptyString_none() throws Exception {
    loadCcToolchainConfigLib();
    createToolPathRule("three", /* name= */ "''", "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//three:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("name parameter of tool_path must be a nonempty string");
  }

  @Test
  public void testToolPath_string_emptyString() throws Exception {
    loadCcToolchainConfigLib();
    createToolPathRule("four", /* name= */ "'abc'", "''");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//four:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("path parameter of tool_path must be a nonempty string");
  }

  @Test
  public void testToolPath_string_escapedString() throws Exception {
    loadCcToolchainConfigLib();
    createToolPathRule("five", /* name= */ "'abc'", "'/d/e/f'");

    ConfiguredTarget t = getConfiguredTarget("//five:a");
    StarlarkInfo toolPathProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("toolpath");
    assertThat(toolPathProvider).isNotNull();
    Pair<String, String> toolPath = CcModule.toolPathFromStarlark(toolPathProvider);
    assertThat(toolPath).isNotNull();
    assertThat(toolPath.first).isEqualTo("abc");
    assertThat(toolPath.second).isEqualTo("/d/e/f");
  }

  @Test
  public void testToolPath_string_string() throws Exception {
    loadCcToolchainConfigLib();
    createVariableWithValueRule("six", /* name= */ "'abc'", /* value= */ "'def'");
    ConfiguredTarget t = getConfiguredTarget("//six:a");
    StarlarkInfo variable = (StarlarkInfo) getMyInfoFromTarget(t).getValue("variable");
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.toolPathFromStarlark(variable));
    assertThat(e)
        .hasMessageThat()
        .contains("Expected object of type 'tool_path', received 'variable_with_value");
  }

  private void createToolPathRule(String pkg, String name, String path) throws IOException {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl', 'tool_path')",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(toolpath = tool_path(",
        "       name = " + name + ",",
        "       path = " + path + "))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testCustomToolPath_name_mustBeNonEmpty() throws Exception {
    loadCcToolchainConfigLib();
    createCustomToolPathRule("one", /* name= */ "None", /* path= */ "None");

    ConfiguredTarget t = getConfiguredTarget("//one:a");
    StarlarkInfo toolPath = (StarlarkInfo) getMyInfoFromTarget(t).getValue("toolpath");
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.toolPathFromStarlark(toolPath));
    assertThat(e)
        .hasMessageThat()
        .contains("'name' parameter of tool_path must be a nonempty string.");
  }

  @Test
  public void testCustomToolPath_path_mustBeNonEmpty() throws Exception {
    loadCcToolchainConfigLib();
    createCustomToolPathRule("two", /* name= */ "'abc'", /* path= */ "None");

    ConfiguredTarget t = getConfiguredTarget("//two:a");
    StarlarkInfo toolPath = (StarlarkInfo) getMyInfoFromTarget(t).getValue("toolpath");
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.toolPathFromStarlark(toolPath));
    assertThat(e)
        .hasMessageThat()
        .contains("'path' parameter of tool_path must be a nonempty string.");
  }

  @Test
  public void testCustomToolPath_path_mustBeString() throws Exception {
    loadCcToolchainConfigLib();
    createCustomToolPathRule("three", /* name= */ "'abc'", /* path= */ "struct()");

    ConfiguredTarget t = getConfiguredTarget("//three:a");
    StarlarkInfo toolPath = (StarlarkInfo) getMyInfoFromTarget(t).getValue("toolpath");
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.toolPathFromStarlark(toolPath));
    assertThat(e).hasMessageThat().contains("Field 'path' is not of 'java.lang.String' type.");
  }

  @Test
  public void testCustomToolPath_name_mustBeString() throws Exception {
    loadCcToolchainConfigLib();
    createCustomToolPathRule("four", /* name= */ "True", /* path= */ "'abc'");

    ConfiguredTarget t = getConfiguredTarget("//four:a");
    StarlarkInfo toolPath = (StarlarkInfo) getMyInfoFromTarget(t).getValue("toolpath");
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.toolPathFromStarlark(toolPath));
    assertThat(e).hasMessageThat().contains("Field 'name' is not of 'java.lang.String' type.");
  }

  private void createCustomToolPathRule(String pkg, String name, String path) throws IOException {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl', 'tool_path')",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(toolpath = struct(",
        "       name = " + name + ",",
        "       path = " + path + ",",
        "       type_name = 'tool_path'))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testMakeVariable() throws Exception {
    loadCcToolchainConfigLib();
    createMakeVariablerule("one", /* name= */ "None", /* value= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//one:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("name parameter of make_variable should be a string, found NoneType");

    createMakeVariablerule("two", /* name= */ "'abc'", /* value= */ "None");

    e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//two:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("value parameter of make_variable should be a string, found NoneType");

    createMakeVariablerule("three", /* name= */ "''", /* value= */ "None");

    e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//three:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("name parameter of make_variable must be a nonempty string");

    createMakeVariablerule("four", /* name= */ "'abc'", /* value= */ "''");

    e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//four:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("value parameter of make_variable must be a nonempty string");

    createMakeVariablerule("five", /* name= */ "'abc'", /* value= */ "'val'");

    ConfiguredTarget t = getConfiguredTarget("//five:a");
    StarlarkInfo makeVariableProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("variable");
    assertThat(makeVariableProvider).isNotNull();
    Pair<String, String> makeVariable = CcModule.makeVariableFromStarlark(makeVariableProvider);
    assertThat(makeVariable).isNotNull();
    assertThat(makeVariable.first).isEqualTo("abc");
    assertThat(makeVariable.second).isEqualTo("val");

    createVariableWithValueRule("six", /* name= */ "'abc'", /* value= */ "'def'");
    t = getConfiguredTarget("//six:a");
    StarlarkInfo variable = (StarlarkInfo) getMyInfoFromTarget(t).getValue("variable");
    EvalException ee =
        assertThrows(EvalException.class, () -> CcModule.makeVariableFromStarlark(variable));
    assertThat(ee)
        .hasMessageThat()
        .contains("Expected object of type 'make_variable', received 'variable_with_value");
  }

  private void createMakeVariablerule(String pkg, String name, String value) throws IOException {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl', 'make_variable')",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(variable = make_variable(",
        "       name = " + name + ",",
        "       value = " + value + "))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testCustomMakeVariable_none_none() throws Exception {
    createCustomMakeVariableRule("one", /* name= */ "None", /* value= */ "None");

    ConfiguredTarget t = getConfiguredTarget("//one:a");
    StarlarkInfo makeVariableProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("variable");
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.makeVariableFromStarlark(makeVariableProvider));
    assertThat(e)
        .hasMessageThat()
        .contains("'name' parameter of make_variable must be a nonempty string.");
  }

  @Test
  public void testCustomMakeVariable_string_none() throws Exception {
    createCustomMakeVariableRule("two", /* name= */ "'abc'", /* value= */ "None");

    ConfiguredTarget t = getConfiguredTarget("//two:a");
    StarlarkInfo makeVariableProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("variable");
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.makeVariableFromStarlark(makeVariableProvider));
    assertThat(e)
        .hasMessageThat()
        .contains("'value' parameter of make_variable must be a nonempty string.");
  }

  @Test
  public void testCustomMakeVariable_list_none() throws Exception {
    createCustomMakeVariableRule("three", /* name= */ "[]", /* value= */ "None");

    ConfiguredTarget t = getConfiguredTarget("//three:a");
    StarlarkInfo makeVariableProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("variable");
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.makeVariableFromStarlark(makeVariableProvider));
    assertThat(e).hasMessageThat().contains("Field 'name' is not of 'java.lang.String' type.");
  }

  @Test
  public void testCustomMakeVariable_string_boolean() throws Exception {
    createCustomMakeVariableRule("four", /* name= */ "'abc'", /* value= */ "True");

    ConfiguredTarget t = getConfiguredTarget("//four:a");
    StarlarkInfo makeVariableProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("variable");
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.makeVariableFromStarlark(makeVariableProvider));
    assertThat(e).hasMessageThat().contains("Field 'value' is not of 'java.lang.String' type.");
  }

  private void createCustomMakeVariableRule(String pkg, String name, String value)
      throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(variable = struct(",
        "       name = " + name + ",",
        "       value = " + value + ",",
        "       type_name = 'make_variable'))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testWithFeatureSet() throws Exception {
    loadCcToolchainConfigLib();
    createWithFeatureSetRule("one", /* features= */ "None", /* notFeatures= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//one:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("features parameter of with_feature_set should be a list, found NoneType");

    createWithFeatureSetRule("two", /* features= */ "['abc']", /* notFeatures= */ "None");

    e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//two:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("not_features parameter of with_feature_set should be a list, found NoneType");

    createWithFeatureSetRule("three", /* features= */ "'asdf'", /* notFeatures= */ "None");

    e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//three:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("features parameter of with_feature_set should be a list, found string");

    createWithFeatureSetRule("four", /* features= */ "['abc']", /* notFeatures= */ "'def'");

    e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//four:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("not_features parameter of with_feature_set should be a list, found string");

    createWithFeatureSetRule(
        "five", /* features= */ "['f1', 'f2']", /* notFeatures= */ "['nf1', 'nf2']");

    ConfiguredTarget t = getConfiguredTarget("//five:a");
    StarlarkInfo withFeatureSetProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("wfs");
    assertThat(withFeatureSetProvider).isNotNull();
    WithFeatureSet withFeatureSet = CcModule.withFeatureSetFromStarlark(withFeatureSetProvider);
    assertThat(withFeatureSet).isNotNull();
    assertThat(withFeatureSet.getFeatures()).containsExactly("f1", "f2");
    assertThat(withFeatureSet.getNotFeatures()).containsExactly("nf1", "nf2");

    createVariableWithValueRule("six", /* name= */ "'abc'", /* value= */ "'def'");
    t = getConfiguredTarget("//six:a");
    StarlarkInfo variable = (StarlarkInfo) getMyInfoFromTarget(t).getValue("variable");
    EvalException ee =
        assertThrows(EvalException.class, () -> CcModule.withFeatureSetFromStarlark(variable));
    assertThat(ee)
        .hasMessageThat()
        .contains("Expected object of type 'with_feature_set', received 'variable_with_value");
  }

  private void createWithFeatureSetRule(String pkg, String features, String notFeatures)
      throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl', 'with_feature_set')",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(wfs = with_feature_set(",
        "       features = " + features + ",",
        "       not_features = " + notFeatures + "))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testCustomWithFeatureSet_struct_none() throws Exception {
    createCustomWithFeatureSetRule("one", /* features= */ "struct()", /* notFeatures= */ "None");

    ConfiguredTarget t = getConfiguredTarget("//one:a");
    StarlarkInfo withFeatureSetProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("wfs");
    assertThat(withFeatureSetProvider).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.withFeatureSetFromStarlark(withFeatureSetProvider));
    assertThat(e).hasMessageThat().contains("for features, got struct, want sequence");
  }

  @Test
  public void testCustomWithFeatureSet_listOfString_struct() throws Exception {
    createCustomWithFeatureSetRule("two", /* features= */ "['abc']", /* notFeatures= */ "struct()");

    ConfiguredTarget t = getConfiguredTarget("//two:a");
    StarlarkInfo withFeatureSetProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("wfs");
    assertThat(withFeatureSetProvider).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.withFeatureSetFromStarlark(withFeatureSetProvider));
    assertThat(e).hasMessageThat().contains("for not_features, got struct, want sequence");
  }

  @Test
  public void testCustomWithFeatureSet_listOfStruct_emptyList() throws Exception {
    createCustomWithFeatureSetRule("three", /* features= */ "[struct()]", /* notFeatures= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//three:a");
    StarlarkInfo withFeatureSetProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("wfs");
    assertThat(withFeatureSetProvider).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.withFeatureSetFromStarlark(withFeatureSetProvider));
    assertThat(e)
        .hasMessageThat()
        .contains("at index 0 of features, got element of type struct, want string");
  }

  @Test
  public void testCustomWithFeatureSet_emptyList_listOfStruct() throws Exception {
    createCustomWithFeatureSetRule("four", /* features= */ "[]", /* notFeatures= */ "[struct()]");

    ConfiguredTarget t = getConfiguredTarget("//four:a");
    StarlarkInfo withFeatureSetProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("wfs");
    assertThat(withFeatureSetProvider).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.withFeatureSetFromStarlark(withFeatureSetProvider));
    assertThat(e)
        .hasMessageThat()
        .contains("at index 0 of not_features, got element of type struct, want string");
  }

  private void createCustomWithFeatureSetRule(String pkg, String features, String notFeatures)
      throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(wfs = struct(",
        "       features = " + features + ",",
        "       not_features = " + notFeatures + ",",
        "       type_name = 'with_feature_set'))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testEnvSet_none_none() throws Exception {
    loadCcToolchainConfigLib();
    createEnvSetRule(
        "one", /* actions= */ "['a1']", /* envEntries= */ "None", /* withFeatures= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//one:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("env_entries parameter of env_set should be a list, found NoneType");
  }

  @Test
  public void testEnvSet_list_none() throws Exception {
    loadCcToolchainConfigLib();
    createEnvSetRule(
        "two", /* actions= */ "['a1']", /* envEntries= */ "['abc']", /* withFeatures= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//two:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("with_features parameter of env_set should be a list, found NoneType");
  }

  @Test
  public void testEnvSet_string_none() throws Exception {
    loadCcToolchainConfigLib();
    createEnvSetRule(
        "three", /* actions= */ "['a1']", /* envEntries= */ "'asdf'", /* withFeatures= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//three:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("env_entries parameter of env_set should be a list, found string");
  }

  @Test
  public void testEnvSet_list_string() throws Exception {
    loadCcToolchainConfigLib();
    createEnvSetRule(
        "four", /* actions= */ "['a1']", /* envEntries= */ "['abc']", /* withFeatures= */ "'def'");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//four:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("with_features parameter of env_set should be a list, found string");
  }

  @Test
  public void testEnvSet_envEntry_emptyList() throws Exception {
    loadCcToolchainConfigLib();
    createEnvSetRule(
        "five",
        /* actions= */ "['a1']",
        /* envEntries= */ "[env_entry(key = 'a', value = 'b'),"
            + "variable_with_value(name = 'a', value = 'b')]",
        /* withFeatures= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//five:a");
    StarlarkInfo envSetProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("envset");
    assertThat(envSetProvider).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.envSetFromStarlark(envSetProvider));
    assertThat(e)
        .hasMessageThat()
        .contains("Expected object of type 'env_entry', received 'variable_with_value'");
  }

  @Test
  public void testEnvSet_emptyList_emptyList() throws Exception {
    loadCcToolchainConfigLib();
    createEnvSetRule("six", /* actions= */ "[]", /* envEntries= */ "[]", /* withFeatures= */ "[]");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//six:a"));
    assertThat(e).hasMessageThat().contains("actions parameter of env_set must be a nonempty list");
  }

  @Test
  public void testEnvSet_envEntry_featureSet() throws Exception {
    loadCcToolchainConfigLib();
    createEnvSetRule(
        "seven",
        /* actions= */ "['a1']",
        /* envEntries= */ "[env_entry(key = 'a', value = 'b')]",
        /* withFeatures= */ "[with_feature_set(features = ['a'])]");

    ConfiguredTarget t = getConfiguredTarget("//seven:a");
    StarlarkInfo envSetProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("envset");
    assertThat(envSetProvider).isNotNull();
    EnvSet envSet = CcModule.envSetFromStarlark(envSetProvider);
    assertThat(envSet).isNotNull();
  }

  @Test
  public void testEnvSet_string_string() throws Exception {
    loadCcToolchainConfigLib();
    createVariableWithValueRule("eight", /* name= */ "'abc'", /* value= */ "'def'");
    ConfiguredTarget t = getConfiguredTarget("//eight:a");
    StarlarkInfo variable = (StarlarkInfo) getMyInfoFromTarget(t).getValue("variable");
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.envSetFromStarlark(variable));
    assertThat(e)
        .hasMessageThat()
        .contains("Expected object of type 'env_set', received 'variable_with_value");
  }

  private void createEnvSetRule(String pkg, String actions, String envEntries, String withFeatures)
      throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl',",
        "   'env_set', 'env_entry', 'with_feature_set', 'variable_with_value')",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(envset = env_set(",
        "       actions = " + actions + ",",
        "       env_entries = " + envEntries + ",",
        "       with_features = " + withFeatures + "))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testCustomEnvSet_none_none() throws Exception {
    loadCcToolchainConfigLib();
    createCustomEnvSetRule(
        "one", /* actions= */ "[]", /* envEntries= */ "None", /* withFeatures= */ "None");
    ConfiguredTarget t = getConfiguredTarget("//one:a");
    StarlarkInfo envSetProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("envset");
    assertThat(envSetProvider).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.envSetFromStarlark(envSetProvider));
    assertThat(e).hasMessageThat().contains("actions parameter of env_set must be a nonempty list");
  }

  @Test
  public void testCustomEnvSet_struct_none() throws Exception {
    loadCcToolchainConfigLib();
    createCustomEnvSetRule(
        "two", /* actions= */ "['a1']", /* envEntries= */ "struct()", /* withFeatures= */ "None");
    ConfiguredTarget t = getConfiguredTarget("//two:a");
    StarlarkInfo envSetProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("envset");
    assertThat(envSetProvider).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.envSetFromStarlark(envSetProvider));
    assertThat(e).hasMessageThat().contains("for env_entries, got struct, want sequence");
  }

  @Test
  public void testCustomEnvSet_structList_none() throws Exception {
    loadCcToolchainConfigLib();
    createCustomEnvSetRule(
        "three",
        /* actions= */ "['a1']",
        /* envEntries= */ "[struct()]",
        /* withFeatures= */ "None");
    ConfiguredTarget t = getConfiguredTarget("//three:a");
    StarlarkInfo envSetProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("envset");
    assertThat(envSetProvider).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.envSetFromStarlark(envSetProvider));
    assertThat(e)
        .hasMessageThat()
        .contains("Expected object of type 'env_entry', received 'struct'");
  }

  @Test
  public void testCustomEnvSet_envEntry_string() throws Exception {
    loadCcToolchainConfigLib();
    createCustomEnvSetRule(
        "four",
        /* actions= */ "['a1']",
        /* envEntries= */ "[env_entry(key = 'a', value = 'b')]",
        /* withFeatures= */ "'a'");
    ConfiguredTarget t = getConfiguredTarget("//four:a");
    StarlarkInfo envSetProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("envset");
    assertThat(envSetProvider).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.envSetFromStarlark(envSetProvider));
    assertThat(e).hasMessageThat().contains("for with_features, got string, want sequence");
  }

  @Test
  public void testCustomEnvSet_envEntry_envEntry() throws Exception {
    loadCcToolchainConfigLib();

    createCustomEnvSetRule(
        "five",
        /* actions= */ "['a1']",
        /* envEntries= */ "[env_entry(key = 'a', value = 'b')]",
        /* withFeatures= */ "[env_entry(key = 'a', value = 'b')]");
    ConfiguredTarget t = getConfiguredTarget("//five:a");
    StarlarkInfo envSetProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("envset");
    assertThat(envSetProvider).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.envSetFromStarlark(envSetProvider));
    assertThat(e)
        .hasMessageThat()
        .contains("Expected object of type 'with_feature_set', received 'env_entry'.");
  }

  private void createCustomEnvSetRule(
      String pkg, String actions, String envEntries, String withFeatures) throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl',",
        "   'env_entry', 'with_feature_set', 'variable_with_value')",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(envset = struct(",
        "       actions = " + actions + ",",
        "       env_entries = " + envEntries + ",",
        "       with_features = " + withFeatures + ",",
        "       type_name = 'env_set'))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testFlagGroup_flagGroup_notListofFlags() throws Exception {
    loadCcToolchainConfigLib();
    createFlagGroupRule(
        "one",
        /* flags= */ "[]",
        /* flagGroups= */ "[]",
        /* iterateOver= */ "None",
        /* expandIfTrue= */ "None",
        /* expandIfFalse= */ "None",
        /* expandIfAvailable= */ "None",
        /* expandIfNotAvailable= */ "None",
        /* expandIfEqual= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//one:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("flag_group must contain either a list of flags or a list of flag_groups");
  }

  @Test
  public void testFlagGroup_iterateOver_notString() throws Exception {
    loadCcToolchainConfigLib();
    createFlagGroupRule(
        "two",
        /* flags= */ "['a']",
        /* flagGroups= */ "[]",
        /* iterateOver= */ "struct(val = 'a')",
        /* expandIfTrue= */ "None",
        /* expandIfFalse= */ "None",
        /* expandIfAvailable= */ "None",
        /* expandIfNotAvailable= */ "None",
        /* expandIfEqual= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//two:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("iterate_over parameter of flag_group should be a string, found struct");
  }

  @Test
  public void testFlagGroup_expandIfTrue_notString() throws Exception {
    loadCcToolchainConfigLib();
    createFlagGroupRule(
        "three",
        /* flags= */ "['a']",
        /* flagGroups= */ "[]",
        /* iterateOver= */ "None",
        /* expandIfTrue= */ "struct(val = 'a')",
        /* expandIfFalse= */ "None",
        /* expandIfAvailable= */ "None",
        /* expandIfNotAvailable= */ "None",
        /* expandIfEqual= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//three:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("expand_if_true parameter of flag_group should be a string, found struct");
  }

  @Test
  public void testFlagGroup_expandIfFalse_notString() throws Exception {
    loadCcToolchainConfigLib();
    createFlagGroupRule(
        "four",
        /* flags= */ "['a']",
        /* flagGroups= */ "[]",
        /* iterateOver= */ "None",
        /* expandIfTrue= */ "None",
        /* expandIfFalse= */ "struct(val = 'a')",
        /* expandIfAvailable= */ "None",
        /* expandIfNotAvailable= */ "None",
        /* expandIfEqual= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//four:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("expand_if_false parameter of flag_group should be a string, found struct");
  }

  @Test
  public void testFlagGroup_expandIfAvailable_notString() throws Exception {
    loadCcToolchainConfigLib();
    createFlagGroupRule(
        "five",
        /* flags= */ "['a']",
        /* flagGroups= */ "[]",
        /* iterateOver= */ "None",
        /* expandIfTrue= */ "None",
        /* expandIfFalse= */ "None",
        /* expandIfAvailable= */ "struct(val = 'a')",
        /* expandIfNotAvailable= */ "None",
        /* expandIfEqual= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//five:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("expand_if_available parameter of flag_group should be a string, found struct");
  }

  @Test
  public void testFlagGroup_expandIfNotAvailable_notString() throws Exception {
    loadCcToolchainConfigLib();
    createFlagGroupRule(
        "six",
        /* flags= */ "['a']",
        /* flagGroups= */ "[]",
        /* iterateOver= */ "None",
        /* expandIfTrue= */ "None",
        /* expandIfFalse= */ "None",
        /* expandIfAvailable= */ "None",
        /* expandIfNotAvailable= */ "struct(val = 'a')",
        /* expandIfEqual= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//six:a"));
    assertThat(e)
        .hasMessageThat()
        .contains(
            "expand_if_not_available parameter of flag_group should be a string, found struct");
  }

  @Test
  public void testFlagGroup_flagGroup_cannotContainFlagAndGroup() throws Exception {
    loadCcToolchainConfigLib();
    createFlagGroupRule(
        "seven",
        /* flags= */ "['a']",
        /* flagGroups= */ "['b']",
        /* iterateOver= */ "None",
        /* expandIfTrue= */ "None",
        /* expandIfFalse= */ "None",
        /* expandIfAvailable= */ "None",
        /* expandIfNotAvailable= */ "struct(val = 'a')",
        /* expandIfEqual= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//seven:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("flag_group must not contain both a flag and another flag_group");
  }

  @Test
  public void testFlagGroup_expandIfEqual_notStarlarkInfo() throws Exception {
    loadCcToolchainConfigLib();
    createFlagGroupRule(
        "eight",
        /* flags= */ "['a']",
        /* flagGroups= */ "[]",
        /* iterateOver= */ "'a'",
        /* expandIfTrue= */ "'b'",
        /* expandIfFalse= */ "''",
        /* expandIfAvailable= */ "''",
        /* expandIfNotAvailable= */ "''",
        /* expandIfEqual= */ "'a'");

    ConfiguredTarget t = getConfiguredTarget("//eight:a");
    StarlarkInfo flagGroupProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flaggroup");
    assertThat(flagGroupProvider).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.flagGroupFromStarlark(flagGroupProvider));
    assertThat(e)
        .hasMessageThat()
        .contains(
            "Field 'expand_if_equal' is not of "
                + "'com.google.devtools.build.lib.packages.StarlarkInfo' type.");
  }

  @Test
  public void testFlagGroup() throws Exception {
    loadCcToolchainConfigLib();
    createFlagGroupRule(
        "nine",
        /* flags= */ "[]",
        /* flagGroups= */ "[flag_group(flags = ['a']), flag_group(flags = ['b'])]",
        /* iterateOver= */ "''",
        /* expandIfTrue= */ "''",
        /* expandIfFalse= */ "''",
        /* expandIfAvailable= */ "''",
        /* expandIfNotAvailable= */ "''",
        /* expandIfEqual= */ "variable_with_value(name = 'a', value = 'b')");

    ConfiguredTarget t = getConfiguredTarget("//nine:a");
    StarlarkInfo flagGroupProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flaggroup");
    assertThat(flagGroupProvider).isNotNull();
    FlagGroup f = CcModule.flagGroupFromStarlark(flagGroupProvider);
    assertThat(f).isNotNull();
  }

  @Test
  public void testFlagGroup_flagGroup_notStruct() throws Exception {
    loadCcToolchainConfigLib();
    createFlagGroupRule(
        "ten",
        /* flags= */ "[]",
        /* flagGroups= */ "[flag_group(flags = ['a']), struct(value = 'a')]",
        /* iterateOver= */ "''",
        /* expandIfTrue= */ "''",
        /* expandIfFalse= */ "''",
        /* expandIfAvailable= */ "''",
        /* expandIfNotAvailable= */ "''",
        /* expandIfEqual= */ "variable_with_value(name = 'a', value = 'b')");

    ConfiguredTarget t = getConfiguredTarget("//ten:a");
    StarlarkInfo flagGroupProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flaggroup");
    assertThat(flagGroupProvider).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.flagGroupFromStarlark(flagGroupProvider));
    assertThat(e)
        .hasMessageThat()
        .contains("Expected object of type 'flag_group', received 'struct'");
  }

  private void createFlagGroupRule(
      String pkg,
      String flags,
      String flagGroups,
      String iterateOver,
      String expandIfTrue,
      String expandIfFalse,
      String expandIfAvailable,
      String expandIfNotAvailable,
      String expandIfEqual)
      throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl',",
        "   'env_set', 'env_entry', 'with_feature_set', 'variable_with_value', 'flag_group')",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(flaggroup = flag_group(",
        "       flags = " + flags + ",",
        "       flag_groups = " + flagGroups + ",",
        "       expand_if_true = " + expandIfTrue + ",",
        "       expand_if_false = " + expandIfFalse + ",",
        "       expand_if_available = " + expandIfAvailable + ",",
        "       expand_if_not_available = " + expandIfNotAvailable + ",",
        "       expand_if_equal = " + expandIfEqual + ",",
        "       iterate_over = " + iterateOver + "))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testSingleChunkFlagIsUsed() throws Exception {
    loadCcToolchainConfigLib();

    createCustomFlagGroupRule(
        "single_chunk_flag",
        /* flags= */ "['a']",
        /* flagGroups= */ "[]",
        /* iterateOver= */ "''",
        /* expandIfTrue= */ "''",
        /* expandIfFalse= */ "''",
        /* expandIfAvailable= */ "''",
        /* expandIfNotAvailable= */ "''",
        /* expandIfEqual= */ "None");

    ConfiguredTarget t = getConfiguredTarget("//single_chunk_flag:a");
    StarlarkInfo flagGroupProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flaggroup");
    assertThat(flagGroupProvider).isNotNull();
    FlagGroup flagGroup = CcModule.flagGroupFromStarlark(flagGroupProvider);
    assertThat(flagGroup.getExpandables()).isNotEmpty();
    assertThat(flagGroup.getExpandables().get(0)).isInstanceOf(SingleChunkFlag.class);
  }

  @Test
  public void testCustomFlagGroup_iterateOver_notString() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFlagGroupRule(
        "one",
        /* flags= */ "['a']",
        /* flagGroups= */ "[]",
        /* iterateOver= */ "struct()",
        /* expandIfTrue= */ "'b'",
        /* expandIfFalse= */ "''",
        /* expandIfAvailable= */ "''",
        /* expandIfNotAvailable= */ "''",
        /* expandIfEqual= */ "None");

    ConfiguredTarget t = getConfiguredTarget("//one:a");
    StarlarkInfo flagGroupProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flaggroup");
    assertThat(flagGroupProvider).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.flagGroupFromStarlark(flagGroupProvider));
    assertThat(e)
        .hasMessageThat()
        .contains("Field 'iterate_over' is not of 'java.lang.String' type.");
  }

  @Test
  public void testCustomFlagGroup_expandIfTrue_notString() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFlagGroupRule(
        "two",
        /* flags= */ "[]",
        /* flagGroups= */ "[flag_group(flags = ['a']), flag_group(flags = ['b'])]",
        /* iterateOver= */ "''",
        /* expandIfTrue= */ "struct()",
        /* expandIfFalse= */ "''",
        /* expandIfAvailable= */ "''",
        /* expandIfNotAvailable= */ "''",
        /* expandIfEqual= */ "variable_with_value(name = 'a', value = 'b')");

    ConfiguredTarget t = getConfiguredTarget("//two:a");
    StarlarkInfo flagGroupProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flaggroup");
    assertThat(flagGroupProvider).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.flagGroupFromStarlark(flagGroupProvider));
    assertThat(e)
        .hasMessageThat()
        .contains("Field 'expand_if_true' is not of 'java.lang.String' type.");
  }

  @Test
  public void testCustomFlagGroup_expandIfFalse_notString() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFlagGroupRule(
        "three",
        /* flags= */ "[]",
        /* flagGroups= */ "[flag_group(flags = ['a'])]",
        /* iterateOver= */ "''",
        /* expandIfTrue= */ "''",
        /* expandIfFalse= */ "True",
        /* expandIfAvailable= */ "''",
        /* expandIfNotAvailable= */ "''",
        /* expandIfEqual= */ "variable_with_value(name = 'a', value = 'b')");

    ConfiguredTarget t = getConfiguredTarget("//three:a");
    StarlarkInfo flagGroupProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flaggroup");
    assertThat(flagGroupProvider).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.flagGroupFromStarlark(flagGroupProvider));
    assertThat(e)
        .hasMessageThat()
        .contains("Field 'expand_if_false' is not of 'java.lang.String' type.");
  }

  @Test
  public void testCustomFlagGroup_expandIfAvailable_notString() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFlagGroupRule(
        "four",
        /* flags= */ "[]",
        /* flagGroups= */ "[flag_group(flags = ['a'])]",
        /* iterateOver= */ "''",
        /* expandIfTrue= */ "''",
        /* expandIfFalse= */ "''",
        /* expandIfAvailable= */ "struct()",
        /* expandIfNotAvailable= */ "''",
        /* expandIfEqual= */ "variable_with_value(name = 'a', value = 'b')");

    ConfiguredTarget t = getConfiguredTarget("//four:a");
    StarlarkInfo flagGroupProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flaggroup");
    assertThat(flagGroupProvider).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.flagGroupFromStarlark(flagGroupProvider));
    assertThat(e)
        .hasMessageThat()
        .contains("Field 'expand_if_available' is not of 'java.lang.String' type.");
  }

  @Test
  public void testCustomFlagGroup_expandIfNotAvailable_notString() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFlagGroupRule(
        "five",
        /* flags= */ "[]",
        /* flagGroups= */ "[flag_group(flags = ['a'])]",
        /* iterateOver= */ "''",
        /* expandIfTrue= */ "''",
        /* expandIfFalse= */ "''",
        /* expandIfAvailable= */ "''",
        /* expandIfNotAvailable= */ "3",
        /* expandIfEqual= */ "variable_with_value(name = 'a', value = 'b')");

    ConfiguredTarget t = getConfiguredTarget("//five:a");
    StarlarkInfo flagGroupProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flaggroup");
    assertThat(flagGroupProvider).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.flagGroupFromStarlark(flagGroupProvider));
    assertThat(e)
        .hasMessageThat()
        .contains("Field 'expand_if_not_available' is not of 'java.lang.String' type.");
  }

  @Test
  public void testCustomFlagGroup_expandIfEqual_notStruct() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFlagGroupRule(
        "six",
        /* flags= */ "[]",
        /* flagGroups= */ "[flag_group(flags = ['a'])]",
        /* iterateOver= */ "''",
        /* expandIfTrue= */ "''",
        /* expandIfFalse= */ "''",
        /* expandIfAvailable= */ "''",
        /* expandIfNotAvailable= */ "''",
        /* expandIfEqual= */ "struct(name = 'a', value = 'b')");

    ConfiguredTarget t = getConfiguredTarget("//six:a");
    StarlarkInfo flagGroupProvider = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flaggroup");
    assertThat(flagGroupProvider).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.flagGroupFromStarlark(flagGroupProvider));
    assertThat(e)
        .hasMessageThat()
        .contains("Expected object of type 'variable_with_value', received 'struct'.");
  }

  private void createCustomFlagGroupRule(
      String pkg,
      String flags,
      String flagGroups,
      String iterateOver,
      String expandIfTrue,
      String expandIfFalse,
      String expandIfAvailable,
      String expandIfNotAvailable,
      String expandIfEqual)
      throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl',",
        "   'env_set', 'env_entry', 'with_feature_set', 'variable_with_value', 'flag_group')",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(flaggroup = struct(",
        "       flags = " + flags + ",",
        "       flag_groups = " + flagGroups + ",",
        "       expand_if_true = " + expandIfTrue + ",",
        "       expand_if_false = " + expandIfFalse + ",",
        "       expand_if_available = " + expandIfAvailable + ",",
        "       expand_if_not_available = " + expandIfNotAvailable + ",",
        "       expand_if_equal = " + expandIfEqual + ",",
        "       iterate_over = " + iterateOver + ",",
        "       type_name = 'flag_group'))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testTool_path_mustBeNonEmpty() throws Exception {
    loadCcToolchainConfigLib();
    createToolRule("one", /* path= */ "''", /* withFeatures= */ "[]", /* requirements= */ "[]");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//one:a"));
    assertThat(e).hasMessageThat().contains("path parameter of tool must be a nonempty string");
  }

  @Test
  public void testTool_withFeatures_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createToolRule("two", /* path= */ "'a'", /* withFeatures= */ "None", /* requirements= */ "[]");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//two:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("with_features parameter of tool should be a list, found NoneType");
  }

  @Test
  public void testTool_executionRequirements_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createToolRule(
        "three", /* path= */ "'a'", /* withFeatures= */ "[]", /* requirements= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//three:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("execution_requirements parameter of tool should be a list, found NoneType");
  }

  @Test
  public void testTool_withFeatures_mustBeWithFeatureSet() throws Exception {
    loadCcToolchainConfigLib();
    createToolRule(
        "four",
        /* path= */ "'a'",
        /* withFeatures= */ "[struct(val = 'a')]",
        /* requirements= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//four:a");
    StarlarkInfo toolStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("tool");
    assertThat(toolStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.toolFromStarlark(toolStruct));
    assertThat(e)
        .hasMessageThat()
        .contains("Expected object of type 'with_feature_set', received 'struct'");
  }

  @Test
  public void testTool_requirements_mustBeString() throws Exception {
    loadCcToolchainConfigLib();
    createToolRule(
        "five",
        /* path= */ "'a'",
        /* withFeatures= */ "[]",
        /* requirements= */ "[struct(val = 'a')]");

    ConfiguredTarget t = getConfiguredTarget("//five:a");
    StarlarkInfo toolStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("tool");
    assertThat(toolStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.toolFromStarlark(toolStruct));
    assertThat(e)
        .hasMessageThat()
        .contains("at index 0 of execution_requirements, got element of type struct, want string");
  }

  @Test
  public void testTool() throws Exception {
    loadCcToolchainConfigLib();
    createToolRule(
        "six",
        /* path= */ "'/a/b/c'",
        /* withFeatures= */ "[with_feature_set(features = ['a'])]",
        /* requirements= */ "['a', 'b']");

    ConfiguredTarget t = getConfiguredTarget("//six:a");
    StarlarkInfo toolStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("tool");
    assertThat(toolStruct).isNotNull();
    Tool tool = CcModule.toolFromStarlark(toolStruct);
    assertThat(tool.getExecutionRequirements()).containsExactly("a", "b");
    assertThat(tool.getToolPathString(PathFragment.EMPTY_FRAGMENT)).isEqualTo("/a/b/c");
    assertThat(tool.getWithFeatureSetSets())
        .contains(new WithFeatureSet(ImmutableSet.of("a"), ImmutableSet.of()));
  }

  private void createToolRule(String pkg, String path, String withFeatures, String requirements)
      throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl', 'with_feature_set', 'tool')",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(tool = tool(",
        "       path = " + path + ",",
        "       with_features = " + withFeatures + ",",
        "       execution_requirements = " + requirements + "))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testCustomTool_path_nonEmpty() throws Exception {
    loadCcToolchainConfigLib();
    createCustomToolRule(
        "one", /* path= */ "''", /* withFeatures= */ "[]", /* requirements= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//one:a");
    StarlarkInfo toolStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("tool");
    assertThat(toolStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.toolFromStarlark(toolStruct));
    assertThat(e).hasMessageThat().contains("The 'path' field of tool must be a nonempty string.");
  }

  @Test
  public void testCustomTool_path_mustBeString() throws Exception {
    loadCcToolchainConfigLib();
    createCustomToolRule(
        "two", /* path= */ "struct()", /* withFeatures= */ "[]", /* requirements= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//two:a");
    StarlarkInfo toolStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("tool");
    assertThat(toolStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.toolFromStarlark(toolStruct));
    assertThat(e).hasMessageThat().contains("Field 'path' is not of 'java.lang.String' type.");
  }

  @Test
  public void testCustomTool_withFeatures_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createCustomToolRule(
        "three", /* path= */ "'a'", /* withFeatures= */ "struct()", /* requirements= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//three:a");
    StarlarkInfo toolStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("tool");
    assertThat(toolStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.toolFromStarlark(toolStruct));
    assertThat(e).hasMessageThat().contains("for with_features, got struct, want sequence");
  }

  @Test
  public void testCustomTool_withFeatures_mustBeWithFeatureSet() throws Exception {
    loadCcToolchainConfigLib();
    createCustomToolRule(
        "four",
        /* path= */ "'a'",
        /* withFeatures= */ "[struct(val = 'a')]",
        /* requirements= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//four:a");
    StarlarkInfo toolStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("tool");
    assertThat(toolStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.toolFromStarlark(toolStruct));
    assertThat(e)
        .hasMessageThat()
        .contains("Expected object of type 'with_feature_set', received 'struct'");
  }

  @Test
  public void testCustomTool_executionRequirements_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createCustomToolRule(
        "five", /* path= */ "'a'", /* withFeatures= */ "[]", /* requirements= */ "'a'");

    ConfiguredTarget t = getConfiguredTarget("//five:a");
    StarlarkInfo toolStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("tool");
    assertThat(toolStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.toolFromStarlark(toolStruct));
    assertThat(e)
        .hasMessageThat()
        .contains("for execution_requirements, got string, want sequence");
  }

  @Test
  public void testCustomTool_executionRequirements_mustBeString() throws Exception {
    loadCcToolchainConfigLib();
    createCustomToolRule(
        "six", /* path= */ "'a'", /* withFeatures= */ "[]", /* requirements= */ "[struct()]");

    ConfiguredTarget t = getConfiguredTarget("//six:a");
    StarlarkInfo toolStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("tool");
    assertThat(toolStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.toolFromStarlark(toolStruct));
    assertThat(e)
        .hasMessageThat()
        .contains("at index 0 of execution_requirements, got element of type struct, want string");
  }

  private void createCustomToolRule(
      String pkg, String path, String withFeatures, String requirements) throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl', 'with_feature_set')",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(tool = struct(",
        "       path = " + path + ",",
        "       with_features = " + withFeatures + ",",
        "       execution_requirements = " + requirements + ",",
        "       type_name = 'tool'))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testFlagSet_withFeatures_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createFlagSetRule(
        "two", /* actions= */ "['a']", /* flagGroups= */ "[]", /* withFeatures= */ "None");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//two:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("with_features parameter of flag_set should be a list, found NoneType");
  }

  @Test
  public void testFlagSet_flagGroups_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createFlagSetRule(
        "three", /* actions= */ "['a']", /* flagGroups= */ "None", /* withFeatures= */ "[]");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//three:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("flag_groups parameter of flag_set should be a list, found NoneType");
  }

  @Test
  public void testFlagSet_actions_mustBeString() throws Exception {
    loadCcToolchainConfigLib();
    createFlagSetRule(
        "four",
        /* actions= */ "['a', struct(val = 'a')]",
        /* flagGroups= */ "[]",
        /* withFeatures= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//four:a");
    StarlarkInfo flagSetStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flagset");
    assertThat(flagSetStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class,
            () -> CcModule.flagSetFromStarlark(flagSetStruct, /* actionName= */ null));
    assertThat(e)
        .hasMessageThat()
        .contains("at index 0 of actions, got element of type struct, want string");
  }

  @Test
  public void testFlagSet_flagGroups_mustBeFlagGroup() throws Exception {
    loadCcToolchainConfigLib();
    createFlagSetRule(
        "five",
        /* actions= */ "['a']",
        /* flagGroups= */ "[flag_group(flags = ['a']), struct(value = 'a')]",
        /* withFeatures= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//five:a");
    StarlarkInfo flagSetStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flagset");
    assertThat(flagSetStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class,
            () -> CcModule.flagSetFromStarlark(flagSetStruct, /* actionName= */ null));
    assertThat(e)
        .hasMessageThat()
        .contains("Expected object of type 'flag_group', received 'struct'");
  }

  @Test
  public void testFlagSet_withFeatures_mustBeWithFeatureSet() throws Exception {
    loadCcToolchainConfigLib();
    createFlagSetRule(
        "six",
        /* actions= */ "['a']",
        /* flagGroups= */ "[flag_group(flags = ['a'])]",
        /* withFeatures= */ "[struct(val = 'a')]");

    ConfiguredTarget t = getConfiguredTarget("//six:a");
    StarlarkInfo flagSetStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flagset");
    assertThat(flagSetStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class,
            () -> CcModule.flagSetFromStarlark(flagSetStruct, /* actionName= */ null));
    assertThat(e)
        .hasMessageThat()
        .contains("Expected object of type 'with_feature_set', received 'struct'");
  }

  @Test
  public void testFlagSet() throws Exception {
    loadCcToolchainConfigLib();
    createFlagSetRule(
        "seven",
        /* actions= */ "['a']",
        /* flagGroups= */ "[flag_group(flags = ['a'])]",
        /* withFeatures= */ "[with_feature_set(features = ['a'])]");
    ConfiguredTarget t = getConfiguredTarget("//seven:a");
    StarlarkInfo flagSetStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flagset");
    assertThat(flagSetStruct).isNotNull();
    FlagSet f = CcModule.flagSetFromStarlark(flagSetStruct, /* actionName= */ null);
    assertThat(f).isNotNull();
  }

  @Test
  public void testFlagSet_actionConfig_notActionList() throws Exception {
    loadCcToolchainConfigLib();
    createFlagSetRule(
        "eight",
        /* actions= */ "['a']",
        /* flagGroups= */ "[flag_group(flags = ['a'])]",
        /* withFeatures= */ "[struct(val = 'a')]");

    ConfiguredTarget t = getConfiguredTarget("//eight:a");
    StarlarkInfo flagSetStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flagset");
    assertThat(flagSetStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class,
            () -> CcModule.flagSetFromStarlark(flagSetStruct, /* actionName= */ "action"));
    assertThat(e)
        .hasMessageThat()
        .contains("Thus, you must not specify action lists in an action_config's flag set.");
  }

  @Test
  public void testFlagSet_emptyAction() throws Exception {
    loadCcToolchainConfigLib();
    createFlagSetRule(
        "nine",
        /* actions= */ "[]",
        /* flagGroups= */ "[flag_group(flags = ['a'])]",
        /* withFeatures= */ "[with_feature_set(features = ['a'])]");
    ConfiguredTarget t = getConfiguredTarget("//nine:a");
    StarlarkInfo flagSetStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flagset");
    assertThat(flagSetStruct).isNotNull();
    FlagSet f = CcModule.flagSetFromStarlark(flagSetStruct, /* actionName= */ "action");
    assertThat(f).isNotNull();
    assertThat(f.getActions()).containsExactly("action");
  }

  private void createFlagSetRule(String pkg, String actions, String flagGroups, String withFeatures)
      throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl',",
        "   'env_set', 'env_entry', 'with_feature_set', 'variable_with_value', 'flag_group',",
        "   'flag_set')",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(flagset = flag_set(",
        "       flag_groups = " + flagGroups + ",",
        "       actions = " + actions + ",",
        "       with_features = " + withFeatures + "))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testCustomFlagSet() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFlagSetRule(
        "one", /* actions= */ "[]", /* flagGroups= */ "[]", /* withFeatures= */ "[]");

    ConfiguredTarget target = getConfiguredTarget("//one:a");
    StarlarkInfo flagSet = (StarlarkInfo) getMyInfoFromTarget(target).getValue("flagset");
    assertThat(flagSet).isNotNull();
    FlagSet flagSetObject = CcModule.flagSetFromStarlark(flagSet, /* actionName */ null);
    assertThat(flagSetObject).isNotNull();
  }

  @Test
  public void testCustomFlagSet_flagGroups_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFlagSetRule(
        "two", /* actions= */ "['a']", /* flagGroups= */ "struct()", /* withFeatures= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//two:a");
    StarlarkInfo flagSetStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flagset");
    assertThat(flagSetStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class,
            () -> CcModule.flagSetFromStarlark(flagSetStruct, /* actionName */ null));
    assertThat(e).hasMessageThat().contains("for flag_groups, got struct, want sequence");
  }

  @Test
  public void testCustomFlagSet_withFeatures_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFlagSetRule(
        "three", /* actions= */ "['a']", /* flagGroups= */ "[]", /* withFeatures= */ "struct()");

    ConfiguredTarget t = getConfiguredTarget("//three:a");
    StarlarkInfo flagSetStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flagset");
    assertThat(flagSetStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class,
            () -> CcModule.flagSetFromStarlark(flagSetStruct, /* actionName */ null));
    assertThat(e).hasMessageThat().contains("for with_features, got struct, want sequence");
  }

  @Test
  public void testCustomFlagSet_actions_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFlagSetRule(
        "four", /* actions= */ "struct()", /* flagGroups= */ "[]", /* withFeatures= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//four:a");
    StarlarkInfo flagSetStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("flagset");
    assertThat(flagSetStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class,
            () -> CcModule.flagSetFromStarlark(flagSetStruct, /* actionName */ null));
    assertThat(e).hasMessageThat().contains("for actions, got struct, want sequence");
  }

  private void createCustomFlagSetRule(
      String pkg, String actions, String flagGroups, String withFeatures) throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl',",
        "   'env_set', 'env_entry', 'with_feature_set', 'variable_with_value', 'flag_group',",
        "   'flag_set')",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(flagset = struct(",
        "       flag_groups = " + flagGroups + ",",
        "       actions = " + actions + ",",
        "       with_features = " + withFeatures + ",",
        "       type_name = 'flag_set'))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testActionConfig_actionName_mustBeNonEmpty() throws Exception {
    loadCcToolchainConfigLib();
    createActionConfigRule(
        "one",
        /* actionName= */ "''",
        /* enabled= */ "True",
        /* tools= */ "[]",
        /* flagSets= */ "[]",
        /* implies= */ "[]");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//one:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("name parameter of action_config must be a nonempty string");
  }

  @Test
  public void testActionConfig_enabled_mustBeBool() throws Exception {
    loadCcToolchainConfigLib();
    createActionConfigRule(
        "two",
        /* actionName= */ "'actionname'",
        /* enabled= */ "['asd']",
        /* tools= */ "[]",
        /* flagSets= */ "[]",
        /* implies= */ "[]");
    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//two:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("enabled parameter of action_config should be a bool, found list");
  }

  @Test
  public void testActionConfig_tools_mustBeTool() throws Exception {
    loadCcToolchainConfigLib();
    createActionConfigRule(
        "three",
        /* actionName= */ "'actionname'",
        /* enabled= */ "True",
        /* tools= */ "[with_feature_set(features = ['a'])]",
        /* flagSets= */ "[]",
        /* implies= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//three:a");
    StarlarkInfo actionConfigStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("config");
    assertThat(actionConfigStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.actionConfigFromStarlark(actionConfigStruct));
    assertThat(e)
        .hasMessageThat()
        .contains("Expected object of type 'tool', received 'with_feature_set'");
  }

  @Test
  public void testActionConfig_flagSets_mustBeFlagSet() throws Exception {
    loadCcToolchainConfigLib();
    createActionConfigRule(
        "four",
        /* actionName= */ "'actionname'",
        /* enabled= */ "True",
        /* tools= */ "[tool(path = 'a/b/c')]",
        /* flagSets= */ "[tool(path = 'a/b/c')]",
        /* implies= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//four:a");
    StarlarkInfo actionConfigStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("config");
    assertThat(actionConfigStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.actionConfigFromStarlark(actionConfigStruct));
    assertThat(e).hasMessageThat().contains("Expected object of type 'flag_set', received 'tool'");
  }

  @Test
  public void testActionConfig_implies_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createActionConfigRule(
        "five",
        /* actionName= */ "'actionname'",
        /* enabled= */ "True",
        /* tools= */ "[tool(path = 'a/b/c')]",
        /* flagSets= */ "[]",
        /* implies= */ "flag_set(actions = ['a', 'b'])");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//five:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("implies parameter of action_config should be a list, found struct");
  }

  @Test
  public void testActionConfig_implies_mustContainString() throws Exception {
    loadCcToolchainConfigLib();
    createActionConfigRule(
        "six",
        /* actionName= */ "'actionname'",
        /* enabled= */ "True",
        /* tools= */ "[tool(path = 'a/b/c')]",
        /* flagSets= */ "[]",
        /* implies= */ "[flag_set(actions = ['a', 'b'])]");

    ConfiguredTarget t = getConfiguredTarget("//six:a");
    StarlarkInfo actionConfigStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("config");
    assertThat(actionConfigStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.actionConfigFromStarlark(actionConfigStruct));
    assertThat(e)
        .hasMessageThat()
        .contains("at index 0 of implies, got element of type struct, want string");
  }

  @Test
  public void testActionConfig_implies_mustContainString_notStruct() throws Exception {
    loadCcToolchainConfigLib();
    createActionConfigRule(
        "seven",
        /* actionName= */ "'actionname'",
        /* enabled= */ "True",
        /* tools= */ "[tool(path = 'a/b/c')]",
        /* flagSets= */ "[]",
        /* implies= */ "[flag_set(actions = ['a', 'b'])]");

    ConfiguredTarget t = getConfiguredTarget("//seven:a");
    StarlarkInfo actionConfigStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("config");
    assertThat(actionConfigStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.actionConfigFromStarlark(actionConfigStruct));
    assertThat(e)
        .hasMessageThat()
        .contains("at index 0 of implies, got element of type struct, want string");
  }

  @Test
  public void testActionConfig() throws Exception {
    loadCcToolchainConfigLib();
    createActionConfigRule(
        "eight",
        /* actionName= */ "'actionname32._++-'",
        /* enabled= */ "True",
        /* tools= */ "[tool(path = 'a/b/c')]",
        /* flagSets= */ "[flag_set(flag_groups=[flag_group(flags=['a'])])]",
        /* implies= */ "['a', 'b']");

    ConfiguredTarget t = getConfiguredTarget("//eight:a");
    StarlarkInfo actionConfigStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("config");
    assertThat(actionConfigStruct).isNotNull();
    ActionConfig a = CcModule.actionConfigFromStarlark(actionConfigStruct);
    assertThat(a).isNotNull();
    assertThat(a.getActionName()).isEqualTo("actionname32._++-");
    assertThat(a.getImplies()).containsExactly("a", "b").inOrder();
    assertThat(Iterables.getOnlyElement(a.getFlagSets()).getActions())
        .containsExactly("actionname32._++-");
  }

  @Test
  public void testActionConfig_actionName_validChars_notUpper() throws Exception {
    loadCcToolchainConfigLib();
    createActionConfigRule(
        "nine",
        /* actionName= */ "'Upper'",
        /* enabled= */ "True",
        /* tools= */ "[tool(path = 'a/b/c')]",
        /* flagSets= */ "[]",
        /* implies= */ "[flag_set(actions = ['a', 'b'])]");

    ConfiguredTarget t = getConfiguredTarget("//nine:a");
    StarlarkInfo actionConfigStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("config");
    assertThat(actionConfigStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.actionConfigFromStarlark(actionConfigStruct));
    assertThat(e)
        .hasMessageThat()
        .contains(
            "An action_config's name must consist solely "
                + "of lowercase ASCII letters, digits, '.', '_', '+', and '-', got 'Upper'");
  }

  @Test
  public void testActionConfig_actionName_validChars_notWhitespace() throws Exception {
    loadCcToolchainConfigLib();
    createActionConfigRule(
        "ten",
        /* actionName= */ "'white\tspace'",
        /* enabled= */ "True",
        /* tools= */ "[tool(path = 'a/b/c')]",
        /* flagSets= */ "[]",
        /* implies= */ "[flag_set(actions = ['a', 'b'])]");

    ConfiguredTarget t = getConfiguredTarget("//ten:a");
    StarlarkInfo actionConfigStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("config");
    assertThat(actionConfigStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.actionConfigFromStarlark(actionConfigStruct));
    assertThat(e)
        .hasMessageThat()
        .contains(
            "An action_config's name must consist solely "
                + "of lowercase ASCII letters, digits, '.', '_', '+', and '-', "
                + "got 'white\tspace'");
  }

  private void createActionConfigRule(
      String pkg, String actionName, String enabled, String tools, String flagSets, String implies)
      throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl', 'with_feature_set',",
        "             'tool', 'flag_set', 'action_config', 'flag_group')",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(config = action_config(",
        "       action_name = " + actionName + ",",
        "       enabled = " + enabled + ",",
        "       tools = " + tools + ",",
        "       flag_sets = " + flagSets + ",",
        "       implies = " + implies + "))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testCustomActionConfig_actionName_mustBeString() throws Exception {
    loadCcToolchainConfigLib();
    createCustomActionConfigRule(
        "one",
        /* actionName= */ "struct()",
        /* enabled= */ "True",
        /* tools= */ "[]",
        /* flagSets= */ "[]",
        /* implies= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//one:a");
    StarlarkInfo actionConfigStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("config");
    assertThat(actionConfigStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.actionConfigFromStarlark(actionConfigStruct));
    assertThat(e)
        .hasMessageThat()
        .contains("Field 'action_name' is not of 'java.lang.String' type.");
  }

  @Test
  public void testCustomActionConfig_enabled_mustBeBool() throws Exception {
    loadCcToolchainConfigLib();
    createCustomActionConfigRule(
        "two",
        /* actionName= */ "'actionname'",
        /* enabled= */ "['asd']",
        /* tools= */ "[]",
        /* flagSets= */ "[]",
        /* implies= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//two:a");
    StarlarkInfo actionConfigStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("config");
    assertThat(actionConfigStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.actionConfigFromStarlark(actionConfigStruct));
    assertThat(e).hasMessageThat().contains("Field 'enabled' is not of 'java.lang.Boolean' type.");
  }

  @Test
  public void testCustomActionConfig_tools_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createCustomActionConfigRule(
        "three",
        /* actionName= */ "'actionname'",
        /* enabled= */ "True",
        /* tools= */ "struct()",
        /* flagSets= */ "[]",
        /* implies= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//three:a");
    StarlarkInfo actionConfigStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("config");
    assertThat(actionConfigStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.actionConfigFromStarlark(actionConfigStruct));
    assertThat(e).hasMessageThat().contains("for tools, got struct, want sequence");
  }

  @Test
  public void testCustomActionConfig_flagSets_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createCustomActionConfigRule(
        "four",
        /* actionName= */ "'actionname'",
        /* enabled= */ "True",
        /* tools= */ "[tool(path = 'a/b/c')]",
        /* flagSets= */ "True",
        /* implies= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//four:a");
    StarlarkInfo actionConfigStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("config");
    assertThat(actionConfigStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.actionConfigFromStarlark(actionConfigStruct));
    assertThat(e).hasMessageThat().contains("for flag_sets, got bool, want sequence");
  }

  @Test
  public void testCustomActionConfig_implies_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createCustomActionConfigRule(
        "five",
        /* actionName= */ "'actionname'",
        /* enabled= */ "True",
        /* tools= */ "[tool(path = 'a/b/c')]",
        /* flagSets= */ "[]",
        /* implies= */ "flag_set(actions = ['a', 'b'])");

    ConfiguredTarget t = getConfiguredTarget("//five:a");
    StarlarkInfo actionConfigStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("config");
    assertThat(actionConfigStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class, () -> CcModule.actionConfigFromStarlark(actionConfigStruct));
    assertThat(e).hasMessageThat().contains("for implies, got struct, want sequence");
  }

  private void createCustomActionConfigRule(
      String pkg, String actionName, String enabled, String tools, String flagSets, String implies)
      throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl', 'with_feature_set',",
        "             'tool', 'flag_set', 'action_config', )",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(config = struct(",
        "       action_name = " + actionName + ",",
        "       enabled = " + enabled + ",",
        "       tools = " + tools + ",",
        "       flag_sets = " + flagSets + ",",
        "       implies = " + implies + ",",
        "       type_name = 'action_config'))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testFeature_name_mustBeNonempty() throws Exception {
    loadCcToolchainConfigLib();
    createFeatureRule(
        "one",
        /* name= */ "''",
        /* enabled= */ "False",
        /* flagSets= */ "[]",
        /* envSets= */ "[]",
        /* requires= */ "[]",
        /* implies= */ "[]",
        /* provides= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//one:a");
    StarlarkInfo featureStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("f");
    assertThat(featureStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.featureFromStarlark(featureStruct));
    String msg = e.getMessage();
    assertThat(msg).contains("A feature must either have a nonempty 'name' field or be enabled.");
    assertThat(msg)
        .contains(
            "in FeatureInfo instantiated at /workspace/tools/cpp/cc_toolchain_config_lib.bzl:");
  }

  @Test
  public void testFeature_enabled_mustBeBool() throws Exception {
    loadCcToolchainConfigLib();
    createFeatureRule(
        "two",
        /* name= */ "'featurename'",
        /* enabled= */ "None",
        /* flagSets= */ "[]",
        /* envSets= */ "[]",
        /* requires= */ "[]",
        /* implies= */ "[]",
        /* provides= */ "[]");
    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//two:a"));
    assertThat(e)
        .hasMessageThat()
        .contains("enabled parameter of feature should be a bool, found NoneType");
  }

  @Test
  public void testFeature_flagSets_mustBeFlagSet() throws Exception {
    loadCcToolchainConfigLib();
    createFeatureRule(
        "three",
        /* name= */ "'featurename'",
        /* enabled= */ "True",
        /* flagSets= */ "[struct()]",
        /* envSets= */ "[]",
        /* requires= */ "[]",
        /* implies= */ "[]",
        /* provides= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//three:a");
    StarlarkInfo featureStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("f");
    assertThat(featureStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.featureFromStarlark(featureStruct));
    assertThat(e)
        .hasMessageThat()
        .contains("Expected object of type 'flag_set', received 'struct'");
  }

  @Test
  public void testFeature_envSets_mustBeEnvSet() throws Exception {
    loadCcToolchainConfigLib();
    createFeatureRule(
        "four",
        /* name= */ "'featurename'",
        /* enabled= */ "True",
        /* flagSets= */ "[flag_set(actions = ['a'], flag_groups = [flag_group(flags = ['a'])])]",
        /* envSets= */ "[tool(path = 'a/b/c')]",
        /* requires= */ "[]",
        /* implies= */ "[]",
        /* provides= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//four:a");
    StarlarkInfo featureStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("f");
    assertThat(featureStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.featureFromStarlark(featureStruct));
    assertThat(e).hasMessageThat().contains("Expected object of type 'env_set', received 'tool'");
  }

  @Test
  public void testFeature_something_mustBeFeatureSet() throws Exception {
    loadCcToolchainConfigLib();
    createFeatureRule(
        "five",
        /* name= */ "'featurename'",
        /* enabled= */ "True",
        /* flagSets= */ "[flag_set(actions = ['a'], flag_groups = [flag_group(flags = ['a'])])]",
        /* envSets= */ "[env_set(actions = ['a1'], "
            + "env_entries = [env_entry(key = 'a', value = 'b')])]",
        /* requires= */ "[tool(path = 'a/b/c')]",
        /* implies= */ "[]",
        /* provides= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//five:a");
    StarlarkInfo featureStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("f");
    assertThat(featureStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.featureFromStarlark(featureStruct));
    assertThat(e).hasMessageThat().contains("expected object of type 'feature_set'");
  }

  @Test
  public void testFeature_implies_mustBeString() throws Exception {
    loadCcToolchainConfigLib();
    createFeatureRule(
        "six",
        /* name= */ "'featurename'",
        /* enabled= */ "True",
        /* flagSets= */ "[flag_set(actions = ['a'], flag_groups = [flag_group(flags = ['a'])])]",
        /* envSets= */ "[env_set(actions = ['a1'], "
            + "env_entries = [env_entry(key = 'a', value = 'b')])]",
        /* requires= */ "[feature_set(features = ['f1', 'f2'])]",
        /* implies= */ "[tool(path = 'a/b/c')]",
        /* provides= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//six:a");
    StarlarkInfo featureStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("f");
    assertThat(featureStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.featureFromStarlark(featureStruct));
    assertThat(e)
        .hasMessageThat()
        .contains("at index 0 of implies, got element of type struct, want string");
  }

  @Test
  public void testFeature_provides_mustBeString() throws Exception {
    loadCcToolchainConfigLib();
    createFeatureRule(
        "seven",
        /* name= */ "'featurename'",
        /* enabled= */ "True",
        /* flagSets= */ "[flag_set(actions = ['a'], flag_groups = [flag_group(flags = ['a'])])]",
        /* envSets= */ "[env_set(actions = ['a1'], "
            + "env_entries = [env_entry(key = 'a', value = 'b')])]",
        /* requires= */ "[feature_set(features = ['f1', 'f2'])]",
        /* implies= */ "['a', 'b', 'c']",
        /* provides= */ "[struct()]");

    ConfiguredTarget t = getConfiguredTarget("//seven:a");
    StarlarkInfo featureStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("f");
    assertThat(featureStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.featureFromStarlark(featureStruct));
    assertThat(e)
        .hasMessageThat()
        .contains("at index 0 of provides, got element of type struct, want string");
  }

  @Test
  public void testFeature() throws Exception {
    loadCcToolchainConfigLib();
    createFeatureRule(
        "eight",
        /* name= */ "'featurename32+.-_'",
        /* enabled= */ "True",
        /* flagSets= */ "[flag_set(actions = ['a'], flag_groups = [flag_group(flags = ['a'])])]",
        /* envSets= */ "[env_set(actions = ['a1'], "
            + "env_entries = [env_entry(key = 'a', value = 'b')])]",
        /* requires= */ "[feature_set(features = ['f1', 'f2'])]",
        /* implies= */ "['a', 'b', 'c']",
        /* provides= */ "['a', 'b', 'c']");

    ConfiguredTarget t = getConfiguredTarget("//eight:a");
    StarlarkInfo featureStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("f");
    assertThat(featureStruct).isNotNull();
    Feature a = CcModule.featureFromStarlark(featureStruct);
    assertThat(a).isNotNull();
  }

  @Test
  public void testFeature_name_validCharacters_notUpper() throws Exception {
    loadCcToolchainConfigLib();
    createFeatureRule(
        "nine",
        /* name= */ "'UpperCase'",
        /* enabled= */ "False",
        /* flagSets= */ "[]",
        /* envSets= */ "[]",
        /* requires= */ "[]",
        /* implies= */ "[]",
        /* provides= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//nine:a");
    StarlarkInfo featureStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("f");
    assertThat(featureStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.featureFromStarlark(featureStruct));
    assertThat(e)
        .hasMessageThat()
        .contains(
            "A feature's name must consist solely of lowercase ASCII letters, digits, "
                + "'.', '_', '+', and '-', got 'UpperCase'");
  }

  @Test
  public void testFeature_name_validCharacters_notWhitespace() throws Exception {
    loadCcToolchainConfigLib();
    createFeatureRule(
        "ten",
        /* name= */ "'white space'",
        /* enabled= */ "False",
        /* flagSets= */ "[]",
        /* envSets= */ "[]",
        /* requires= */ "[]",
        /* implies= */ "[]",
        /* provides= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//ten:a");
    StarlarkInfo featureStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("f");
    assertThat(featureStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.featureFromStarlark(featureStruct));
    assertThat(e)
        .hasMessageThat()
        .contains(
            "A feature's name must consist solely of "
                + "lowercase ASCII letters, digits, '.', '_', '+', and '-', got 'white space");
  }

  private void createFeatureRule(
      String pkg,
      String name,
      String enabled,
      String flagSets,
      String envSets,
      String requires,
      String implies,
      String provides)
      throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl', 'with_feature_set', 'feature_set',",
        "             'flag_set', 'flag_group', 'tool', 'env_set', 'env_entry', 'feature')",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(f = feature(",
        "       name = " + name + ",",
        "       enabled = " + enabled + ",",
        "       flag_sets = " + flagSets + ",",
        "       env_sets = " + envSets + ",",
        "       requires = " + requires + ",",
        "       implies = " + implies + ",",
        "       provides = " + provides + "))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testCustomFeature_name_mustBeString() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFeatureRule(
        "one",
        /* name= */ "struct()",
        /* enabled= */ "False",
        /* flagSets= */ "[]",
        /* envSets= */ "[]",
        /* requires= */ "[]",
        /* implies= */ "[]",
        /* provides= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//one:a");
    StarlarkInfo featureStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("f");
    assertThat(featureStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.featureFromStarlark(featureStruct));
    assertThat(e).hasMessageThat().contains("Field 'name' is not of 'java.lang.String' type.");
  }

  @Test
  public void testCustomFeature_enabled_mustBeBool() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFeatureRule(
        "two",
        /* name= */ "'featurename'",
        /* enabled= */ "struct()",
        /* flagSets= */ "[]",
        /* envSets= */ "[]",
        /* requires= */ "[]",
        /* implies= */ "[]",
        /* provides= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//two:a");
    StarlarkInfo featureStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("f");
    assertThat(featureStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.featureFromStarlark(featureStruct));
    assertThat(e).hasMessageThat().contains("Field 'enabled' is not of 'java.lang.Boolean' type.");
  }

  @Test
  public void testCustomFeature_flagSets_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFeatureRule(
        "three",
        /* name= */ "'featurename'",
        /* enabled= */ "True",
        /* flagSets= */ "struct()",
        /* envSets= */ "[]",
        /* requires= */ "[]",
        /* implies= */ "[]",
        /* provides= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//three:a");
    StarlarkInfo featureStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("f");
    assertThat(featureStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.featureFromStarlark(featureStruct));
    assertThat(e).hasMessageThat().contains("for flag_sets, got struct, want sequence");
  }

  @Test
  public void testCustomFeature_envSets_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFeatureRule(
        "four",
        /* name= */ "'featurename'",
        /* enabled= */ "True",
        /* flagSets= */ "[]",
        /* envSets= */ "struct()",
        /* requires= */ "[]",
        /* implies= */ "[]",
        /* provides= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//four:a");
    StarlarkInfo featureStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("f");
    assertThat(featureStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.featureFromStarlark(featureStruct));
    assertThat(e).hasMessageThat().contains("for env_sets, got struct, want sequence");
  }

  @Test
  public void testCustomFeature_requires_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFeatureRule(
        "five",
        /* name= */ "'featurename'",
        /* enabled= */ "True",
        /* flagSets= */ "[]",
        /* envSets= */ "[]",
        /* requires= */ "struct()",
        /* implies= */ "[]",
        /* provides= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//five:a");
    StarlarkInfo featureStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("f");
    assertThat(featureStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.featureFromStarlark(featureStruct));
    assertThat(e).hasMessageThat().contains("for requires, got struct, want sequence");
  }

  @Test
  public void testCustomFeature_implies_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFeatureRule(
        "six",
        /* name= */ "'featurename'",
        /* enabled= */ "True",
        /* flagSets= */ "[]",
        /* envSets= */ "[]",
        /* requires= */ "[]",
        /* implies= */ "struct()",
        /* provides= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//six:a");
    StarlarkInfo featureStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("f");
    assertThat(featureStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.featureFromStarlark(featureStruct));
    assertThat(e).hasMessageThat().contains("for implies, got struct, want sequence");
  }

  @Test
  public void testCustomFeature_provides_mustBeList() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFeatureRule(
        "seven",
        /* name= */ "'featurename'",
        /* enabled= */ "True",
        /* flagSets= */ "[]",
        /* envSets= */ "[]",
        /* requires= */ "[]",
        /* implies= */ "[]",
        /* provides= */ "struct()");

    ConfiguredTarget t = getConfiguredTarget("//seven:a");
    StarlarkInfo featureStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("f");
    assertThat(featureStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.featureFromStarlark(featureStruct));
    assertThat(e).hasMessageThat().contains("for provides, got struct, want sequence");
  }

  @Test
  public void testCustomFeature_flagSet_musthaveActions() throws Exception {
    loadCcToolchainConfigLib();
    createCustomFeatureRule(
        "eight",
        /* name= */ "'featurename'",
        /* enabled= */ "True",
        /* flagSets= */ "[flag_set()]",
        /* envSets= */ "[]",
        /* requires= */ "[]",
        /* implies= */ "[]",
        /* provides= */ "[]");

    ConfiguredTarget t = getConfiguredTarget("//eight:a");
    StarlarkInfo featureStruct = (StarlarkInfo) getMyInfoFromTarget(t).getValue("f");
    assertThat(featureStruct).isNotNull();
    EvalException e =
        assertThrows(EvalException.class, () -> CcModule.featureFromStarlark(featureStruct));
    assertThat(e)
        .hasMessageThat()
        .contains("A flag_set that belongs to a feature must have nonempty 'actions' parameter.");
  }

  private void createCustomFeatureRule(
      String pkg,
      String name,
      String enabled,
      String flagSets,
      String envSets,
      String requires,
      String implies,
      String provides)
      throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl', 'with_feature_set', 'feature_set',",
        "             'flag_set', 'flag_group', 'tool', 'env_set', 'env_entry', 'feature')",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(f = struct(",
        "       name = " + name + ",",
        "       enabled = " + enabled + ",",
        "       flag_sets = " + flagSets + ",",
        "       env_sets = " + envSets + ",",
        "       requires = " + requires + ",",
        "       implies = " + implies + ",",
        "       provides = " + provides + ",",
        "       type_name = 'feature'))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testCustomArtifactNamePattern_categoryName_mustBeString() throws Exception {
    loadCcToolchainConfigLib();
    createCustomArtifactNamePatternRule(
        "one", /* categoryName= */ "struct()", /* extension= */ "'a'", /* prefix= */ "'a'");

    ConfiguredTarget t = getConfiguredTarget("//one:a");
    StarlarkInfo artifactNamePatternStruct =
        (StarlarkInfo) getMyInfoFromTarget(t).getValue("namepattern");
    assertThat(artifactNamePatternStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class,
            () -> CcModule.artifactNamePatternFromStarlark(artifactNamePatternStruct));
    assertThat(e)
        .hasMessageThat()
        .contains("Field 'category_name' is not of 'java.lang.String' type.");
  }

  @Test
  public void testCustomArtifactNamePattern_extension_mustBeString() throws Exception {
    loadCcToolchainConfigLib();
    createCustomArtifactNamePatternRule(
        "two",
        /* categoryName= */ "'static_library'",
        /* extension= */ "struct()",
        /* prefix= */ "'a'");

    ConfiguredTarget t = getConfiguredTarget("//two:a");
    StarlarkInfo artifactNamePatternStruct =
        (StarlarkInfo) getMyInfoFromTarget(t).getValue("namepattern");
    assertThat(artifactNamePatternStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class,
            () -> CcModule.artifactNamePatternFromStarlark(artifactNamePatternStruct));
    assertThat(e).hasMessageThat().contains("Field 'extension' is not of 'java.lang.String' type.");
  }

  @Test
  public void testCustomArtifactNamePattern_prefix_mustBeString() throws Exception {
    loadCcToolchainConfigLib();
    createCustomArtifactNamePatternRule(
        "three",
        /* categoryName= */ "'static_library'",
        /* extension= */ "'.a'",
        /* prefix= */ "struct()");

    ConfiguredTarget t = getConfiguredTarget("//three:a");
    StarlarkInfo artifactNamePatternStruct =
        (StarlarkInfo) getMyInfoFromTarget(t).getValue("namepattern");
    assertThat(artifactNamePatternStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class,
            () -> CcModule.artifactNamePatternFromStarlark(artifactNamePatternStruct));
    assertThat(e).hasMessageThat().contains("Field 'prefix' is not of 'java.lang.String' type.");
  }

  @Test
  public void testCustomArtifactNamePattern_categoryName_mustBeNonempty() throws Exception {
    loadCcToolchainConfigLib();
    createCustomArtifactNamePatternRule(
        "four", /* categoryName= */ "''", /* extension= */ "'.a'", /* prefix= */ "'a'");

    ConfiguredTarget t = getConfiguredTarget("//four:a");
    StarlarkInfo artifactNamePatternStruct =
        (StarlarkInfo) getMyInfoFromTarget(t).getValue("namepattern");
    assertThat(artifactNamePatternStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class,
            () -> CcModule.artifactNamePatternFromStarlark(artifactNamePatternStruct));
    assertThat(e)
        .hasMessageThat()
        .contains("The 'category_name' field of artifact_name_pattern must be a nonempty string.");
  }

  @Test
  public void testCustomArtifactNamePattern_emptyString_emptyString() throws Exception {
    loadCcToolchainConfigLib();
    createCustomArtifactNamePatternRule(
        "five", /* categoryName= */ "'executable'", /* extension= */ "''", /* prefix= */ "''");

    ConfiguredTarget t = getConfiguredTarget("//five:a");
    StarlarkInfo artifactNamePatternStruct =
        (StarlarkInfo) getMyInfoFromTarget(t).getValue("namepattern");
    assertThat(artifactNamePatternStruct).isNotNull();
    ArtifactNamePattern artifactNamePattern =
        CcModule.artifactNamePatternFromStarlark(artifactNamePatternStruct);
    assertThat(artifactNamePattern).isNotNull();
  }

  @Test
  public void testCustomArtifactNamePattern_none_none() throws Exception {
    loadCcToolchainConfigLib();
    createCustomArtifactNamePatternRule(
        "six", /* categoryName= */ "'executable'", /* extension= */ "None", /* prefix= */ "None");

    ConfiguredTarget t = getConfiguredTarget("//six:a");
    StarlarkInfo artifactNamePatternStruct =
        (StarlarkInfo) getMyInfoFromTarget(t).getValue("namepattern");
    assertThat(artifactNamePatternStruct).isNotNull();
    ArtifactNamePattern artifactNamePattern =
        CcModule.artifactNamePatternFromStarlark(artifactNamePatternStruct);
    assertThat(artifactNamePattern).isNotNull();
  }

  @Test
  public void testCustomArtifactNamePattern_categoryName_unknown() throws Exception {
    loadCcToolchainConfigLib();
    createCustomArtifactNamePatternRule(
        "seven", /* categoryName= */ "'unknown'", /* extension= */ "'.a'", /* prefix= */ "'a'");

    ConfiguredTarget t = getConfiguredTarget("//seven:a");
    StarlarkInfo artifactNamePatternStruct =
        (StarlarkInfo) getMyInfoFromTarget(t).getValue("namepattern");
    assertThat(artifactNamePatternStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class,
            () -> CcModule.artifactNamePatternFromStarlark(artifactNamePatternStruct));
    assertThat(e).hasMessageThat().contains("Artifact category unknown not recognized");
  }

  @Test
  public void testCustomArtifactNamePattern_fileExtension_unknown() throws Exception {
    loadCcToolchainConfigLib();
    createCustomArtifactNamePatternRule(
        "eight",
        /* categoryName= */ "'static_library'",
        /* extension= */ "'a'",
        /* prefix= */ "'a'");

    ConfiguredTarget t = getConfiguredTarget("//eight:a");
    StarlarkInfo artifactNamePatternStruct =
        (StarlarkInfo) getMyInfoFromTarget(t).getValue("namepattern");
    assertThat(artifactNamePatternStruct).isNotNull();
    EvalException e =
        assertThrows(
            EvalException.class,
            () -> CcModule.artifactNamePatternFromStarlark(artifactNamePatternStruct));
    assertThat(e).hasMessageThat().contains("Unrecognized file extension 'a'");
  }

  private void createCustomArtifactNamePatternRule(
      String pkg, String categoryName, String extension, String prefix) throws Exception {
    scratch.file(
        pkg + "/foo.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "   return [MyInfo(namepattern = struct(",
        "       category_name = " + categoryName + ",",
        "       extension = " + extension + ",",
        "       prefix = " + prefix + ",",
        "       type_name = 'artifact_name_pattern'))]",
        "crule = rule(implementation = _impl)");
    scratch.file(pkg + "/BUILD", "load(':foo.bzl', 'crule')", "crule(name = 'a')");
  }

  @Test
  public void testCcToolchainInfoFromStarlark() throws Exception {
    loadCcToolchainConfigLib();
    scratch.file(
        "foo/crosstool.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl',",
        "        'feature',",
        "        'action_config',",
        "        'artifact_name_pattern',",
        "        'env_entry',",
        "        'variable_with_value',",
        "        'make_variable',",
        "        'feature_set',",
        "        'with_feature_set',",
        "        'env_set',",
        "        'flag_group',",
        "        'flag_set',",
        "        'tool_path',",
        "        'tool')",
        "",
        "def _impl(ctx):",
        "    return cc_common.create_cc_toolchain_config_info(",
        "                ctx = ctx,",
        "                features = [feature(name = 'featureone')],",
        "                action_configs = [action_config(action_name = 'action', enabled=True)],",
        "                artifact_name_patterns = [artifact_name_pattern(",
        "                   category_name = 'static_library',",
        "                   prefix = 'prefix',",
        "                   extension = '.a')],",
        "                cxx_builtin_include_directories = ['dir1', 'dir2', 'dir3'],",
        "                toolchain_identifier = 'toolchain',",
        "                host_system_name = 'host',",
        "                target_system_name = 'target',",
        "                target_cpu = 'cpu',",
        "                target_libc = 'libc',",
        "                compiler = 'compiler',",
        "                abi_libc_version = 'abi_libc',",
        "                abi_version = 'abi',",
        "                tool_paths = [tool_path(name = 'name1', path = 'path1')],",
        "                cc_target_os = 'os',",
        "                builtin_sysroot = 'sysroot',",
        "                make_variables = [make_variable(name = 'acs', value = 'asd')])",
        "cc_toolchain_config_rule = rule(",
        "    implementation = _impl,",
        "    attrs = {},",
        "    provides = [CcToolchainConfigInfo], ",
        ")");

    scratch.file(
        "foo/BUILD",
        "load(':crosstool.bzl', 'cc_toolchain_config_rule')",
        "cc_toolchain_alias(name='alias')",
        "cc_toolchain_config_rule(name='r')");
    ConfiguredTarget target = getConfiguredTarget("//foo:r");
    assertThat(target).isNotNull();
    CcToolchainConfigInfo ccToolchainConfigInfo =
        (CcToolchainConfigInfo) target.get(CcToolchainConfigInfo.PROVIDER.getKey());
    assertThat(ccToolchainConfigInfo).isNotNull();
  }

  @Test
  public void testCcToolchainInfoFromStarlarkRequiredToolchainIdentifier() throws Exception {
    setupStarlarkRuleForStringFieldsTesting("toolchain_identifier");
    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:r"));
    assertThat(e)
        .hasMessageThat()
        .contains("missing 1 required named argument: toolchain_identifier");
  }

  @Test
  public void testCcToolchainInfoFromStarlarkRequiredHostSystemName() throws Exception {
    setupStarlarkRuleForStringFieldsTesting("host_system_name");
    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:r"));
    assertThat(e).hasMessageThat().contains("missing 1 required named argument: host_system_name");
  }

  @Test
  public void testCcToolchainInfoFromStarlarkRequiredTargetSystemName() throws Exception {
    setupStarlarkRuleForStringFieldsTesting("target_system_name");
    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:r"));
    assertThat(e)
        .hasMessageThat()
        .contains("missing 1 required named argument: target_system_name");
  }

  @Test
  public void testCcToolchainInfoFromStarlarkRequiredTargetCpu() throws Exception {
    setupStarlarkRuleForStringFieldsTesting("target_cpu");
    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:r"));
    assertThat(e).hasMessageThat().contains("missing 1 required named argument: target_cpu");
  }

  @Test
  public void testCcToolchainInfoFromStarlarkRequiredTargetLibc() throws Exception {
    setupStarlarkRuleForStringFieldsTesting("target_libc");
    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:r"));
    assertThat(e).hasMessageThat().contains("missing 1 required named argument: target_libc");
  }

  @Test
  public void testCcToolchainInfoFromStarlarkRequiredCompiler() throws Exception {
    setupStarlarkRuleForStringFieldsTesting("compiler");
    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:r"));
    assertThat(e).hasMessageThat().contains("missing 1 required named argument: compiler");
  }

  @Test
  public void testCcToolchainInfoFromStarlarkRequiredAbiVersion() throws Exception {
    setupStarlarkRuleForStringFieldsTesting("abi_version");
    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:r"));
    assertThat(e).hasMessageThat().contains("missing 1 required named argument: abi_version");
  }

  @Test
  public void testCcToolchainInfoFromStarlarkRequiredAbiLibcVersion() throws Exception {
    setupStarlarkRuleForStringFieldsTesting("abi_libc_version");
    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:r"));
    assertThat(e).hasMessageThat().contains("missing 1 required named argument: abi_libc_version");
  }

  @Test
  public void testCcToolchainInfoFromStarlarkAllRequiredStringsPresent() throws Exception {
    setupStarlarkRuleForStringFieldsTesting("");
    ConfiguredTarget target = getConfiguredTarget("//foo:r");
    assertThat(target).isNotNull();
    CcToolchainConfigInfo ccToolchainConfigInfo =
        (CcToolchainConfigInfo) target.get(CcToolchainConfigInfo.PROVIDER.getKey());
    assertThat(ccToolchainConfigInfo).isNotNull();
  }

  private void setupStarlarkRuleForStringFieldsTesting(String fieldToExclude) throws Exception {
    ImmutableList<String> fields =
        ImmutableList.of(
            "toolchain_identifier = 'identifier'",
            "host_system_name = 'host_system_name'",
            "target_system_name = 'target_system_name'",
            "target_cpu = 'target_cpu'",
            "target_libc = 'target_libc'",
            "compiler = 'compiler'",
            "abi_version = 'abi'",
            "abi_libc_version = 'abi_libc'");

    scratch.file(
        "foo/crosstool.bzl",
        "def _impl(ctx):",
        "    return cc_common.create_cc_toolchain_config_info(",
        "    ctx = ctx,",
        Joiner.on(",\n")
            .join(fields.stream().filter(el -> !el.startsWith(fieldToExclude + " =")).toArray()),
        ")",
        "cc_toolchain_config_rule = rule(",
        "    implementation = _impl,",
        "    attrs = {},",
        "    provides = [CcToolchainConfigInfo], ",
        ")");
    scratch.file(
        "foo/BUILD",
        "load(':crosstool.bzl', 'cc_toolchain_config_rule')",
        "cc_toolchain_alias(name='alias')",
        "cc_toolchain_config_rule(name='r')");
  }

  @Test
  public void testCcToolchainInfoFromStarlarkNoLegacyFeatures() throws Exception {
    loadCcToolchainConfigLib();
    scratch.file(
        "foo/crosstool.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl',",
        "        'feature',",
        "        'action_config',",
        "        'artifact_name_pattern',",
        "        'env_entry',",
        "        'variable_with_value',",
        "        'make_variable',",
        "        'feature_set',",
        "        'with_feature_set',",
        "        'env_set',",
        "        'flag_group',",
        "        'flag_set',",
        "        'tool_path',",
        "        'tool')",
        "",
        "def _impl(ctx):",
        "    return cc_common.create_cc_toolchain_config_info(",
        "                ctx = ctx,",
        "                features = [",
        "                    feature(name = 'no_legacy_features'),",
        "                    feature(name = 'custom_feature'),",
        "                ],",
        "                action_configs = [action_config(action_name = 'custom_action')],",
        "                artifact_name_patterns = [artifact_name_pattern(",
        "                   category_name = 'static_library',",
        "                   prefix = 'prefix',",
        "                   extension = '.a')],",
        "                toolchain_identifier = 'toolchain',",
        "                host_system_name = 'host',",
        "                target_system_name = 'target',",
        "                target_cpu = 'cpu',",
        "                target_libc = 'libc',",
        "                compiler = 'compiler',",
        "                abi_libc_version = 'abi_libc',",
        "                abi_version = 'abi')",
        "cc_toolchain_config_rule = rule(",
        "    implementation = _impl,",
        "    attrs = {},",
        "    provides = [CcToolchainConfigInfo], ",
        ")");

    scratch.file(
        "foo/BUILD",
        "load(':crosstool.bzl', 'cc_toolchain_config_rule')",
        "cc_toolchain_alias(name='alias')",
        "cc_toolchain_config_rule(name='r')");
    ConfiguredTarget target = getConfiguredTarget("//foo:r");
    assertThat(target).isNotNull();
    CcToolchainConfigInfo ccToolchainConfigInfo =
        (CcToolchainConfigInfo) target.get(CcToolchainConfigInfo.PROVIDER.getKey());
    ImmutableSet<String> featureNames =
        ccToolchainConfigInfo.getFeatures().stream()
            .map(feature -> feature.getName())
            .collect(ImmutableSet.toImmutableSet());
    ImmutableSet<String> actionConfigNames =
        ccToolchainConfigInfo.getActionConfigs().stream()
            .map(actionConfig -> actionConfig.getActionName())
            .collect(ImmutableSet.toImmutableSet());
    assertThat(featureNames).containsExactly("no_legacy_features", "custom_feature");
    assertThat(actionConfigNames).containsExactly("custom_action");
  }

  @Test
  public void testCcToolchainInfoFromStarlarkWithLegacyFeatures() throws Exception {
    loadCcToolchainConfigLib();
    scratch.file(
        "foo/crosstool.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl',",
        "        'feature',",
        "        'action_config',",
        "        'artifact_name_pattern',",
        "        'env_entry',",
        "        'variable_with_value',",
        "        'make_variable',",
        "        'feature_set',",
        "        'with_feature_set',",
        "        'env_set',",
        "        'flag_group',",
        "        'flag_set',",
        "        'tool_path',",
        "        'tool')",
        "",
        "def _impl(ctx):",
        "    return cc_common.create_cc_toolchain_config_info(",
        "                ctx = ctx,",
        "                features = [",
        "                    feature(name = 'custom_feature'),",
        "                    feature(name = 'legacy_compile_flags'),",
        "                    feature(name = 'fdo_optimize'),",
        "                    feature(name = 'default_compile_flags'),",
        "                ],",
        "                action_configs = [action_config(action_name = 'custom-action')],",
        "                artifact_name_patterns = [artifact_name_pattern(",
        "                   category_name = 'static_library',",
        "                   prefix = 'prefix',",
        "                   extension = '.a')],",
        "                toolchain_identifier = 'toolchain',",
        "                host_system_name = 'host',",
        "                target_system_name = 'target',",
        "                target_cpu = 'cpu',",
        "                target_libc = 'libc',",
        "                compiler = 'compiler',",
        "                abi_libc_version = 'abi_libc',",
        "                abi_version = 'abi')",
        "cc_toolchain_config_rule = rule(",
        "    implementation = _impl,",
        "    attrs = {},",
        "    provides = [CcToolchainConfigInfo], ",
        ")");

    scratch.file(
        "foo/BUILD",
        "load(':crosstool.bzl', 'cc_toolchain_config_rule')",
        "cc_toolchain_alias(name='alias')",
        "cc_toolchain_config_rule(name='r')");
    ConfiguredTarget target = getConfiguredTarget("//foo:r");
    assertThat(target).isNotNull();
    CcToolchainConfigInfo ccToolchainConfigInfo =
        (CcToolchainConfigInfo) target.get(CcToolchainConfigInfo.PROVIDER.getKey());
    ImmutableList<String> featureNames =
        ccToolchainConfigInfo.getFeatures().stream()
            .map(feature -> feature.getName())
            .collect(ImmutableList.toImmutableList());
    ImmutableSet<String> actionConfigNames =
        ccToolchainConfigInfo.getActionConfigs().stream()
            .map(actionConfig -> actionConfig.getActionName())
            .collect(ImmutableSet.toImmutableSet());
    // fdo_optimize should not be re-added to the list of features by legacy behavior
    assertThat(featureNames).containsNoDuplicates();
    // legacy_compile_flags should appear first in the list of features, followed by
    // default_compile_flags.
    assertThat(featureNames)
        .containsAtLeast(
            "legacy_compile_flags", "default_compile_flags", "custom_feature", "fdo_optimize")
        .inOrder();
    // assemble is one of the action_configs added as a legacy behavior, therefore it needs to be
    // prepended to the action configs defined by the user.
    assertThat(actionConfigNames).containsAtLeast("assemble", "custom-action").inOrder();
  }

  @Test
  public void testCcToolchainInfoToProto() throws Exception {
    loadCcToolchainConfigLib();
    scratch.file(
        "foo/crosstool.bzl",
        "load('//tools/cpp:cc_toolchain_config_lib.bzl',",
        "        'feature',",
        "        'action_config',",
        "        'artifact_name_pattern',",
        "        'env_entry',",
        "        'variable_with_value',",
        "        'make_variable',",
        "        'feature_set',",
        "        'with_feature_set',",
        "        'env_set',",
        "        'flag_group',",
        "        'flag_set',",
        "        'tool_path',",
        "        'tool')",
        "",
        "def _impl(ctx):",
        "    return cc_common.create_cc_toolchain_config_info(",
        "                ctx = ctx,",
        "                features = [",
        "                    feature(name = 'featureone', enabled = True),",
        "                    feature(name = 'sysroot',",
        "                        flag_sets = [",
        "                            flag_set(",
        "                                actions = ['assemble', 'preprocess-assemble'],",
        "                                flag_groups = [",
        "                                    flag_group(",
        "                                        expand_if_available= 'available',",
        "                                        expand_if_not_available= 'notavailable',",
        "                                        expand_if_true = 'true',",
        "                                        expand_if_false = 'false',",
        "                                        expand_if_equal = variable_with_value(",
        "                                            name = 'variable', value = 'value'),",
        "                                        iterate_over = 'iterate_over',",
        "                                        flag_groups = [",
        "                                            flag_group(flags = ",
        "                                                ['foo%{libraries_to_link}bar',",
        "                                                 '-D__DATE__=\"redacted\"'])],",
        "                                    ),",
        "                                    flag_group(flags = ['a', 'b'])],",
        "                        )],",
        "                        implies = ['imply2', 'imply1'],",
        "                        provides = ['provides2', 'provides1'],",
        "                        requires = [feature_set(features = ['r1', 'r2']),",
        "                                    feature_set(features = ['r3'])],",
        "                        env_sets = [",
        "                             env_set(actions = ['a1', 'a2'],",
        "                                     env_entries = [",
        "                                         env_entry(key = 'k1', value = 'v1'),",
        "                                         env_entry(key = 'k2', value = 'v2')],",
        "                                     with_features = [",
        "                                         with_feature_set(",
        "                                             features = ['f1', 'f2'],",
        "                                             not_features = ['nf1', 'nf2'])]),",
        "                             env_set(actions = ['a1', 'a2'])]",
        "                    ),",
        "                ],",
        "                action_configs = [",
        "                    action_config(action_name = 'action_one', enabled=True),",
        "                    action_config(",
        "                        action_name = 'action_two',",
        "                        tools = [tool(path = 'fake/path',",
        "                                      with_features = [",
        "                                          with_feature_set(features = ['a'],",
        "                                                           not_features=['b', 'c']),",
        "                                          with_feature_set(features=['b'])],",
        "                                      execution_requirements = ['a', 'b', 'c'])],",
        "                        implies = ['compiler_input_flags', 'compiler_output_flags'],",
        "                        flag_sets = [flag_set(flag_groups = [flag_group(flags = ['a'])]",
        "                                             )])],",
        "                artifact_name_patterns = [artifact_name_pattern(",
        "                   category_name = 'static_library',",
        "                   prefix = 'prefix',",
        "                   extension = '.a')],",
        "                cxx_builtin_include_directories = ['dir1', 'dir2', 'dir3'],",
        "                toolchain_identifier = 'toolchain',",
        "                host_system_name = 'host',",
        "                target_system_name = 'target',",
        "                target_cpu = 'cpu',",
        "                target_libc = 'libc',",
        "                compiler = 'compiler',",
        "                abi_libc_version = 'abi_libc',",
        "                abi_version = 'abi',",
        "                tool_paths = [tool_path(name = 'name1', path = 'path1')],",
        "                make_variables = [make_variable(name = 'variable', value = '--a -b -c')],",
        "                builtin_sysroot = 'sysroot',",
        "                cc_target_os = 'os',",
        "        )",
        "cc_toolchain_config_rule = rule(",
        "    implementation = _impl,",
        "    attrs = {},",
        "    provides = [CcToolchainConfigInfo], ",
        ")");

    scratch.file(
        "foo/BUILD",
        "load(':crosstool.bzl', 'cc_toolchain_config_rule')",
        "cc_toolchain_alias(name='alias')",
        "cc_toolchain_config_rule(name='r')");

    ConfiguredTarget target = getConfiguredTarget("//foo:r");
    assertThat(target).isNotNull();
    CcToolchainConfigInfo ccToolchainConfigInfo =
        (CcToolchainConfigInfo) target.get(CcToolchainConfigInfo.PROVIDER.getKey());
    assertThat(ccToolchainConfigInfo).isNotNull();
    CToolchain.Builder toolchainBuilder = CToolchain.newBuilder();
    TextFormat.merge(ccToolchainConfigInfo.getProto(), toolchainBuilder);
    CToolchain toolchain = toolchainBuilder.build();

    assertThat(toolchain.getCxxBuiltinIncludeDirectoryList())
        .containsExactly("dir1", "dir2", "dir3");
    assertThat(toolchain.getToolchainIdentifier()).isEqualTo("toolchain");
    assertThat(toolchain.getHostSystemName()).isEqualTo("host");
    assertThat(toolchain.getTargetSystemName()).isEqualTo("target");
    assertThat(toolchain.getTargetCpu()).isEqualTo("cpu");
    assertThat(toolchain.getTargetLibc()).isEqualTo("libc");
    assertThat(toolchain.getCompiler()).isEqualTo("compiler");
    assertThat(toolchain.getAbiLibcVersion()).isEqualTo("abi_libc");
    assertThat(toolchain.getAbiVersion()).isEqualTo("abi");
    ToolPath toolPath = Iterables.getOnlyElement(toolchain.getToolPathList());
    assertThat(toolPath.getName()).isEqualTo("name1");
    assertThat(toolPath.getPath()).isEqualTo("path1");
    MakeVariable makeVariable = Iterables.getOnlyElement(toolchain.getMakeVariableList());
    assertThat(makeVariable.getName()).isEqualTo("variable");
    assertThat(makeVariable.getValue()).isEqualTo("--a -b -c");
    assertThat(toolchain.getBuiltinSysroot()).isEqualTo("sysroot");
    assertThat(toolchain.getCcTargetOs()).isEqualTo("os");
    assertThat(
            toolchain.getFeatureList().stream()
                .map(feature -> feature.getName())
                .collect(ImmutableList.toImmutableList()))
        .containsAtLeast("featureone", "sysroot")
        .inOrder();
    // check for legacy features
    assertThat(toolchain.getFeatureCount()).isGreaterThan(2);
    CToolchain.Feature feature =
        toolchain.getFeatureList().stream()
            .filter(f -> f.getName().equals("sysroot"))
            .findFirst()
            .get();
    assertThat(feature.getName()).isEqualTo("sysroot");
    assertThat(feature.getImpliesList()).containsExactly("imply2", "imply1").inOrder();
    assertThat(feature.getProvidesList()).containsExactly("provides2", "provides1").inOrder();
    assertThat(feature.getRequires(0).getFeatureList()).containsExactly("r1", "r2");
    assertThat(feature.getRequires(1).getFeatureList()).containsExactly("r3");
    assertThat(feature.getEnvSetCount()).isEqualTo(2);
    CToolchain.EnvSet envSet = feature.getEnvSet(0);
    assertThat(envSet.getActionList()).containsExactly("a1", "a2");
    assertThat(envSet.getEnvEntry(0).getKey()).isEqualTo("k1");
    assertThat(envSet.getEnvEntry(0).getValue()).isEqualTo("v1");
    assertThat(Iterables.getOnlyElement(envSet.getWithFeatureList()).getFeatureList())
        .containsExactly("f1", "f2");
    assertThat(Iterables.getOnlyElement(envSet.getWithFeatureList()).getNotFeatureList())
        .containsExactly("nf1", "nf2");
    CToolchain.FlagSet flagSet = Iterables.getOnlyElement(feature.getFlagSetList());
    assertThat(flagSet.getActionList()).containsExactly("assemble", "preprocess-assemble");
    assertThat(flagSet.getFlagGroupCount()).isEqualTo(2);
    CToolchain.FlagGroup flagGroup = flagSet.getFlagGroup(0);
    assertThat(flagGroup.getExpandIfAllAvailableList()).containsExactly("available");
    assertThat(flagGroup.getExpandIfNoneAvailableList()).containsExactly("notavailable");
    assertThat(flagGroup.getIterateOver()).isEqualTo("iterate_over");
    assertThat(flagGroup.getExpandIfTrue()).isEqualTo("true");
    assertThat(flagGroup.getExpandIfFalse()).isEqualTo("false");
    CToolchain.VariableWithValue variableWithValue = flagGroup.getExpandIfEqual();
    assertThat(variableWithValue.getVariable()).isEqualTo("variable");
    assertThat(variableWithValue.getValue()).isEqualTo("value");
    assertThat(flagGroup.getFlagGroup(0).getFlagList())
        .containsExactly("foo%{libraries_to_link}bar", "-D__DATE__=\"redacted\"")
        .inOrder();

    assertThat(
            toolchain.getActionConfigList().stream()
                .map(actionConfig -> actionConfig.getActionName())
                .collect(ImmutableList.toImmutableList()))
        .containsAtLeast("action_one", "action_two")
        .inOrder();

    // legacy crosstool patching adds the missing action_configs as well
    assertThat(toolchain.getActionConfigCount()).isGreaterThan(2);

    CToolchain.ActionConfig actionConfig =
        toolchain.getActionConfigList().stream()
            .filter(config -> config.getConfigName().equals("action_two"))
            .findFirst()
            .get();
    assertThat(actionConfig.getImpliesList())
        .containsExactly("compiler_input_flags", "compiler_output_flags")
        .inOrder();
    CToolchain.Tool tool = Iterables.getOnlyElement(actionConfig.getToolList());
    assertThat(tool.getToolPath()).isEqualTo("fake/path");
    assertThat(tool.getExecutionRequirementList()).containsExactly("a", "b", "c");
    assertThat(tool.getWithFeature(0).getFeatureList()).containsExactly("a");
    assertThat(tool.getWithFeature(0).getNotFeatureList()).containsExactly("b", "c");
    // When we create an ActionConfig from a proto we put the action name as the only element of its
    // FlagSet.action lists. So when we convert back to proto, we need to remove it.
    assertThat(
            ccToolchainConfigInfo.getActionConfigs().stream()
                .filter(config -> config.getName().equals("action_two"))
                .findFirst()
                .get()
                .getFlagSets()
                .get(0)
                .getActions())
        .containsExactly("action_two");
    CToolchain.FlagSet actionConfigFlagSet =
        Iterables.getOnlyElement(actionConfig.getFlagSetList());
    assertThat(actionConfigFlagSet.getActionCount()).isEqualTo(0);

    // Missing artifact name patterns are filled in too
    assertThat(toolchain.getArtifactNamePatternCount()).isGreaterThan(1);
    assertThat(toolchain.getArtifactNamePattern(0))
        .isEqualTo(
            CToolchain.ArtifactNamePattern.newBuilder()
                .setCategoryName("static_library")
                .setPrefix("prefix")
                .setExtension(".a")
                .build());
  }

  // Tests that default None values in non-required fields do not cause trouble while building
  // the CToolchain
  @Test
  public void testCcToolchainInfoToProtoBareMinimum() throws Exception {
    loadCcToolchainConfigLib();
    scratch.file(
        "foo/crosstool.bzl",
        "def _impl(ctx):",
        "    return cc_common.create_cc_toolchain_config_info(",
        "                ctx = ctx,",
        "                toolchain_identifier = 'toolchain',",
        "                host_system_name = 'host',",
        "                target_system_name = 'target',",
        "                target_cpu = 'cpu',",
        "                target_libc = 'libc',",
        "                compiler = 'compiler',",
        "                abi_libc_version = 'abi_libc',",
        "                abi_version = 'abi',",
        "        )",
        "cc_toolchain_config_rule = rule(",
        "    implementation = _impl,",
        "    attrs = {},",
        "    provides = [CcToolchainConfigInfo], ",
        ")");

    scratch.file(
        "foo/BUILD",
        "load(':crosstool.bzl', 'cc_toolchain_config_rule')",
        "cc_toolchain_alias(name='alias')",
        "cc_toolchain_config_rule(name='r')");

    ConfiguredTarget target = getConfiguredTarget("//foo:r");
    assertThat(target).isNotNull();
    CcToolchainConfigInfo ccToolchainConfigInfo =
        (CcToolchainConfigInfo) target.get(CcToolchainConfigInfo.PROVIDER.getKey());
    assertThat(ccToolchainConfigInfo).isNotNull();
    CToolchain.Builder toolchainBuilder = CToolchain.newBuilder();
    TextFormat.merge(ccToolchainConfigInfo.getProto(), toolchainBuilder);
    assertNoEvents();
  }

  @Test
  public void testWrongElementTypeInListParameter_features() throws Exception {
    getBasicCcToolchainConfigInfoWithAdditionalParameter(
        "features = ['string_instead_of_feature']");
    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//foo:r");
    assertContainsEvent(
        "'features' parameter of cc_common.create_cc_toolchain_config_info() contains an element"
            + " of type 'string' instead of a 'FeatureInfo' provider.");
  }

  @Test
  public void testWrongElementTypeInListParameter_actionConfigs() throws Exception {
    getBasicCcToolchainConfigInfoWithAdditionalParameter("action_configs = [None]");
    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//foo:r");
    assertContainsEvent(
        "'action_configs' parameter of cc_common.create_cc_toolchain_config_info() contains an"
            + " element of type 'NoneType' instead of a 'ActionConfigInfo' provider.");
  }

  @Test
  public void testWrongElementTypeInListParameter_artifactNamePatterns() throws Exception {
    getBasicCcToolchainConfigInfoWithAdditionalParameter("artifact_name_patterns = [1]");
    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//foo:r");
    assertContainsEvent(
        "'artifact_name_patterns' parameter of cc_common.create_cc_toolchain_config_info()"
            + " contains an element of type 'int' instead of a 'ArtifactNamePatternInfo'"
            + " provider.");
  }

  @Test
  public void testWrongElementTypeInListParameter_makeVariables() throws Exception {
    getBasicCcToolchainConfigInfoWithAdditionalParameter("make_variables = [True]");
    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//foo:r");
    assertContainsEvent(
        "'make_variables' parameter of cc_common.create_cc_toolchain_config_info() contains an"
            + " element of type 'bool' instead of a 'MakeVariableInfo' provider.");
  }

  @Test
  public void testWrongElementTypeInListParameter_toolPaths() throws Exception {
    getBasicCcToolchainConfigInfoWithAdditionalParameter("tool_paths = [{}]");
    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//foo:r");
    assertContainsEvent(
        "'tool_paths' parameter of cc_common.create_cc_toolchain_config_info() contains an element"
            + " of type 'dict' instead of a 'ToolPathInfo' provider.");
  }

  private void getBasicCcToolchainConfigInfoWithAdditionalParameter(String s) throws Exception {
    scratch.file(
        "foo/crosstool.bzl",
        "def _impl(ctx):",
        "    return cc_common.create_cc_toolchain_config_info(",
        "                ctx = ctx,",
        "                toolchain_identifier = 'toolchain',",
        "                host_system_name = 'host',",
        "                target_system_name = 'target',",
        "                target_cpu = 'cpu',",
        "                target_libc = 'libc',",
        "                compiler = 'compiler',",
        "                abi_libc_version = 'abi_libc',",
        "                abi_version = 'abi',",
        "                " + s + ",",
        "        )",
        "cc_toolchain_config_rule = rule(",
        "    implementation = _impl,",
        "    attrs = {},",
        "    provides = [CcToolchainConfigInfo], ",
        ")");

    scratch.file(
        "foo/BUILD",
        "load(':crosstool.bzl', 'cc_toolchain_config_rule')",
        "cc_toolchain_alias(name='alias')",
        "cc_toolchain_config_rule(name='r')");
  }

  @Test
  public void testGetLegacyCcFlagsMakeVariable() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder()
                .withMakeVariables(Pair.of("CC_FLAGS", "-test-cflag1 -testcflag2")));

    loadCcToolchainConfigLib();
    scratch.file(
        "a/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  cc_flags = cc_common.legacy_cc_flags_make_variable_do_not_use(",
        "      cc_toolchain = toolchain)",
        "  return [MyInfo(",
        "    cc_flags = cc_flags)]",
        "cc_flags = rule(",
        "  _impl,",
        "  attrs = { ",
        "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
        "  },",
        "  fragments = ['cpp'],",
        ");");

    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'cc_flags')",
        "cc_toolchain_alias(name='alias')",
        "cc_flags(name='r')");

    String ccFlags =
        (String) getMyInfoFromTarget(getConfiguredTarget("//a:r")).getValue("cc_flags");

    assertThat(ccFlags).isEqualTo("-test-cflag1 -testcflag2");
  }

  private boolean toolchainResolutionEnabled() throws Exception {
    scratch.file(
        "a/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  toolchain_resolution_enabled = cc_common.is_cc_toolchain_resolution_enabled_do_not_use(",
        "      ctx = ctx)",
        "  return [MyInfo(",
        "    toolchain_resolution_enabled = toolchain_resolution_enabled)]",
        "toolchain_resolution_enabled = rule(",
        "  _impl,",
        ");");

    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'toolchain_resolution_enabled')",
        "toolchain_resolution_enabled(name='r')");

    ConfiguredTarget r = getConfiguredTarget("//a:r");
    // Use an extra variable in order to suppress the warning.
    boolean toolchainResolutionEnabled =
        (boolean) getMyInfoFromTarget(r).getValue("toolchain_resolution_enabled");
    return toolchainResolutionEnabled;
  }

  @Test
  public void testIsToolchainResolutionEnabled_disabled() throws Exception {
    useConfiguration("--incompatible_enable_cc_toolchain_resolution=false");

    assertThat(toolchainResolutionEnabled()).isFalse();
  }

  @Test
  public void testIsToolchainResolutionEnabled_enabled() throws Exception {
    useConfiguration("--incompatible_enable_cc_toolchain_resolution");

    assertThat(toolchainResolutionEnabled()).isTrue();
  }

  @Test
  public void testWrongExtensionThrowsError() throws Exception {
    setUpCcLinkingContextTest(false);
    scratch.file(
        "foo/BUILD",
        "load('//tools/build_defs/cc:rule.bzl', 'crule')",
        "cc_binary(name='bin',",
        "   deps = [':a'],",
        ")",
        "crule(name='a',",
        "   static_library = 'a.o',",
        "   pic_static_library = 'a.pic.o',",
        "   dynamic_library = 'a.ifso',",
        "   interface_library = 'a.so',",
        "   dynamic_library_symlink_path = 'a.lib',",
        "   interface_library_symlink_path = 'a.dll',",
        ")");
    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:bin"));
    assertThat(e)
        .hasMessageThat()
        .contains("'a.o' does not have any of the allowed extensions .a, .lib or .pic.a");
    assertThat(e)
        .hasMessageThat()
        .contains("'a.pic.o' does not have any of the allowed extensions .a, .lib or .pic.a");
    assertThat(e)
        .hasMessageThat()
        .contains("'a.ifso' does not have any of the allowed extensions .so, .dylib or .dll");
    assertThat(e)
        .hasMessageThat()
        .contains("'a.so' does not have any of the allowed extensions .ifso, .tbd or .lib");
    assertThat(e)
        .hasMessageThat()
        .contains("'a.lib' does not have any of the allowed extensions .so, .dylib or .dll");
    assertThat(e)
        .hasMessageThat()
        .contains("'a.dll' does not have any of the allowed extensions .ifso, .tbd or .lib");
  }

  @Test
  public void testCcOutputsMerging() throws Exception {
    setupCcOutputsTest();
    scratch.file(
        "foo/BUILD",
        "load('//tools/build_defs/foo:extension.bzl', 'cc_starlark_library')",
        "cc_starlark_library(",
        "    name = 'starlark_lib',",
        "    object1 = 'object1.o',",
        "    pic_object1 = 'pic_object1.o',",
        "    object2 = 'object2.o',",
        "    pic_object2 = 'pic_object2.o',",
        ")");
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    CcCompilationOutputs compilationOutputs =
        (CcCompilationOutputs) getMyInfoFromTarget(target).getValue("compilation_outputs");
    assertThat(
            AnalysisTestUtil.artifactsToStrings(
                masterConfig, compilationOutputs.getObjectFiles(/* usePic= */ true)))
        .containsExactly("src foo/pic_object1.o", "src foo/pic_object2.o");
    assertThat(
            AnalysisTestUtil.artifactsToStrings(
                masterConfig, compilationOutputs.getObjectFiles(/* usePic= */ false)))
        .containsExactly("src foo/object1.o", "src foo/object2.o");
  }

  @Test
  public void testObjectsWrongExtension() throws Exception {
    doTestCcOutputsWrongExtension("object1", "objects");
  }

  @Test
  public void testPicObjectsWrongExtension() throws Exception {
    doTestCcOutputsWrongExtension("pic_object1", "pic_objects");
  }

  @Test
  public void testObjectsRightExtension() throws Exception {
    doTestCcOutputsRightExtension("object1");
  }

  @Test
  public void testPicObjectsRightExtension() throws Exception {
    doTestCcOutputsRightExtension("pic_object1");
  }

  @Test
  public void testCreateOnlyPic() throws Exception {
    getAnalysisMock()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig, CcToolchainConfig.builder().withFeatures(CppRuleClasses.SUPPORTS_PIC));
    createFilesForTestingCompilation(
        scratch, "tools/build_defs/foo", String.join("", "disallow_nopic_outputs=True"));
    assertThat(getConfiguredTarget("//foo:bin")).isNotNull();
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(getFilenamesToBuild(target)).doesNotContain("starlark_lib.o");
    assertThat(getFilenamesToBuild(target)).contains("starlark_lib.pic.o");
  }

  @Test
  public void testCreateOnlyNoPic() throws Exception {
    createFilesForTestingCompilation(
        scratch, "tools/build_defs/foo", String.join("", "disallow_pic_outputs=True"));
    assertThat(getConfiguredTarget("//foo:bin")).isNotNull();
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(getFilenamesToBuild(target)).contains("starlark_lib.o");
    assertThat(getFilenamesToBuild(target)).doesNotContain("starlark_lib.pic.o");
  }

  @Test
  public void testCreatePicAndNoPic() throws Exception {
    getAnalysisMock()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig, CcToolchainConfig.builder().withFeatures(CppRuleClasses.SUPPORTS_PIC));
    createFilesForTestingCompilation(scratch, "tools/build_defs/foo", "");
    useConfiguration("--compilation_mode=opt");
    assertThat(getConfiguredTarget("//foo:bin")).isNotNull();
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(getFilenamesToBuild(target)).contains("starlark_lib.pic.o");
    assertThat(getFilenamesToBuild(target)).contains("starlark_lib.o");
  }

  @Test
  public void testDoNotCreateEitherPicOrNoPic() throws Exception {
    createFilesForTestingCompilation(
        scratch,
        "tools/build_defs/foo",
        String.join("", "disallow_nopic_outputs=True, disallow_pic_outputs=True"));
    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//foo:bin");
    assertContainsEvent("Either PIC or no PIC actions have to be created.");
  }

  @Test
  public void testCreateStaticLibraries() throws Exception {
    getAnalysisMock()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder()
                .withFeatures(CppRuleClasses.SUPPORTS_DYNAMIC_LINKER, CppRuleClasses.SUPPORTS_PIC));
    createFilesForTestingLinking(scratch, "tools/build_defs/foo", /* linkProviderLines= */ "");
    assertThat(getConfiguredTarget("//foo:starlark_lib")).isNotNull();
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(
            getFilesToBuild(target).toList().stream()
                .map(x -> x.getFilename())
                .collect(ImmutableList.toImmutableList()))
        .contains("libstarlark_lib.a");
  }

  @Test
  public void testDoNotCreateStaticLibraries() throws Exception {
    createFilesForTestingLinking(scratch, "tools/build_defs/foo", "disallow_static_libraries=True");
    assertThat(getConfiguredTarget("//foo:starlark_lib")).isNotNull();
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(
            getFilesToBuild(target).toList().stream()
                .map(x -> x.getFilename())
                .collect(ImmutableList.toImmutableList()))
        .doesNotContain("libstarlark_lib.a");
  }

  private List<String> getFilenamesToBuild(ConfiguredTarget target) {
    return getFilesToBuild(target).toList().stream()
        .map(Artifact::getFilename)
        .collect(ImmutableList.toImmutableList());
  }

  @Test
  public void testCcNativeRuleDependingOnStarlarkDefinedRule() throws Exception {
    createFiles(scratch, "tools/build_defs/cc");
    assertThat(getConfiguredTarget("//foo:bin")).isNotNull();
  }

  @Test
  public void testUserCompileFlagsInRulesApi() throws Exception {
    createFilesForTestingCompilation(
        scratch, "tools/build_defs/foo", "user_compile_flags=['-COMPILATION_OPTION']");
    assertThat(getConfiguredTarget("//foo:bin")).isNotNull();
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    CppCompileAction action =
        (CppCompileAction) getGeneratingAction(artifactByPath(getFilesToBuild(target), ".o"));
    assertThat(action.getArguments()).contains("-COMPILATION_OPTION");
  }

  @Test
  public void testIncludeDirs() throws Exception {
    createFilesForTestingCompilation(
        scratch, "tools/build_defs/foo", "includes=['foo/bar', 'baz/qux']");
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(target).isNotNull();
    CppCompileAction action =
        (CppCompileAction) getGeneratingAction(artifactByPath(getFilesToBuild(target), ".o"));
    assertThat(action.getArguments()).containsAtLeast("-Ifoo/bar", "-Ibaz/qux");
  }

  @Test
  public void testSystemIncludeDirs() throws Exception {
    createFilesForTestingCompilation(
        scratch, "tools/build_defs/foo", "system_includes=['foo/bar', 'baz/qux']");
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(target).isNotNull();
    CppCompileAction action =
        (CppCompileAction) getGeneratingAction(artifactByPath(getFilesToBuild(target), ".o"));
    assertThat(action.getArguments())
        .containsAtLeast("-isystem", "foo/bar", "-isystem", "baz/qux")
        .inOrder();
  }

  @Test
  public void testQuoteIncludeDirs() throws Exception {
    createFilesForTestingCompilation(
        scratch, "tools/build_defs/foo", "quote_includes=['foo/bar', 'baz/qux']");
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(target).isNotNull();
    CppCompileAction action =
        (CppCompileAction) getGeneratingAction(artifactByPath(getFilesToBuild(target), ".o"));
    assertThat(action.getArguments())
        .containsAtLeast("-iquote", "foo/bar", "-iquote", "baz/qux")
        .inOrder();
  }

  @Test
  public void testFrameworkIncludeDirs() throws Exception {
    createFilesForTestingCompilation(
        scratch, "tools/build_defs/foo", "framework_includes=['foo/bar', 'baz/qux']");
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(target).isNotNull();
    CppCompileAction action =
        (CppCompileAction) getGeneratingAction(artifactByPath(getFilesToBuild(target), ".o"));
    assertThat(action.getArguments()).containsAtLeast("-Ffoo/bar", "-Fbaz/qux").inOrder();
  }

  @Test
  public void testDefines() throws Exception {
    createFilesForTestingCompilation(
        scratch, "tools/build_defs/foo", "defines=['DEFINE1', 'DEFINE2']");
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(target).isNotNull();
    CppCompileAction action =
        (CppCompileAction) getGeneratingAction(artifactByPath(getFilesToBuild(target), ".o"));
    assertThat(action.getArguments()).containsAtLeast("-DDEFINE1", "-DDEFINE2");
  }

  @Test
  public void testLocalDefines() throws Exception {
    createFilesForTestingCompilation(
        scratch, "tools/build_defs/foo", "local_defines=['DEFINE1', 'DEFINE2']");
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(target).isNotNull();
    CppCompileAction action =
        (CppCompileAction) getGeneratingAction(artifactByPath(getFilesToBuild(target), ".o"));
    assertThat(action.getArguments()).containsAtLeast("-DDEFINE1", "-DDEFINE2");
  }

  @Test
  public void testIncludePrefix() throws Exception {
    createFilesForTestingCompilation(
        scratch, "third_party/tools/build_defs/foo", "include_prefix='prefix'");
    scratch.file(
        "bar/BUILD",
        "load('//third_party/tools/build_defs/foo:extension.bzl', 'cc_starlark_library')",
        "cc_starlark_library(",
        "    name = 'starlark_lib',",
        "    srcs = ['starlark_lib.cc'],",
        "    public_hdrs = ['starlark_lib.h'],",
        "    private_hdrs = ['private_starlark_lib.h'],",
        ")");
    ConfiguredTarget target = getConfiguredTarget("//bar:starlark_lib");
    assertThat(target).isNotNull();
    CcInfo ccInfo = target.get(CcInfo.PROVIDER);
    assertThat(artifactsToStrings(ccInfo.getCcCompilationContext().getDirectPublicHdrs()))
        .contains("bin bar/_virtual_includes/starlark_lib/prefix/starlark_lib.h");
  }

  @Test
  public void testStripIncludePrefix() throws Exception {
    createFilesForTestingCompilation(
        scratch, "third_party/tools/build_defs/foo", "strip_include_prefix='v1'");
    scratch.file(
        "bar/BUILD",
        "load('//third_party/tools/build_defs/foo:extension.bzl', 'cc_starlark_library')",
        "cc_starlark_library(",
        "    name = 'starlark_lib',",
        "    srcs = ['starlark_lib.cc'],",
        "    public_hdrs = ['v1/starlark_lib.h'],",
        "    private_hdrs = ['v1/private_starlark_lib.h'],",
        ")");
    ConfiguredTarget target = getConfiguredTarget("//bar:starlark_lib");
    assertThat(target).isNotNull();
    CcInfo ccInfo = target.get(CcInfo.PROVIDER);
    assertThat(artifactsToStrings(ccInfo.getCcCompilationContext().getDirectPublicHdrs()))
        .contains("bin bar/_virtual_includes/starlark_lib/starlark_lib.h");
  }

  @Test
  public void testStripIncludePrefixAndIncludePrefix() throws Exception {
    createFilesForTestingCompilation(
        scratch,
        "third_party/tools/build_defs/foo",
        "strip_include_prefix='v1', include_prefix='prefix'");
    scratch.file(
        "bar/BUILD",
        "load('//third_party/tools/build_defs/foo:extension.bzl', 'cc_starlark_library')",
        "cc_starlark_library(",
        "    name = 'starlark_lib',",
        "    srcs = ['starlark_lib.cc'],",
        "    public_hdrs = ['v1/starlark_lib.h'],",
        "    private_hdrs = ['v1/private_starlark_lib.h'],",
        ")");
    ConfiguredTarget target = getConfiguredTarget("//bar:starlark_lib");
    assertThat(target).isNotNull();
    CcInfo ccInfo = target.get(CcInfo.PROVIDER);
    assertThat(artifactsToStrings(ccInfo.getCcCompilationContext().getDirectPublicHdrs()))
        .contains("bin bar/_virtual_includes/starlark_lib/prefix/starlark_lib.h");
  }

  @Test
  public void testHeaders() throws Exception {
    createFilesForTestingCompilation(
        scratch, "tools/build_defs/foo", /* compileProviderLines= */ "");
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(target).isNotNull();
    CcInfo ccInfo = target.get(CcInfo.PROVIDER);
    assertThat(artifactsToStrings(ccInfo.getCcCompilationContext().getDeclaredIncludeSrcs()))
        .containsAtLeast(
            "src foo/dep2.h", "src foo/starlark_lib.h", "src foo/private_starlark_lib.h");
  }

  @Test
  public void testCompileOutputHasSuffix() throws Exception {
    createFilesForTestingCompilation(
        scratch, "tools/build_defs/foo", /* compileProviderLines= */ "");
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(target).isNotNull();
    assertThat(artifactsToStrings(getFilesToBuild(target)))
        .contains("bin foo/_objs/starlark_lib_suffix/starlark_lib.o");
  }

  @Test
  public void testCompilationContexts() throws Exception {
    createFilesForTestingCompilation(
        scratch, "tools/build_defs/foo", /* compileProviderLines= */ "");
    assertThat(getConfiguredTarget("//foo:bin")).isNotNull();
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    CppCompileAction action =
        (CppCompileAction) getGeneratingAction(artifactByPath(getFilesToBuild(target), ".o"));
    assertThat(action.getArguments()).containsAtLeast("-DDEFINE_DEP1", "-DDEFINE_DEP2");
  }

  @Test
  public void testLinkingOutputs() throws Exception {
    createFiles(scratch, "tools/build_defs/foo");
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(target).isNotNull();
    @SuppressWarnings("unchecked")
    Sequence<LibraryToLink> libraries =
        (Sequence<LibraryToLink>) getMyInfoFromTarget(target).getValue("libraries");
    assertThat(
            libraries.stream()
                .map(x -> x.getResolvedSymlinkDynamicLibrary().getFilename())
                .collect(ImmutableList.toImmutableList()))
        .contains("libstarlark_lib.so");
  }

  @Test
  public void testUserLinkFlags() throws Exception {
    createFilesForTestingLinking(
        scratch, "tools/build_defs/foo", "user_link_flags=['-LINKING_OPTION']");
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(target).isNotNull();
    assertThat(target.get(CcInfo.PROVIDER).getCcLinkingContext().getFlattenedUserLinkFlags())
        .contains("-LINKING_OPTION");
  }

  @Test
  public void testLinkingContexts() throws Exception {
    createFilesForTestingLinking(scratch, "tools/build_defs/foo", /* linkProviderLines= */ "");
    assertThat(getConfiguredTarget("//foo:bin")).isNotNull();
    ConfiguredTarget target = getConfiguredTarget("//foo:bin");
    CppLinkAction action =
        (CppLinkAction) getGeneratingAction(artifactByPath(getFilesToBuild(target), "bin"));
    assertThat(action.getArguments()).containsAtLeast("-DEP1_LINKOPT", "-DEP2_LINKOPT");
  }

  @Test
  public void testAlwayslinkTrue() throws Exception {
    createFilesForTestingLinking(scratch, "tools/build_defs/foo", "alwayslink=True");
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(target).isNotNull();
    assertThat(
            target.get(CcInfo.PROVIDER).getCcLinkingContext().getLibraries().toList().stream()
                .filter(LibraryToLink::getAlwayslink)
                .collect(ImmutableList.toImmutableList()))
        .hasSize(1);
  }

  @Test
  public void testAlwayslinkFalse() throws Exception {
    createFilesForTestingLinking(scratch, "tools/build_defs/foo", "alwayslink=False");
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(target).isNotNull();
    assertThat(
            target.get(CcInfo.PROVIDER).getCcLinkingContext().getLibraries().toList().stream()
                .filter(LibraryToLink::getAlwayslink)
                .collect(ImmutableList.toImmutableList()))
        .isEmpty();
  }

  @Test
  public void testAdditionalLinkingInputs() throws Exception {
    createFilesForTestingLinking(
        scratch, "tools/build_defs/foo", "additional_inputs=ctx.files._additional_inputs");
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(target).isNotNull();
    assertThat(target.get(CcInfo.PROVIDER).getCcLinkingContext().getNonCodeInputs().toList())
        .hasSize(1);
  }

  @Test
  public void testAdditionalCompilationInputs() throws Exception {
    createFilesForTestingCompilation(
        scratch, "tools/build_defs/foo", "additional_inputs=ctx.files._additional_compiler_inputs");
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(target).isNotNull();
    CppCompileAction action =
        (CppCompileAction) getGeneratingAction(artifactByPath(getFilesToBuild(target), ".o"));
    assertThat(artifactsToStrings(action.getMandatoryInputs()))
        .contains("src foo/extra_compiler_input");
  }

  @Test
  public void testPossibleSrcsExtensions() throws Exception {
    doTestPossibleExtensionsOfSrcsAndHdrs(
        "srcs", CppFileTypes.ALL_C_CLASS_SOURCE.including(CppFileTypes.ASSEMBLER).getExtensions());
  }

  @Test
  public void testPossiblePrivateHdrExtensions() throws Exception {
    doTestPossibleExtensionsOfSrcsAndHdrs("private_hdrs", CppFileTypes.CPP_HEADER.getExtensions());
  }

  @Test
  public void testPossiblePublicHdrExtensions() throws Exception {
    doTestPossibleExtensionsOfSrcsAndHdrs("public_hdrs", CppFileTypes.CPP_HEADER.getExtensions());
  }

  @Test
  public void testWrongSrcsExtensionGivesError() throws Exception {
    doTestWrongExtensionOfSrcsAndHdrs("srcs");
  }

  @Test
  public void testWrongPrivateHdrExtensionGivesError() throws Exception {
    doTestWrongExtensionOfSrcsAndHdrs("private_hdrs");
  }

  @Test
  public void testWrongPublicHdrExtensionGivesError() throws Exception {
    doTestWrongExtensionOfSrcsAndHdrs("public_hdrs");
  }

  @Test
  public void testWrongSrcExtensionGivesError() throws Exception {
    createFiles(scratch, "tools/build_defs/foo");

    scratch.file(
        "bar/BUILD",
        "load('//tools/build_defs/foo:extension.bzl', 'cc_starlark_library')",
        "cc_starlark_library(",
        "    name = 'starlark_lib',",
        "    srcs = ['starlark_lib.qweqwe'],",
        ")");
    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//bar:starlark_lib");
    assertContainsEvent("The list of possible extensions for 'srcs'");
  }

  private static void createFilesForTestingCompilation(
      Scratch scratch, String bzlFilePath, String compileProviderLines) throws Exception {
    createFiles(scratch, bzlFilePath, compileProviderLines, "");
  }

  private static void createFilesForTestingLinking(
      Scratch scratch, String bzlFilePath, String linkProviderLines) throws Exception {
    createFiles(scratch, bzlFilePath, "", linkProviderLines);
  }

  private static void createFiles(Scratch scratch, String bzlFilePath) throws Exception {
    createFiles(scratch, bzlFilePath, "", "");
  }

  @Test
  public void testTransitiveLinkWithDeps() throws Exception {
    setupTestTransitiveLink(scratch, "linking_contexts = dep_linking_contexts");
    ConfiguredTarget target = getConfiguredTarget("//foo:bin");
    assertThat(target).isNotNull();
    Artifact executable = (Artifact) getMyInfoFromTarget(target).getValue("executable");
    assertThat(artifactsToStrings(getGeneratingAction(executable).getInputs()))
        .containsAtLeast("bin foo/libdep1.a", "bin foo/libdep2.a");
  }

  @Test
  public void testTransitiveLinkForDynamicLibrary() throws Exception {
    setupTestTransitiveLink(scratch, "output_type = 'dynamic_library'");
    ConfiguredTarget target = getConfiguredTarget("//foo:bin");
    assertThat(target).isNotNull();
    LibraryToLink library = (LibraryToLink) getMyInfoFromTarget(target).getValue("library");
    assertThat(library).isNotNull();
    Object executable = getMyInfoFromTarget(target).getValue("executable");
    assertThat(Starlark.isNullOrNone(executable)).isTrue();
  }

  @Test
  public void testInterfaceLibraryProducedForTransitiveLinkOnWindows() throws Exception {
    getAnalysisMock()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder()
                .withFeatures(
                    CppRuleClasses.SUPPORTS_DYNAMIC_LINKER,
                    CppRuleClasses.TARGETS_WINDOWS,
                    CppRuleClasses.SUPPORTS_INTERFACE_SHARED_LIBRARIES,
                    CppRuleClasses.COPY_DYNAMIC_LIBRARIES_TO_BINARY));
    setupTestTransitiveLink(scratch, "output_type = 'dynamic_library'");
    ConfiguredTarget target = getConfiguredTarget("//foo:bin");
    assertThat(target).isNotNull();
    LibraryToLink library = (LibraryToLink) getMyInfoFromTarget(target).getValue("library");
    assertThat(library).isNotNull();
    assertThat(library.getDynamicLibrary()).isNotNull();
    assertThat(library.getInterfaceLibrary()).isNotNull();
  }

  @Test
  public void testTransitiveLinkForExecutable() throws Exception {
    setupTestTransitiveLink(scratch, "output_type = 'executable'");
    ConfiguredTarget target = getConfiguredTarget("//foo:bin");
    assertThat(target).isNotNull();
    Artifact executable = (Artifact) getMyInfoFromTarget(target).getValue("executable");
    assertThat(executable).isNotNull();
    Object library = getMyInfoFromTarget(target).getValue("library");
    assertThat(Starlark.isNullOrNone(library)).isTrue();
  }

  @Test
  public void testPassGrepIncludesToApiEvenThoughItDoesntDoAnything() throws Exception {
    setupTestTransitiveLink(scratch, "grep_includes = ctx.executable._grep_includes");
    ConfiguredTarget target = getConfiguredTarget("//foo:bin");
    assertThat(target).isNotNull();
  }

  @Test
  public void testTransitiveLinkWithCompilationOutputs() throws Exception {
    setupTestTransitiveLink(scratch, "compilation_outputs=objects");
    ConfiguredTarget target = getConfiguredTarget("//foo:bin");
    assertThat(target).isNotNull();
    Artifact executable = (Artifact) getMyInfoFromTarget(target).getValue("executable");
    assertThat(artifactsToStrings(getGeneratingAction(executable).getInputs()))
        .contains("src foo/file.o");
  }

  @Test
  public void testLinkStampExpliciltyEnabledOverridesNoStampFlag() throws Exception {
    useConfiguration("--nostamp");
    setupTestTransitiveLink(scratch, "stamp=1", "linking_contexts=dep_linking_contexts");
    assertStampEnabled(getLinkstampCompileAction("//foo:bin"));
  }

  @Test
  public void testLinkExplicitlyDisabledOverridesStampFlag() throws Exception {
    useConfiguration("--nostamp");
    setupTestTransitiveLink(scratch, "stamp=0", "linking_contexts=dep_linking_contexts");
    assertStampDisabled(getLinkstampCompileAction("//foo:bin"));
  }

  @Test
  public void testLinkStampUseFlagStamp() throws Exception {
    useConfiguration("--stamp");
    setupTestTransitiveLink(scratch, "stamp=-1", "linking_contexts=dep_linking_contexts");
    assertStampEnabled(getLinkstampCompileAction("//foo:bin"));
  }

  @Test
  public void testLinkStampUseFlagNoStamp() throws Exception {
    useConfiguration("--nostamp");
    setupTestTransitiveLink(scratch, "stamp=-1", "linking_contexts=dep_linking_contexts");
    assertStampDisabled(getLinkstampCompileAction("//foo:bin"));
  }

  @Test
  public void testLinkStampDisabledByDefaultDespiteStampFlag() throws Exception {
    useConfiguration("--stamp");
    setupTestTransitiveLink(scratch, "linking_contexts=dep_linking_contexts");
    assertStampDisabled(getLinkstampCompileAction("//foo:bin"));
  }

  @Test
  public void testLinkStampInvalid() throws Exception {
    setupTestTransitiveLink(scratch, "stamp=2");
    checkError(
        "//foo:bin",
        "stamp value 2 is not supported, must be 0 (disabled), 1 (enabled), or -1 (default)");
  }

  private CppCompileAction getLinkstampCompileAction(String label)
      throws LabelSyntaxException, EvalException {
    ConfiguredTarget target = getConfiguredTarget(label);
    Artifact executable = (Artifact) getMyInfoFromTarget(target).getValue("executable");
    CppLinkAction generatingAction = (CppLinkAction) getGeneratingAction(executable);
    Artifact compiledLinkstamp =
        ActionsTestUtil.getFirstArtifactEndingWith(generatingAction.getInputs(), "version.o");
    CppCompileAction linkstampCompileAction =
        (CppCompileAction) getGeneratingAction(compiledLinkstamp);
    assertThat(linkstampCompileAction.getMnemonic()).isEqualTo("CppLinkstampCompile");
    return linkstampCompileAction;
  }

  private void assertStampEnabled(CppCompileAction linkstampAction)
      throws CommandLineExpansionException {
    assertThat(linkstampAction.getArguments())
        .contains(getRelativeOutputPath() + "/k8-fastbuild/include/build-info-volatile.h");
  }

  private void assertStampDisabled(CppCompileAction linkstampAction)
      throws CommandLineExpansionException {
    assertThat(linkstampAction.getArguments())
        .contains(getRelativeOutputPath() + "/k8-fastbuild/include/build-info-redacted.h");
  }

  @Test
  public void testApiWithAspectsOnTargetsInExternalRepos() throws Exception {
    if (!AnalysisMock.get().isThisBazel()) {
      return;
    }
    createFilesForTestingCompilation(
        scratch, "tools/build_defs/foo", /* compileProviderLines= */ "");
    FileSystemUtils.appendIsoLatin1(
        scratch.resolve("WORKSPACE"), "local_repository(name='r', path='/r')");
    scratch.file("/r/WORKSPACE");
    scratch.file("/r/p/BUILD", "cc_library(", "    name = 'a',", "    srcs = ['a.cc'],", ")");
    invalidatePackages();
    scratch.file(
        "b/BUILD",
        "load('//tools/build_defs/foo:extension.bzl', 'cc_starlark_library')",
        "cc_starlark_library(",
        "    name = 'b',",
        "    srcs = ['b.cc'],",
        "    aspect_deps = ['@r//p:a']",
        ")");
    assertThat(getConfiguredTarget("//b:b")).isNotNull();
  }

  @Test
  public void testObjectsApi() throws Exception {
    useConfiguration("--compilation_mode=opt");
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder()
                .withFeatures(CppRuleClasses.SUPPORTS_PIC, CppRuleClasses.PIC));

    scratchObjectsProvidingRule();

    Provider.Key key =
        new StarlarkProvider.Key(
            Label.parseAbsolute("//foo:foo.bzl", ImmutableMap.of()), "FooInfo");
    LibraryToLink fooLibrary =
        Iterables.getOnlyElement(
            getConfiguredTarget("//foo:dep")
                .get(CcInfo.PROVIDER)
                .getCcLinkingContext()
                .getLibraries()
                .toList());
    StarlarkInfo fooInfo =
        (StarlarkInfo) getConfiguredTarget("//foo:foo").get(StarlarkProviderIdentifier.forKey(key));

    assertThat(fooLibrary.getObjectFiles()).isEqualTo(fooInfo.getValue("objects"));
    assertThat(fooLibrary.getPicObjectFiles()).isEqualTo(fooInfo.getValue("pic_objects"));
  }

  @Test
  public void testObjectsApiNeverReturningNones() throws Exception {
    scratchObjectsProvidingRule();

    Provider.Key key =
        new StarlarkProvider.Key(
            Label.parseAbsolute("//foo:foo.bzl", ImmutableMap.of()), "FooInfo");

    // Default toolchain is without PIC support, so pic_objects should be None
    StarlarkInfo fooInfoForPic =
        (StarlarkInfo) getConfiguredTarget("//foo:foo").get(StarlarkProviderIdentifier.forKey(key));

    Object picObjects = fooInfoForPic.getValue("pic_objects");
    assertThat(picObjects).isNotEqualTo(Starlark.NONE);
    assertThat((List) picObjects).isEmpty();

    // With PIC and the default compilation_mode which is fastbuild C++ rules only produce PIC
    // objects.
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder()
                .withFeatures(CppRuleClasses.SUPPORTS_PIC, CppRuleClasses.PIC));
    invalidatePackages();
    StarlarkInfo fooInfoForNoPic =
        (StarlarkInfo) getConfiguredTarget("//foo:foo").get(StarlarkProviderIdentifier.forKey(key));

    Object objects = fooInfoForNoPic.getValue("objects");
    assertThat(objects).isNotEqualTo(Starlark.NONE);
    assertThat((List) objects).isEmpty();
  }

  @Test
  public void testLtoBitcodeFilesApi() throws Exception {
    useConfiguration("--compilation_mode=opt", "--features=thin_lto");
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder()
                .withFeatures(
                    CppRuleClasses.THIN_LTO, CppRuleClasses.SUPPORTS_PIC, CppRuleClasses.PIC));

    scratchObjectsProvidingRule();

    Provider.Key key =
        new StarlarkProvider.Key(
            Label.parseAbsolute("//foo:foo.bzl", ImmutableMap.of()), "FooInfo");
    LibraryToLink fooLibrary =
        Iterables.getOnlyElement(
            getConfiguredTarget("//foo:dep")
                .get(CcInfo.PROVIDER)
                .getCcLinkingContext()
                .getLibraries()
                .toList());
    StarlarkInfo fooInfo =
        (StarlarkInfo) getConfiguredTarget("//foo:foo").get(StarlarkProviderIdentifier.forKey(key));

    assertThat(ImmutableList.copyOf(fooLibrary.getLtoCompilationContext().getBitcodeFiles()))
        .isEqualTo(fooInfo.getValue("lto_bitcode_files"));
    assertThat(fooLibrary.getLtoCompilationContext().getBitcodeFiles()).isNotEmpty();

    assertThat(ImmutableList.copyOf(fooLibrary.getPicLtoCompilationContext().getBitcodeFiles()))
        .isEqualTo(fooInfo.getValue("pic_lto_bitcode_files"));
    assertThat(fooLibrary.getPicLtoCompilationContext().getBitcodeFiles()).isNotEmpty();
  }

  @Test
  public void testLtoBitcodeFilesApiNeverReturningNones() throws Exception {
    // We do not add --features=thin_lto for this test.
    useConfiguration("--compilation_mode=opt");
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder()
                // We do not enable the THIN_LTO feature for this test.
                .withFeatures(CppRuleClasses.SUPPORTS_PIC, CppRuleClasses.PIC));

    scratchObjectsProvidingRule();

    Provider.Key key =
        new StarlarkProvider.Key(
            Label.parseAbsolute("//foo:foo.bzl", ImmutableMap.of()), "FooInfo");
    StarlarkInfo fooInfo =
        (StarlarkInfo) getConfiguredTarget("//foo:foo").get(StarlarkProviderIdentifier.forKey(key));

    Object picLtoBitcodeFiles = fooInfo.getValue("pic_lto_bitcode_files");
    assertThat(picLtoBitcodeFiles).isNotEqualTo(Starlark.NONE);
    assertThat((List) picLtoBitcodeFiles).isEmpty();

    Object ltoBitcodeFiles = fooInfo.getValue("lto_bitcode_files");
    assertThat(ltoBitcodeFiles).isNotEqualTo(Starlark.NONE);
    assertThat((List) ltoBitcodeFiles).isEmpty();
  }

  private void scratchObjectsProvidingRule() throws IOException {
    scratch.file(
        "foo/BUILD",
        "load(':foo.bzl', 'foo')",
        "foo(",
        "  name = 'foo',",
        "  dep = ':dep',",
        ")",
        "cc_library(",
        "  name = 'dep',",
        "  srcs = ['dep.cc'],",
        ")");
    scratch.file(
        "foo/foo.bzl",
        "FooInfo = provider(fields=['objects',"
            + " 'pic_objects','lto_bitcode_files','pic_lto_bitcode_files'])",
        "",
        "def _foo_impl(ctx):",
        "  lib = ctx.attr.dep[CcInfo].linking_context.linker_inputs.to_list()[0].libraries[0]",
        "  return [FooInfo(objects=lib.objects, pic_objects=lib.pic_objects,"
            + " lto_bitcode_files=lib.lto_bitcode_files,"
            + " pic_lto_bitcode_files=lib.pic_lto_bitcode_files)]",
        "",
        "foo = rule(",
        "  implementation = _foo_impl,",
        "  attrs = {",
        "    'dep': attr.label(),",
        "  }",
        ")");
  }

  private static void createFiles(
      Scratch scratch, String bzlFilePath, String compileProviderLines, String linkProviderLines)
      throws Exception {
    String fragments = "    fragments = ['google_cpp', 'cpp'],";
    if (AnalysisMock.get().isThisBazel()) {
      fragments = "    fragments = ['cpp'],";
    }
    scratch.overwriteFile(bzlFilePath + "/BUILD");
    scratch.file(
        bzlFilePath + "/extension.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _cc_aspect_impl(target, ctx):",
        "    toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "    feature_configuration = cc_common.configure_features(",
        "        ctx = ctx,",
        "        cc_toolchain = toolchain,",
        "        requested_features = ctx.features,",
        "        unsupported_features = ctx.disabled_features,",
        "    )",
        "    (compilation_context, compilation_outputs) = cc_common.compile(",
        "        actions = ctx.actions,",
        "        feature_configuration = feature_configuration,",
        "        cc_toolchain = toolchain,",
        "        name = ctx.label.name + '_aspect',",
        "        srcs = ctx.rule.files.srcs,",
        "        public_hdrs = ctx.rule.files.hdrs,",
        "    )",
        "    (linking_context, linking_outputs) = (",
        "        cc_common.create_linking_context_from_compilation_outputs(",
        "            actions = ctx.actions,",
        "            feature_configuration = feature_configuration,",
        "            name = ctx.label.name + '_aspect',",
        "            cc_toolchain = toolchain,",
        "            compilation_outputs = compilation_outputs,",
        "        )",
        "    )",
        "    return []",
        "_cc_aspect = aspect(",
        "    implementation = _cc_aspect_impl,",
        "    attrs = {",
        "        '_cc_toolchain': attr.label(default ="
            + " '@bazel_tools//tools/cpp:current_cc_toolchain'),",
        "    },",
        fragments,
        ")",
        "def _cc_starlark_library_impl(ctx):",
        "    dep_compilation_contexts = []",
        "    dep_linking_contexts = []",
        "    for dep in ctx.attr._deps:",
        "        dep_compilation_contexts.append(dep[CcInfo].compilation_context)",
        "        dep_linking_contexts.append(dep[CcInfo].linking_context)",
        "    toolchain = ctx.attr._my_cc_toolchain[cc_common.CcToolchainInfo]",
        "    feature_configuration = cc_common.configure_features(",
        "        ctx = ctx,",
        "        cc_toolchain=toolchain,",
        "        requested_features = ctx.features,",
        "        unsupported_features = ctx.disabled_features)",
        "    (compilation_context, compilation_outputs) = cc_common.compile(",
        "        actions=ctx.actions,",
        "        feature_configuration=feature_configuration,",
        "        cc_toolchain=toolchain,",
        "        srcs=ctx.files.srcs,",
        "        name=ctx.label.name + '_suffix',",
        "        compilation_contexts = dep_compilation_contexts,",
        "        public_hdrs=ctx.files.public_hdrs,",
        "        private_hdrs=ctx.files.private_hdrs" + (compileProviderLines.isEmpty() ? "" : ","),
        "        " + compileProviderLines,
        "    )",
        "    (linking_context,",
        "     linking_outputs) = cc_common.create_linking_context_from_compilation_outputs(",
        "        actions=ctx.actions,",
        "        feature_configuration=feature_configuration,",
        "        compilation_outputs=compilation_outputs,",
        "        name = ctx.label.name,",
        "        linking_contexts = dep_linking_contexts,",
        "        cc_toolchain=toolchain" + (linkProviderLines.isEmpty() ? "" : ","),
        "        " + linkProviderLines,
        "    )",
        "    files_to_build = []",
        "    files_to_build.extend(compilation_outputs.pic_objects)",
        "    files_to_build.extend(compilation_outputs.objects)",
        "    library_to_link = None",
        "    if len(ctx.files.srcs) > 0:",
        "        library_to_link = linking_outputs.library_to_link",
        "        if library_to_link.pic_static_library != None:",
        "            files_to_build.append(library_to_link.pic_static_library)",
        "        files_to_build.append(library_to_link.dynamic_library)",
        "    return [MyInfo(libraries=[library_to_link]),",
        "            DefaultInfo(files=depset(files_to_build)),",
        "            CcInfo(compilation_context=compilation_context,",
        "                   linking_context=linking_context)]",
        "cc_starlark_library = rule(",
        "    implementation = _cc_starlark_library_impl,",
        "    attrs = {",
        "      'srcs': attr.label_list(allow_files=True),",
        "      'public_hdrs': attr.label_list(allow_files=True),",
        "      'private_hdrs': attr.label_list(allow_files=True),",
        "      '_additional_inputs': attr.label_list(allow_files=True,"
            + " default=['//foo:script.lds']),",
        "      '_additional_compiler_inputs': attr.label_list(allow_files=True,"
            + " default=['//foo:extra_compiler_input']),",
        "      '_deps': attr.label_list(default=['//foo:dep1', '//foo:dep2']),",
        "      'aspect_deps': attr.label_list(aspects=[_cc_aspect]),",
        "      '_my_cc_toolchain': attr.label(default =",
        "          configuration_field(fragment = 'cpp', name = 'cc_toolchain'))",
        "    },",
        fragments,
        ")");
    scratch.file(
        "foo/BUILD",
        "load('//" + bzlFilePath + ":extension.bzl', 'cc_starlark_library')",
        "cc_library(",
        "    name = 'dep1',",
        "    srcs = ['dep1.cc'],",
        "    hdrs = ['dep1.h'],",
        "    defines = ['DEFINE_DEP1'],",
        "    linkopts = ['-DEP1_LINKOPT'],",
        ")",
        "cc_library(",
        "    name = 'dep2',",
        "    srcs = ['dep2.cc'],",
        "    hdrs = ['dep2.h'],",
        "    defines = ['DEFINE_DEP2'],",
        "    linkopts = ['-DEP2_LINKOPT'],",
        ")",
        "cc_starlark_library(",
        "    name = 'starlark_lib',",
        "    srcs = ['starlark_lib.cc'],",
        "    public_hdrs = ['starlark_lib.h'],",
        "    private_hdrs = ['private_starlark_lib.h'],",
        ")",
        "cc_binary(",
        "    name = 'bin',",
        "    deps = ['starlark_lib'],",
        ")");
  }

  private void doTestWrongExtensionOfSrcsAndHdrs(String attrName) throws Exception {
    createFiles(scratch, "tools/build_defs/foo");
    scratch.file(
        "bar/BUILD",
        "load('//tools/build_defs/foo:extension.bzl', 'cc_starlark_library')",
        "cc_starlark_library(",
        "    name = 'starlark_lib',",
        "    " + attrName + " = ['starlark_lib.cannotpossiblybevalid'],",
        ")");
    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//bar:starlark_lib");
    assertContainsEvent(
        "has wrong extension. The list of possible extensions for '" + attrName + "'");
  }

  private void doTestPossibleExtensionsOfSrcsAndHdrs(String attrName, List<String> extensions)
      throws Exception {
    createFiles(scratch, "tools/build_defs/foo");
    reporter.removeHandler(failFastHandler);

    for (String extension : extensions) {
      scratch.deleteFile("bar/BUILD");
      scratch.file(
          "bar/BUILD",
          "load('//tools/build_defs/foo:extension.bzl', 'cc_starlark_library')",
          "cc_starlark_library(",
          "    name = 'starlark_lib',",
          "    " + attrName + " = ['file" + extension + "'],",
          ")");
      getConfiguredTarget("//bar:starlark_lib");
      assertNoEvents();
    }
  }

  private void doTestCcOutputsWrongExtension(String attrName, String paramName) throws Exception {
    setupCcOutputsTest();
    scratch.file(
        "foo/BUILD",
        "load('//tools/build_defs/foo:extension.bzl', 'cc_starlark_library')",
        "cc_starlark_library(",
        "    name = 'starlark_lib',",
        "    " + attrName + " = 'object.cannotpossiblybevalid',",
        ")");
    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//foo:starlark_lib");
    assertContainsEvent(
        "has wrong extension. The list of possible extensions for '" + paramName + "'");
  }

  private void doTestCcOutputsRightExtension(String paramName) throws Exception {
    setupCcOutputsTest();
    reporter.removeHandler(failFastHandler);

    for (String extension : Link.OBJECT_FILETYPES.getExtensions()) {
      scratch.deleteFile("foo/BUILD");
      scratch.file(
          "foo/BUILD",
          "load('//tools/build_defs/foo:extension.bzl', 'cc_starlark_library')",
          "cc_starlark_library(",
          "    name = 'starlark_lib',",
          "    " + paramName + " = 'object1" + extension + "',",
          ")");
      getConfiguredTarget("//foo:starlark_lib");
      assertNoEvents();
    }
  }

  private void setupCcOutputsTest() throws Exception {
    scratch.overwriteFile("tools/build_defs/foo/BUILD");
    scratch.file(
        "tools/build_defs/foo/extension.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _cc_starlark_library_impl(ctx):",
        "    objects = []",
        "    pic_objects = []",
        "    if ctx.file.object1 != None:",
        "        objects.append(ctx.file.object1)",
        "    if ctx.file.pic_object1 != None:",
        "        pic_objects.append(ctx.file.pic_object1)",
        "    c1 = cc_common.create_compilation_outputs(objects=depset(objects),",
        "        pic_objects=depset(pic_objects))",
        "    objects = []",
        "    pic_objects = []",
        "    if ctx.file.object2 != None:",
        "        objects.append(ctx.file.object2)",
        "    if ctx.file.pic_object2 != None:",
        "        pic_objects.append(ctx.file.pic_object2)",
        "    c2 = cc_common.create_compilation_outputs(objects=depset(objects),",
        "        pic_objects=depset(pic_objects))",
        "    compilation_outputs = cc_common.merge_compilation_outputs(",
        "        compilation_outputs=[c1, c2])",
        "    return [MyInfo(compilation_outputs=compilation_outputs)]",
        "cc_starlark_library = rule(",
        "    implementation = _cc_starlark_library_impl,",
        "    attrs = {",
        "      'object1': attr.label(allow_single_file=True),",
        "      'pic_object1': attr.label(allow_single_file=True),",
        "      'object2': attr.label(allow_single_file=True),",
        "      'pic_object2': attr.label(allow_single_file=True),",
        "    },",
        ")");
  }

  private static void createCcBinRule(Scratch scratch, String... additionalLines) throws Exception {
    String fragments = "    fragments = ['google_cpp', 'cpp'],";
    if (AnalysisMock.get().isThisBazel()) {
      fragments = "    fragments = ['cpp'],";
    }
    scratch.overwriteFile("tools/build_defs/BUILD");
    /*scratch.overwriteFile("tools/cpp/grep-includes");*/
    scratch.overwriteFile("tools/cpp/grep_includes/grep-includes.sh");
    scratch.appendFile(
        "tools/cpp/grep_includes/BUILD",
        "sh_binary(",
        "    name = 'grep-includes',",
        "    srcs = ['grep-includes.sh'],",
        ")");
    scratch.file(
        "tools/build_defs/extension.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _cc_bin_impl(ctx):",
        "    toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "    feature_configuration = cc_common.configure_features(",
        "      ctx = ctx,",
        "      cc_toolchain = toolchain,",
        "    )",
        "    dep_linking_contexts = []",
        "    for dep in ctx.attr.deps:",
        "        dep_linking_contexts.append(dep[CcInfo].linking_context)",
        "    objects = cc_common.create_compilation_outputs(objects=depset(ctx.files.objects),",
        "        pic_objects=depset(ctx.files.pic_objects))",
        "    linking_outputs = cc_common.link(",
        "        actions=ctx.actions,",
        "        feature_configuration=feature_configuration,",
        "        name = ctx.label.name,",
        "        cc_toolchain=toolchain,",
        "        " + Joiner.on(",\n        ").join(additionalLines),
        "    )",
        "    return [",
        "      MyInfo(",
        "          library=linking_outputs.library_to_link,",
        "          executable=linking_outputs.executable",
        "      ),",
        "    ]",
        "cc_bin = rule(",
        "    implementation = _cc_bin_impl,",
        "    attrs = {",
        "      'objects': attr.label_list(allow_files=True),",
        "      'pic_objects': attr.label_list(allow_files=True),",
        "      'deps': attr.label_list(),",
        "      '_cc_toolchain': attr.label(default =",
        "          configuration_field(fragment = 'cpp', name = 'cc_toolchain')),",
        "      '_grep_includes': attr.label(",
        "             executable = True,",
        "             default = Label('//tools/cpp/grep_includes:grep-includes'),",
        "             cfg = 'host'",
        "       ),",
        "      'additional_outputs': attr.output_list(),",
        "    },",
        fragments,
        ")");
  }

  private static void setupTestTransitiveLink(Scratch scratch, String... additionalLines)
      throws Exception {
    createCcBinRule(scratch, additionalLines);
    scratch.file(
        "foo/BUILD",
        "load('//tools/build_defs:extension.bzl', 'cc_bin')",
        "cc_library(",
        "    name = 'dep1',",
        "    srcs = ['dep1.cc'],",
        "    linkstamp = 'version.cc',",
        "    hdrs = ['dep1.h'],",
        "    includes = ['dep1/baz'],",
        "    defines = ['DEP1'],",
        ")",
        "cc_library(",
        "    name = 'dep2',",
        "    srcs = ['dep2.cc'],",
        "    hdrs = ['dep2.h'],",
        "    includes = ['dep2/qux'],",
        "    defines = ['DEP2'],",
        ")",
        "cc_bin(",
        "    name = 'bin',",
        "    objects = ['file.o'],",
        "    pic_objects = ['file.pic.o'],",
        "    deps = [':dep1', ':dep2'],",
        ")");
  }

  private static void setupDirectHeaderExtractionSupport(Scratch scratch) throws Exception {
    scratch.file(
        "direct/cc_info_extractor.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _cc_info_extractor_impl(ctx):",
        "    compilation_context = ctx.attr.dep[CcInfo].compilation_context",
        "    return [MyInfo(",
        "        direct_headers = compilation_context.direct_headers,",
        "        direct_public_headers = compilation_context.direct_public_headers,",
        "        direct_private_headers = compilation_context.direct_private_headers,",
        "        direct_textual_headers = compilation_context.direct_textual_headers,",
        "    )]",
        "cc_info_extractor = rule(",
        "    _cc_info_extractor_impl,",
        "    attrs = {",
        "        'dep': attr.label(providers = [[CcInfo]]),",
        "    }",
        ")");
    scratch.file(
        "direct/BUILD",
        "load('//direct:cc_info_extractor.bzl', 'cc_info_extractor')",
        "cc_info_extractor(",
        "    name = 'foo',",
        "    dep = '//direct/libs:foo_lib',",
        ")",
        "cc_info_extractor(",
        "    name = 'bar',",
        "    dep = '//direct/libs:bar_lib',",
        ")");
  }

  private static void setupCcLibraryDirectPropagationTestTargets(Scratch scratch) throws Exception {
    scratch.file(
        "direct/libs/BUILD",
        "cc_library(",
        "    name = 'foo_lib',",
        "    srcs = ['foo.cc', 'foo_impl.h'],",
        "    hdrs = ['foo.h'],",
        "    textual_hdrs = ['foo.def'],",
        ")",
        "cc_library(",
        "    name = 'bar_lib',",
        "    hdrs = ['bar.h'],",
        "    textual_hdrs = ['bar.def'],",
        "    deps = [':foo_lib'],",
        ")");
  }

  @Test
  public void testCcLibraryPropagatesCcInfoWithDirectHeaders() throws Exception {
    setupDirectHeaderExtractionSupport(scratch);
    setupCcLibraryDirectPropagationTestTargets(scratch);

    ConfiguredTarget fooTarget = getConfiguredTarget("//direct:foo");
    Iterable<Artifact> fooDirectHeaders = getArtifactsFromMyInfo(fooTarget, "direct_headers");
    assertThat(baseArtifactNames(fooDirectHeaders)).containsExactly("foo.h", "foo_impl.h");

    Iterable<Artifact> fooDirectPublicHeaders =
        getArtifactsFromMyInfo(fooTarget, "direct_public_headers");
    assertThat(baseArtifactNames(fooDirectPublicHeaders)).containsExactly("foo.h");

    Iterable<Artifact> fooDirectPrivateHeaders =
        getArtifactsFromMyInfo(fooTarget, "direct_private_headers");
    assertThat(baseArtifactNames(fooDirectPrivateHeaders)).containsExactly("foo_impl.h");

    ConfiguredTarget barTarget = getConfiguredTarget("//direct:bar");
    Iterable<Artifact> barDirectHeaders = getArtifactsFromMyInfo(barTarget, "direct_headers");
    assertThat(baseArtifactNames(barDirectHeaders)).containsExactly("bar.h");

    Iterable<Artifact> barDirectPublicHeaders =
        getArtifactsFromMyInfo(barTarget, "direct_public_headers");
    assertThat(baseArtifactNames(barDirectPublicHeaders)).containsExactly("bar.h");

    Iterable<Artifact> barDirectPrivateHeaders =
        getArtifactsFromMyInfo(barTarget, "direct_private_headers");
    assertThat(barDirectPrivateHeaders).isEmpty();
  }

  @Test
  public void testCcLibraryPropagatesCcInfoWithDirectTextualHeaders() throws Exception {
    setupDirectHeaderExtractionSupport(scratch);
    setupCcLibraryDirectPropagationTestTargets(scratch);

    ConfiguredTarget fooTarget = getConfiguredTarget("//direct:foo");
    Iterable<Artifact> fooDirectTextualHeaders =
        getArtifactsFromMyInfo(fooTarget, "direct_textual_headers");
    assertThat(baseArtifactNames(fooDirectTextualHeaders)).containsExactly("foo.def");

    ConfiguredTarget barTarget = getConfiguredTarget("//direct:bar");
    Iterable<Artifact> barDirectTextualHeaders =
        getArtifactsFromMyInfo(barTarget, "direct_textual_headers");
    assertThat(baseArtifactNames(barDirectTextualHeaders)).containsExactly("bar.def");
  }

  /** Fixes #10580 */
  @Test
  public void testMixedLinkerInputsWithOwnerAndWithout() throws Exception {
    setBuildLanguageOptions("--noincompatible_require_linker_input_cc_api");
    setUpCcLinkingContextTest(false);
    scratch.file("foo/BUILD", "load(':rule.bzl', 'crule')", "crule(name='a')");
    scratch.file(
        "foo/rule.bzl",
        "load('//myinfo:myinfo.bzl', 'MyInfo')",
        "def _impl(ctx):",
        "  linker_input = cc_common.create_linker_input(owner=ctx.label)",
        "  linking_context = cc_common.create_linking_context(",
        "     linker_inputs=depset([linker_input]))",
        "  linking_context = cc_common.create_linking_context(",
        "     libraries_to_link=[],)",
        "  cc_info = CcInfo(linking_context=linking_context)",
        "  if cc_info.linking_context.linker_inputs.to_list()[0] == linker_input:",
        "     pass",
        "  return [cc_info]",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "  },",
        "  fragments = ['cpp'],",
        ");");

    assertThat(getConfiguredTarget("//foo:a")).isNotNull();
    assertNoEvents();
  }

  @Test
  public void testMergeCcInfosWithDirects() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder().withFeatures(MockCcSupport.HEADER_MODULES_FEATURES));

    scratch.file(
        "direct/cc_merger.bzl",
        "def _cc_merger_impl(ctx):",
        "    direct_cc_infos = [dep[CcInfo] for dep in ctx.attr.exports]",
        "    cc_infos = [dep[CcInfo] for dep in ctx.attr.deps]",
        "    return [cc_common.merge_cc_infos(",
        "        direct_cc_infos = direct_cc_infos,",
        "        cc_infos = cc_infos,",
        "    )]",
        "cc_merger = rule(",
        "    _cc_merger_impl,",
        "    attrs = {",
        "        'deps': attr.label_list(providers = [[CcInfo]]),",
        "        'exports': attr.label_list(providers = [[CcInfo]]),",
        "    }",
        ")");
    scratch.file(
        "direct/BUILD",
        "load('//direct:cc_merger.bzl', 'cc_merger')",
        "cc_library(",
        "    name = 'public1',",
        "    srcs = ['public1.cc', 'public1_impl.h'],",
        "    hdrs = ['public1.h'],",
        "    textual_hdrs = ['public1.inc'],",
        ")",
        "cc_library(",
        "    name = 'public2',",
        "    srcs = ['public2.cc', 'public2_impl.h'],",
        "    hdrs = ['public2.h'],",
        "    textual_hdrs = ['public2.inc'],",
        ")",
        "cc_library(",
        "    name = 'private',",
        "    srcs = ['private.cc', 'private_impl.h'],",
        "    hdrs = ['private.h'],",
        "    textual_hdrs = ['private.inc'],",
        ")",
        "cc_merger(",
        "    name = 'merge',",
        "    exports = [':public1', ':public2'],",
        "    deps = [':private'],",
        ")");

    ConfiguredTarget lib = getConfiguredTarget("//direct:merge");
    CcCompilationContext ccCompilationContext = lib.get(CcInfo.PROVIDER).getCcCompilationContext();
    assertThat(
            baseArtifactNames(
                ccCompilationContext.getExportingModuleMaps().stream()
                    .map(CppModuleMap::getArtifact)
                    .collect(ImmutableList.toImmutableList())))
        .containsExactly("public1.cppmap", "public2.cppmap");
    assertThat(baseArtifactNames(ccCompilationContext.getDirectPublicHdrs()))
        .containsExactly("public1.h", "public2.h");
    assertThat(baseArtifactNames(ccCompilationContext.getDirectPrivateHdrs()))
        .containsExactly("public1_impl.h", "public2_impl.h");
    assertThat(baseArtifactNames(ccCompilationContext.getTextualHdrs()))
        .containsExactly("public1.inc", "public2.inc");
  }

  @Test
  public void testObjectFilesInCreateLibraryToLinkApiGuardedByFlag() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig, CcToolchainConfig.builder().withFeatures("foo_feature"));
    useConfiguration("--noexperimental_starlark_cc_import");
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'crule')",
        "cc_toolchain_alias(name='alias')",
        "crule(name='r')");

    scratch.file(
        "a/rule.bzl",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "      ctx = ctx,",
        "      cc_toolchain = toolchain,",
        "      requested_features = ['foo_feature'])",
        "  cc_common.create_library_to_link(",
        "    actions=ctx.actions, feature_configuration=feature_configuration, ",
        "    cc_toolchain = toolchain, objects = [])",
        "  return CcInfo()",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
        "  },",
        "  fragments = ['cpp']",
        ")");
    checkError("//a:r", "Cannot use objects/pic_objects without --experimental_starlark_cc_import");
  }

  @Test
  public void testObjectFilesInCreateLibrary() throws Exception {
    setUpCcLinkingContextTest(true);
    scratch.file(
        "b/BUILD",
        "load('//tools/build_defs/cc:rule.bzl', 'crule')",
        "crule(name='import_objects',",
        "   static_library = 'lib.a',",
        "   pic_static_library = 'lib.pic.a',",
        "   objects = ['object.o'],",
        "   pic_objects = ['object.pic.o'],",
        ")");

    assertNoEvents();
    ConfiguredTarget lib = getConfiguredTarget("//b:import_objects");
    CcLinkingContext ccLinkingContext = lib.get(CcInfo.PROVIDER).getCcLinkingContext();
    ImmutableList<LibraryToLink> libraries =
        ccLinkingContext.getLinkerInputs().toList().stream()
            .flatMap(i -> i.getLibraries().stream())
            .collect(ImmutableList.toImmutableList());

    assertThat(
            baseArtifactNames(
                libraries.stream()
                    .flatMap(l -> l.getObjectFiles().stream())
                    .collect(ImmutableList.toImmutableList())))
        .containsExactly("object.o");
    assertThat(
            baseArtifactNames(
                libraries.stream()
                    .flatMap(l -> l.getPicObjectFiles().stream())
                    .collect(ImmutableList.toImmutableList())))
        .containsExactly("object.pic.o");
  }

  @Test
  public void testObjectFilesInCreateLibraryWithoutStaticLibrary() throws Exception {
    setUpCcLinkingContextTest(true);
    scratch.file(
        "b/BUILD",
        "load('//tools/build_defs/cc:rule.bzl', 'crule')",
        "crule(name='import_objects_no_lib',",
        "   objects = ['object.o'],",
        ")");

    checkError(
        "//b:import_objects_no_lib", "If you pass 'objects' you must also pass a 'static_library'");
  }

  @Test
  public void testObjectFilesInCreateLibraryWithoutPicStaticLibrary() throws Exception {
    setUpCcLinkingContextTest(true);
    scratch.file(
        "b/BUILD",
        "load('//tools/build_defs/cc:rule.bzl', 'crule')",
        "crule(name='import_objects_no_pic_lib',",
        "   pic_objects = ['object.pic.o'],",
        ")");

    checkError(
        "//b:import_objects_no_pic_lib",
        "If you pass 'pic_objects' you must also pass a 'pic_static_library'");
  }

  private void setupDebugPackageProviderTest(String fission) throws Exception {
    getAnalysisMock()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder().withFeatures(CppRuleClasses.PER_OBJECT_DEBUG_INFO));
    useConfiguration(fission);
    scratch.file(
        "a/rule.bzl",
        "def _impl(ctx):",
        "    out = ctx.actions.declare_file(ctx.label.name)",
        "    ctx.actions.run_shell(",
        "        inputs = [ctx.executable.cc_binary],",
        "        tools = [],",
        "        outputs = [out],",
        "        command = 'cp %s %s' % (ctx.executable.cc_binary.path, out.path),",
        "    )",
        "    wrapped_defaultinfo = ctx.attr.cc_binary[DefaultInfo]",
        "    runfiles = ctx.runfiles(files = [out])",
        "    wrapped_default_runfiles = wrapped_defaultinfo.default_runfiles.files.to_list()",
        "    if ctx.executable.cc_binary in wrapped_default_runfiles:",
        "        wrapped_default_runfiles.remove(ctx.executable.cc_binary)",
        "    result = [",
        "        DefaultInfo(",
        "            executable = out,",
        "            files = depset([out]),",
        "            runfiles = runfiles.merge(ctx.runfiles(files = wrapped_default_runfiles)),",
        "        ),",
        "    ]",
        "    if ctx.file.stripped_file:",
        "        wrapped_dbginfo = ctx.attr.cc_binary[DebugPackageInfo]",
        "        result.append(",
        "            DebugPackageInfo(",
        "                target_label = ctx.label,",
        "                stripped_file = ctx.file.stripped_file \\",
        "                                if wrapped_dbginfo.stripped_file else None,",
        "                unstripped_file = out,",
        "                dwp_file = ctx.file.dwp_file if wrapped_dbginfo.dwp_file else None,",
        "            ),",
        "        )",
        "    return result",
        "wrapped_binary = rule(",
        "    _impl,",
        "    attrs = {",
        "        'cc_binary': attr.label(",
        "            allow_single_file = True,",
        "            mandatory = True,",
        "            executable = True,",
        "            cfg = 'target',",
        "        ),",
        "        'stripped_file': attr.label(",
        "            allow_single_file = True,",
        "            default = None,",
        "        ),",
        "        'dwp_file': attr.label(",
        "            allow_single_file = True,",
        "            default = None,",
        "        )",
        "    },",
        "    executable = True,",
        ")");
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'wrapped_binary')",
        "wrapped_binary(name = 'w',",
        "    cc_binary = ':native_binary',",
        "    stripped_file = ':w.stripped',",
        "    dwp_file = ':w.dwp',",
        ")",
        "wrapped_binary(name = 'w.stripped',",
        "    cc_binary = ':native_binary.stripped'",
        ")",
        "wrapped_binary(name = 'w.dwp',",
        "    cc_binary = ':native_binary.dwp'",
        ")",
        "cc_binary(name = 'native_binary',",
        "    srcs = ['main.cc']",
        ")");
    scratch.file("a/main.cc", "int main() {}");
  }

  @Test
  public void testDebugPackageProviderFissionDisabled() throws Exception {
    setupDebugPackageProviderTest("--fission=no");
    ConfiguredTarget target = getConfiguredTarget("//a:w");
    assertNoEvents();
    assertThat(target).isNotNull();
    DebugPackageProvider debugPackageProvider = target.get(DebugPackageProvider.PROVIDER);
    assertThat(debugPackageProvider.getStrippedArtifact().getFilename()).isEqualTo("w.stripped");
    assertThat(debugPackageProvider.getUnstrippedArtifact().getFilename()).isEqualTo("w");
    assertThat(debugPackageProvider.getDwpArtifact()).isNull();
  }

  @Test
  public void testDebugPackageProviderFissionEnabled() throws Exception {
    setupDebugPackageProviderTest("--fission=yes");
    ConfiguredTarget target = getConfiguredTarget("//a:w");
    assertNoEvents();
    assertThat(target).isNotNull();
    DebugPackageProvider debugPackageProvider = target.get(DebugPackageProvider.PROVIDER);
    assertThat(debugPackageProvider.getStrippedArtifact().getFilename()).isEqualTo("w.stripped");
    assertThat(debugPackageProvider.getUnstrippedArtifact().getFilename()).isEqualTo("w");
    assertThat(debugPackageProvider.getDwpArtifact().getFilename()).isEqualTo("w.dwp");
  }

  @Test
  public void testCcDebugContextDisabled() throws Exception {
    scratch.file(
        "b/BUILD",
        "load('//my_rules:rule.bzl', 'cc_compile_rule')",
        "cc_compile_rule(",
        "  name='b_lib',",
        "  srcs = ['b_lib.cc'],",
        ")");
    scratch.file("my_rules/BUILD");
    scratch.file(
        "my_rules/rule.bzl",
        "def _impl(ctx):",
        "  comp_context = cc_common.create_compilation_context()",
        "  comp_outputs = cc_common.create_compilation_outputs()",
        "  debug_info = cc_common.create_debug_context(comp_outputs)",
        "  return [CcInfo(compilation_context = comp_context, debug_info = debug_info)]",
        "cc_compile_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files = ['.cc']),",
        "  },",
        ")");
    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//b:b_lib"));
    assertThat(e).hasMessageThat().contains("Rule in 'my_rules' cannot use private API");
  }

  @Test
  public void testCcDebugContext() throws Exception {
    useConfiguration("--fission=yes");
    scratch.file(
        "b/BUILD",
        "load('//bazel_internal/test_rules/cc:rule.bzl', 'cc_compile_rule')",
        "cc_toolchain_alias(name='alias')",
        "cc_compile_rule(",
        "  name='b_lib',",
        "  srcs = ['b_lib.cc'],",
        ")");
    scratch.file("bazel_internal/test_rules/cc/BUILD");
    scratch.file(
        "bazel_internal/test_rules/cc/rule.bzl",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "    ctx=ctx,",
        "    cc_toolchain=toolchain,",
        "    requested_features=ctx.features + ['per_object_debug_info'],",
        "    unsupported_features=ctx.disabled_features)",
        "  (comp_context, comp_outputs) = cc_common.compile(",
        "    name = ctx.label.name,",
        "    actions = ctx.actions,",
        "    feature_configuration = feature_configuration,",
        "    cc_toolchain = toolchain,",
        "    srcs = ctx.files.srcs,",
        "  )",
        "  debug_info = cc_common.create_debug_context(comp_outputs)",
        "  return [CcInfo(compilation_context = comp_context, debug_context = debug_info)]",
        "cc_compile_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    '_cc_toolchain': attr.label(default=Label('//b:alias')),",
        "    'srcs': attr.label_list(allow_files = ['.cc']),",
        "  },",
        "  fragments = ['cpp'],",
        ")");
    ConfiguredTarget target = getConfiguredTarget("//b:b_lib");
    assertThat(
            target
                .get(CcInfo.PROVIDER)
                .getCcDebugInfoContext()
                .getTransitiveDwoFiles()
                .toList()
                .stream()
                .map(Artifact::getFilename))
        .containsExactly("b_lib.dwo");
    assertThat(
            target.get(CcInfo.PROVIDER).getCcDebugInfoContext().getTransitivePicDwoFiles().toList())
        .isEmpty();
  }

  @Test
  public void testExpandedToolchainApiBlocked() throws Exception {
    List<String> toolchainCalls =
        ImmutableList.of(
            "toolchain.as_files()",
            "toolchain.ar_files()",
            "toolchain.objcopy_files()",
            "toolchain.tool_path(tool='ld')",
            "toolchain.solib_dir()",
            "toolchain.dynamic_runtime_solib_dir()",
            "toolchain.linker_files()",
            "toolchain.coverage_files()",
            "toolchain.strip_files()");
    scratch.file(
        "a/BUILD",
        "load(':rule.bzl', 'crule')",
        "cc_toolchain_alias(name='alias')",
        "crule(name='r')");

    for (String call : toolchainCalls) {
      scratch.overwriteFile(
          "a/rule.bzl",
          "CruleInfo = provider()",
          "def _impl(ctx):",
          "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
          "  " + call,
          "  return [CruleInfo()]",
          "crule = rule(",
          "  _impl,",
          "  attrs = { ",
          "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
          "  },",
          "  fragments = ['cpp'],",
          ");");
      invalidatePackages();
      AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//a:r"));
      assertThat(e).hasMessageThat().contains("cannot use private API");
    }
  }

  @Test
  public void testExpandedCompileApiBlocked() throws Exception {
    scratch.file(
        "bazel_internal/test_rules/cc/BUILD",
        "load(':module_map.bzl', 'module_map')",
        "module_map(name='module_map', file = 'a_file.txt')");

    scratch.file(
        "bazel_internal/test_rules/cc/module_map.bzl",
        "ModuleMapInfo = provider(fields=['module_map', 'file'])",
        "def _impl(ctx):",
        "  module_map = cc_common.create_module_map(file=ctx.file.file,",
        "        umbrella_header=ctx.file.file, name='module')",
        "  return [ModuleMapInfo(module_map=module_map, file=ctx.file.file)]",
        "module_map = rule(",
        "  _impl,",
        "  attrs = { ",
        "    'file': attr.label(allow_single_file=True)",
        "  },",
        "  fragments = ['cpp'],",
        ");");

    String compileCall =
        "cc_common.compile(actions = ctx.actions, feature_configuration = feature_configuration,"
            + " name = 'name', cc_toolchain = toolchain, ";
    List<String> calls =
        ImmutableList.of(
            "cc_common.create_module_map(file=file, umbrella_header=file, name='name')",
            "module_map.file()",
            "module_map.umbrella_header()",
            compileCall + " module_map = module_map)",
            compileCall + " additional_module_maps = [module_map])",
            compileCall + "textual_hdrs = [])",
            compileCall + "additional_exported_hdrs = [])",
            compileCall + "propagate_module_map_to_compile_action = True)",
            compileCall + "do_not_generate_module_map = True)",
            compileCall + "code_coverage_enabled = True)",
            compileCall + "hdrs_checking_mode = 'strict')");
    scratch.overwriteFile(
        "a/BUILD",
        "load(':rule.bzl', 'crule')",
        "cc_toolchain_alias(name='alias')",
        "crule(name='r', deps=['//bazel_internal/test_rules/cc:module_map'])");

    for (String call : calls) {
      scratch.overwriteFile(
          "a/rule.bzl",
          "load('//bazel_internal/test_rules/cc:module_map.bzl', 'ModuleMapInfo')",
          "CruleInfo = provider()",
          "def _impl(ctx):",
          "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
          "  feature_configuration = cc_common.configure_features(",
          "    ctx = ctx,",
          "    cc_toolchain = toolchain,",
          "  )",
          "  module_map = ctx.attr.deps[0][ModuleMapInfo].module_map",
          "  file = ctx.attr.deps[0][ModuleMapInfo].file",
          "  " + call,
          "  return [CruleInfo()]",
          "crule = rule(",
          "  _impl,",
          "  attrs = { ",
          "    'deps': attr.label_list(),",
          "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
          "  },",
          "  fragments = ['cpp'],",
          ");");
      invalidatePackages();
      AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//a:r"));
      assertThat(e).hasMessageThat().contains("cannot use private API");
    }
  }

  @Test
  public void testExpandedCcCompilationContextApiBlocked() throws Exception {
    scratch.file(
        "b/BUILD",
        "load('//my_rules:rule.bzl', 'method_rule', 'param_1_rule', 'param_2_rule')",
        "param_1_rule(",
        "  name = 'p1',",
        ")",
        "param_2_rule(",
        "  name = 'p2',",
        ")",
        "method_rule(",
        "  name = 'm',",
        ")");
    scratch.file("my_rules/BUILD");
    scratch.file(
        "my_rules/rule.bzl",
        "def _m_impl(ctx):",
        "  comp_context = cc_common.create_compilation_context()",
        "  comp_context.transitive_compilation_prerequisites()",
        "  return [CcInfo(compilation_context = comp_context)]",
        "def _p1_impl(ctx):",
        "  comp_context = cc_common.create_compilation_context(textual_hdrs = ['dummy.h'])",
        "  return [CcInfo(compilation_context = comp_context)]",
        "def _p2_impl(ctx):",
        "  comp_context = cc_common.create_compilation_context(purpose = 'testing')",
        "  return [CcInfo(compilation_context = comp_context)]",
        "method_rule = rule(",
        "  implementation = _m_impl,",
        ")",
        "param_1_rule = rule(",
        "  implementation = _p1_impl,",
        ")",
        "param_2_rule = rule(",
        "  implementation = _p2_impl,",
        ")");
    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//b:m"));
    assertThat(e).hasMessageThat().contains("Rule in 'my_rules' cannot use private API");
    e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//b:p1"));
    assertThat(e).hasMessageThat().contains("Rule in 'my_rules' cannot use private API");
    e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//b:p2"));
    assertThat(e).hasMessageThat().contains("Rule in 'my_rules' cannot use private API");
  }

  @Test
  public void testExpandedLinkApiRaisesError() throws Exception {
    scratch.file(
        "b/BUILD",
        "load('//b:rule.bzl', 'link_rule')",
        "cc_toolchain_alias(name='alias')",
        "link_rule(name = 'foo')");
    String callFormatString =
        "cc_common.link(name='test', actions=ctx.actions,"
            + "feature_configuration=feature_configuration, cc_toolchain=toolchain, %s)";
    ImmutableList<String> calls =
        ImmutableList.of(
            String.format(callFormatString, "link_artifact_name_suffix='test'"),
            String.format(callFormatString, "never_link=False"),
            String.format(callFormatString, "test_only_target=False"),
            String.format(callFormatString, "always_link=False"),
            String.format(callFormatString, "additional_linkstamp_defines=[]"),
            String.format(callFormatString, "whole_archive=False"),
            String.format(callFormatString, "native_deps=False"),
            String.format(callFormatString, "only_for_dynamic_libs=False"));
    for (String call : calls) {
      scratch.overwriteFile(
          "b/rule.bzl",
          "def _impl(ctx):",
          "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
          "  feature_configuration = cc_common.configure_features(",
          "    ctx = ctx,",
          "    cc_toolchain = toolchain,",
          "  )",
          "  " + call,
          "  return [DefaultInfo()]",
          "link_rule = rule(",
          "  implementation = _impl,",
          "  attrs = {",
          "    '_cc_toolchain': attr.label(default=Label('//b:alias'))",
          "  },",
          "  fragments = ['cpp'],",
          ")");
      invalidatePackages();
      AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//b:foo"));
      assertThat(e).hasMessageThat().contains("Rule in 'b' cannot use private API");
    }
  }

  @Test
  public void testExpandedCcCompilationOutputsApiRaisesError() throws Exception {
    scratch.file("b/BUILD", "load('//b:rule.bzl', 'cc_rule')", "cc_rule(", "  name='foo',", ")");
    ImmutableList<String> calls =
        ImmutableList.of(
            "comp_outputs.temps()",
            "comp_outputs.files_to_compile(parse_headers=False, use_pic=True)",
            "comp_outputs.header_tokens()");
    for (String call : calls) {
      scratch.overwriteFile(
          "b/rule.bzl",
          "def _impl(ctx):",
          "  comp_outputs = cc_common.create_compilation_outputs()",
          "  " + call,
          "  return [DefaultInfo()]",
          "cc_rule = rule(",
          "  implementation = _impl,",
          ")");
      invalidatePackages();
      AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//b:foo"));
      assertThat(e).hasMessageThat().contains("Rule in 'b' cannot use private API");
    }
  }

  @Test
  public void testExpandedLtoAndFdoApiRaisesError() throws Exception {
    useConfiguration("--fdo_optimize=pkg/profile.afdo", "--compilation_mode=opt");
    scratch.file(
        "bazel_internal/test_rules/cc/BUILD",
        "load(':lto_backend_artifacts.bzl', 'lto_backend_artifacts')",
        "lto_backend_artifacts(name='lto_backend_artifacts', file = 'a_file.txt')");

    scratch.file(
        "bazel_internal/test_rules/cc/lto_backend_artifacts.bzl",
        "LtoBackendArtifactsInfo = provider(fields=['lto_backend_artifacts',",
        "                                              'fdo_context', 'branch_fdo_profile'])",
        "def _impl(ctx):",
        "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "    ctx = ctx,",
        "    cc_toolchain = toolchain,",
        "  )",
        "  fdo_context = toolchain.fdo_context()",
        "  branch_fdo_profile = fdo_context.branch_fdo_profile()",
        "  lto_backend_artifacts = cc_common.create_lto_backend_artifacts(ctx=ctx,",
        "        lto_output_root_prefix=ctx.label.package, bitcode_file=ctx.file.file,",
        "        feature_configuration=feature_configuration, cc_toolchain=toolchain,",
        "        fdo_context=fdo_context, use_pic=True,",
        "        should_create_per_object_debug_info=False, argv=[])",
        "  return [LtoBackendArtifactsInfo(lto_backend_artifacts=lto_backend_artifacts,",
        "          fdo_context=fdo_context, branch_fdo_profile=branch_fdo_profile)]",
        "lto_backend_artifacts = rule(",
        "  _impl,",
        "  attrs = { ",
        "    'file': attr.label(allow_single_file=True),",
        "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
        "  },",
        "  fragments = ['cpp'],",
        ");");

    ImmutableList<String> calls =
        ImmutableList.of(
            "toolchain.fdo_context()",
            "library_to_link.shared_non_lto_backends()",
            "library_to_link.pic_shared_non_lto_backends()",
            "lto_backend_artifacts_info.lto_backend_artifacts.object_file()",
            "lto_backend_artifacts_info.fdo_context.branch_fdo_profile()",
            "lto_backend_artifacts_info.branch_fdo_profile.auto_fdo()",
            "lto_backend_artifacts_info.branch_fdo_profile.auto_xbinary_fdo()",
            "lto_backend_artifacts_info.branch_fdo_profile.llvm_fdo()",
            "lto_backend_artifacts_info.branch_fdo_profile.llvm_cs_fdo()");
    scratch.overwriteFile(
        "a/BUILD",
        "load(':rule.bzl', 'crule')",
        "cc_toolchain_alias(name='alias')",
        "cc_library(name='clib', srcs=['clib.cc'], hdrs=['clib.h'])",
        "crule(name='r', lto_dep='//bazel_internal/test_rules/cc:lto_backend_artifacts',",
        "      cc_dep=':clib')");

    for (String call : calls) {
      scratch.overwriteFile(
          "a/rule.bzl",
          "load('//bazel_internal/test_rules/cc:lto_backend_artifacts.bzl',",
          "             'LtoBackendArtifactsInfo')",
          "CruleInfo = provider()",
          "def _impl(ctx):",
          "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
          "  feature_configuration = cc_common.configure_features(",
          "    ctx = ctx,",
          "    cc_toolchain = toolchain,",
          "  )",
          "  library_to_link = (ctx.attr.cc_dep[CcInfo].linking_context",
          "                                     .linker_inputs.to_list()[0].libraries[0])",
          "  lto_backend_artifacts_info = ctx.attr.lto_dep[LtoBackendArtifactsInfo]",
          "  " + call,
          "  return [CruleInfo()]",
          "crule = rule(",
          "  _impl,",
          "  attrs = { ",
          "    'lto_dep': attr.label(),",
          "    'cc_dep': attr.label(),",
          "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
          "  },",
          "  fragments = ['cpp'],",
          ");");
      invalidatePackages();
      AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//a:r"));
      assertThat(e).hasMessageThat().contains("cannot use private API");
    }
  }

  @Test
  public void testExpandedLibraryToLinkApiRaisesError() throws Exception {
    scratch.file(
        "b/BUILD",
        "load('//b:rule.bzl', 'cc_rule')",
        "cc_library(name='cc_dep', srcs=['cc_dep.cc'])",
        "cc_toolchain_alias(name='alias')",
        "cc_rule(name='foo', cc_dep=':cc_dep')");
    ImmutableList<String> calls =
        ImmutableList.of(
            "cc_common.create_library_to_link(actions=ctx.actions,"
                + "feature_configuration=feature_configuration, cc_toolchain=toolchain,"
                + " must_keep_debug=False)",
            "library_to_link.must_keep_debug()");
    for (String call : calls) {
      scratch.overwriteFile(
          "b/rule.bzl",
          "def _impl(ctx):",
          "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
          "  feature_configuration = cc_common.configure_features(",
          "    ctx = ctx,",
          "    cc_toolchain = toolchain,",
          "  )",
          "  library_to_link = (ctx.attr.cc_dep[CcInfo].linking_context",
          "                                     .linker_inputs.to_list()[0].libraries[0])",
          "  " + call,
          "  return [DefaultInfo()]",
          "cc_rule = rule(",
          "  implementation = _impl,",
          "  attrs = { ",
          "    'cc_dep': attr.label(),",
          "    '_cc_toolchain': attr.label(default=Label('//b:alias'))",
          "  },",
          "  fragments = ['cpp'],",
          ")");
      invalidatePackages();
      AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//b:foo"));
      assertThat(e).hasMessageThat().contains("Rule in 'b' cannot use private API");
    }
  }

  @Test
  public void testExpandedLinkstampApiRaisesError() throws Exception {
    scratch.file(
        "bazel_internal/test_rules/cc/BUILD",
        "load(':linkstamps.bzl', 'linkstamps')",
        "cc_library(name='cc_dep', srcs=['cc_dep.cc'], linkstamp='stamp.cc')",
        "linkstamps(name='linkstamps', deps = [':cc_dep'])");

    scratch.file(
        "bazel_internal/test_rules/cc/linkstamps.bzl",
        "LinkstampsInfo = provider(fields=['linkstamps'])",
        "def _impl(ctx):",
        "  linkstamps = ctx.attr.deps[0][CcInfo].linking_context.linkstamps().to_list()",
        "  return [LinkstampsInfo(linkstamps=linkstamps)]",
        "linkstamps = rule(",
        "  _impl,",
        "  attrs = { ",
        "    'deps': attr.label_list(),",
        "  },",
        ");");

    scratch.file(
        "b/BUILD",
        "load('//b:rule.bzl', 'cc_rule')",
        "cc_library(name='cc_dep', srcs=['cc_dep.cc'])",
        "cc_toolchain_alias(name='alias')",
        "cc_rule(name='foo', cc_dep=':cc_dep',",
        "        file='file.cc',",
        "        linkstamps_dep='//bazel_internal/test_rules/cc:linkstamps')");
    scratch.appendFile(
        "tools/cpp/grep_includes/BUILD",
        "sh_binary(",
        "    name = 'grep-includes',",
        "    srcs = ['grep-includes.sh'],",
        ")");
    List<String> calls =
        new ArrayList<>(
            Arrays.asList("linkstamp.file()", "linkstamp.hdrs()", "linking_context.linkstamps()"));
    if (!analysisMock.isThisBazel()) {
      calls.add(
          "cc_common.register_linkstamp_compile_action(actions=ctx.actions,cc_toolchain=toolchain,"
              + " feature_configuration=feature_configuration, "
              + " grep_includes=ctx.executable._grep_includes, source_file=file, output_file=file,"
              + " compilation_inputs=depset([]), inputs_for_validation=depset([]),"
              + " label_replacement='', output_replacement='')");
    }
    for (String call : calls) {
      scratch.overwriteFile(
          "b/rule.bzl",
          "load('//bazel_internal/test_rules/cc:linkstamps.bzl',",
          "             'LinkstampsInfo')",
          "def _impl(ctx):",
          "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
          "  feature_configuration = cc_common.configure_features(",
          "    ctx = ctx,",
          "    cc_toolchain = toolchain,",
          "  )",
          "  linkstamp = ctx.attr.linkstamps_dep[LinkstampsInfo].linkstamps[0]",
          "  linking_context = ctx.attr.cc_dep[CcInfo].linking_context",
          "  file = ctx.file.file",
          "  " + call,
          "  return [DefaultInfo()]",
          "cc_rule = rule(",
          "  implementation = _impl,",
          "  attrs = { ",
          "    'cc_dep': attr.label(),",
          "    'linkstamps_dep': attr.label(),",
          "    '_cc_toolchain': attr.label(default=Label('//b:alias')),",
          "    'file': attr.label(allow_single_file=True),",
          "    '_grep_includes': attr.label(",
          "          executable = True,",
          "          default = Label('//tools/cpp/grep_includes:grep-includes'),",
          "          cfg = 'host'",
          "    ),",
          "  },",
          "  fragments = ['cpp'],",
          ")");
      invalidatePackages();
      AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//b:foo"));
      assertThat(e).hasMessageThat().contains("Rule in 'b' cannot use private API");
    }
  }

  @Test
  public void testExtraLinkTimeLibraryApiRaisesError() throws Exception {
    scratch.file(
        "b/BUILD",
        "load('//b:rule.bzl', 'cc_rule')",
        "cc_library(name='cc_dep', srcs=['cc_dep.cc'])",
        "cc_rule(name='foo', cc_dep=':cc_dep')");
    ImmutableList<String> calls =
        ImmutableList.of(
            "cc_common.create_linking_context(linker_inputs=depset([]), go_link_c_archive=None)",
            "linking_context.go_link_c_archive()");
    for (String call : calls) {
      scratch.overwriteFile(
          "b/rule.bzl",
          "def _impl(ctx):",
          "  linking_context = ctx.attr.cc_dep[CcInfo].linking_context",
          "  " + call,
          "  return [DefaultInfo()]",
          "cc_rule = rule(",
          "  implementation = _impl,",
          "  attrs = { ",
          "    'cc_dep': attr.label(),",
          "  },",
          ")");
      invalidatePackages();
      AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//b:foo"));
      assertThat(e).hasMessageThat().contains("Rule in 'b' cannot use private API");
    }
  }

  @Test
  public void testDisallowedCcNativeLibraryRaisesError() throws Exception {
    scratch.file(
        "b/BUILD", "load('//b:rule.bzl', 'test_rule')", "test_rule(", "  name = 'test',", ")");
    scratch.file(
        "b/rule.bzl",
        "def _impl(ctx):",
        "  cc_common.get_CcNativeLibraryProvider()",
        "  return DefaultInfo()",
        "test_rule = rule(implementation = _impl)");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//b:test"));
    assertThat(e).hasMessageThat().contains("Rule in 'b' cannot use private API");
  }

  @Test
  public void testAllowedCcNativeLibraryProviderIsUsable() throws Exception {
    scratch.file(
        "b/BUILD",
        "load('//bazel_internal/test_rules/cc:rule.bzl', 'test_rule')",
        "test_rule(",
        "  name = 'test',",
        "  cc_dep = ':foo',",
        ")",
        "cc_library(",
        "  name = 'foo',",
        "  srcs = ['foo.cc'],",
        ")");
    scratch.file("bazel_internal/test_rules/cc/BUILD");
    scratch.file(
        "bazel_internal/test_rules/cc/rule.bzl",
        "def _impl(ctx):",
        "  CcNativeLibraryProvider = cc_common.get_CcNativeLibraryProvider()",
        "  libs = ctx.attr.cc_dep[CcNativeLibraryProvider].libs",
        "  files = []",
        "  for l in libs.to_list():",
        "    files.append(l.dynamic_library)",
        "    files.append(l.interface_library)",
        "    files.append(l.static_library)",
        "    files.append(l.pic_static_library)",
        "  files = [f for f in files if f != None]",
        "  runfiles = ctx.runfiles(files=files)",
        "  return [DefaultInfo(runfiles=runfiles)]",
        "test_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {",
        "    'cc_dep': attr.label(),",
        "    },",
        ")");

    ConfiguredTarget test = getConfiguredTarget("//b:test");

    assertThat(
            test.get(DefaultInfo.PROVIDER).getDefaultRunfiles().getAllArtifacts().toList().stream()
                .map(Artifact::getFilename))
        .containsExactly("libfoo.a");
  }

  @Test
  public void testAllowedVariableExtensionCompileApi() throws Exception {
    runTestVariableExtension(/* call= */ "compile", /* allowed= */ true);
  }

  @Test
  public void testAllowedVariableExtensionLinkApi() throws Exception {
    runTestVariableExtension(/* call= */ "link", /* allowed= */ true);
  }

  @Test
  public void testVariableExtensionCompileApiRaisesError() throws Exception {
    runTestVariableExtension(/* call= */ "compile", /* allowed= */ false);
  }

  @Test
  public void testVariableExtensionLinkApiRaisesError() throws Exception {
    runTestVariableExtension(/* call= */ "link", /* allowed= */ false);
  }

  private void runTestVariableExtension(String call, boolean allowed) throws Exception {
    scratch.overwriteFile("bazel_internal/test_rules/cc/BUILD", "");
    String rulePkg = "b";
    if (allowed) {
      rulePkg = "bazel_internal/test_rules/cc";
    }
    scratch.overwriteFile(
        "b/BUILD",
        "load('//" + rulePkg + ":rule.bzl', 'cc_rule')",
        "cc_library(name='cc_dep', srcs=['cc_dep.cc'])",
        "cc_toolchain_alias(name='alias')",
        "cc_rule(name='foo', cc_dep=':cc_dep')");
    scratch.overwriteFile(
        rulePkg + "/rule.bzl",
        getVariablesExtensionStarlarkRule(
            call,
            Joiner.on("\n")
                .join(
                    "dict = {'string_variable': 'foo',",
                    "        'string_sequence_variable' : ['foo'],",
                    "        'string_depset_variable': depset(['foo'])}")));
    invalidatePackages();
    if (allowed) {
      getConfiguredTarget("//b:foo");
      assertNoEvents();
    } else {
      AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//b:foo"));
      assertThat(e).hasMessageThat().contains("Rule in 'b' cannot use private API");
    }
  }

  @Test
  public void testVariablesExtensionValueTypes() throws Exception {
    String rulePkg = "bazel_internal/test_rules/cc";
    scratch.overwriteFile(rulePkg + "/BUILD", "");
    scratch.overwriteFile(
        "b/BUILD",
        "load('//" + rulePkg + ":rule.bzl', 'cc_rule')",
        "cc_library(name='cc_dep', srcs=['cc_dep.cc'])",
        "cc_toolchain_alias(name='alias')",
        "cc_rule(name='foo', cc_dep=':cc_dep')");
    for (String value : ImmutableList.of("1", "[1]", "depset([1])")) {
      scratch.overwriteFile(
          rulePkg + "/rule.bzl",
          getVariablesExtensionStarlarkRule("compile", "dict = {'variable': " + value + "}"));
      invalidatePackages();
      AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//b:foo"));
      assertThat(e).hasMessageThat().contains("Trying to build UserVariableExtension");
    }
  }

  @Test
  public void testAdditionalLinkingOutputsAppearAsOutputsOfLinkAction() throws Exception {
    createCcBinRule(scratch, "additional_outputs=ctx.outputs.additional_outputs");
    scratch.file(
        "foo/BUILD",
        "load('//tools/build_defs:extension.bzl', 'cc_bin')",
        "cc_bin(",
        "    name = 'bin',",
        "    objects = ['file.o'],",
        "    pic_objects = ['file.pic.o'],",
        "    additional_outputs = [':bin.map'],",
        ")");
    ConfiguredTarget target = getConfiguredTarget("//foo:bin");
    assertThat(target).isNotNull();
    CppLinkAction action =
        (CppLinkAction) getGeneratingAction(artifactByPath(getFilesToBuild(target), ".map"));
    assertThat(artifactsToStrings(action.getOutputs())).contains("bin foo/bin.map");
  }

  private String getVariablesExtensionStarlarkRule(String call, String dictionaryEntries) {
    return Joiner.on("\n")
        .join(
            "def _impl(ctx):",
            "  toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
            "  feature_configuration = cc_common.configure_features(",
            "      ctx = ctx,",
            "      cc_toolchain = toolchain,",
            "      requested_features = ctx.features,",
            "      unsupported_features = ctx.disabled_features,",
            "  )",
            "  " + dictionaryEntries,
            "  cc_common." + call + "(",
            "      actions = ctx.actions,",
            "      feature_configuration = feature_configuration,",
            "      cc_toolchain = toolchain,",
            "      name = ctx.label.name + '_aspect',",
            "      variables_extension = dict,",
            "  )",
            "  return [DefaultInfo()]",
            "cc_rule = rule(",
            "  implementation = _impl,",
            "  attrs = { ",
            "    'cc_dep': attr.label(),",
            "    '_cc_toolchain': attr.label(default=Label('//b:alias'))",
            "  },",
            "  fragments = ['cpp'],",
            ")");
  }
}
