// 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.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.CompilationMode;
import com.google.devtools.build.lib.analysis.platform.ToolchainInfo;
import com.google.devtools.build.lib.cmdline.Label;
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.events.Location;
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.FdoProvider.FdoMode;
import com.google.devtools.build.lib.rules.cpp.Link.LinkingMode;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.skylarkbuildapi.cpp.CcToolchainProviderApi;
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.util.Pair;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CToolchain;
import java.util.Map;
import javax.annotation.Nullable;

/** Information about a C++ compiler used by the <code>cc_*</code> rules. */
@Immutable
@AutoCodec
public final class CcToolchainProvider extends ToolchainInfo implements CcToolchainProviderApi {
  public static final String SKYLARK_NAME = "CcToolchainInfo";

  /** An empty toolchain to be returned in the error case (instead of null). */
  public static final CcToolchainProvider EMPTY_TOOLCHAIN_IS_ERROR =
      new CcToolchainProvider(
          /* values= */ ImmutableMap.of(),
          /* cppConfiguration= */ null,
          /* toolchainInfo= */ null,
          /* crosstoolTopPathFragment= */ null,
          /* crosstool= */ NestedSetBuilder.emptySet(Order.STABLE_ORDER),
          /* crosstoolMiddleman= */ NestedSetBuilder.emptySet(Order.STABLE_ORDER),
          /* compile= */ NestedSetBuilder.emptySet(Order.STABLE_ORDER),
          /* compileWithoutIncludes= */ NestedSetBuilder.emptySet(Order.STABLE_ORDER),
          /* strip= */ NestedSetBuilder.emptySet(Order.STABLE_ORDER),
          /* objCopy= */ NestedSetBuilder.emptySet(Order.STABLE_ORDER),
          /* as= */ NestedSetBuilder.emptySet(Order.STABLE_ORDER),
          /* ar= */ NestedSetBuilder.emptySet(Order.STABLE_ORDER),
          /* link= */ NestedSetBuilder.emptySet(Order.STABLE_ORDER),
          /* interfaceSoBuilder= */ null,
          /* dwp= */ NestedSetBuilder.emptySet(Order.STABLE_ORDER),
          /* coverage= */ NestedSetBuilder.emptySet(Order.STABLE_ORDER),
          /* libcLink= */ NestedSetBuilder.emptySet(Order.STABLE_ORDER),
          /* staticRuntimeLinkInputs= */ NestedSetBuilder.emptySet(Order.STABLE_ORDER),
          /* staticRuntimeLinkMiddleman= */ null,
          /* dynamicRuntimeLinkInputs= */ NestedSetBuilder.emptySet(Order.STABLE_ORDER),
          /* dynamicRuntimeLinkMiddleman= */ null,
          /* dynamicRuntimeSolibDir= */ PathFragment.EMPTY_FRAGMENT,
          CcCompilationContext.EMPTY,
          /* supportsParamFiles= */ false,
          /* supportsHeaderParsing= */ false,
          CcToolchainVariables.EMPTY,
          /* builtinIncludeFiles= */ ImmutableList.of(),
          /* coverageEnvironment= */ NestedSetBuilder.emptySet(Order.COMPILE_ORDER),
          /* linkDynamicLibraryTool= */ null,
          /* builtInIncludeDirectories= */ ImmutableList.of(),
          /* sysroot= */ null,
          FdoMode.OFF,
          /* fdoProvider= */ null,
          /* useLLVMCoverageMapFormat= */ false,
          /* codeCoverageEnabled= */ false,
          /* isHostConfiguration= */ false);

