Generalise DeniedImplicitOutputMarkerProvider

This was created to limit the use of implicit outputs for cc_library.
Because we will need to do this with rules in other languages, it
makes for the rule providing this provider to specify the error message.

PiperOrigin-RevId: 354508623
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/BUILD b/src/main/java/com/google/devtools/build/lib/analysis/BUILD
index 9e72473..1cc968c 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/analysis/BUILD
@@ -321,6 +321,7 @@
         ":constraints/environment_collection",
         ":constraints/supported_environments",
         ":constraints/supported_environments_provider",
+        ":denied_implicit_outputs_marker_provider",
         ":dependency",
         ":dependency_key",
         ":dependency_kind",
@@ -406,7 +407,6 @@
         "//src/main/java/com/google/devtools/build/lib/profiler",
         "//src/main/java/com/google/devtools/build/lib/profiler:google-auto-profiler-utils",
         "//src/main/java/com/google/devtools/build/lib/profiler/memory:current_rule_tracker",
-        "//src/main/java/com/google/devtools/build/lib/rules/cpp:denied_implicit_outputs_marker_provider",
         "//src/main/java/com/google/devtools/build/lib/shell",
         "//src/main/java/com/google/devtools/build/lib/skyframe:aspect_creation_exception",
         "//src/main/java/com/google/devtools/build/lib/skyframe:aspect_value_key",
