<commit_before>// 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 static com.google.common.base.Preconditions.checkState;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
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.ActionOwner;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.Artifact.DerivedArtifact;
import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact;
import com.google.devtools.build.lib.actions.MiddlemanFactory;
import com.google.devtools.build.lib.analysis.AnalysisUtils;
import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
import com.google.devtools.build.lib.analysis.actions.ActionConstructionContext;
import com.google.devtools.build.lib.analysis.config.BuildConfigurationValue;
import com.google.devtools.build.lib.bugreport.BugReport;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.compacthashmap.CompactHashMap;
import com.google.devtools.build.lib.collect.compacthashset.CompactHashSet;
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.rules.cpp.IncludeScanner.IncludeScanningHeaderData;
import com.google.devtools.build.lib.skyframe.TreeArtifactValue;
import com.google.devtools.build.lib.starlarkbuildapi.cpp.CcCompilationContextApi;
import com.google.devtools.build.lib.util.Pair;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.skyframe.SkyFunction.Environment;
import com.google.devtools.build.skyframe.SkyValue;
import com.google.devtools.build.skyframe.SkyframeIterableResult;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.util.AbstractCollection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
import net.starlark.java.eval.EvalException;
import net.starlark.java.eval.StarlarkList;
import net.starlark.java.eval.StarlarkThread;

/**
 * Immutable store of information needed for C++ compilation that is aggregated across dependencies.
 */
@Immutable
public final class CcCompilationContext implements CcCompilationContextApi<Artifact> {
  /** An empty {@code CcCompilationContext}. */
  public static final CcCompilationContext EMPTY =
      builder(/* actionConstructionContext= */ null, /* configuration= */ null, /* label= */ null)
          .build();

  private final CommandLineCcCompilationContext commandLineCcCompilationContext;

  private final NestedSet<PathFragment> looseHdrsDirs;
  private final NestedSet<Artifact> declaredIncludeSrcs;

  /** Module maps from direct dependencies. */
  private final ImmutableList<Artifact> directModuleMaps;

  /** Module maps from dependencies that will be re-exported by this compilation context. */
  private final ImmutableList<CppModuleMap> exportingModuleMaps;

  /** Non-code mandatory compilation inputs. */
  private final NestedSet<Artifact> nonCodeInputs;

  private final HeaderInfo headerInfo;
  private final NestedSet<Artifact> transitiveModules;
  private final NestedSet<Artifact> transitivePicModules;

  private final CppModuleMap cppModuleMap;

  private final boolean propagateModuleMapAsActionInput;

  // Derived from depsContexts.
  private final NestedSet<Artifact> compilationPrerequisites;

  private final CppConfiguration.HeadersCheckingMode headersCheckingMode;

  // Each pair maps the Bazel generated paths of virtual include headers back to their original path
  // relative to the workspace directory.
  // For example it can map
  // "bazel-out/k8-fastbuild/bin/include/common/_virtual_includes/strategy/strategy.h"
  // back to the path of the header in the workspace directory "include/common/strategy.h".
  // This is needed only when code coverage collection is enabled, to report the actual source file
  // name in the coverage output file.
  private final NestedSet<Pair<String, String>> virtualToOriginalHeaders;
  /**
   * Caches the actual number of transitive headers reachable through transitiveHeaderInfos. We need
   * to create maps to store these and so caching this count can substantially help with memory
   * allocations.
   */
  private int transitiveHeaderCount;
  /** Aftifacts generated by the header validation actions. */
  private final NestedSet<Artifact> headerTokens;

  private CcCompilationContext(
      CommandLineCcCompilationContext commandLineCcCompilationContext,
      NestedSet<Artifact> compilationPrerequisites,
      NestedSet<PathFragment> looseHdrsDirs,
      NestedSet<Artifact> declaredIncludeSrcs,
      NestedSet<Artifact> nonCodeInputs,
      HeaderInfo headerInfo,
      NestedSet<Artifact> transitiveModules,
      NestedSet<Artifact> transitivePicModules,
      ImmutableList<Artifact> directModuleMaps,
      ImmutableList<CppModuleMap> exportingModuleMaps,
      CppModuleMap cppModuleMap,
      boolean propagateModuleMapAsActionInput,
      CppConfiguration.HeadersCheckingMode headersCheckingMode,
      NestedSet<Pair<String, String>> virtualToOriginalHeaders,
      NestedSet<Artifact> headerTokens) {
    Preconditions.checkNotNull(commandLineCcCompilationContext);
    this.commandLineCcCompilationContext = commandLineCcCompilationContext;
    this.looseHdrsDirs = looseHdrsDirs;
    this.declaredIncludeSrcs = declaredIncludeSrcs;
    this.directModuleMaps = directModuleMaps;
    this.exportingModuleMaps = exportingModuleMaps;
    this.headerInfo = headerInfo;
    this.transitiveModules = transitiveModules;
    this.transitivePicModules = transitivePicModules;
    this.cppModuleMap = cppModuleMap;
    this.nonCodeInputs = nonCodeInputs;
    this.compilationPrerequisites = compilationPrerequisites;
    this.propagateModuleMapAsActionInput = propagateModuleMapAsActionInput;
    this.headersCheckingMode = headersCheckingMode;
    this.virtualToOriginalHeaders = virtualToOriginalHeaders;
    this.transitiveHeaderCount = -1;
    this.headerTokens = headerTokens;
  }