  @Nullable private final CppConfiguration cppConfiguration;
  private final CppToolchainInfo toolchainInfo;
  private final PathFragment crosstoolTopPathFragment;
  private final NestedSet<Artifact> crosstool;
  private final NestedSet<Artifact> crosstoolMiddleman;
  private final NestedSet<Artifact> compile;
  private final NestedSet<Artifact> compileWithoutIncludes;
  private final NestedSet<Artifact> strip;
  private final NestedSet<Artifact> objCopy;
  private final NestedSet<Artifact> as;
  private final NestedSet<Artifact> ar;
  private final NestedSet<Artifact> link;
  private final Artifact interfaceSoBuilder;
  private final NestedSet<Artifact> dwp;
  private final NestedSet<Artifact> coverage;
  private final NestedSet<Artifact> libcLink;
  private final NestedSet<Artifact> staticRuntimeLinkInputs;
  @Nullable private final Artifact staticRuntimeLinkMiddleman;
  private final NestedSet<Artifact> dynamicRuntimeLinkInputs;
  @Nullable private final Artifact dynamicRuntimeLinkMiddleman;
  private final PathFragment dynamicRuntimeSolibDir;
  private final CcCompilationInfo ccCompilationInfo;
  private final boolean supportsParamFiles;
  private final boolean supportsHeaderParsing;
  private final CcToolchainVariables buildVariables;
  private final ImmutableList<Artifact> builtinIncludeFiles;
  private final NestedSet<Pair<String, String>> coverageEnvironment;
  @Nullable private final Artifact linkDynamicLibraryTool;
  private final ImmutableList<PathFragment> builtInIncludeDirectories;
  @Nullable private final PathFragment sysroot;
  private final FdoMode fdoMode;
  private final boolean useLLVMCoverageMapFormat;
  private final boolean codeCoverageEnabled;
  private final boolean isHostConfiguration;
  private final boolean forcePic;
  private final boolean shouldStripBinaries;
  /**
   * WARNING: We don't like {@link FdoProvider}. Its {@link FdoProvider#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 FdoProvider fdoProvider;

  public CcToolchainProvider(
      ImmutableMap<String, Object> values,
      @Nullable CppConfiguration cppConfiguration,
      CppToolchainInfo toolchainInfo,
      PathFragment crosstoolTopPathFragment,
      NestedSet<Artifact> crosstool,
      NestedSet<Artifact> crosstoolMiddleman,
      NestedSet<Artifact> compile,
      NestedSet<Artifact> compileWithoutIncludes,
      NestedSet<Artifact> strip,
      NestedSet<Artifact> objCopy,
      NestedSet<Artifact> as,
      NestedSet<Artifact> ar,
      NestedSet<Artifact> link,
      Artifact interfaceSoBuilder,
      NestedSet<Artifact> dwp,
      NestedSet<Artifact> coverage,
      NestedSet<Artifact> libcLink,
      NestedSet<Artifact> staticRuntimeLinkInputs,
      @Nullable Artifact staticRuntimeLinkMiddleman,
      NestedSet<Artifact> dynamicRuntimeLinkInputs,
      @Nullable Artifact dynamicRuntimeLinkMiddleman,
      PathFragment dynamicRuntimeSolibDir,
      CcCompilationContext ccCompilationContext,
      boolean supportsParamFiles,
      boolean supportsHeaderParsing,
      CcToolchainVariables buildVariables,
      ImmutableList<Artifact> builtinIncludeFiles,
      NestedSet<Pair<String, String>> coverageEnvironment,
      Artifact linkDynamicLibraryTool,
      ImmutableList<PathFragment> builtInIncludeDirectories,
      @Nullable PathFragment sysroot,
      FdoMode fdoMode,
      FdoProvider fdoProvider,
      boolean useLLVMCoverageMapFormat,
      boolean codeCoverageEnabled,
      boolean isHostConfiguration) {
    super(values, Location.BUILTIN);
    this.cppConfiguration = cppConfiguration;
    this.toolchainInfo = toolchainInfo;
    this.crosstoolTopPathFragment = crosstoolTopPathFragment;
    this.crosstool = Preconditions.checkNotNull(crosstool);
    this.crosstoolMiddleman = Preconditions.checkNotNull(crosstoolMiddleman);
    this.compile = Preconditions.checkNotNull(compile);
    this.compileWithoutIncludes = Preconditions.checkNotNull(compileWithoutIncludes);
    this.strip = Preconditions.checkNotNull(strip);
    this.objCopy = Preconditions.checkNotNull(objCopy);
    this.as = Preconditions.checkNotNull(as);
    this.ar = Preconditions.checkNotNull(ar);
    this.link = Preconditions.checkNotNull(link);
    this.interfaceSoBuilder = interfaceSoBuilder;
    this.dwp = Preconditions.checkNotNull(dwp);
    this.coverage = Preconditions.checkNotNull(coverage);
    this.libcLink = Preconditions.checkNotNull(libcLink);
    this.staticRuntimeLinkInputs = Preconditions.checkNotNull(staticRuntimeLinkInputs);
    this.staticRuntimeLinkMiddleman = staticRuntimeLinkMiddleman;
    this.dynamicRuntimeLinkInputs = Preconditions.checkNotNull(dynamicRuntimeLinkInputs);
    this.dynamicRuntimeLinkMiddleman = dynamicRuntimeLinkMiddleman;
    this.dynamicRuntimeSolibDir = Preconditions.checkNotNull(dynamicRuntimeSolibDir);
    this.ccCompilationInfo =
        new CcCompilationInfo(Preconditions.checkNotNull(ccCompilationContext));
    this.supportsParamFiles = supportsParamFiles;
    this.supportsHeaderParsing = supportsHeaderParsing;
    this.buildVariables = buildVariables;
    this.builtinIncludeFiles = builtinIncludeFiles;
    this.coverageEnvironment = coverageEnvironment;
    this.linkDynamicLibraryTool = linkDynamicLibraryTool;
    this.builtInIncludeDirectories = builtInIncludeDirectories;
    this.sysroot = sysroot;
    this.fdoMode = fdoMode;
    this.fdoProvider = fdoProvider;
    this.useLLVMCoverageMapFormat = useLLVMCoverageMapFormat;
    this.codeCoverageEnabled = codeCoverageEnabled;
    this.isHostConfiguration = isHostConfiguration;
    if (cppConfiguration != null) {
      this.forcePic = cppConfiguration.forcePic();
      this.shouldStripBinaries = cppConfiguration.shouldStripBinaries();
    } else {
      this.forcePic = false;
      this.shouldStripBinaries = false;
    }
  }

  /** Returns c++ Make variables. */
  public static Map<String, String> getCppBuildVariables(
      Function<Tool, PathFragment> getToolPathFragment,
      String targetLibc,
      String compiler,
      String targetCpu,
      PathFragment crosstoolTopPathFragment,
      String abiGlibcVersion,
      String abi,
      Map<String, String> additionalMakeVariables) {
    ImmutableMap.Builder<String, String> result = ImmutableMap.builder();

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

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

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

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

    result.put("C_COMPILER", compiler);

    // Deprecated variables

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

    // TODO(kmensah): Remove when skylark dependencies can be updated to rely on
    // CcToolchainProvider.
    result.putAll(additionalMakeVariables);

    result.put("ABI_GLIBC_VERSION", abiGlibcVersion);
    result.put("ABI", abi);

    return result.build();
  }

