C++:Add a flag to disable the legacy C++ provider.

Working towards #7036
RELNOTES: None.
PiperOrigin-RevId: 227838975
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java
index 7ebcaf9..4194236 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java
@@ -575,6 +575,7 @@
           "interface_library", dynamicLibraryForLinking.get(0).getOriginalLibraryArtifact());
     }
 
+    CcSkylarkApiProvider.maybeAdd(ruleContext, ruleBuilder);
     return ruleBuilder
         .addProvider(RunfilesProvider.class, RunfilesProvider.simple(runfiles))
         .addProvider(
@@ -582,7 +583,6 @@
             new DebugPackageProvider(ruleContext.getLabel(), strippedFile, binary, explicitDwpFile))
         .setRunfilesSupport(runfilesSupport, binary)
         .addNativeDeclaredProvider(ccLauncherInfo)
-        .addSkylarkTransitiveInfo(CcSkylarkApiProvider.NAME, new CcSkylarkApiProvider())
         .build();
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcImport.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcImport.java
index ddb6775..b580857 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcImport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcImport.java
@@ -103,17 +103,19 @@
                 ccToolchain,
                 targetWindows));
 
-    return new RuleConfiguredTargetBuilder(ruleContext)
-        .addProvider(compilationInfo.getCppDebugFileProvider())
-        .addNativeDeclaredProvider(
-            CcInfo.builder()
-                .setCcCompilationContext(compilationInfo.getCcCompilationContext())
-                .setCcLinkingInfo(ccLinkingInfo)
-                .build())
-        .addSkylarkTransitiveInfo(CcSkylarkApiProvider.NAME, new CcSkylarkApiProvider())
-        .addOutputGroups(compilationInfo.getOutputGroups())
-        .addProvider(RunfilesProvider.class, RunfilesProvider.simple(Runfiles.EMPTY))
-        .build();
+    RuleConfiguredTargetBuilder result =
+        new RuleConfiguredTargetBuilder(ruleContext)
+            .addProvider(compilationInfo.getCppDebugFileProvider())
+            .addNativeDeclaredProvider(
+                CcInfo.builder()
+                    .setCcCompilationContext(compilationInfo.getCcCompilationContext())
+                    .setCcLinkingInfo(ccLinkingInfo)
+                    .build())
+            .addOutputGroups(compilationInfo.getOutputGroups())
+            .addProvider(RunfilesProvider.class, RunfilesProvider.simple(Runfiles.EMPTY));
+
+    CcSkylarkApiProvider.maybeAdd(ruleContext, result);
+    return result.build();
   }
 
   private void performErrorChecks(
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java
index 41364da..500d637 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java
@@ -437,6 +437,7 @@
             .merge(runfiles)
             .addArtifacts(ccLinkingOutputsWithPrecompiledLibraries.getLibrariesForRunfiles(false));
 
+    CcSkylarkApiProvider.maybeAdd(ruleContext, targetBuilder);
     targetBuilder
         .setFilesToBuild(filesToBuild)
         .addProvider(compilationInfo.getCppDebugFileProvider())
@@ -446,7 +447,6 @@
                 .setCcCompilationContext(compilationInfo.getCcCompilationContext())
                 .setCcLinkingInfo(ccLinkingInfo)
                 .build())
-        .addSkylarkTransitiveInfo(CcSkylarkApiProvider.NAME, new CcSkylarkApiProvider())
         .addOutputGroups(
             CcCommon.mergeOutputGroups(
                 ImmutableList.of(compilationInfo.getOutputGroups(), outputGroups.build())))
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcSkylarkApiProvider.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcSkylarkApiProvider.java
index ea5e479..d54a2b4 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcSkylarkApiProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcSkylarkApiProvider.java
@@ -16,6 +16,8 @@
 
 import com.google.common.collect.ImmutableList;
 import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder;
+import com.google.devtools.build.lib.analysis.RuleContext;
 import com.google.devtools.build.lib.analysis.skylark.SkylarkApiProvider;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
 import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
@@ -33,6 +35,12 @@
   /** The name of the field in Skylark used to access this class. */
   public static final String NAME = "cc";
 
+  public static void maybeAdd(RuleContext ruleContext, RuleConfiguredTargetBuilder builder) {
+    if (ruleContext.getFragment(CppConfiguration.class).enableLegacyCcProvider()) {
+      builder.addSkylarkTransitiveInfo(NAME, new CcSkylarkApiProvider());
+    }
+  }
+
   @Override
   public NestedSet<Artifact> getTransitiveHeaders() {
     CcCompilationContext ccCompilationContext =
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java
index d5df659..c2c398f 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java
@@ -601,4 +601,8 @@
   public boolean disableGenruleCcToolchainDependency() {
     return cppOptions.disableGenruleCcToolchainDependency;
   }
+
+  public boolean enableLegacyCcProvider() {
+    return !cppOptions.disableLegacyCcProvider;
+  }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppOptions.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppOptions.java
index b94478b..4761189 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppOptions.java
@@ -818,6 +818,19 @@
               + "the new cc_flags_supplier rule.")
   public boolean disableGenruleCcToolchainDependency;
 