@@ -711,6 +711,15 @@
 )
 
 java_library(
+    name = "denied_implicit_outputs_marker_provider",
+    srcs = ["DeniedImplicitOutputMarkerProvider.java"],
+    deps = [
+        "//src/main/java/com/google/devtools/build/lib/concurrent",
+        "//src/main/java/com/google/devtools/build/lib/packages",
+    ],
+)
+
+java_library(
     name = "dependency",
     srcs = ["Dependency.java"],
     deps = [
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java
index 2892050..1c4c336 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java
@@ -67,7 +67,6 @@
 import com.google.devtools.build.lib.packages.Target;
 import com.google.devtools.build.lib.packages.semantics.BuildLanguageOptions;
 import com.google.devtools.build.lib.profiler.memory.CurrentRuleTracker;
-import com.google.devtools.build.lib.rules.cpp.DeniedImplicitOutputMarkerProvider;
 import com.google.devtools.build.lib.server.FailureDetails.FailAction.Code;
 import com.google.devtools.build.lib.skyframe.AspectValueKey;
 import com.google.devtools.build.lib.skyframe.ConfiguredTargetAndData;
@@ -91,10 +90,6 @@
 @ThreadSafe
 public final class ConfiguredTargetFactory {
 
-  public static final String CC_LIB_IMPLICIT_OUTPUTS_ERROR =
-      "Using implicit outputs from cc_library (%s) is forbidden. Use"
-          + " the rule cc_implicit_output as an alternative.";
-
   // This class is not meant to be outside of the analysis phase machinery and is only public
   // in order to be accessible from the .view.skyframe package.
 
@@ -232,10 +227,10 @@
       Verify.verifyNotNull(rule);
       Artifact artifact = rule.getArtifactByOutputLabel(outputFile.getLabel());
 
-      if (rule.get(DeniedImplicitOutputMarkerProvider.PROVIDER) != null) {
-        analysisEnvironment
-            .getEventHandler()
-            .handle(Event.error(String.format(CC_LIB_IMPLICIT_OUTPUTS_ERROR, rule.getLabel())));
+      DeniedImplicitOutputMarkerProvider deniedProvider =
+          rule.get(DeniedImplicitOutputMarkerProvider.PROVIDER);
+      if (deniedProvider != null) {
+        analysisEnvironment.getEventHandler().handle(Event.error(deniedProvider.getErrorMessage()));
         return null;
       }
 
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/DeniedImplicitOutputMarkerProvider.java b/src/main/java/com/google/devtools/build/lib/analysis/DeniedImplicitOutputMarkerProvider.java
similarity index 75%
rename from src/main/java/com/google/devtools/build/lib/rules/cpp/DeniedImplicitOutputMarkerProvider.java
rename to src/main/java/com/google/devtools/build/lib/analysis/DeniedImplicitOutputMarkerProvider.java
index 395e8fd..015fbc8 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/DeniedImplicitOutputMarkerProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/DeniedImplicitOutputMarkerProvider.java
@@ -12,19 +12,33 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.devtools.build.lib.rules.cpp;
+package com.google.devtools.build.lib.analysis;
 
 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;
 
-/** TODO(plf): Remove once implicit outputs are removed from cc_library */
+/**
+ * A provider used to signal the denial of implicit outputs.
+ *
+ * <p>Used to facilitate migration away from using implicit outputs.
+ */
 @Immutable
 public class DeniedImplicitOutputMarkerProvider extends NativeInfo {
   public static final BuiltinProvider<DeniedImplicitOutputMarkerProvider> PROVIDER =
       new BuiltinProvider<DeniedImplicitOutputMarkerProvider>(
           "DeniedImplicitOutputMarkerProvider", DeniedImplicitOutputMarkerProvider.class) {};
 
+  private final String errorMessage;
+
+  public DeniedImplicitOutputMarkerProvider(String errorMessage) {
+    this.errorMessage = errorMessage;
+  }
+
+  public String getErrorMessage() {
+    return errorMessage;
+  }
+
   @Override
   public BuiltinProvider<DeniedImplicitOutputMarkerProvider> getProvider() {
     return PROVIDER;
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/BUILD b/src/main/java/com/google/devtools/build/lib/rules/cpp/BUILD
index 11bbd10..13aa8d9 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/BUILD
@@ -25,13 +25,10 @@
     name = "cpp",
     srcs = glob(
         ["*.java"],
-        exclude = INTERFACE_SOURCES + [
-            "DeniedImplicitOutputMarkerProvider.java",
-        ],
+        exclude = INTERFACE_SOURCES,
     ),
     deps = [
         ":cpp_interface",
-        ":denied_implicit_outputs_marker_provider",
         "//src/main/java/com/google/devtools/build/docgen/annot",
         "//src/main/java/com/google/devtools/build/lib/actions",
         "//src/main/java/com/google/devtools/build/lib/actions:action_lookup_key",
@@ -65,6 +62,7 @@
         "//src/main/java/com/google/devtools/build/lib/analysis:config/per_label_options",
         "//src/main/java/com/google/devtools/build/lib/analysis:config/transitions/no_transition",
         "//src/main/java/com/google/devtools/build/lib/analysis:configured_target",
+        "//src/main/java/com/google/devtools/build/lib/analysis:denied_implicit_outputs_marker_provider",
         "//src/main/java/com/google/devtools/build/lib/analysis:file_provider",
         "//src/main/java/com/google/devtools/build/lib/analysis:licenses_provider",
         "//src/main/java/com/google/devtools/build/lib/analysis:make_variable_supplier",
@@ -146,12 +144,3 @@
         "//third_party:jsr305",
     ],
 )
-
-java_library(
-    name = "denied_implicit_outputs_marker_provider",
-    srcs = ["DeniedImplicitOutputMarkerProvider.java"],
-    deps = [
-        "//src/main/java/com/google/devtools/build/lib/concurrent",
-        "//src/main/java/com/google/devtools/build/lib/packages",
-    ],
-)
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 905f022..d4f91cb 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
@@ -25,6 +25,7 @@
 import com.google.devtools.build.lib.analysis.Allowlist;
 import com.google.devtools.build.lib.analysis.AnalysisUtils;
 import com.google.devtools.build.lib.analysis.ConfiguredTarget;
+import com.google.devtools.build.lib.analysis.DeniedImplicitOutputMarkerProvider;
 import com.google.devtools.build.lib.analysis.FileProvider;
 import com.google.devtools.build.lib.analysis.FilesToRunProvider;
 import com.google.devtools.build.lib.analysis.MakeVariableSupplier.MapBackedMakeVariableSupplier;
@@ -500,7 +501,12 @@
       RuleConfiguredTargetBuilder targetBuilder, RuleContext ruleContext) {
     if (ruleContext.getRule().getImplicitOutputsFunction() != ImplicitOutputsFunction.NONE
         && !Allowlist.isAvailable(ruleContext, IMPLICIT_OUTPUTS_ALLOWLIST)) {
-      targetBuilder.addNativeDeclaredProvider(new DeniedImplicitOutputMarkerProvider());
+      targetBuilder.addNativeDeclaredProvider(
+          new DeniedImplicitOutputMarkerProvider(
+              String.format(
+                  "Using implicit outputs from cc_library (%s) is forbidden. Use the rule"
+                      + " cc_implicit_output as an alternative.",
+                  ruleContext.getLabel())));
     }
   }