  /**
   * 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
   */
  @Override
  public boolean usePicForDynamicLibraries() {
    return forcePic || toolchainNeedsPic();
  }

  /**
   * Returns true if Fission is specified and supported by the CROSSTOOL for the build implied by
   * the given configuration and toolchain.
   */
  public boolean useFission() {
    return Preconditions.checkNotNull(cppConfiguration).fissionIsActiveForCurrentCompilationMode()
        && supportsFission();
  }

  /** 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) {
    // If parse_headers_verifies_modules is switched on, we verify that headers are
    // self-contained by building the module instead.
    return !cppConfiguration.getParseHeadersVerifiesModules()
        && featureConfiguration.isEnabled(CppRuleClasses.PARSE_HEADERS);
  }

  /**
   * Returns true if Fission and 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) {
    return useFission() && featureConfiguration.isEnabled(CppRuleClasses.PER_OBJECT_DEBUG_INFO);
  }

  @Override
  public void addGlobalMakeVariables(ImmutableMap.Builder<String, String> globalMakeEnvBuilder) {
    globalMakeEnvBuilder.putAll(
        getCppBuildVariables(
            this::getToolPathFragment,
            getTargetLibc(),
            getCompiler(),
            getTargetCpu(),
            crosstoolTopPathFragment,
            getAbiGlibcVersion(),
            getAbi(),
            getAdditionalMakeVariables()));
  }

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

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

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

  /**
   * Returns all the files in Crosstool. Is not a middleman.
   */
  public NestedSet<Artifact> getCrosstool() {
    return crosstool;
  }

