// 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 com.google.devtools.build.lib.actions.util.ActionsTestUtil.prettyArtifactNames;
import static com.google.devtools.build.lib.rules.cpp.SolibSymlinkAction.MAX_FILENAME_LENGTH;
import static org.junit.Assert.assertThrows;

import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.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.FileProvider;
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.CcCommon.Language;
import com.google.devtools.build.lib.rules.cpp.CcLinkingContext.Linkstamp;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.ActionConfig;
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 java.util.concurrent.atomic.AtomicBoolean;
import net.starlark.java.eval.EvalException;
import net.starlark.java.eval.Sequence;
import net.starlark.java.eval.Starlark;
import net.starlark.java.eval.StarlarkList;
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 setUp() throws Exception {
    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.parseCanonical("//myinfo:myinfo.bzl"), "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 testGetValuesFromCcToolchain() 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(",
        "    dynamic_runtime_solib_dir = toolchain.dynamic_runtime_solib_dir,",
        "    toolchain_id = toolchain.toolchain_id,",
        "  )]",
        "crule = rule(",
        "  _impl,",
        "  attrs = { ",
        "    '_cc_toolchain': attr.label(default=Label('//a:alias'))",
        "  },",
        "  fragments = ['cpp'],",
        ");");

    ConfiguredTarget r = getConfiguredTarget("//a:r");
    StructImpl info = getMyInfoFromTarget(r);
    String dynamicRuntimeSolibDir = (String) info.getValue("dynamic_runtime_solib_dir");
    String toolchainId = (String) info.getValue("toolchain_id");

    RuleContext ruleContext = getRuleContext(r);
    CcToolchainProvider toolchain =
        CppHelper.getToolchain(ruleContext, ruleContext.getPrerequisite("$cc_toolchain"));

    assertThat(dynamicRuntimeSolibDir).isEqualTo(toolchain.getDynamicRuntimeSolibDirForStarlark());
    assertThat(toolchainId).isEqualTo(toolchain.getToolchainIdentifier());
  }

  @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(),
            Language.CPP,
            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(),
            Language.CPP,
            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(),
            Language.CPP,
            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 testCompileBuildVariablesWithVariablesExtension() throws Exception {
    AnalysisMock.get()
        .ccSupport()
        .setupCcToolchainConfig(
            mockToolsConfig,
            CcToolchainConfig.builder().withFeatures("check_additional_variables_feature"));
    useConfiguration("--features=check_additional_variables_feature");
    assertThat(
            commandLineForVariables(
                CppActionNames.CPP_COMPILE,
                "cc_common.create_compile_variables(",
                "    feature_configuration = feature_configuration,",
                "    cc_toolchain = toolchain,",
                "    variables_extension = {",
                "        'string_variable': 'foo',",
                "        'list_variable': ['bar', 'baz']",
                "    }",
                ")"))
        .containsAtLeast("--my_string=foo", "--my_list_element=bar", "--my_list_element=baz");
  }

  @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);
    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]),",
        "    direct_textual_headers=[ctx.file._textual_header],",
        "    direct_public_headers=[ctx.file._public_header],",
        "    direct_private_headers=[ctx.file._private_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,",
        "          textual_headers=compilation_context.direct_textual_headers,",
        "          public_headers=compilation_context.direct_public_headers,",
        "          private_headers=compilation_context.direct_private_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')),",
        "    '_textual_header': attr.label(allow_single_file=True,",
        "        default=Label('//a:textual_header.h')),",
        "    '_public_header': attr.label(allow_single_file=True,",
        "        default=Label('//a:public_header.h')),",
        "    '_private_header': attr.label(allow_single_file=True,",
        "        default=Label('//a:private_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");

    @SuppressWarnings("unchecked")
    List<Artifact> textualHeaders =
        ((Sequence<Artifact>) myInfo.getValue("textual_headers")).getImmutableList();
    assertThat(
            textualHeaders.stream()
                .map(Artifact::getFilename)
                .collect(ImmutableList.toImmutableList()))
        .contains("textual_header.h");
    @SuppressWarnings("unchecked")
    List<Artifact> publicHeaders =
        ((Sequence<Artifact>) myInfo.getValue("public_headers")).getImmutableList();
    assertThat(
            publicHeaders.stream()
                .map(Artifact::getFilename)
                .collect(ImmutableList.toImmutableList()))
        .contains("public_header.h");
    @SuppressWarnings("unchecked")
    List<Artifact> privateHeaders =
        ((Sequence<Artifact>) myInfo.getValue("private_headers")).getImmutableList();
    assertThat(
            privateHeaders.stream()
                .map(Artifact::getFilename)
                .collect(ImmutableList.toImmutableList()))
        .contains("private_header.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.rlib", "c.a", "d.a", "libdep1.a"),
        ImmutableList.of("a.pic.a", "b.rlib", "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_61.so", "b.so", "e.so", "libdep1_61.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.rlib", "c.a", "d.a"),
        ImmutableList.of("a.pic.a", "libdep2.a", "b.rlib", "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.rlib", "c.a", "d.a"),
        ImmutableList.of("a.pic.a", "libdep2.a", "b.rlib", "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.rlib", "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.rlib", "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");
  }

  @Test
  public void testReallyLongSolibLink() throws Exception {
    setUpCcLinkingContextTest(false);

    String longpath =
        "this/is/a/really/really/really/really/really/really/really/really/really/really/"
            + "really/really/really/really/really/really/really/really/really/really/really/"
            + "really/really/long/path/that/generates/really/long/solib/link/path";
    scratch.file(
        longpath + "/BUILD",
        "load('//tools/build_defs/cc:rule.bzl', 'crule')",
        "crule(name='a',",
        "   dynamic_library = 'a.so',",
        ")");

    ConfiguredTarget a = getConfiguredTarget("//" + longpath + ":a");
    StructImpl info = ((StructImpl) getMyInfoFromTarget(a).getValue("info"));
    Depset librariesToLink = info.getValue("libraries_to_link", Depset.class);
    ImmutableList<String> dynamicLibraryParentDirectories =
        librariesToLink.toList(LibraryToLink.class).stream()
            .filter(x -> x.getDynamicLibrary() != null)
            .map(
                x -> x.getDynamicLibrary().getRootRelativePath().getParentDirectory().getBaseName())
            .collect(ImmutableList.toImmutableList());
    for (String dynamicLibraryParentDirectory : dynamicLibraryParentDirectories) {
      assertThat(dynamicLibraryParentDirectory.length()).isLessThan(MAX_FILENAME_LENGTH + 1);
    }
  }

  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(Artifact::getFilename))
        .containsExactly("b.lds", "d.lds");
    Depset linkstamps = info.getValue("linkstamps", Depset.class);
    assertThat(
            artifactsToStrings(
                linkstamps.toList(Linkstamp.class).stream()
                    .map(Linkstamp::getArtifact)
                    .collect(ImmutableList.toImmutableList())))
        .containsExactly("src a/linkstamp.cc");
    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.rlib',",
        "   pic_static_library = 'b.rlib',",
        "   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'],",
        "    linkstamp = 'linkstamp.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=[['-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 = []",
        "  merged_linkstamps = []",
        "  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)",
        "      merged_linkstamps.extend(l.linkstamps)",
        "  linkstamps_linker_input = cc_common.create_linker_input(",
        "                   owner=ctx.label,",
        "                   linkstamps=depset(merged_linkstamps))",
        "  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),",
        "             linkstamps = depset(linkstamps_linker_input.linkstamps),",
        "             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 1 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, (c, p, ext) -> {}));
    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, (c, p, ext) -> {}));
    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, (c, p, ext) -> {}));
    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, (c, p, ext) -> {}));
    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();
    AtomicBoolean called = new AtomicBoolean(false);
    CcModule.artifactNamePatternFromStarlark(
        artifactNamePatternStruct, (c, p, ext) -> called.set(true));
    assertThat(called.get()).isTrue();
  }

  @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();
    AtomicBoolean called = new AtomicBoolean(false);
    CcModule.artifactNamePatternFromStarlark(
        artifactNamePatternStruct, (c, p, ext) -> called.set(true));
    assertThat(called.get()).isTrue();
  }

  @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, (c, p, ext) -> {}));
    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, (c, p, ext) -> {}));
    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 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 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::getName)
            .collect(ImmutableSet.toImmutableSet());
    ImmutableSet<String> actionConfigNames =
        ccToolchainConfigInfo.getActionConfigs().stream()
            .map(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::getName)
            .collect(ImmutableList.toImmutableList());
    ImmutableSet<String> actionConfigNames =
        ccToolchainConfigInfo.getActionConfigs().stream()
            .map(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(CToolchain.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(CToolchain.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',",
        "        )",
        "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, .pic.a or .rlib");
    assertThat(e)
        .hasMessageThat()
        .contains(
            "'a.pic.o' does not have any of the allowed extensions .a, .lib, .pic.a or .rlib");
    assertThat(e)
        .hasMessageThat()
        .contains(
            "'a.ifso' does not have any of the allowed extensions .so, .dylib, .dll, .pyd or"
                + " .wasm");
    assertThat(e)
        .hasMessageThat()
        .contains(
            "'a.lib' does not have any of the allowed extensions .so, .dylib, .dll, .pyd or .wasm");
    assertThat(e)
        .hasMessageThat()
        .contains(
            "'a.dll' does not have any of the allowed extensions .ifso, .tbd, .lib or .dll.a");
  }

  @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(Artifact::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(Artifact::getFilename)
                .collect(ImmutableList.toImmutableList()))
        .doesNotContain("libstarlark_lib.a");
  }

  private static ImmutableList<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(
        "third_party/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("//third_party/bar:starlark_lib");
    assertThat(target).isNotNull();
    CcInfo ccInfo = target.get(CcInfo.PROVIDER);
    assertThat(artifactsToStrings(ccInfo.getCcCompilationContext().getDirectPublicHdrs()))
        .contains("bin third_party/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(
        "third_party/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("//third_party/bar:starlark_lib");
    assertThat(target).isNotNull();
    CcInfo ccInfo = target.get(CcInfo.PROVIDER);
    assertThat(artifactsToStrings(ccInfo.getCcCompilationContext().getDirectPublicHdrs()))
        .contains("bin third_party/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(
        "third_party/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("//third_party/bar:starlark_lib");
    assertThat(target).isNotNull();
    CcInfo ccInfo = target.get(CcInfo.PROVIDER);
    assertThat(artifactsToStrings(ccInfo.getCcCompilationContext().getDirectPublicHdrs()))
        .contains("bin third_party/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");
    assertThat(artifactsToStrings(ccInfo.getCcCompilationContext().getTextualHdrs()))
        .containsExactly("src foo/textual_hdr.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 testTreeArtifactSrcs() throws Exception {
    doTestTreeAtrifactInSrcsAndHdrs("srcs");
  }

  @Test
  public void testTreeArtifactPrivateHdrs() throws Exception {
    doTestTreeAtrifactInSrcsAndHdrs("private_hdrs");
  }

  @Test
  public void testTreeArtifactPublicHdrs() throws Exception {
    doTestTreeAtrifactInSrcsAndHdrs("public_hdrs");
  }

  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, "", "");
  }

  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)",
        "    foo_dict = {'string_variable': 'foo',",
        "            'string_sequence_variable' : ['foo'],",
        "            'string_depset_variable': depset(['foo'])}",
        "    (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,",
        "        textual_hdrs=ctx.files.textual_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)",
        "        if library_to_link.static_library != None:",
        "            files_to_build.append(library_to_link.static_library)",
        "        if library_to_link.dynamic_library != None:",
        "            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),",
        "      'textual_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'],",
        "    textual_hdrs = ['textual_hdr.h'],",
        "    private_hdrs = ['private_starlark_lib.h'],",
        ")",
        "cc_binary(",
        "    name = 'bin',",
        "    deps = ['starlark_lib'],",
        ")");
  }

  @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 testCustomNameOutputArtifact() throws Exception {
    createCcBinRule(
        scratch,
        /* internalApi= */ true,
        "output_type = 'dynamic_library'",
        " main_output=ctx.actions.declare_file('custom_name.so')");
    scratch.file(
        "foo/BUILD",
        "load('//bazel_internal/test_rules/cc:extension.bzl', 'cc_bin')",
        "cc_bin(",
        "    name = 'bin',",
        ")");

    ConfiguredTarget target = getConfiguredTarget("//foo:bin");
    assertThat(target).isNotNull();

    LibraryToLink library = (LibraryToLink) getMyInfoFromTarget(target).getValue("library");
    Artifact dynamicLibrary = library.getResolvedSymlinkDynamicLibrary();
    if (dynamicLibrary == null) {
      dynamicLibrary = library.getDynamicLibrary();
    }

    assertThat(dynamicLibrary).isNotNull();
    assertThat(dynamicLibrary.getFilename()).isEqualTo("custom_name.so");
  }

  @Test
  public void testCustomNameOutputArtifactRaisesError() throws Exception {
    setupTestTransitiveLink(scratch, "output_type = 'dynamic_library'", " main_output=None");

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

  @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 testWindowsDoesNotProduceDynamicLibraryWithoutWinDef() 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));
    createFilesForTestingLinking(scratch, "tools/build_defs/foo", /* linkProviderLines= */ "");
    assertThat(getConfiguredTarget("//foo:bin")).isNotNull();
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    assertThat(target).isNotNull();
    LibraryToLink library =
        (LibraryToLink) ((StarlarkList) getMyInfoFromTarget(target).getValue("libraries")).get(0);
    assertThat(library).isNotNull();
    assertThat(library.getDynamicLibrary()).isNull();
    assertThat(library.getInterfaceLibrary()).isNull();
  }

  @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.parseCanonical("//foo:foo.bzl"), "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.parseCanonical("//foo:foo.bzl"), "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.parseCanonical("//foo:foo.bzl"), "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.parseCanonical("//foo:foo.bzl"), "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 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 doTestTreeAtrifactInSrcsAndHdrs(String attrName) throws Exception {
    createFiles(scratch, "tools/build_defs/foo");
    reporter.removeHandler(failFastHandler);

    scratch.file(
        "bar/create_tree_artifact.bzl",
        "def _impl(ctx):",
        "    tree = ctx.actions.declare_directory('dir')",
        "    ctx.actions.run_shell(",
        "        outputs = [tree],",
        "        inputs = [],",
        "        arguments = [tree.path],",
        "        command = 'mkdir $1',",
        "    )",
        "    return [DefaultInfo(files = depset([tree]))]",
        "create_tree_artifact = rule(implementation = _impl)");
    scratch.file(
        "bar/BUILD",
        "load('//tools/build_defs/foo:extension.bzl', 'cc_starlark_library')",
        "load(':create_tree_artifact.bzl', 'create_tree_artifact')",
        "create_tree_artifact(name = 'tree_artifact')",
        "cc_starlark_library(",
        "    name = 'starlark_lib',",
        "    " + attrName + " = [':tree_artifact'],",
        ")");
    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, boolean internalApi, 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'],",
        ")");

    String extensionDirectory = "tools/build_defs";
    if (internalApi) {
      extensionDirectory = "bazel_internal/test_rules/cc";
      scratch.overwriteFile(extensionDirectory + "/BUILD", "");
    }
    scratch.file(
        extensionDirectory + "/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))",
        "    foo_dict = {'string_variable': 'foo',",
        "            'string_sequence_variable' : ['foo'],",
        "            'string_depset_variable': depset(['foo'])}",
        "    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, /* internalApi= */ false, 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, user_link_flags=['-l'])",
        "  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 testMergeCompilationContexts() 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):",
        "    compilation_contexts = [dep[CcInfo].compilation_context for dep in ctx.attr.deps]",
        "    merged_context = cc_common.merge_compilation_contexts(",
        "        compilation_contexts = compilation_contexts,",
        "    )",
        "    return [CcInfo(compilation_context = merged_context)]",
        "cc_merger = rule(",
        "    _cc_merger_impl,",
        "    attrs = {",
        "        'deps': 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_merger(",
        "    name = 'merge',",
        "    deps = [':public1', ':public2'],",
        ")");

    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");
  }

  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.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 testExpandedCppConfigurationApiBlocked() throws Exception {
    List<String> cppConfigurationOptions =
        ImmutableList.of(
            "strip_opts()",
            "incompatible_enable_cc_test_feature()",
            "build_test_dwp()",
            "grte_top()",
            "enable_legacy_cc_provider()",
            "experimental_cc_implementation_deps()",
            "share_native_deps()",
            "experimental_platform_cc_test()");
    scratch.file(
        "foo/BUILD",
        "load(':custom_rule.bzl', 'cpp_config_rule')",
        "cpp_config_rule(name = 'custom')");
    for (String option : cppConfigurationOptions) {
      scratch.overwriteFile(
          "foo/custom_rule.bzl",
          "def _impl(ctx):",
          "  ctx.fragments.cpp." + option,
          "  return []",
          "cpp_config_rule = rule(",
          "  implementation = _impl,",
          "  fragments = [\"cpp\"],",
          ")");
      invalidatePackages();

      AssertionError e =
          assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:custom"));

      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 + "additional_exported_hdrs = [])",
            compileCall + "propagate_module_map_to_compile_action = True)",
            compileCall + "do_not_generate_module_map = True)",
            compileCall + "code_coverage_enabled = True)",
            compileCall + "separate_module_headers = [])",
            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'],",
          ");");
      initializeSkyframeExecutor();
      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_2_rule', 'additional_inputs_rule',"
            + " 'transitive_modules_rule')",
        "param_2_rule(",
        "  name = 'p2',",
        ")",
        "method_rule(",
        "  name = 'm',",
        ")",
        "additional_inputs_rule(",
        "  name = 'ai',",
        ")",
        "transitive_modules_rule(",
        "  name = 'tm',",
        ")");
    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 _p2_impl(ctx):",
        "  comp_context = cc_common.create_compilation_context(purpose = 'testing')",
        "  return [CcInfo(compilation_context = comp_context)]",
        "def _additional_inputs_impl(ctx):",
        "  comp_context = cc_common.create_compilation_context()",
        "  comp_context.additional_inputs()",
        "def _transitive_modules_impl(ctx):",
        "  comp_context = cc_common.create_compilation_context()",
        "  comp_context.transitive_modules(use_pic = True)",
        "method_rule = rule(",
        "  implementation = _m_impl,",
        ")",
        "param_2_rule = rule(",
        "  implementation = _p2_impl)",
        "additional_inputs_rule = rule(",
        "  implementation = _additional_inputs_impl)",
        "transitive_modules_rule = rule(",
        "  implementation = _transitive_modules_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:p2"));
    assertThat(e).hasMessageThat().contains("Rule in 'my_rules' cannot use private API");
    e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//b:ai"));
    assertThat(e).hasMessageThat().contains("Rule in 'my_rules' cannot use private API");
    e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//b:tm"));
    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'],",
          ")");
      initializeSkyframeExecutor();
      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 testVariableExtensionCompileApi() throws Exception {
    createFilesForTestingCompilation(
        scratch, "tools/build_defs/foo", "variables_extension = foo_dict");
    assertThat(getConfiguredTarget("//foo:bin")).isNotNull();
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    CppCompileAction action =
        (CppCompileAction) getGeneratingAction(artifactByPath(getFilesToBuild(target), ".o"));

    action.getCompileCommandLine().getVariables().getSequenceVariable("string_sequence_variable");
    action.getCompileCommandLine().getVariables().getStringVariable("string_variable");
    action.getCompileCommandLine().getVariables().getSequenceVariable("string_depset_variable");
  }

  @Test
  public void testVariableExtensionLinkingContextApi() throws Exception {
    createFilesForTestingLinking(scratch, "tools/build_defs/foo", "variables_extension = foo_dict");
    assertThat(getConfiguredTarget("//foo:bin")).isNotNull();
    ConfiguredTarget target = getConfiguredTarget("//foo:starlark_lib");
    CppLinkAction action =
        (CppLinkAction) getGeneratingAction(artifactByPath(getFilesToBuild(target), ".a"));

    action.getLinkCommandLine().getBuildVariables().getSequenceVariable("string_sequence_variable");
    action.getLinkCommandLine().getBuildVariables().getStringVariable("string_variable");
    action.getLinkCommandLine().getBuildVariables().getSequenceVariable("string_depset_variable");
  }

  @Test
  public void testVariableExtensionLinkApi() throws Exception {
    setupTestTransitiveLink(
        scratch, "output_type = 'executable'", "variables_extension = foo_dict");
    ConfiguredTarget target = getConfiguredTarget("//foo:bin");
    assertThat(target).isNotNull();
    CppLinkAction action =
        (CppLinkAction)
            getGeneratingAction((Artifact) getMyInfoFromTarget(target).getValue("executable"));

    action.getLinkCommandLine().getBuildVariables().getSequenceVariable("string_sequence_variable");
    action.getLinkCommandLine().getBuildVariables().getStringVariable("string_variable");
    action.getLinkCommandLine().getBuildVariables().getSequenceVariable("string_depset_variable");
  }

  @Test
  public void testVariablesExtensionInvalidValueTypesThrowsError() throws Exception {
    String rulePkg = "b";
    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, /* internalApi= */ false, "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'],",
            ")");
  }


  @Test
  public void testMissingToolchainAndFeatureConfigurationRaisesErrorInCreateLibraryToLink()
      throws Exception {
    scratch.file(
        "b/BUILD",
        "load('//b:rule.bzl', 'cc_rule')",
        "cc_toolchain_alias(name='alias')",
        "cc_rule(name='foo')");

    runTestMissingToolchainAndFeatureConfigurationRaisesErrorInCreateLibraryToLink(
        "None,", "feature_configuration,", "ctx.file._artifact,", "None,");
    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//b:foo"));
    assertThat(e)
        .hasMessageThat()
        .contains("If you pass 'dynamic_library', you must also pass a 'cc_toolchain'");

    runTestMissingToolchainAndFeatureConfigurationRaisesErrorInCreateLibraryToLink(
        "toolchain,", "None,", "ctx.file._artifact,", "None,");
    e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//b:foo"));
    assertThat(e)
        .hasMessageThat()
        .contains("If you pass 'dynamic_library', you must also pass a 'feature_configuration'");

    runTestMissingToolchainAndFeatureConfigurationRaisesErrorInCreateLibraryToLink(
        "None,", "feature_configuration,", "None,", "ctx.file._artifact,");
    e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//b:foo"));
    assertThat(e)
        .hasMessageThat()
        .contains("If you pass 'interface_library', you must also pass a 'cc_toolchain'");

    runTestMissingToolchainAndFeatureConfigurationRaisesErrorInCreateLibraryToLink(
        "toolchain,", "None,", "None,", "ctx.file._artifact,");
    e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//b:foo"));
    assertThat(e)
        .hasMessageThat()
        .contains("If you pass 'interface_library', you must also pass a 'feature_configuration'");
  }

  private void runTestMissingToolchainAndFeatureConfigurationRaisesErrorInCreateLibraryToLink(
      String toolchain, String featureConfiguration, String dynamicLibrary, String interfaceLibrary)
      throws Exception {
    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,",
        "  )",
        "  cc_common.create_library_to_link(",
        "    actions=ctx.actions, ",
        "    cc_toolchain = " + toolchain,
        "    feature_configuration = " + featureConfiguration,
        "    dynamic_library =" + dynamicLibrary,
        "    interface_library =" + interfaceLibrary,
        "  )",
        "  return [DefaultInfo()]",
        "cc_rule = rule(",
        "  implementation = _impl,",
        "  attrs = { ",
        "    '_artifact': attr.label(allow_single_file=True, default=Label('//b:foo.soifso')),",
        "    '_cc_toolchain': attr.label(default=Label('//b:alias'))",
        "  },",
        "  fragments = ['cpp'],",
        ")");
    invalidatePackages();
  }

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

    scratch.file(
        "a/rule.bzl",
        "def _impl(ctx):",
        "  cc_internal",
        "  return DefaultInfo()",
        "crule = rule(",
        "  _impl,",
        ")");

    AssertionError e = assertThrows(AssertionError.class, () -> getConfiguredTarget("//a:r"));
    assertThat(e).hasMessageThat().contains("name 'cc_internal' is not defined");
  }

  @Test
  public void testExtendedBuildConfigurationApiBlocked() throws Exception {
    scratch.file(
        "foo/BUILD",
        "load(':custom_rule.bzl', 'build_config_rule')",
        "build_config_rule(name = 'custom')");
    scratch.file(
        "foo/custom_rule.bzl",
        "def _impl(ctx):",
        "  ctx.configuration.stamp_binaries()",
        "  return []",
        "build_config_rule = rule(",
        "  implementation = _impl,",
        ")");
    invalidatePackages();

    AssertionError e =
        assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:custom"));

    assertThat(e).hasMessageThat().contains("private API only for use in builtins");
  }

  @Test
  public void testExtendedCcCompilationOutputsLtoCompilationContextBlocked() throws Exception {
    scratch.file(
        "foo/BUILD",
        "load(':custom_rule.bzl', 'compilation_outputs_rule')",
        "compilation_outputs_rule(name = 'custom')");

    scratch.file(
        "foo/custom_rule.bzl",
        "def _impl(ctx):",
        "  cc_common.create_compilation_outputs().lto_compilation_context()",
        "  return []",
        "compilation_outputs_rule = rule(",
        "  implementation = _impl,",
        ")");
    invalidatePackages();

    AssertionError e =
        assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:custom"));

    assertThat(e).hasMessageThat().contains("cannot use private API");
  }

  @Test
  public void testExtendedCcCompilationOutputsDwoFilesBlocked() throws Exception {
    scratch.file(
        "foo/BUILD",
        "load(':custom_rule.bzl', 'compilation_outputs_rule')",
        "compilation_outputs_rule(name = 'custom')");

    scratch.file(
        "foo/custom_rule.bzl",
        "def _impl(ctx):",
        "  cc_common.create_compilation_outputs().dwo_files()",
        "  return []",
        "compilation_outputs_rule = rule(",
        "  implementation = _impl,",
        ")");
    invalidatePackages();

    AssertionError e =
        assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:custom"));

    assertThat(e).hasMessageThat().contains("cannot use private API");
  }

  @Test
  public void testExtendedCcCompilationOutputsPicDwoFilesBlocked() throws Exception {
    scratch.file(
        "foo/BUILD",
        "load(':custom_rule.bzl', 'compilation_outputs_rule')",
        "compilation_outputs_rule(name = 'custom')");

    scratch.file(
        "foo/custom_rule.bzl",
        "def _impl(ctx):",
        "  cc_common.create_compilation_outputs().pic_dwo_files()",
        "  return []",
        "compilation_outputs_rule = rule(",
        "  implementation = _impl,",
        ")");
    invalidatePackages();

    AssertionError e =
        assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:custom"));

    assertThat(e).hasMessageThat().contains("cannot use private API");
  }

  @Test
  public void testExtendedCcLinkingContextApiBlocked() throws Exception {
    scratch.file(
        "foo/BUILD",
        "load(':custom_rule.bzl', 'cc_linking_context_rule')",
        "cc_linking_context_rule(name = 'custom')");
    scratch.file(
        "foo/custom_rule.bzl",
        "def _impl(ctx):",
        "  cc_common.create_linking_context(linker_inputs = depset()).extra_link_time_libraries()",
        "  return []",
        "cc_linking_context_rule = rule(",
        "  implementation = _impl,",
        ")");
    invalidatePackages();

    AssertionError e =
        assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:custom"));

    assertThat(e).hasMessageThat().contains("cannot use private API");
  }

  @Test
  public void testExtendedCcLinkingOutputsApiBlocked() throws Exception {
    scratch.file(
        "foo/BUILD",
        "load(':custom_rule.bzl', 'cc_linking_outputs_rule')",
        "cc_toolchain_alias(name='alias')",
        "cc_linking_outputs_rule(name = 'custom')");
    scratch.file(
        "foo/custom_rule.bzl",
        "def _impl(ctx):",
        "  cc_toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(ctx = ctx, cc_toolchain ="
            + " cc_toolchain)",
        "  cc_linking_outputs = cc_common.link(actions = ctx.actions, feature_configuration ="
            + " feature_configuration, cc_toolchain = cc_toolchain, name = ctx.label.name)",
        "  cc_linking_outputs.all_lto_artifacts()",
        "  return []",
        "cc_linking_outputs_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {'_cc_toolchain':" + " attr.label(default=Label('//foo:alias'))},",
        "  fragments = ['cpp'],",
        ")");
    invalidatePackages();

    AssertionError e =
        assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:custom"));

    assertThat(e).hasMessageThat().contains("cannot use private API");
  }

  @Test
  public void testToolRequirementForActionIsNotAccessibleFromOutsideBuiltins() throws Exception {
    scratch.file(
        "foo/BUILD",
        "load(':custom_rule.bzl', 'custom_rule')",
        "cc_toolchain_alias(name='alias')",
        "custom_rule(name = 'custom')");
    scratch.file(
        "foo/custom_rule.bzl",
        "def _impl(ctx):",
        "  cc_toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(ctx = ctx, cc_toolchain ="
            + " cc_toolchain)",
        "  cc_common.get_tool_requirement_for_action(feature_configuration = feature_configuration,"
            + " action_name = 'test')",
        "  return []",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {'_cc_toolchain':" + " attr.label(default=Label('//foo:alias'))},",
        "  fragments = ['cpp'],",
        ")");
    invalidatePackages();

    AssertionError e =
        assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:custom"));

    assertThat(e).hasMessageThat().contains("cannot use private API");
  }

  @Test
  public void testCreateCompilationOutputsPrivateParameterIsNotAccessibleFromOutsideBuiltins()
      throws Exception {
    scratch.file(
        "foo/BUILD", "load(':custom_rule.bzl', 'custom_rule')", "custom_rule(name = 'custom')");
    scratch.file(
        "foo/custom_rule.bzl",
        "def _impl(ctx):",
        "  cc_common.create_compilation_outputs(objects = None, pic_objects = None,"
            + " lto_compilation_context = None)",
        "  return []",
        "custom_rule = rule(",
        "  implementation = _impl,",
        ")");
    invalidatePackages();

    AssertionError e =
        assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:custom"));

    assertThat(e).hasMessageThat().contains("cannot use private API");
  }

  @Test
  public void testGetCompileBuildVariablesStripOptsNotAcessibleFromOutsideBuiltins()
      throws Exception {
    scratch.file(
        "foo/BUILD",
        "load(':custom_rule.bzl', 'custom_rule')",
        "cc_toolchain_alias(name='alias')",
        "custom_rule(name = 'custom')");
    scratch.file(
        "foo/custom_rule.bzl",
        "def _impl(ctx):",
        "  cc_toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(ctx = ctx, cc_toolchain ="
            + " cc_toolchain)",
        "  cc_common.create_compile_variables(cc_toolchain = cc_toolchain, feature_configuration ="
            + " feature_configuration, strip_opts = [])",
        "  return []",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {'_cc_toolchain':" + " attr.label(default=Label('//foo:alias'))},",
        "  fragments = ['cpp'],",
        ")");
    invalidatePackages();

    AssertionError e =
        assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:custom"));

    assertThat(e).hasMessageThat().contains("cannot use private API");
  }

  @Test
  public void testGetCompileBuildVariablesInputFileNotAcessibleFromOutsideBuiltins()
      throws Exception {
    scratch.file(
        "foo/BUILD",
        "load(':custom_rule.bzl', 'custom_rule')",
        "cc_toolchain_alias(name='alias')",
        "custom_rule(name = 'custom')");
    scratch.file(
        "foo/custom_rule.bzl",
        "def _impl(ctx):",
        "  cc_toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(ctx = ctx, cc_toolchain ="
            + " cc_toolchain)",
        "  cc_common.create_compile_variables(cc_toolchain = cc_toolchain, feature_configuration ="
            + " feature_configuration, input_file = '')",
        "  return []",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {'_cc_toolchain':" + " attr.label(default=Label('//foo:alias'))},",
        "  fragments = ['cpp'],",
        ")");
    invalidatePackages();

    AssertionError e =
        assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:custom"));

    assertThat(e).hasMessageThat().contains("cannot use private API");
  }

  @Test
  public void testCreateLinkingContextFromCompilationOutputsStampNotAcessibleFromOutsideBuiltins()
      throws Exception {
    scratch.file(
        "foo/BUILD",
        "load(':custom_rule.bzl', 'custom_rule')",
        "cc_toolchain_alias(name='alias')",
        "custom_rule(name = 'custom')");
    scratch.file(
        "foo/custom_rule.bzl",
        "def _impl(ctx):",
        "  cc_toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(ctx = ctx, cc_toolchain ="
            + " cc_toolchain)",
        "  cc_common.create_linking_context_from_compilation_outputs(actions = ctx.actions,"
            + " cc_toolchain = cc_toolchain, feature_configuration ="
            + " feature_configuration,compilation_outputs = cc_common.create_compilation_outputs(),"
            + " name = 'test', stamp = 0)",
        "  return []",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {'_cc_toolchain':" + " attr.label(default=Label('//foo:alias'))},",
        "  fragments = ['cpp'],",
        ")");
    invalidatePackages();

    AssertionError e =
        assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:custom"));

    assertThat(e).hasMessageThat().contains("cannot use private API");
  }

  @Test
  public void testLinkUseTestOnlyFlagNotAcessibleFromOutsideBuiltins() throws Exception {
    scratch.file(
        "foo/BUILD",
        "load(':custom_rule.bzl', 'custom_rule')",
        "cc_toolchain_alias(name='alias')",
        "custom_rule(name = 'custom')");
    scratch.file(
        "foo/custom_rule.bzl",
        "def _impl(ctx):",
        "  cc_toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(ctx = ctx, cc_toolchain ="
            + " cc_toolchain)",
        "  cc_common.link(actions = ctx.actions, cc_toolchain = cc_toolchain, feature_configuration"
            + " = feature_configuration,use_test_only_flags = True, name = 'test')",
        "  return []",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {'_cc_toolchain':" + " attr.label(default=Label('//foo:alias'))},",
        "  fragments = ['cpp'],",
        ")");
    invalidatePackages();

    AssertionError e =
        assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:custom"));

    assertThat(e).hasMessageThat().contains("cannot use private API");
  }

  @Test
  public void testLinkUsePdbFileNotAcessibleFromOutsideBuiltins() throws Exception {
    scratch.file(
        "foo/BUILD",
        "load(':custom_rule.bzl', 'custom_rule')",
        "cc_toolchain_alias(name='alias')",
        "custom_rule(name = 'custom')");
    scratch.file(
        "foo/custom_rule.bzl",
        "def _impl(ctx):",
        "  cc_toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(ctx = ctx, cc_toolchain ="
            + " cc_toolchain)",
        "  cc_common.link(actions = ctx.actions, cc_toolchain = cc_toolchain, feature_configuration"
            + " = feature_configuration,pdb_file = None, name = 'test')",
        "  return []",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {'_cc_toolchain':" + " attr.label(default=Label('//foo:alias'))},",
        "  fragments = ['cpp'],",
        ")");
    invalidatePackages();

    AssertionError e =
        assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:custom"));

    assertThat(e).hasMessageThat().contains("cannot use private API");
  }

  @Test
  public void testLinkUseWinDefFileNotAcessibleFromOutsideBuiltins() throws Exception {
    scratch.file(
        "foo/BUILD",
        "load(':custom_rule.bzl', 'custom_rule')",
        "cc_toolchain_alias(name='alias')",
        "custom_rule(name = 'custom')");
    scratch.file(
        "foo/custom_rule.bzl",
        "def _impl(ctx):",
        "  cc_toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(ctx = ctx, cc_toolchain ="
            + " cc_toolchain)",
        "  cc_common.link(actions = ctx.actions, cc_toolchain = cc_toolchain, feature_configuration"
            + " = feature_configuration,win_def_file = None, name = 'test')",
        "  return []",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {'_cc_toolchain':" + " attr.label(default=Label('//foo:alias'))},",
        "  fragments = ['cpp'],",
        ")");
    invalidatePackages();

    AssertionError e =
        assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:custom"));

    assertThat(e).hasMessageThat().contains("cannot use private API");
  }

  @Test
  public void testCcToolchainRuntimeSysrootNotAccessibleFromOutsideBuiltins() throws Exception {
    scratch.file(
        "foo/BUILD",
        "load(':custom_rule.bzl', 'custom_rule')",
        "cc_toolchain_alias(name='alias')",
        "custom_rule(name = 'custom')");
    scratch.file(
        "foo/custom_rule.bzl",
        "def _impl(ctx):",
        "  cc_toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  cc_toolchain.runtime_sysroot()",
        "  return [DefaultInfo()]",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {'_cc_toolchain': attr.label(default=Label('//foo:alias'))},",
        "  fragments = ['cpp'],",
        ")");
    invalidatePackages();

    AssertionError e =
        assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:custom"));

    assertThat(e).hasMessageThat().contains("cannot use private API");
  }

  @Test
  public void testCcToolchainCompileFilesNotAccessibleFromOutsideBuiltins() throws Exception {
    scratch.file(
        "foo/BUILD",
        "load(':custom_rule.bzl', 'custom_rule')",
        "cc_toolchain_alias(name='alias')",
        "custom_rule(name = 'custom')");
    scratch.file(
        "foo/custom_rule.bzl",
        "def _impl(ctx):",
        "  cc_toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  cc_toolchain.compiler_files()",
        "  return [DefaultInfo()]",
        "custom_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {'_cc_toolchain': attr.label(default=Label('//foo:alias'))},",
        "  fragments = ['cpp'],",
        ")");
    invalidatePackages();

    AssertionError e =
        assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:custom"));

    assertThat(e).hasMessageThat().contains("cannot use private API");
  }

  @Test
  public void testGetBuildInfoArtifactsIsPrivateApi() throws Exception {
    scratch.file(
        "foo/BUILD", "load(':custom_rule.bzl', 'custom_rule')", "custom_rule(name = 'custom')");
    scratch.file(
        "foo/custom_rule.bzl",
        "def _impl(ctx):",
        "  cc_common.get_build_info(ctx)",
        "  return []",
        "custom_rule = rule(",
        "  implementation = _impl,",
        ")");
    invalidatePackages();

    AssertionError e =
        assertThrows(AssertionError.class, () -> getConfiguredTarget("//foo:custom"));

    assertThat(e)
        .hasMessageThat()
        .contains("Error in get_build_info: Rule in 'foo' cannot use private API");
  }

  @Test
  public void testBuildInfoArtifacts() throws Exception {
    scratch.file(
        "bazel_internal/test_rules/cc/rule.bzl",
        "def _impl(ctx):",
        "  artifacts = cc_common.get_build_info(ctx)",
        "  return [DefaultInfo(files = depset(artifacts))]",
        "build_info_rule = rule(",
        "  implementation = _impl,",
        "  attrs = {'stamp': attr.int()},",
        ")");
    scratch.file(
        "bazel_internal/test_rules/cc/BUILD",
        "load(':rule.bzl', 'build_info_rule')",
        "build_info_rule(name = 'stamped', stamp = 1,)",
        "build_info_rule(name = 'unstamped', stamp = 0,)");
    assertThat(
            prettyArtifactNames(
                getConfiguredTarget("//bazel_internal/test_rules/cc:stamped")
                    .getProvider(FileProvider.class)
                    .getFilesToBuild()))
        .containsExactly("build-info-nonvolatile.h", "build-info-volatile.h");
    assertThat(
            prettyArtifactNames(
                getConfiguredTarget("//bazel_internal/test_rules/cc:unstamped")
                    .getProvider(FileProvider.class)
                    .getFilesToBuild()))
        .containsExactly("build-info-redacted.h");
  }
}