+  @Option(
+      name = "incompatible_disable_legacy_cc_provider",
+      defaultValue = "false",
+      documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
+      effectTags = {OptionEffectTag.LOADING_AND_ANALYSIS},
+      metadataTags = {
+        OptionMetadataTag.INCOMPATIBLE_CHANGE,
+        OptionMetadataTag.TRIGGERED_BY_ALL_INCOMPATIBLE_CHANGES
+      },
+      help = "If true, the legacy provider accessible by 'dep.cc.' is removed. See #7036.")
+  // TODO(b/122328491): Document migration steps. See #7036.
+  public boolean disableLegacyCcProvider;
+
   @Override
   public FragmentOptions getHost() {
     CppOptions host = (CppOptions) getDefault();
@@ -865,6 +878,7 @@
     host.disableDepsetInUserFlags = disableDepsetInUserFlags;
     host.disableRuntimesFilegroups = disableRuntimesFilegroups;
     host.disableExpandIfAllAvailableInFlagSet = disableExpandIfAllAvailableInFlagSet;
+    host.disableLegacyCcProvider = disableLegacyCcProvider;
 
     return host;
   }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoLibrary.java
index 91d76eb..3350623 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoLibrary.java
@@ -52,12 +52,13 @@
         .addProvider(
             RunfilesProvider.class, RunfilesProvider.withData(Runfiles.EMPTY, Runfiles.EMPTY))
         .addProviders(depProviders.providerMap);
+
     for (String groupName : depProviders.outputGroupInfo) {
       ruleConfiguredTargetBuilder.addOutputGroup(groupName,
           depProviders.outputGroupInfo.getOutputGroup(groupName));
     }
-    return ruleConfiguredTargetBuilder
-        .addSkylarkTransitiveInfo(CcSkylarkApiProvider.NAME, new CcSkylarkApiProvider())
-        .build();
+
+    CcSkylarkApiProvider.maybeAdd(ruleContext, ruleConfiguredTargetBuilder);
+    return ruleConfiguredTargetBuilder.build();
   }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoLibraryRule.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoLibraryRule.java
index f65f762..e89c43e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoLibraryRule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoLibraryRule.java
@@ -21,6 +21,7 @@
 import com.google.devtools.build.lib.analysis.RuleDefinition;
 import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
 import com.google.devtools.build.lib.packages.RuleClass;
+import com.google.devtools.build.lib.rules.cpp.CppConfiguration;
 
 /** Declaration part of cc_proto_library. */
 public class CcProtoLibraryRule implements RuleDefinition {
@@ -34,6 +35,7 @@
   @Override
   public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment environment) {
     return builder
+        .requiresConfigurationFragments(CppConfiguration.class)
         /* <!-- #BLAZE_RULE(cc_proto_library).ATTRIBUTE(deps) -->
         The list of <a href="protocol-buffer.html#proto_library"><code>proto_library</code></a>
         rules to generate C++ code for.
diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcSkylarkApiProviderTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcSkylarkApiProviderTest.java
index c79d7b0..ec4ffed 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcSkylarkApiProviderTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcSkylarkApiProviderTest.java
@@ -18,6 +18,7 @@
 import com.google.devtools.build.lib.actions.util.ActionsTestUtil;
 import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget;
 import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
+import com.google.devtools.build.lib.vfs.FileSystemUtils;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
@@ -33,6 +34,61 @@
   }
 
   @Test
+  public void testDisableInCcLibrary() throws Exception {
+    useConfiguration("--incompatible_disable_legacy_cc_provider");
+    scratch.file("a/BUILD", "cc_library(name='a', srcs=['a.cc'])");
+    assertThat(getApi("//a:a")).isNull();
+  }
+
+  @Test
+  public void testDisableInCcBinary() throws Exception {
+    useConfiguration("--incompatible_disable_legacy_cc_provider");
+    scratch.file("a/BUILD", "cc_binary(name='a', srcs=['a.cc'])");
+    assertThat(getApi("//a:a")).isNull();
+  }
+
+  @Test
+  public void testDisableInCcImport() throws Exception {
+    useConfiguration("--incompatible_disable_legacy_cc_provider");
+    scratch.file("a/BUILD", "cc_import(name='a', static_library='a.a')");
+    assertThat(getApi("//a:a")).isNull();
+  }
+
+  @Test
+  public void testDisableInCcProtoLibrary() throws Exception {
+    if (!analysisMock.isThisBazel()) {
+      // Our internal version does not have this rule
+      return;
+    }
+
+    mockToolsConfig.create("/protobuf/WORKSPACE");
+    mockToolsConfig.overwrite(
+        "/protobuf/BUILD",
+        "package(default_visibility=['//visibility:public'])",
+        "exports_files(['protoc'])",
+        "proto_lang_toolchain(",
+        "    name = 'cc_toolchain',",
+        "    command_line = '--cpp_out=$(OUT)',",
+        "    blacklisted_protos = [],",
+        ")");
+
+    String existingWorkspace =
+        new String(FileSystemUtils.readContentAsLatin1(rootDirectory.getRelative("WORKSPACE")));
+    mockToolsConfig.overwrite(
+        "WORKSPACE",
+        "local_repository(name = 'com_google_protobuf', path = '/protobuf/')",
+        existingWorkspace);
+    invalidatePackages(); // A dash of magic to re-evaluate the WORKSPACE file.
+
+    useConfiguration("--incompatible_disable_legacy_cc_provider");
+    scratch.file(
+        "a/BUILD",
+        "cc_proto_library(name='a', deps=[':p'])",
+        "proto_library(name='p', srcs=['p.proto'])");
+    assertThat(getApi("//a:a")).isNull();
+  }
+
+  @Test
   public void testTransitiveHeaders() throws Exception {
     scratch.file(
         "pkg/BUILD",