  /**
   * Returns a middleman for all the files in Crosstool.
   */
  public NestedSet<Artifact> getCrosstoolMiddleman() {
    return crosstoolMiddleman;
  }

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

  /**
   * 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 #getCompile()}.
   */
  public NestedSet<Artifact> getCompileWithoutIncludes() {
    if (compileWithoutIncludes.isEmpty()) {
      return getCompile();
    }
    return compileWithoutIncludes;
  }

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

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

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

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

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

  public NestedSet<Artifact> getDwp() {
    return dwp;
  }

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

  public NestedSet<Artifact> getLibcLink() {
    return libcLink;
  }

  /**
   * 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) {
    if (shouldStaticallyLinkCppRuntimes(featureConfiguration)) {
      return staticRuntimeLinkInputs;
    } else {
      return NestedSetBuilder.emptySet(Order.STABLE_ORDER);
    }
  }

  /** Returns an aggregating middleman that represents the static runtime libraries. */
  @Nullable
  public Artifact getStaticRuntimeLinkMiddleman(FeatureConfiguration featureConfiguration) {
    if (shouldStaticallyLinkCppRuntimes(featureConfiguration)) {
      return staticRuntimeLinkMiddleman;
    } else {
      return null;
    }
  }

  /** Returns the dynamic runtime libraries. */
  public NestedSet<Artifact> getDynamicRuntimeLinkInputs(
      FeatureConfiguration featureConfiguration) {
    if (shouldStaticallyLinkCppRuntimes(featureConfiguration)) {
      return dynamicRuntimeLinkInputs;
    } else {
      return NestedSetBuilder.emptySet(Order.STABLE_ORDER);
    }
  }

  /** Returns an aggregating middleman that represents the dynamic runtime libraries. */
  @Nullable
  public Artifact getDynamicRuntimeLinkMiddleman(FeatureConfiguration featureConfiguration) {
    if (shouldStaticallyLinkCppRuntimes(featureConfiguration)) {
      return dynamicRuntimeLinkMiddleman;
    } else {
      return null;
    }
  }

  /**
   * 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;
  }

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

  /** Returns the {@code CcCompilationContext} for the toolchain. */
  public CcCompilationInfo getCcCompilationInfo() {
    return ccCompilationInfo;
  }

  /**
   * Whether the toolchains supports parameter files.
   */
  public boolean supportsParamFiles() {
    return supportsParamFiles;
  }
  
  /**
   * Returns the configured features of the toolchain.
   */
  @Nullable
  public CcToolchainFeatures getFeatures() {
    return toolchainInfo.getFeatures();
  }

  public Label getCcToolchainLabel() {
    return toolchainInfo.getCcToolchainLabel();
  }

  /**
   * Returns whether shared libraries must be compiled with position independent code on this
   * platform.
   */
  public boolean toolchainNeedsPic() {
    return toolchainInfo.toolchainNeedsPic();
  }

  /**
   * 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 toolchainInfo.getRuntimeSysroot();
  }

  /**
   * 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 toolchainInfo.getSolibDirectory();
  }

  /**
   * Returns the compilation mode.
   */
  @Nullable
  public CompilationMode getCompilationMode() {
    return cppConfiguration == null ? null : cppConfiguration.getCompilationMode();
  }

  /**
   * Returns whether the toolchain supports the gold linker.
   */
  public boolean supportsGoldLinker() {
    return toolchainInfo.supportsGoldLinker();
  }

  /**
   * Returns whether the toolchain supports dynamic linking.
   */
  public boolean supportsDynamicLinker() {
    return toolchainInfo.supportsDynamicLinker();
  }

  /**
   * Returns whether the toolchain supports linking C/C++ runtime libraries
   * supplied inside the toolchain distribution.
   */
  public boolean supportsEmbeddedRuntimes() {
    return toolchainInfo.supportsEmbeddedRuntimes();
  }

  /**
   * Returns whether the toolchain supports EXEC_ORIGIN libraries resolution.
   */
  public boolean supportsExecOrigin() {
    // We're rolling out support for this in the same release that also supports embedded runtimes.
    return toolchainInfo.supportsEmbeddedRuntimes();
  }

