Add flag --incompatible_blacklisted_protos_requires_proto_info

This change adds a new incompatible flag that makes ProtoInfo mandatory
for skipping code-gen for some proto sources (e.g. WKPs that are already
provided by the proto runtime). Flipping this flag will allow us to get rid of
ProtoInfo#getOriginal{Direct,Transitive}ProtoSources().

https://docs.google.com/document/d/1UmF_P4NDVl6Nw4JsHoHYp74iCdEQNh1O3-SVAX1CdjU/edit#

RELNOTES: Adds --incompatible_blacklisted_protos_requires_proto_info to indicate whether proto_lang_toolchain.blacklisted_protos requires ProtoInfo.

Closes #11617.

PiperOrigin-RevId: 319386644
diff --git a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoConfiguration.java
index ce41835..98d9754 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoConfiguration.java
@@ -183,6 +183,19 @@
                 + "the Starlark rules instead at https://github.com/bazelbuild/rules_proto")
     public boolean loadProtoRulesFromBzl;
 
+    @Option(
+        name = "incompatible_blacklisted_protos_requires_proto_info",
+        defaultValue = "false",
+        documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
+        effectTags = {OptionEffectTag.LOADING_AND_ANALYSIS},
+        metadataTags = {
+          OptionMetadataTag.INCOMPATIBLE_CHANGE,
+          OptionMetadataTag.TRIGGERED_BY_ALL_INCOMPATIBLE_CHANGES
+        },
+        help =
+            "If enabled, 'proto_lang_toolchain.blacklisted_protos' requires provider 'ProtoInfo'")
+    public boolean blacklistedProtosRequiresProtoInfo;
+
     @Override
     public FragmentOptions getHost() {
       Options host = (Options) super.getHost();
@@ -203,6 +216,7 @@
       host.experimentalJavaProtoAddAllowedPublicImports =
           experimentalJavaProtoAddAllowedPublicImports;
       host.generatedProtosInVirtualImports = generatedProtosInVirtualImports;
+      host.blacklistedProtosRequiresProtoInfo = blacklistedProtosRequiresProtoInfo;
       return host;
     }
   }
@@ -300,4 +314,8 @@
   public boolean loadProtoRulesFromBzl() {
     return options.loadProtoRulesFromBzl;
   }
+
+  public boolean blacklistedProtosRequiresProtoInfo() {
+    return options.blacklistedProtosRequiresProtoInfo;
+  }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchain.java b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchain.java
index b9e28a2..abe2eec 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchain.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchain.java
@@ -42,7 +42,13 @@
     for (TransitiveInfoCollection protos :
         ruleContext.getPrerequisites("blacklisted_protos", TARGET)) {
       ProtoInfo protoInfo = protos.get(ProtoInfo.PROVIDER);
-      // TODO(cushon): it would be nice to make this mandatory and stop adding files to build too
+      if (protoInfo == null
+          && ruleContext
+              .getFragment(ProtoConfiguration.class)
+              .blacklistedProtosRequiresProtoInfo()) {
+        ruleContext.ruleError(
+            "'" + ruleContext.getLabel() + "' does not have mandatory provider 'ProtoInfo'.");
+      }
       if (protoInfo != null) {
         blacklistedProtos.addTransitive(protoInfo.getOriginalTransitiveProtoSources());
       } else {