  @Override
  public boolean isImmutable() {
    return true; // immutable and Starlark-hashable
  }

  @Override
  public Depset getStarlarkDefines() {
    return Depset.of(
        Depset.ElementType.STRING, NestedSetBuilder.wrap(Order.STABLE_ORDER, getDefines()));
  }

  @Override
  public Depset getStarlarkNonTransitiveDefines() {
    return Depset.of(
        Depset.ElementType.STRING,
        NestedSetBuilder.wrap(Order.STABLE_ORDER, getNonTransitiveDefines()));
  }

  @Override
  public Depset getStarlarkHeaders() {
    return Depset.of(Artifact.TYPE, getDeclaredIncludeSrcs());
  }

  @Override
  public StarlarkList<Artifact> getStarlarkDirectModularHeaders() {
    return StarlarkList.immutableCopyOf(
        ImmutableList.<Artifact>builder()
            .addAll(getDirectPublicHdrs())
            .addAll(getDirectPrivateHdrs())
            .build());
  }

  @Override
  public StarlarkList<Artifact> getStarlarkDirectPublicHeaders() {
    return StarlarkList.immutableCopyOf(getDirectPublicHdrs());
  }

  @Override
  public StarlarkList<Artifact> getStarlarkDirectPrivateHeaders() {
    return StarlarkList.immutableCopyOf(getDirectPrivateHdrs());
  }