  /** Returns whether the toolchain supports the --start-lib/--end-lib options. */
  public boolean supportsStartEndLib() {
    return toolchainInfo.supportsStartEndLib();
  }

  /**
   * Returns whether this toolchain supports interface shared objects.
   *
   * <p>Should be true if this toolchain generates ELF objects.
   */
  public boolean supportsInterfaceSharedObjects() {
    return toolchainInfo.supportsInterfaceSharedObjects();
  }

  @Nullable
  public CppConfiguration getCppConfiguration() {
    return cppConfiguration;
  }

  /** Returns build variables to be templated into the crosstool. */
  public CcToolchainVariables getBuildVariables() {
    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.
   */
  public ImmutableList<Artifact> getBuiltinIncludeFiles() {
    return builtinIncludeFiles;
  }

  /**
   * Returns the environment variables that need to be added to tests that collect code coverage.
   */
  public NestedSet<Pair<String, String>> getCoverageEnvironment() {
    return coverageEnvironment;
  }

  /**
   * 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
  public String getSysroot() {
    return sysroot != null ? sysroot.getPathString() : null;
  }

  public PathFragment getSysrootPathFragment() {
    return sysroot;
  }

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

  /**
   * 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 toolchainInfo.getAbi();
  }

  /**
   * 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 toolchainInfo.getAbiGlibcVersion();
  }

  /**
   * Returns a label that references the library files needed to statically
   * link the C++ runtime (i.e. libgcc.a, libgcc_eh.a, libstdc++.a) for the
   * target architecture.
   */
  public Label getStaticRuntimeLibsLabel() {
    return toolchainInfo.getStaticRuntimeLibsLabel();
  }

  /**
   * Returns a label that references the library files needed to dynamically
   * link the C++ runtime (i.e. libgcc_s.so, libstdc++.so) for the target
   * architecture.
   */
  public Label getDynamicRuntimeLibsLabel() {
    return toolchainInfo.getDynamicRuntimeLibsLabel();
  }

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

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

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

  /**
   * 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 toolchainInfo.getAdditionalMakeVariables();
  }

  public FdoProvider getFdoProvider() {
    return fdoProvider;
  }

  /**
   * Returns whether the toolchain supports "Fission" C++ builds, i.e. builds where compilation
   * partitions object code and debug symbols into separate output files.
   */
  public boolean supportsFission() {
    return toolchainInfo.supportsFission();
  }

  @Override
  // TODO(b/24373706): Remove this method once new C++ toolchain API is available
  public ImmutableList<String> getUnfilteredCompilerOptionsWithSysroot(
      Iterable<String> featuresNotUsedAnymore) throws EvalException {
    cppConfiguration.checkForLegacyCompilationApiAvailability();
    return toolchainInfo.getUnfilteredCompilerOptions(sysroot);
  }

  public ImmutableList<String> getUnfilteredCompilerOptions() {
    return toolchainInfo.getUnfilteredCompilerOptions(/* sysroot= */ null);
  }

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

  @Override
  public ImmutableList<String> getLinkOptionsWithSysroot() throws EvalException {
    if (cppConfiguration == null) {
      return ImmutableList.of();
    }
    cppConfiguration.checkForLegacyLinkingApiAvailability();
    return cppConfiguration.getLinkOptionsDoNotUse(sysroot);
  }

  public ImmutableList<String> getLinkOptions() {
    return cppConfiguration.getLinkOptionsDoNotUse(/* sysroot= */ null);
  }

  /**
   * Returns test-only link options such that certain test-specific features can be configured
   * separately (e.g. lazy binding).
   */
  public ImmutableList<String> getTestOnlyLinkOptions() {
    return toolchainInfo.getTestOnlyLinkOptions();
  }

  /** Returns the system name which is required by the toolchain to run. */
  public String getHostSystemName() {
    return toolchainInfo.getHostSystemName();
  }

  /**
   * Returns the list of options to be used with 'objcopy' when converting binary files to object
   * files, or {@code null} if this operation is not supported.
   */
  public ImmutableList<String> getObjCopyOptionsForEmbedding() {
    return toolchainInfo.getObjCopyOptionsForEmbedding();
  }

  /**
   * Returns the list of options to be used with 'ld' when converting binary files to object files,
   * or {@code null} if this operation is not supported.
   */
  public ImmutableList<String> getLdOptionsForEmbedding() {
    return toolchainInfo.getLdOptionsForEmbedding();
  }

  /**
   * Returns link options for the specified flag list, combined with universal options for all
   * shared libraries (regardless of link staticness).
   */
  ImmutableList<String> getSharedLibraryLinkOptions(ImmutableList<String> flags) {
    return toolchainInfo.getSharedLibraryLinkOptions(flags);
  }

  /** Returns compiler flags arising from the {@link CToolchain}. */
  ImmutableList<String> getToolchainCompilerFlags() {
    return toolchainInfo.getCompilerFlags();
  }

  /** Returns additional compiler flags for C++ arising from the {@link CToolchain} */
  ImmutableList<String> getToolchainCxxFlags() {
    return toolchainInfo.getCxxFlags();
  }

  /**
   * Returns compiler flags arising from the {@link CToolchain} for C compilation by compilation
   * mode.
   */
  ImmutableListMultimap<CompilationMode, String> getCFlagsByCompilationMode() {
    return toolchainInfo.getCFlagsByCompilationMode();
  }

  /**
   * Returns compiler flags arising from the {@link CToolchain} for C++ compilation by compilation
   * mode.
   */
  ImmutableListMultimap<CompilationMode, String> getCxxFlagsByCompilationMode() {
    return toolchainInfo.getCxxFlagsByCompilationMode();
  }

  /** Returns linker flags for fully statically linked outputs. */
  ImmutableList<String> getLegacyFullyStaticLinkFlags(CompilationMode compilationMode) {
    return configureAllLegacyLinkOptions(compilationMode, LinkingMode.LEGACY_FULLY_STATIC);
  }

  /** Returns linker flags for mostly static linked outputs. */
  ImmutableList<String> getLegacyMostlyStaticLinkFlags(CompilationMode compilationMode) {
    return configureAllLegacyLinkOptions(compilationMode, LinkingMode.STATIC);
  }

  /** Returns linker flags for mostly static shared linked outputs. */
  ImmutableList<String> getLegacyMostlyStaticSharedLinkFlags(CompilationMode compilationMode) {
    return configureAllLegacyLinkOptions(
        compilationMode, LinkingMode.LEGACY_MOSTLY_STATIC_LIBRARIES);
  }

  /** Returns linker flags for artifacts that are not fully or mostly statically linked. */
  ImmutableList<String> getLegacyDynamicLinkFlags(CompilationMode compilationMode) {
    return configureAllLegacyLinkOptions(compilationMode, LinkingMode.DYNAMIC);
  }

  /**
   * Return all flags coming from naked {@code linker_flag} fields in the crosstool. {@code
   * linker_flag}s coming from linking_mode_flags and compilation_mode_flags are not included. If
   * you need all possible linker flags, use {@link #configureAllLegacyLinkOptions(CompilationMode,
   * LinkingMode)}.
   */
  public ImmutableList<String> getLegacyLinkOptions() {
    return toolchainInfo.getLegacyLinkOptions();
  }

  /**
   * Return all flags coming from {@code compiler_flag} crosstool fields excluding flags coming from
   * --copt options and copts attribute.
   */
  public ImmutableList<String> getLegacyCompileOptions() {
    ImmutableList.Builder<String> coptsBuilder =
        ImmutableList.<String>builder()
            .addAll(getToolchainCompilerFlags())
            .addAll(getCFlagsByCompilationMode().get(cppConfiguration.getCompilationMode()));

    if (cppConfiguration.isOmitfp()) {
      coptsBuilder.add("-fomit-frame-pointer");
      coptsBuilder.add("-fasynchronous-unwind-tables");
      coptsBuilder.add("-DNO_FRAME_POINTER");
    }

    return coptsBuilder.build();
  }

  public ImmutableList<String> getLegacyCompileOptionsWithCopts() {
    return ImmutableList.<String>builder()
        .addAll(getLegacyCompileOptions())
        .addAll(cppConfiguration.getCopts())
        .build();
  }

  /** Return all possible {@code linker_flag} flags from the crosstool. */
  ImmutableList<String> configureAllLegacyLinkOptions(
      CompilationMode compilationMode, LinkingMode linkingMode) {
    return toolchainInfo.configureAllLegacyLinkOptions(compilationMode, linkingMode);
  }

  /** Returns the GNU System Name */
  @Override
  public String getTargetGnuSystemName() {
    return toolchainInfo == null ? null : toolchainInfo.getTargetGnuSystemName();
  }

  /** Returns the architecture component of the GNU System Name */
  public String getGnuSystemArch() {
    return toolchainInfo.getGnuSystemArch();
  }

  public final boolean isLLVMCompiler() {
    return toolchainInfo.isLLVMCompiler();
  }

  public FdoMode getFdoMode() {
    return fdoMode;
  }

  /**
   * WARNING: This method is only added to allow incremental migration of existing users. Please do
   * not use in new code. Will be removed soon as part of the new Skylark API to the C++ toolchain.
   */
  @Override
  public ImmutableList<String> getCompilerOptions() throws EvalException {
    cppConfiguration.checkForLegacyCompilationApiAvailability();
    return getLegacyCompileOptionsWithCopts();
  }

  /**
   * WARNING: This method is only added to allow incremental migration of existing users. Please do
   * not use in new code. Will be removed soon as part of the new Skylark API to the C++ toolchain.
   *
   * <p>Returns the list of additional C-specific options to use for compiling C. These should be go
   * on the command line after the common options returned by {@link
   * CcToolchainProvider#getLegacyCompileOptionsWithCopts()}.
   */
  @Override
  public ImmutableList<String> getCOptions() throws EvalException {
    cppConfiguration.checkForLegacyCompilationApiAvailability();
    return cppConfiguration.getCOptions();
  }

  /**
   * WARNING: This method is only added to allow incremental migration of existing users. Please do
   * not use in new code. Will be removed soon as part of the new Skylark API to the C++ toolchain.
   *
   * <p>Returns the list of additional C++-specific options to use for compiling C++. These should
   * be on the command line after the common options returned by {@link #getCompilerOptions}.
   */
  @Override
  @Deprecated
  public ImmutableList<String> getCxxOptionsWithCopts() throws EvalException {
    cppConfiguration.checkForLegacyCompilationApiAvailability();
    return ImmutableList.<String>builder()
        .addAll(getLegacyCxxOptions())
        .addAll(cppConfiguration.getCxxopts())
        .build();
  }

  public ImmutableList<String> getLegacyCxxOptions() {
    return ImmutableList.<String>builder()
        .addAll(getToolchainCxxFlags())
        .addAll(getCxxFlagsByCompilationMode().get(cppConfiguration.getCompilationMode()))
        .build();
  }

  /**
   * WARNING: This method is only added to allow incremental migration of existing users. Please do
   * not use in new code. Will be removed soon as part of the new Skylark API to the C++ toolchain.
   *
   * <p>Returns the immutable list of linker options for fully statically linked outputs. Does not
   * include command-line options passed via --linkopt or --linkopts.
   *
   * @param sharedLib true if the output is a shared lib, false if it's an executable
   */
  @Override
  @Deprecated
  public ImmutableList<String> getFullyStaticLinkOptions(Boolean sharedLib) throws EvalException {
    cppConfiguration.checkForLegacyLinkingApiAvailability();
    if (!sharedLib) {
      throw new EvalException(
          Location.BUILTIN, "fully_static_link_options is deprecated, new uses are not allowed.");
    }
    return CppHelper.getFullyStaticLinkOptions(cppConfiguration, this, sharedLib);
  }

  /**
   * WARNING: This method is only added to allow incremental migration of existing users. Please do
   * not use in new code. Will be removed soon as part of the new Skylark API to the C++ toolchain.
   *
   * <p>Returns the immutable list of linker options for mostly statically linked outputs. Does not
   * include command-line options passed via --linkopt or --linkopts.
   *
   * @param sharedLib true if the output is a shared lib, false if it's an executable
   */
  @Override
  @Deprecated
  public ImmutableList<String> getMostlyStaticLinkOptions(Boolean sharedLib) throws EvalException {
    cppConfiguration.checkForLegacyLinkingApiAvailability();
    return CppHelper.getMostlyStaticLinkOptions(
        cppConfiguration, this, sharedLib, /* shouldStaticallyLinkCppRuntimes= */ true);
  }

  /**
   * WARNING: This method is only added to allow incremental migration of existing users. Please do
   * not use in new code. Will be removed soon as part of the new Skylark API to the C++ toolchain.
   *
   * <p>Returns the immutable list of linker options for artifacts that are not fully or mostly
   * statically linked. Does not include command-line options passed via --linkopt or --linkopts.
   *
   * @param sharedLib true if the output is a shared lib, false if it's an executable
   */
  @Override
  @Deprecated
  public ImmutableList<String> getDynamicLinkOptions(Boolean sharedLib) throws EvalException {
    cppConfiguration.checkForLegacyLinkingApiAvailability();
    return CppHelper.getDynamicLinkOptions(cppConfiguration, this, sharedLib);
  }

  /**
   * WARNING: This method is only added to allow incremental migration of existing users. Please do
   * not use in new code. Will be removed soon as part of the new Skylark API to the C++ toolchain.
   *
   * Returns the execution path to the linker binary to use for this build. Relative paths are
   * relative to the execution root.
   */
  @Override
  public String getLdExecutableForSkylark() {
    PathFragment ldExecutable = getToolPathFragment(CppConfiguration.Tool.LD);
    return ldExecutable != null ? ldExecutable.getPathString() : "";
  }

  /**
   * WARNING: This method is only added to allow incremental migration of existing users. Please do
   * not use in new code. Will be removed soon as part of the new Skylark API to the C++ toolchain.
   *
   * Returns the path to the GNU binutils 'objcopy' binary to use for this build. (Corresponds to
   * $(OBJCOPY) in make-dbg.) Relative paths are relative to the execution root.
   */
  @Override
  public String getObjCopyExecutableForSkylark() {
    PathFragment objCopyExecutable = getToolPathFragment(Tool.OBJCOPY);
    return objCopyExecutable != null ? objCopyExecutable.getPathString() : "";
  }

  @Override
  public String getCppExecutableForSkylark() {
    PathFragment cppExecutable = getToolPathFragment(Tool.GCC);
    return cppExecutable != null ? cppExecutable.getPathString() : "";
  }

  @Override
  public String getCpreprocessorExecutableForSkylark() {
    PathFragment cpreprocessorExecutable = getToolPathFragment(Tool.CPP);
    return cpreprocessorExecutable != null ? cpreprocessorExecutable.getPathString() : "";
  }

  @Override
  public String getNmExecutableForSkylark() {
    PathFragment nmExecutable = getToolPathFragment(Tool.NM);
    return nmExecutable != null ? nmExecutable.getPathString() : "";
  }

  @Override
  public String getObjdumpExecutableForSkylark() {
    PathFragment objdumpExecutable = getToolPathFragment(Tool.OBJDUMP);
    return objdumpExecutable != null ? objdumpExecutable.getPathString() : "";
  }

  @Override
  public String getArExecutableForSkylark() {
    PathFragment arExecutable = getToolPathFragment(Tool.AR);
    return arExecutable != null ? arExecutable.getPathString() : "";
  }

  @Override
  public String getStripExecutableForSkylark() {
    PathFragment stripExecutable = getToolPathFragment(Tool.STRIP);
    return stripExecutable != null ? stripExecutable.getPathString() : "";
  }

  // Not all of CcToolchainProvider is exposed to Skylark, which makes implementing deep equality
  // impossible: if Java-only parts are considered, the behavior is surprising in Skylark, 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 useLLVMCoverageMapFormat() {
    return useLLVMCoverageMapFormat;
  }

  public boolean isCodeCoverageEnabled() {
    return codeCoverageEnabled;
  }

  public boolean isHostConfiguration() {
    return isHostConfiguration;
  }

  public boolean getForcePic() {
    return forcePic;
  }

  public boolean getShouldStripBinaries() {
    return shouldStripBinaries;
  }
}

