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

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.LicensesProvider;
import com.google.devtools.build.lib.analysis.PackageSpecificationProvider;
import com.google.devtools.build.lib.analysis.RuleErrorConsumer;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.Depset;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.packages.BuiltinProvider;
import com.google.devtools.build.lib.packages.NativeInfo;
import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
import com.google.devtools.build.lib.rules.cpp.CcToolchain.AdditionalBuildVariablesComputer;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration;
import com.google.devtools.build.lib.rules.cpp.CppConfiguration.Tool;
import com.google.devtools.build.lib.rules.cpp.FdoContext.BranchFdoProfile;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.starlarkbuildapi.cpp.CcToolchainProviderApi;
import com.google.devtools.build.lib.vfs.PathFragment;
import javax.annotation.Nullable;
import net.starlark.java.eval.EvalException;
import net.starlark.java.eval.Starlark;
import net.starlark.java.eval.StarlarkThread;

/** Information about a C++ compiler used by the <code>cc_*</code> rules. */
@Immutable
@AutoCodec
public final class CcToolchainProvider extends NativeInfo
    implements CcToolchainProviderApi<
            FeatureConfigurationForStarlark, BranchFdoProfile, FdoContext>,
        HasCcToolchainLabel {

  public static final BuiltinProvider<CcToolchainProvider> PROVIDER =
      new BuiltinProvider<CcToolchainProvider>("CcToolchainInfo", CcToolchainProvider.class) {};

  @Nullable private final CppConfiguration cppConfiguration;
  private final PathFragment crosstoolTopPathFragment;
  private final NestedSet<Artifact> allFiles;
  private final NestedSet<Artifact> allFilesIncludingLibc;
  private final NestedSet<Artifact> compilerFiles;
  private final NestedSet<Artifact> compilerFilesWithoutIncludes;
  private final NestedSet<Artifact> stripFiles;
  private final NestedSet<Artifact> objcopyFiles;
  private final NestedSet<Artifact> asFiles;
  private final NestedSet<Artifact> arFiles;
  private final NestedSet<Artifact> linkerFiles;
  private final Artifact interfaceSoBuilder;
  private final NestedSet<Artifact> dwpFiles;
  private final NestedSet<Artifact> coverageFiles;
  private final NestedSet<Artifact> libcLink;
  private final NestedSet<Artifact> targetLibcLink;
  @Nullable private final NestedSet<Artifact> staticRuntimeLinkInputs;
  @Nullable private final NestedSet<Artifact> dynamicRuntimeLinkInputs;
  private final PathFragment dynamicRuntimeSolibDir;
  private final CcInfo ccInfo;
  private final boolean supportsParamFiles;
  private final boolean supportsHeaderParsing;
  private final AdditionalBuildVariablesComputer additionalBuildVariablesComputer;
  private final CcToolchainVariables buildVariables;
  private final ImmutableList<Artifact> builtinIncludeFiles;
  private final ImmutableList<Artifact> targetBuiltinIncludeFiles;
  @Nullable private final Artifact linkDynamicLibraryTool;
  private final ImmutableList<PathFragment> builtInIncludeDirectories;
  @Nullable private final PathFragment sysroot;
  private final PathFragment targetSysroot;
  private final boolean isToolConfiguration;
  private final ImmutableMap<String, PathFragment> toolPaths;
  private final CcToolchainFeatures toolchainFeatures;
  private final String toolchainIdentifier;
  private final String compiler;
  private final String targetCpu;
  private final String targetOS;
  private final PathFragment defaultSysroot;
  private final PathFragment runtimeSysroot;
  private final String abiGlibcVersion;
  private final String abi;
  private final String targetLibc;
  private final String targetSystemName;
  private final Label ccToolchainLabel;
  private final String solibDirectory;

  private final ImmutableMap<String, String> additionalMakeVariables;
  // TODO(b/65151735): Remove when cc_flags is entirely from features.
  private final String legacyCcFlagsMakeVariable;
  /**
   * WARNING: We don't like {@link FdoContext}. Its {@link FdoContext#fdoProfilePath} is pure path
   * and that is horrible as it breaks many Bazel assumptions! Don't do bad stuff with it, don't
   * take inspiration from it.
   */
  private final FdoContext fdoContext;

  private final LicensesProvider licensesProvider;
  private final PackageSpecificationProvider allowlistForLayeringCheck;
  private final PackageSpecificationProvider allowListForLooseHeaderCheck;

  private final String objcopyExecutable;
  private final String compilerExecutable;
  private final String preprocessorExecutable;
  private final String nmExecutable;
  private final String objdumpExecutable;
  private final String arExecutable;
  private final String stripExecutable;
  private final String ldExecutable;
  private final String gcovExecutable;

  public CcToolchainProvider(
      @Nullable CppConfiguration cppConfiguration,
      CcToolchainFeatures toolchainFeatures,
      PathFragment crosstoolTopPathFragment,
      NestedSet<Artifact> allFiles,
      NestedSet<Artifact> allFilesIncludingLibc,
      NestedSet<Artifact> compilerFiles,
      NestedSet<Artifact> compilerFilesWithoutIncludes,
      NestedSet<Artifact> stripFiles,
      NestedSet<Artifact> objcopyFiles,
      NestedSet<Artifact> asFiles,
      NestedSet<Artifact> arFiles,
      NestedSet<Artifact> linkerFiles,
      Artifact interfaceSoBuilder,
      NestedSet<Artifact> dwpFiles,
      NestedSet<Artifact> coverageFiles,
      NestedSet<Artifact> libcLink,
      NestedSet<Artifact> targetLibcLink,
      NestedSet<Artifact> staticRuntimeLinkInputs,
      NestedSet<Artifact> dynamicRuntimeLinkInputs,
      PathFragment dynamicRuntimeSolibDir,
      CcCompilationContext ccCompilationContext,
      boolean supportsParamFiles,
      boolean supportsHeaderParsing,
      AdditionalBuildVariablesComputer additionalBuildVariablesComputer,
      CcToolchainVariables buildVariables,
      ImmutableList<Artifact> builtinIncludeFiles,
      ImmutableList<Artifact> targetBuiltinIncludeFiles,
      Artifact linkDynamicLibraryTool,
      ImmutableList<PathFragment> builtInIncludeDirectories,
      @Nullable PathFragment sysroot,
      @Nullable PathFragment targetSysroot,
      FdoContext fdoContext,
      boolean isToolConfiguration,
      LicensesProvider licensesProvider,
      ImmutableMap<String, PathFragment> toolPaths,
      String toolchainIdentifier,
      String compiler,
      String abiGlibcVersion,
      String targetCpu,
      String targetOS,
      PathFragment defaultSysroot,
      PathFragment runtimeSysroot,
      String targetLibc,
      Label ccToolchainLabel,
      String solibDirectory,
      String abi,
      String targetSystemName,
      ImmutableMap<String, String> additionalMakeVariables,
      String legacyCcFlagsMakeVariable,
      PackageSpecificationProvider allowlistForLayeringCheck,
      PackageSpecificationProvider allowListForLooseHeaderCheck,
      String objcopyExecutable,
      String compilerExecutable,
      String preprocessorExecutable,
      String nmExecutable,
      String objdumpExecutable,
      String arExecutable,
      String stripExecutable,
      String ldExecutable,
      String gcovExecutable) {
    super();
    this.cppConfiguration = cppConfiguration;
    this.crosstoolTopPathFragment = crosstoolTopPathFragment;
    this.allFiles = Preconditions.checkNotNull(allFiles);
    this.allFilesIncludingLibc = Preconditions.checkNotNull(allFilesIncludingLibc);
    this.compilerFiles = Preconditions.checkNotNull(compilerFiles);
    this.compilerFilesWithoutIncludes = Preconditions.checkNotNull(compilerFilesWithoutIncludes);
    this.stripFiles = Preconditions.checkNotNull(stripFiles);
    this.objcopyFiles = Preconditions.checkNotNull(objcopyFiles);
    this.asFiles = Preconditions.checkNotNull(asFiles);
    this.arFiles = Preconditions.checkNotNull(arFiles);
    this.linkerFiles = Preconditions.checkNotNull(linkerFiles);
    this.interfaceSoBuilder = interfaceSoBuilder;
    this.dwpFiles = Preconditions.checkNotNull(dwpFiles);
    this.coverageFiles = Preconditions.checkNotNull(coverageFiles);
    this.libcLink = Preconditions.checkNotNull(libcLink);
    this.targetLibcLink = Preconditions.checkNotNull(targetLibcLink);
    this.staticRuntimeLinkInputs = staticRuntimeLinkInputs;
    this.dynamicRuntimeLinkInputs = dynamicRuntimeLinkInputs;
    this.dynamicRuntimeSolibDir = Preconditions.checkNotNull(dynamicRuntimeSolibDir);
    this.ccInfo =
        CcInfo.builder()
            .setCcCompilationContext(Preconditions.checkNotNull(ccCompilationContext))
            .build();
    this.supportsParamFiles = supportsParamFiles;
    this.supportsHeaderParsing = supportsHeaderParsing;
    this.additionalBuildVariablesComputer = additionalBuildVariablesComputer;
    this.buildVariables = buildVariables;
    this.builtinIncludeFiles = builtinIncludeFiles;
    this.targetBuiltinIncludeFiles = targetBuiltinIncludeFiles;
    this.linkDynamicLibraryTool = linkDynamicLibraryTool;
    this.builtInIncludeDirectories = builtInIncludeDirectories;
    this.sysroot = sysroot;
    this.targetSysroot = targetSysroot;
    this.defaultSysroot = defaultSysroot;
    this.runtimeSysroot = runtimeSysroot;
    this.fdoContext = fdoContext == null ? FdoContext.getDisabledContext() : fdoContext;
    this.isToolConfiguration = isToolConfiguration;
    this.licensesProvider = licensesProvider;
    this.toolPaths = toolPaths;
    this.toolchainFeatures = toolchainFeatures;
    this.toolchainIdentifier = toolchainIdentifier;
    this.compiler = compiler;
    this.abiGlibcVersion = abiGlibcVersion;
    this.targetCpu = targetCpu;
    this.targetOS = targetOS;
    this.targetLibc = targetLibc;
    this.ccToolchainLabel = ccToolchainLabel;
    this.solibDirectory = solibDirectory;
    this.abi = abi;
    this.targetSystemName = targetSystemName;
    this.additionalMakeVariables = additionalMakeVariables;
    this.legacyCcFlagsMakeVariable = legacyCcFlagsMakeVariable;
    this.allowlistForLayeringCheck = allowlistForLayeringCheck;
    this.allowListForLooseHeaderCheck = allowListForLooseHeaderCheck;

    this.objcopyExecutable = objcopyExecutable;
    this.compilerExecutable = compilerExecutable;
    this.preprocessorExecutable = preprocessorExecutable;
    this.nmExecutable = nmExecutable;
    this.objdumpExecutable = objdumpExecutable;
    this.arExecutable = arExecutable;
    this.stripExecutable = stripExecutable;
    this.ldExecutable = ldExecutable;
    this.gcovExecutable = gcovExecutable;
  }

  @Override
  public BuiltinProvider<CcToolchainProvider> getProvider() {
    return PROVIDER;
  }

  /**
   * See {@link #usePicForDynamicLibraries(FeatureConfigurationForStarlark)}. This method is there
   * only to serve Starlark callers.
   */
  @Override
  public boolean usePicForDynamicLibrariesFromStarlark(
      FeatureConfigurationForStarlark featureConfiguration) {
    return usePicForDynamicLibraries(
        featureConfiguration
            .getCppConfigurationFromFeatureConfigurationCreatedForStarlark_andIKnowWhatImDoing(),
        featureConfiguration.getFeatureConfiguration());
  }

  /**
   * Determines if we should apply -fPIC for this rule's C++ compilations. This determination is
   * generally made by the global C++ configuration settings "needsPic" and "usePicForBinaries".
   * However, an individual rule may override these settings by applying -fPIC" to its "nocopts"
   * attribute. This allows incompatible rules to "opt out" of global PIC settings (see bug:
   * "Provide a way to turn off -fPIC for targets that can't be built that way").
   *
   * @return true if this rule's compilations should apply -fPIC, false otherwise
   */
  public boolean usePicForDynamicLibraries(
      CppConfiguration cppConfiguration, FeatureConfiguration featureConfiguration) {
    return cppConfiguration.forcePic()
        || featureConfiguration.isEnabled(CppRuleClasses.SUPPORTS_PIC);
  }

  /**
   * Returns true if PER_OBJECT_DEBUG_INFO are specified and supported by the CROSSTOOL for the
   * build implied by the given configuration, toolchain and feature configuration.
   */
  public boolean shouldCreatePerObjectDebugInfo(
      FeatureConfiguration featureConfiguration, CppConfiguration cppConfiguration) {
    return cppConfiguration.fissionIsActiveForCurrentCompilationMode()
        && featureConfiguration.isEnabled(CppRuleClasses.PER_OBJECT_DEBUG_INFO);
  }

  /** Whether the toolchains supports header parsing. */
  public boolean supportsHeaderParsing() {
    return supportsHeaderParsing;
  }

  /**
   * Returns true if headers should be parsed in this build.
   *
   * <p>This means headers in 'srcs' and 'hdrs' will be "compiled" using {@link CppCompileAction}).
   * It will run compiler's parser to ensure the header is self-contained. This is required for
   * layering_check to work.
   */
  public boolean shouldProcessHeaders(
      FeatureConfiguration featureConfiguration, CppConfiguration cppConfiguration) {
    return featureConfiguration.isEnabled(CppRuleClasses.PARSE_HEADERS);
  }

  public void addGlobalMakeVariables(ImmutableMap.Builder<String, String> globalMakeEnvBuilder) {
    ImmutableMap.Builder<String, String> result = ImmutableMap.builder();

    // hardcoded CC->gcc setting for unit tests
    result.put("CC", getToolPathStringOrNull(Tool.GCC));

    // Make variables provided by crosstool/gcc compiler suite.
    result.put("AR", getToolPathStringOrNull(Tool.AR));
    result.put("NM", getToolPathStringOrNull(Tool.NM));
    result.put("LD", getToolPathStringOrNull(Tool.LD));
    String objcopyTool = getToolPathStringOrNull(Tool.OBJCOPY);
    if (objcopyTool != null) {
      // objcopy is optional in Crosstool
      result.put("OBJCOPY", objcopyTool);
    }
    result.put("STRIP", getToolPathStringOrNull(Tool.STRIP));

    String gcovtool = getToolPathStringOrNull(Tool.GCOVTOOL);
    if (gcovtool != null) {
      // gcov-tool is optional in Crosstool
      result.put("GCOVTOOL", gcovtool);
    }

    if (getTargetLibc().startsWith("glibc-")) {
      result.put("GLIBC_VERSION", getTargetLibc().substring("glibc-".length()));
    } else {
      result.put("GLIBC_VERSION", getTargetLibc());
    }

    result.put("C_COMPILER", getCompiler());

    // Deprecated variables

    // TODO(bazel-team): delete all of these.
    result.put("CROSSTOOLTOP", crosstoolTopPathFragment.getPathString());

    // TODO(bazel-team): Remove when Starlark dependencies can be updated to rely on
    // CcToolchainProvider.
    result.putAll(getAdditionalMakeVariables());

    String abiGlibcVersion = getAbiGlibcVersion();
    if (abiGlibcVersion != null) {
      result.put("ABI_GLIBC_VERSION", getAbiGlibcVersion());
    }

    String abi = getAbi();
    if (abi != null) {
      result.put("ABI", getAbi());
    }

    globalMakeEnvBuilder.putAll(result.build());
  }

  /**
   * Returns the path fragment that is either absolute or relative to the execution root that can be
   * used to execute the given tool.
   *
   * @throws RuleErrorException when the tool is not specified by the toolchain.
   */
  public PathFragment getToolPathFragment(
      CppConfiguration.Tool tool, RuleErrorConsumer ruleErrorConsumer) throws RuleErrorException {
    PathFragment toolPathFragment = getToolPathFragmentOrNull(tool);
    if (toolPathFragment == null) {
      throw ruleErrorConsumer.throwWithRuleError(
          String.format(
              "cc_toolchain '%s' with identifier '%s' doesn't define a tool path for '%s'",
              getCcToolchainLabel(), getToolchainIdentifier(), tool.getNamePart()));
    }
    return toolPathFragment;
  }

  /**
   * Returns the path fragment that is either absolute or relative to the execution root that can be
   * used to execute the given tool.
   */
  @Nullable
  public String getToolPathStringOrNull(Tool tool) {
    PathFragment toolPathFragment = getToolPathFragmentOrNull(tool);
    return toolPathFragment == null ? null : toolPathFragment.getPathString();
  }

  @Override
  public String getToolPathStringOrNoneForStarlark(String toolString, StarlarkThread thread)
      throws EvalException {
    CcModule.checkPrivateStarlarkificationAllowlist(thread);
    Tool tool = Tool.valueOf(toolString);
    PathFragment toolPathFragment = getToolPathFragmentOrNull(tool);
    return toolPathFragment == null ? null : toolPathFragment.getPathString();
  }

  /**
   * Returns the path fragment that is either absolute or relative to the execution root that can be
   * used to execute the given tool.
   */
  @Nullable
  public PathFragment getToolPathFragmentOrNull(CppConfiguration.Tool tool) {
    return CcToolchainProviderHelper.getToolPathFragment(toolPaths, tool);
  }

  @Override
  public ImmutableList<String> getBuiltInIncludeDirectoriesAsStrings() {
    return builtInIncludeDirectories.stream()
        .map(PathFragment::getSafePathString)
        .collect(ImmutableList.toImmutableList());
  }

  @Override
  public Depset getAllFilesForStarlark() {
    return Depset.of(Artifact.TYPE, getAllFiles());
  }

  @Override
  public Depset getStaticRuntimeLibForStarlark(
      FeatureConfigurationForStarlark featureConfigurationForStarlark) throws EvalException {
    return Depset.of(
        Artifact.TYPE,
        getStaticRuntimeLinkInputs(featureConfigurationForStarlark.getFeatureConfiguration()));
  }

  @Override
  public Depset getDynamicRuntimeLibForStarlark(
      FeatureConfigurationForStarlark featureConfigurationForStarlark) throws EvalException {
    return Depset.of(
        Artifact.TYPE,
        getDynamicRuntimeLinkInputs(featureConfigurationForStarlark.getFeatureConfiguration()));
  }

  public ImmutableList<PathFragment> getBuiltInIncludeDirectories() {
    return builtInIncludeDirectories;
  }

  /** Returns the identifier of the toolchain as specified in the {@code CToolchain} proto. */
  @Override
  public String getToolchainIdentifier() {
    return toolchainIdentifier;
  }

  /** Returns all the files in Crosstool. */
  public NestedSet<Artifact> getAllFiles() {
    return allFiles;
  }

  /** Returns all the files in Crosstool + libc. */
  public NestedSet<Artifact> getAllFilesIncludingLibc() {
    return allFilesIncludingLibc;
  }

  /** Returns the files necessary for compilation. */
  public NestedSet<Artifact> getCompilerFiles() {
    return compilerFiles;
  }

  /**
   * Returns the files necessary for compilation excluding headers, assuming that included files
   * will be discovered by input discovery. If the toolchain does not provide this fileset, falls
   * back to {@link #getCompilerFiles()}.
   */
  public NestedSet<Artifact> getCompilerFilesWithoutIncludes() {
    if (compilerFilesWithoutIncludes.isEmpty()) {
      return getCompilerFiles();
    }
    return compilerFilesWithoutIncludes;
  }

  /** Returns the files necessary for a 'strip' invocation. */
  public NestedSet<Artifact> getStripFiles() {
    return stripFiles;
  }

  @Override
  public Depset getStripFilesForStarlark(StarlarkThread thread) throws EvalException {
    CcModule.checkPrivateStarlarkificationAllowlist(thread);
    return Depset.of(Artifact.TYPE, getStripFiles());
  }

  /** Returns the files necessary for an 'objcopy' invocation. */
  public NestedSet<Artifact> getObjcopyFiles() {
    return objcopyFiles;
  }

  @Override
  public Depset getObjcopyFilesForStarlark(StarlarkThread thread) throws EvalException {
    CcModule.checkPrivateStarlarkificationAllowlist(thread);
    return Depset.of(Artifact.TYPE, getObjcopyFiles());
  }

  /**
   * Returns the files necessary for an 'as' invocation. May be empty if the CROSSTOOL file does not
   * define as_files.
   */
  public NestedSet<Artifact> getAsFiles() {
    return asFiles;
  }

  @Override
  public Depset getAsFilesForStarlark(StarlarkThread thread) throws EvalException {
    CcModule.checkPrivateStarlarkificationAllowlist(thread);
    return Depset.of(Artifact.TYPE, getAsFiles());
  }

  /**
   * Returns the files necessary for an 'ar' invocation. May be empty if the CROSSTOOL file does not
   * define ar_files.
   */
  public NestedSet<Artifact> getArFiles() {
    return arFiles;
  }

  @Override
  public Depset getArFilesForStarlark(StarlarkThread thread) throws EvalException {
    CcModule.checkPrivateStarlarkificationAllowlist(thread);
    return Depset.of(Artifact.TYPE, getArFiles());
  }

  /** Returns the files necessary for linking, including the files needed for libc. */
  public NestedSet<Artifact> getLinkerFiles() {
    return linkerFiles;
  }

  @Override
  public Depset getLinkerFilesForStarlark(StarlarkThread thread) throws EvalException {
    CcModule.checkPrivateStarlarkificationAllowlist(thread);
    return Depset.of(Artifact.TYPE, getLinkerFiles());
  }

  public NestedSet<Artifact> getDwpFiles() {
    return dwpFiles;
  }

  /** Returns the files necessary for capturing code coverage. */
  public NestedSet<Artifact> getCoverageFiles() {
    return coverageFiles;
  }

  @Override
  public Depset getCoverageFilesForStarlark(StarlarkThread thread) throws EvalException {
    CcModule.checkPrivateStarlarkificationAllowlist(thread);
    return Depset.of(Artifact.TYPE, getCoverageFiles());
  }

  public NestedSet<Artifact> getLibcLink(CppConfiguration cppConfiguration) {
    if (cppConfiguration.equals(getCppConfigurationEvenThoughItCanBeDifferentThanWhatTargetHas())) {
      return libcLink;
    } else {
      return targetLibcLink;
    }
  }

  /**
   * Returns true if the featureConfiguration includes statically linking the cpp runtimes.
   *
   * @param featureConfiguration the relevant FeatureConfiguration.
   */
  public boolean shouldStaticallyLinkCppRuntimes(FeatureConfiguration featureConfiguration) {
    return featureConfiguration.isEnabled(CppRuleClasses.STATIC_LINK_CPP_RUNTIMES);
  }

  /** Returns the static runtime libraries. */
  public NestedSet<Artifact> getStaticRuntimeLinkInputs(FeatureConfiguration featureConfiguration)
      throws EvalException {
    if (shouldStaticallyLinkCppRuntimes(featureConfiguration)) {
      if (staticRuntimeLinkInputs == null) {
        throw Starlark.errorf(
            "Toolchain supports embedded runtimes, but didn't provide static_runtime_lib"
                + " attribute.");
      }
      return staticRuntimeLinkInputs;
    } else {
      return NestedSetBuilder.emptySet(Order.STABLE_ORDER);
    }
  }

  /** Returns the dynamic runtime libraries. */
  public NestedSet<Artifact> getDynamicRuntimeLinkInputs(FeatureConfiguration featureConfiguration)
      throws EvalException {
    if (shouldStaticallyLinkCppRuntimes(featureConfiguration)) {
      if (dynamicRuntimeLinkInputs == null) {
        throw new EvalException(
            "Toolchain supports embedded runtimes, but didn't provide dynamic_runtime_lib"
                + " attribute.");
      }
      return dynamicRuntimeLinkInputs;
    } else {
      return NestedSetBuilder.emptySet(Order.STABLE_ORDER);
    }
  }

  /**
   * Returns the name of the directory where the solib symlinks for the dynamic runtime libraries
   * live. The directory itself will be under the root of the host configuration in the 'bin'
   * directory.
   */
  public PathFragment getDynamicRuntimeSolibDir() {
    return dynamicRuntimeSolibDir;
  }

  @Override
  public String getDynamicRuntimeSolibDirForStarlark() {
    return getDynamicRuntimeSolibDir().getPathString();
  }

  /** Returns the {@code CcCompilationContext} for the toolchain. */
  public CcCompilationContext getCcCompilationContext() {
    return ccInfo.getCcCompilationContext();
  }

  /** Returns the {@code CcInfo} for the toolchain. */
  public CcInfo getCcInfo() {
    return ccInfo;
  }

  /** Whether the toolchains supports parameter files. */
  public boolean supportsParamFiles() {
    return supportsParamFiles;
  }

  /** Returns the configured features of the toolchain. */
  @Nullable
  public CcToolchainFeatures getFeatures() {
    return toolchainFeatures;
  }

  @Override
  public Label getCcToolchainLabel() {
    return ccToolchainLabel;
  }

  /**
   * Returns the run time sysroot, which is where the dynamic linker and system libraries are found
   * at runtime. This is usually an absolute path. If the toolchain compiler does not support
   * sysroots, then this method returns <code>null</code>.
   */
  public PathFragment getRuntimeSysroot() {
    return runtimeSysroot;
  }

  /**
   * Return the name of the directory (relative to the bin directory) that holds mangled links to
   * shared libraries. This name is always set to the '{@code _solib_<cpu_archictecture_name>}.
   */
  public String getSolibDirectory() {
    return solibDirectory;
  }

  @Override
  public String getSolibDirectoryForStarlark(StarlarkThread thread) throws EvalException {
    CcModule.checkPrivateStarlarkificationAllowlist(thread);
    return getSolibDirectory();
  }

  /** Returns whether the toolchain supports dynamic linking. */
  public boolean supportsDynamicLinker(FeatureConfiguration featureConfiguration) {
    return featureConfiguration.isEnabled(CppRuleClasses.SUPPORTS_DYNAMIC_LINKER);
  }

  /** Returns whether the toolchain supports the --start-lib/--end-lib options. */
  public boolean supportsStartEndLib(FeatureConfiguration featureConfiguration) {
    return featureConfiguration.isEnabled(CppRuleClasses.SUPPORTS_START_END_LIB);
  }

  /** Returns whether this toolchain supports interface shared libraries. */
  public boolean supportsInterfaceSharedLibraries(FeatureConfiguration featureConfiguration) {
    return featureConfiguration.isEnabled(CppRuleClasses.SUPPORTS_INTERFACE_SHARED_LIBRARIES);
  }

  /**
   * Return CppConfiguration instance that was used to configure CcToolchain.
   *
   * <p>If C++ rules use platforms/toolchains without
   * https://github.com/bazelbuild/proposals/blob/master/designs/2019-02-12-toolchain-transitions.md
   * implemented, CcToolchain is analyzed in the host configuration. This configuration is not what
   * should be used by rules using the toolchain. This method should only be used to access stuff
   * from CppConfiguration that is identical between host and target (e.g. incompatible flag
   * values). Don't use it if you don't know what you're doing.
   *
   * <p>Once toolchain transitions are implemented, we can safely use the CppConfiguration from the
   * toolchain in rules.
   */
  CppConfiguration getCppConfigurationEvenThoughItCanBeDifferentThanWhatTargetHas() {
    return cppConfiguration;
  }

  /** Return context-sensitive fdo instrumentation path. */
  public String getCSFdoInstrument() {
    return cppConfiguration.getCSFdoInstrument();
  }

  /** Returns build variables to be templated into the crosstool. */
  public CcToolchainVariables getBuildVariables(
      BuildOptions buildOptions, CppConfiguration cppConfiguration) {
    if (cppConfiguration.enableCcToolchainResolution()) {
      // With platforms, cc toolchain is analyzed in the host configuration, so we cannot reuse
      // build variables instance.
      return CcToolchainProviderHelper.getBuildVariables(
          buildOptions,
          cppConfiguration,
          getSysrootPathFragment(cppConfiguration),
          additionalBuildVariablesComputer);
    }
    return buildVariables;
  }

  /**
   * Return the set of include files that may be included even if they are not mentioned in the
   * source file or any of the headers included by it.
   *
   * @param cppConfiguration
   */
  public ImmutableList<Artifact> getBuiltinIncludeFiles(CppConfiguration cppConfiguration) {
    if (cppConfiguration.equals(getCppConfigurationEvenThoughItCanBeDifferentThanWhatTargetHas())) {
      return builtinIncludeFiles;
    } else {
      return targetBuiltinIncludeFiles;
    }
  }

  /**
   * Returns the tool which should be used for linking dynamic libraries, or in case it's not
   * specified by the crosstool this will be @tools_repository/tools/cpp:link_dynamic_library
   */
  public Artifact getLinkDynamicLibraryTool() {
    return linkDynamicLibraryTool;
  }

  /** Returns the tool that builds interface libraries from dynamic libraries. */
  public Artifact getInterfaceSoBuilder() {
    return interfaceSoBuilder;
  }

  @Override
  @Nullable
  public String getSysroot() {
    return sysroot != null ? sysroot.getPathString() : null;
  }

  public PathFragment getSysrootPathFragment(CppConfiguration cppConfiguration) {
    if (cppConfiguration.equals(getCppConfigurationEvenThoughItCanBeDifferentThanWhatTargetHas())) {
      return sysroot;
    } else {
      return targetSysroot;
    }
  }

  /**
   * Returns the abi we're using, which is a gcc version. E.g.: "gcc-3.4". Note that in practice we
   * might be using gcc-3.4 as ABI even when compiling with gcc-4.1.0, because ABIs are backwards
   * compatible.
   */
  // TODO(bazel-team): The javadoc should clarify how this is used in Blaze.
  public String getAbi() {
    return abi;
  }

  /**
   * Returns the glibc version used by the abi we're using. This is a glibc version number (e.g.,
   * "2.2.2"). Note that in practice we might be using glibc 2.2.2 as ABI even when compiling with
   * gcc-4.2.2, gcc-4.3.1, or gcc-4.4.0 (which use glibc 2.3.6), because ABIs are backwards
   * compatible.
   */
  // TODO(bazel-team): The javadoc should clarify how this is used in Blaze.
  public String getAbiGlibcVersion() {
    return abiGlibcVersion;
  }

  /** Returns the compiler version string (e.g. "gcc-4.1.1"). */
  @Override
  public String getCompiler() {
    return compiler;
  }

  /** Returns the libc version string (e.g. "glibc-2.2.2"). */
  @Override
  public String getTargetLibc() {
    return targetLibc;
  }

  /** Returns the target architecture using blaze-specific constants (e.g. "piii"). */
  @Override
  public String getTargetCpu() {
    return targetCpu;
  }

  /**
   * Returns a map of additional make variables for use by {@link BuildConfiguration}. These are to
   * used to allow some build rules to avoid the limits on stack frame sizes and variable-length
   * arrays.
   *
   * <p>The returned map must contain an entry for {@code STACK_FRAME_UNLIMITED}, though the entry
   * may be an empty string.
   */
  public ImmutableMap<String, String> getAdditionalMakeVariables() {
    return additionalMakeVariables;
  }

  /**
   * Returns the legacy value of the CC_FLAGS Make variable.
   *
   * @deprecated Use the CC_FLAGS from feature configuration instead.
   */
  // TODO(b/65151735): Remove when cc_flags is entirely from features.
  @Deprecated
  public String getLegacyCcFlagsMakeVariable() {
    return legacyCcFlagsMakeVariable;
  }

  public FdoContext getFdoContext() {
    return fdoContext;
  }

  @Override
  public FdoContext getFdoContextForStarlark(StarlarkThread thread) throws EvalException {
    CcModule.checkPrivateStarlarkificationAllowlist(thread);
    return fdoContext;
  }

  @Override
  public String objcopyExecutable() {
    return objcopyExecutable;
  }

  @Override
  public String compilerExecutable() {
    return compilerExecutable;
  }

  @Override
  public String preprocessorExecutable() {
    return preprocessorExecutable;
  }

  @Override
  public String nmExecutable() {
    return nmExecutable;
  }

  @Override
  public String objdumpExecutable() {
    return objdumpExecutable;
  }

  @Override
  public String arExecutable() {
    return arExecutable;
  }

  @Override
  public String stripExecutable() {
    return stripExecutable;
  }

  @Override
  public String ldExecutable() {
    return ldExecutable;
  }

  @Override
  public String gcovExecutable() {
    return gcovExecutable;
  }

  /**
   * Unused, for compatibility with things internal to Google.
   *
   * <p>Deprecated: Use platforms.
   */
  @Deprecated
  public String getTargetOS() {
    return targetOS;
  }

  /** Returns the GNU System Name */
  @Override
  public String getTargetGnuSystemName() {
    return targetSystemName;
  }

  /** Returns the architecture component of the GNU System Name */
  public String getGnuSystemArch() {
    if (targetSystemName.indexOf('-') == -1) {
      return targetSystemName;
    }
    return targetSystemName.substring(0, targetSystemName.indexOf('-'));
  }

  // Not all of CcToolchainProvider is exposed to Starlark, which makes implementing deep equality
  // impossible: if Java-only parts are considered, the behavior is surprising in Starlark, if they
  // are not, the behavior is surprising in Java. Thus, object identity it is.
  @Override
  public boolean equals(Object other) {
    return other == this;
  }

  @Override
  public int hashCode() {
    return System.identityHashCode(this);
  }

  public boolean isToolConfiguration() {
    return isToolConfiguration;
  }

  public LicensesProvider getLicensesProvider() {
    return licensesProvider;
  }

  public PathFragment getDefaultSysroot() {
    return defaultSysroot;
  }

  public boolean requireCtxInConfigureFeatures() {
    return getCppConfigurationEvenThoughItCanBeDifferentThanWhatTargetHas()
        .requireCtxInConfigureFeatures();
  }

  @VisibleForTesting
  NestedSet<Artifact> getStaticRuntimeLibForTesting() {
    return staticRuntimeLinkInputs;
  }

  @VisibleForTesting
  NestedSet<Artifact> getDynamicRuntimeLibForTesting() {
    return dynamicRuntimeLinkInputs;
  }

  public PackageSpecificationProvider getAllowlistForLayeringCheck() {
    return allowlistForLayeringCheck;
  }

  public PackageSpecificationProvider getAllowlistForLooseHeaderCheck() {
    return allowListForLooseHeaderCheck;
  }
}