  @Override
  public StarlarkList<Artifact> getStarlarkDirectTextualHeaders() {<commit_msg>Return separate module headers with public and private headers.<commit_after>// 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 static com.google.common.base.Preconditions.checkState;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
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.ActionOwner;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.Artifact.DerivedArtifact;
import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact;
import com.google.devtools.build.lib.actions.MiddlemanFactory;
import com.google.devtools.build.lib.analysis.AnalysisUtils;
import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
import com.google.devtools.build.lib.analysis.actions.ActionConstructionContext;
import com.google.devtools.build.lib.analysis.config.BuildConfigurationValue;
import com.google.devtools.build.lib.bugreport.BugReport;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.compacthashmap.CompactHashMap;
import com.google.devtools.build.lib.collect.compacthashset.CompactHashSet;
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.rules.cpp.IncludeScanner.IncludeScanningHeaderData;
import com.google.devtools.build.lib.skyframe.TreeArtifactValue;
import com.google.devtools.build.lib.starlarkbuildapi.cpp.CcCompilationContextApi;
import com.google.devtools.build.lib.util.Pair;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.skyframe.SkyFunction.Environment;
import com.google.devtools.build.skyframe.SkyValue;
import com.google.devtools.build.skyframe.SkyframeIterableResult;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.util.AbstractCollection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
import net.starlark.java.eval.EvalException;
import net.starlark.java.eval.StarlarkList;
import net.starlark.java.eval.StarlarkThread;

/**
 * Immutable store of information needed for C++ compilation that is aggregated across dependencies.
 */
@Immutable
public final class CcCompilationContext implements CcCompilationContextApi<Artifact> {
  /** An empty {@code CcCompilationContext}. */
  public static final CcCompilationContext EMPTY =
      builder(/* actionConstructionContext= */ null, /* configuration= */ null, /* label= */ null)
          .build();

  private final CommandLineCcCompilationContext commandLineCcCompilationContext;

  private final NestedSet<PathFragment> looseHdrsDirs;
  private final NestedSet<Artifact> declaredIncludeSrcs;

  /** Module maps from direct dependencies. */
  private final ImmutableList<Artifact> directModuleMaps;

  /** Module maps from dependencies that will be re-exported by this compilation context. */
  private final ImmutableList<CppModuleMap> exportingModuleMaps;

  /** Non-code mandatory compilation inputs. */
  private final NestedSet<Artifact> nonCodeInputs;

  private final HeaderInfo headerInfo;
  private final NestedSet<Artifact> transitiveModules;
  private final NestedSet<Artifact> transitivePicModules;

  private final CppModuleMap cppModuleMap;

  private final boolean propagateModuleMapAsActionInput;

  // Derived from depsContexts.
  private final NestedSet<Artifact> compilationPrerequisites;

  private final CppConfiguration.HeadersCheckingMode headersCheckingMode;

  // Each pair maps the Bazel generated paths of virtual include headers back to their original path
  // relative to the workspace directory.
  // For example it can map
  // "bazel-out/k8-fastbuild/bin/include/common/_virtual_includes/strategy/strategy.h"
  // back to the path of the header in the workspace directory "include/common/strategy.h".
  // This is needed only when code coverage collection is enabled, to report the actual source file
  // name in the coverage output file.
  private final NestedSet<Pair<String, String>> virtualToOriginalHeaders;
  /**
   * Caches the actual number of transitive headers reachable through transitiveHeaderInfos. We need
   * to create maps to store these and so caching this count can substantially help with memory
   * allocations.
   */
  private int transitiveHeaderCount;
  /** Aftifacts generated by the header validation actions. */
  private final NestedSet<Artifact> headerTokens;

  private CcCompilationContext(
      CommandLineCcCompilationContext commandLineCcCompilationContext,
      NestedSet<Artifact> compilationPrerequisites,
      NestedSet<PathFragment> looseHdrsDirs,
      NestedSet<Artifact> declaredIncludeSrcs,
      NestedSet<Artifact> nonCodeInputs,
      HeaderInfo headerInfo,
      NestedSet<Artifact> transitiveModules,
      NestedSet<Artifact> transitivePicModules,
      ImmutableList<Artifact> directModuleMaps,
      ImmutableList<CppModuleMap> exportingModuleMaps,
      CppModuleMap cppModuleMap,
      boolean propagateModuleMapAsActionInput,
      CppConfiguration.HeadersCheckingMode headersCheckingMode,
      NestedSet<Pair<String, String>> virtualToOriginalHeaders,
      NestedSet<Artifact> headerTokens) {
    Preconditions.checkNotNull(commandLineCcCompilationContext);
    this.commandLineCcCompilationContext = commandLineCcCompilationContext;
    this.looseHdrsDirs = looseHdrsDirs;
    this.declaredIncludeSrcs = declaredIncludeSrcs;
    this.directModuleMaps = directModuleMaps;
    this.exportingModuleMaps = exportingModuleMaps;
    this.headerInfo = headerInfo;
    this.transitiveModules = transitiveModules;
    this.transitivePicModules = transitivePicModules;
    this.cppModuleMap = cppModuleMap;
    this.nonCodeInputs = nonCodeInputs;
    this.compilationPrerequisites = compilationPrerequisites;
    this.propagateModuleMapAsActionInput = propagateModuleMapAsActionInput;
    this.headersCheckingMode = headersCheckingMode;
    this.virtualToOriginalHeaders = virtualToOriginalHeaders;
    this.transitiveHeaderCount = -1;
    this.headerTokens = headerTokens;
  }

  @Override
  public boolean isImmutable() {
    return true; // immutable and Starlark-hashable
  }

  @Override
  public Depset getStarlarkDefines() {
    return Depset.of(
        Depset.ElementType.STRING, NestedSetBuilder.wrap(Order.STABLE_ORDER, getDefines()));
  }

  @Override
  public Depset getStarlarkNonTransitiveDefines() {
    return Depset.of(
        Depset.ElementType.STRING,
        NestedSetBuilder.wrap(Order.STABLE_ORDER, getNonTransitiveDefines()));
  }

  @Override
  public Depset getStarlarkHeaders() {
    return Depset.of(Artifact.TYPE, getDeclaredIncludeSrcs());
  }

  @Override
  public StarlarkList<Artifact> getStarlarkDirectModularHeaders() {
    return StarlarkList.immutableCopyOf(
        ImmutableList.<Artifact>builder()
            .addAll(getDirectPublicHdrs())
            .addAll(getDirectPrivateHdrs())
            .addAll(headerInfo.separateModuleHeaders)
            .build());
  }

  @Override
  public StarlarkList<Artifact> getStarlarkDirectPublicHeaders() {
    return StarlarkList.immutableCopyOf(getDirectPublicHdrs());
  }

  @Override
  public StarlarkList<Artifact> getStarlarkDirectPrivateHeaders() {
    return StarlarkList.immutableCopyOf(getDirectPrivateHdrs());
  }

  @Override
  public StarlarkList<Artifact> getStarlarkDirectTextualHeaders() {
{'fraction_non_alphanumeric': 0.08411709381612979, 'fraction_numerical': 0.0011756407241946861, 'mean_word_length': 4.9715689715689715, 'pattern_counts': {'":': 0, '<': 59, '<?xml version=': 0, '>': 59, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1921932', 'n_tokens_mistral': 4911, 'n_tokens_neox': 4850, 'n_words': 1069}