Roll forward of https://github.com/bazelbuild/bazel/commit/ae349e9368f90bc5cf27f51ecc773ada9e3a514c: Export ProtoLangToolchainInfo provider and flip proto_lang_toolchain rule

NEW: I've moved ProtoLangToolchainProvider from providers.bzl file to proto_common.bzl file since proto_common doesn't allow loading other components. I've also deleted providers.bzl file since we don't need it anymore.

Automated rollback of commit 5a6b1a85e82f4b034cc2e96fdc84c0c3c0b5571a.

*** Reason for rollback ***

Good to submit since the blocking error has been resolved.

*** Original change description ***

Automated rollback of commit ae349e9368f90bc5cf27f51ecc773ada9e3a514c.

*** Reason for rollback ***

This CL breaks proto_common.bzl file which seems that can't load providers.bzl file.

*** Original change description ***

Export ProtoLangToolchainInfo provider and flip proto_lang_toolchain rule

I’ve exported ProtoLangToolchainInfo provider from it’s native class by adding two new functions: one that’s creating starlark provider (create function), and the other that’s wrapping the starlark provider as a nat

***

PiperOrigin-RevId: 446401388
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
index 6227108..d667b7b 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
@@ -112,7 +112,6 @@
 import com.google.devtools.build.lib.rules.proto.BazelProtoLibraryRule;
 import com.google.devtools.build.lib.rules.proto.ProtoConfiguration;
 import com.google.devtools.build.lib.rules.proto.ProtoInfo;
-import com.google.devtools.build.lib.rules.proto.ProtoLangToolchainProvider;
 import com.google.devtools.build.lib.rules.proto.ProtoLangToolchainRule;
 import com.google.devtools.build.lib.rules.python.PyInfo;
 import com.google.devtools.build.lib.rules.python.PyRuleClasses.PySymlink;
@@ -292,8 +291,6 @@
                   new StarlarkAspectStub(),
                   new ProviderStub());
           builder.addStarlarkBootstrap(bootstrap);
-          builder.addStarlarkBuiltinsInternal(
-              "ProtoLangToolchainInfo", ProtoLangToolchainProvider.PROVIDER);
         }
 
         @Override
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaLiteProtoLibraryRule.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaLiteProtoLibraryRule.java
index fc84eda..fa0b20b 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaLiteProtoLibraryRule.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaLiteProtoLibraryRule.java
@@ -56,7 +56,7 @@
                 .aspect(javaProtoAspect))
         .add(
             attr(JavaProtoAspectCommon.LITE_PROTO_TOOLCHAIN_ATTR, LABEL)
-                .mandatoryProviders(ProtoLangToolchainProvider.PROVIDER.id())
+                .mandatoryProviders(ProtoLangToolchainProvider.PROVIDER_ID)
                 .value(getProtoToolchainLabel(DEFAULT_PROTO_TOOLCHAIN_LABEL)))
         .advertiseStarlarkProvider(StarlarkProviderIdentifier.forKey(JavaInfo.PROVIDER.getKey()))
         .build();
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaProtoAspect.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaProtoAspect.java
index 871e2c1..e89ee0c 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaProtoAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/proto/BazelJavaProtoAspect.java
@@ -25,9 +25,9 @@
 import com.google.devtools.build.lib.bazel.rules.java.BazelJavaSemantics;
 import com.google.devtools.build.lib.packages.AspectDefinition;
 import com.google.devtools.build.lib.packages.AspectParameters;
+import com.google.devtools.build.lib.packages.StarlarkInfo;
 import com.google.devtools.build.lib.rules.java.proto.JavaProtoAspect;
 import com.google.devtools.build.lib.rules.java.proto.RpcSupport;
-import com.google.devtools.build.lib.rules.proto.ProtoLangToolchainProvider;
 
 /** An Aspect which BazelJavaProtoLibrary injects to build Java SPEED protos. */
 public class BazelJavaProtoAspect extends JavaProtoAspect {
@@ -56,7 +56,7 @@
     }
 
     @Override
-    public Optional<ProtoLangToolchainProvider> getToolchain(RuleContext ruleContext) {
+    public Optional<StarlarkInfo> getToolchain(RuleContext ruleContext) {
       return Optional.absent();
     }
 
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/DexArchiveAspect.java b/src/main/java/com/google/devtools/build/lib/rules/android/DexArchiveAspect.java
index f5bcb54..edb407a 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/DexArchiveAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/DexArchiveAspect.java
@@ -186,7 +186,7 @@
                 ImmutableList.of(
                     // For proto_lang_toolchain rules, where we just want to get at their runtime
                     // deps.
-                    ImmutableSet.of(ProtoLangToolchainProvider.PROVIDER.id())))
+                    ImmutableSet.of(ProtoLangToolchainProvider.PROVIDER_ID)))
             .addToolchainTypes(
                 ToolchainTypeRequirement.create(
                     Label.parseAbsoluteUnchecked(toolsRepository + sdkToolchainLabel)))
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoAspect.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoAspect.java
index f8b825f..d1608e0 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoAspect.java
@@ -43,6 +43,7 @@
 import com.google.devtools.build.lib.packages.Attribute.LabelLateBoundDefault;
 import com.google.devtools.build.lib.packages.NativeAspectClass;
 import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
+import com.google.devtools.build.lib.packages.StarlarkInfo;
 import com.google.devtools.build.lib.packages.TargetUtils;
 import com.google.devtools.build.lib.rules.cpp.AspectLegalCppSemantics;
 import com.google.devtools.build.lib.rules.cpp.CcCommon;
@@ -129,7 +130,7 @@
             .useToolchainTransition(true)
             .add(
                 attr(PROTO_TOOLCHAIN_ATTR, LABEL)
-                    .mandatoryProviders(ProtoLangToolchainProvider.PROVIDER.id())
+                    .mandatoryProviders(ProtoLangToolchainProvider.PROVIDER_ID)
                     .value(PROTO_TOOLCHAIN_LABEL))
             .add(
                 attr(CcToolchain.CC_TOOLCHAIN_DEFAULT_ATTRIBUTE_NAME, LABEL)
@@ -288,7 +289,7 @@
 
     private boolean areSrcsExcluded() throws RuleErrorException, InterruptedException {
       return !ProtoCommon.shouldGenerateCode(
-          ruleContext, protoTarget, getProtoToolchainProvider(), "cc_proto_library");
+          ruleContext, protoTarget, getStarlarkProtoToolchainProvider(), "cc_proto_library");
     }
 
     private FeatureConfiguration getFeatureConfiguration()
@@ -461,7 +462,7 @@
         ProtoCommon.compile(
             ruleContext,
             protoTarget,
-            getProtoToolchainProvider(),
+            getStarlarkProtoToolchainProvider(),
             outputs,
             genfilesPath,
             "Generating C++ proto_library %{label}");
@@ -469,7 +470,11 @@
     }
 
     private ProtoLangToolchainProvider getProtoToolchainProvider() {
-      return ruleContext.getPrerequisite(PROTO_TOOLCHAIN_ATTR, ProtoLangToolchainProvider.PROVIDER);
+      return ProtoLangToolchainProvider.get(ruleContext, PROTO_TOOLCHAIN_ATTR);
+    }
+
+    private StarlarkInfo getStarlarkProtoToolchainProvider() {
+      return ProtoLangToolchainProvider.getStarlarkProvider(ruleContext, PROTO_TOOLCHAIN_ATTR);
     }
 
     public void addProviders(ConfiguredAspect.Builder builder) {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoAspect.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoAspect.java
index ac19fbb..87231c6 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaLiteProtoAspect.java
@@ -116,7 +116,7 @@
                 ImmutableList.of(StarlarkProviderIdentifier.forKey(JavaInfo.PROVIDER.getKey())))
             .add(
                 attr(JavaProtoAspectCommon.LITE_PROTO_TOOLCHAIN_ATTR, LABEL)
-                    .mandatoryProviders(ProtoLangToolchainProvider.PROVIDER.id())
+                    .mandatoryProviders(ProtoLangToolchainProvider.PROVIDER_ID)
                     .value(getProtoToolchainLabel(defaultProtoToolchainLabel)))
             .add(
                 attr(JavaRuleClasses.JAVA_TOOLCHAIN_ATTRIBUTE_NAME, LABEL)
@@ -245,7 +245,7 @@
       ProtoCommon.compile(
           ruleContext,
           protoTarget,
-          aspectCommon.getProtoToolchainProvider(),
+          aspectCommon.getStarlarkProtoToolchainProvider(),
           ImmutableList.of(sourceJar),
           sourceJar.getExecPathString(),
           "Generating JavaLite proto_library %{label}");
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoAspect.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoAspect.java
index 4abffa5..de5d19f 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoAspect.java
@@ -224,7 +224,7 @@
       if (ProtoCommon.shouldGenerateCode(
           ruleContext,
           protoTarget,
-          aspectCommon.getProtoToolchainProvider(),
+          aspectCommon.getStarlarkProtoToolchainProvider(),
           "java_proto_library")) {
         Artifact sourceJar = aspectCommon.getSourceJarArtifact();
         createProtoCompileAction(sourceJar);
@@ -320,7 +320,7 @@
       ProtoCommon.compile(
           ruleContext,
           protoTarget,
-          aspectCommon.getProtoToolchainProvider(),
+          aspectCommon.getStarlarkProtoToolchainProvider(),
           ImmutableList.of(sourceJar),
           /* pluginOutput= */ null,
           additionalArgs,
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoAspectCommon.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoAspectCommon.java
index c011456..088aaa6 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoAspectCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoAspectCommon.java
@@ -24,6 +24,7 @@
 import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
 import com.google.devtools.build.lib.analysis.config.CoreOptionConverters.StrictDepsMode;
 import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
+import com.google.devtools.build.lib.packages.StarlarkInfo;
 import com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider;
 import com.google.devtools.build.lib.rules.java.JavaCompilationArtifacts;
 import com.google.devtools.build.lib.rules.java.JavaInfo;
@@ -159,16 +160,22 @@
 
   /** Returns the toolchain that specifies how to generate code from {@code .proto} files. */
   public ProtoLangToolchainProvider getProtoToolchainProvider() {
+    return checkNotNull(ProtoLangToolchainProvider.get(ruleContext, protoToolchainAttr));
+  }
+
+  /**
+   * Returns the Starlark toolchain that specifies how to generate code from {@code .proto} files.
+   */
+  public StarlarkInfo getStarlarkProtoToolchainProvider() {
     return checkNotNull(
-        ruleContext.getPrerequisite(protoToolchainAttr, ProtoLangToolchainProvider.PROVIDER));
+        ProtoLangToolchainProvider.getStarlarkProvider(ruleContext, protoToolchainAttr));
   }
 
   /**
    * Returns the toolchain that specifies how to generate Java-lite code from {@code .proto} files.
    */
   static ProtoLangToolchainProvider getLiteProtoToolchainProvider(RuleContext ruleContext) {
-    return ruleContext.getPrerequisite(
-        LITE_PROTO_TOOLCHAIN_ATTR, ProtoLangToolchainProvider.PROVIDER);
+    return ProtoLangToolchainProvider.get(ruleContext, LITE_PROTO_TOOLCHAIN_ATTR);
   }
 
   /**
@@ -206,9 +213,9 @@
 
     boolean shouldGenerate =
         ProtoCommon.shouldGenerateCode(
-            ruleContext, protoTarget, getProtoToolchainProvider(), ruleName);
+            ruleContext, protoTarget, getStarlarkProtoToolchainProvider(), ruleName);
     if (rpcSupport != null) {
-      Optional<ProtoLangToolchainProvider> toolchain = rpcSupport.getToolchain(ruleContext);
+      Optional<StarlarkInfo> toolchain = rpcSupport.getToolchain(ruleContext);
       if (toolchain.isPresent()) {
         if (!ProtoCommon.shouldGenerateCode(ruleContext, protoTarget, toolchain.get(), ruleName)) {
           shouldGenerate = false;
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoStarlarkCommon.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoStarlarkCommon.java
index 5b3ed3a..ffac1c8 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoStarlarkCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/JavaProtoStarlarkCommon.java
@@ -23,6 +23,7 @@
 import com.google.devtools.build.lib.analysis.platform.ConstraintValueInfo;
 import com.google.devtools.build.lib.analysis.starlark.StarlarkRuleContext;
 import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
+import com.google.devtools.build.lib.packages.StarlarkInfo;
 import com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider;
 import com.google.devtools.build.lib.rules.java.JavaInfo;
 import com.google.devtools.build.lib.rules.proto.ProtoCommon;
@@ -49,7 +50,7 @@
       ProtoCommon.compile(
           starlarkRuleContext.getRuleContext(),
           target,
-          getProtoToolchainProvider(starlarkRuleContext, protoToolchainAttr),
+          getStarlarkProtoToolchainProvider(starlarkRuleContext, protoToolchainAttr),
           ImmutableList.of(sourceJar),
           sourceJar.getExecPathString(),
           "Generating JavaLite proto_library %{label}");
@@ -90,6 +91,13 @@
       StarlarkRuleContext starlarkRuleContext, String protoToolchainAttr) throws EvalException {
     ConfiguredTarget javaliteToolchain =
         (ConfiguredTarget) checkNotNull(starlarkRuleContext.getAttr().getValue(protoToolchainAttr));
-    return checkNotNull(javaliteToolchain.get(ProtoLangToolchainProvider.PROVIDER));
+    return checkNotNull(ProtoLangToolchainProvider.get(javaliteToolchain));
+  }
+
+  private static StarlarkInfo getStarlarkProtoToolchainProvider(
+      StarlarkRuleContext starlarkRuleContext, String protoToolchainAttr) throws EvalException {
+    ConfiguredTarget javaliteToolchain =
+        (ConfiguredTarget) checkNotNull(starlarkRuleContext.getAttr().getValue(protoToolchainAttr));
+    return checkNotNull(ProtoLangToolchainProvider.getStarlarkProvider(javaliteToolchain));
   }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/proto/RpcSupport.java b/src/main/java/com/google/devtools/build/lib/rules/java/proto/RpcSupport.java
index e7658bd..72d26b3 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/proto/RpcSupport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/proto/RpcSupport.java
@@ -23,7 +23,7 @@
 import com.google.devtools.build.lib.analysis.starlark.Args;
 import com.google.devtools.build.lib.packages.AspectDefinition;
 import com.google.devtools.build.lib.packages.AspectParameters;
-import com.google.devtools.build.lib.rules.proto.ProtoLangToolchainProvider;
+import com.google.devtools.build.lib.packages.StarlarkInfo;
 import net.starlark.java.eval.EvalException;
 
 /** Used by java_proto_library to support Google-specific features. */
@@ -35,7 +35,7 @@
 
   boolean allowServices(RuleContext ruleContext);
 
-  Optional<ProtoLangToolchainProvider> getToolchain(RuleContext ruleContext);
+  Optional<StarlarkInfo> getToolchain(RuleContext ruleContext);
 
   ImmutableList<TransitiveInfoCollection> getRuntimes(RuleContext ruleContext);
 
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java
index abc15a4..4a5caa9 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java
@@ -52,6 +52,7 @@
 import com.google.devtools.build.lib.packages.BuildType;
 import com.google.devtools.build.lib.packages.NativeAspectClass;
 import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
+import com.google.devtools.build.lib.packages.StarlarkInfo;
 import com.google.devtools.build.lib.packages.StarlarkProviderIdentifier;
 import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
 import com.google.devtools.build.lib.rules.apple.AppleToolchain;
@@ -386,13 +387,14 @@
   private ConfiguredAspect proto(ConfiguredTarget base, RuleContext ruleContext)
       throws InterruptedException, ActionConflictException {
     ProtoLangToolchainProvider protoToolchain =
-        ruleContext.getPrerequisite(
-            J2OBJC_PROTO_TOOLCHAIN_ATTR, ProtoLangToolchainProvider.PROVIDER);
-
+        ProtoLangToolchainProvider.get(ruleContext, J2OBJC_PROTO_TOOLCHAIN_ATTR);
+    StarlarkInfo starlarkProtoToolchain =
+        ProtoLangToolchainProvider.getStarlarkProvider(ruleContext, J2OBJC_PROTO_TOOLCHAIN_ATTR);
     try {
       // Avoid pulling in any generated files from forbidden protos.
       ImmutableList<Artifact> filteredProtoSources =
-          ImmutableList.copyOf(ProtoCommon.filterSources(ruleContext, base, protoToolchain));
+          ImmutableList.copyOf(
+              ProtoCommon.filterSources(ruleContext, base, starlarkProtoToolchain));
 
       J2ObjcSource j2ObjcSource = protoJ2ObjcSource(ruleContext, base, filteredProtoSources);
 
@@ -403,7 +405,7 @@
 
         directJ2ObjcMappingFileProvider =
             createJ2ObjcProtoCompileActions(
-                base, protoToolchain, ruleContext, filteredProtoSources, j2ObjcSource);
+                base, starlarkProtoToolchain, ruleContext, filteredProtoSources, j2ObjcSource);
       }
 
       return buildAspect(
@@ -637,7 +639,7 @@
 
   private J2ObjcMappingFileProvider createJ2ObjcProtoCompileActions(
       ConfiguredTarget base,
-      ProtoLangToolchainProvider protoToolchain,
+      StarlarkInfo protoToolchain,
       RuleContext ruleContext,
       ImmutableList<Artifact> filteredProtoSources,
       J2ObjcSource j2ObjcSource)
diff --git a/src/main/java/com/google/devtools/build/lib/rules/proto/BUILD b/src/main/java/com/google/devtools/build/lib/rules/proto/BUILD
index aca070a..af13958 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/proto/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/rules/proto/BUILD
@@ -48,6 +48,7 @@
         "//src/main/java/com/google/devtools/common/options",
         "//src/main/java/net/starlark/java/annot",
         "//src/main/java/net/starlark/java/eval",
+        "//src/main/java/net/starlark/java/syntax",
         "//third_party:auto_value",
         "//third_party:guava",
         "//third_party:jsr305",
diff --git a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoCommon.java b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoCommon.java
index 44d0523..99633dd 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoCommon.java
@@ -33,6 +33,7 @@
 import com.google.devtools.build.lib.concurrent.BlazeInterners;
 import com.google.devtools.build.lib.packages.BazelModuleContext;
 import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
+import com.google.devtools.build.lib.packages.StarlarkInfo;
 import com.google.devtools.build.lib.vfs.FileSystemUtils;
 import com.google.devtools.build.lib.vfs.PathFragment;
 import javax.annotation.Nullable;
@@ -195,7 +196,7 @@
   public static void compile(
       RuleContext ruleContext,
       ConfiguredTarget protoTarget,
-      ProtoLangToolchainProvider protoLangToolchainInfo,
+      StarlarkInfo protoLangToolchainInfo,
       Iterable<Artifact> generatedFiles,
       @Nullable Object pluginOutput,
       @Nullable Args additionalArgs,
@@ -229,7 +230,7 @@
   public static void compile(
       RuleContext ruleContext,
       ConfiguredTarget protoTarget,
-      ProtoLangToolchainProvider protoLangToolchainInfo,
+      StarlarkInfo protoLangToolchainInfo,
       Iterable<Artifact> generatedFiles,
       @Nullable Object pluginOutput,
       String progressMessage)
@@ -251,7 +252,7 @@
   public static boolean shouldGenerateCode(
       RuleContext ruleContext,
       ConfiguredTarget protoTarget,
-      ProtoLangToolchainProvider protoLangToolchainInfo,
+      StarlarkInfo protoLangToolchainInfo,
       String ruleName)
       throws RuleErrorException, InterruptedException {
     StarlarkFunction shouldGenerateCode =
@@ -269,9 +270,7 @@
   }
 
   public static Sequence<Artifact> filterSources(
-      RuleContext ruleContext,
-      ConfiguredTarget protoTarget,
-      ProtoLangToolchainProvider protoLangToolchainInfo)
+      RuleContext ruleContext, ConfiguredTarget protoTarget, StarlarkInfo protoLangToolchainInfo)
       throws RuleErrorException, InterruptedException {
     StarlarkFunction filterSources =
         (StarlarkFunction)
diff --git a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchainProvider.java b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchainProvider.java
index ed53f4d..078e473 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchainProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchainProvider.java
@@ -17,13 +17,23 @@
 import com.google.auto.value.AutoValue;
 import com.google.common.collect.ImmutableList;
 import com.google.devtools.build.lib.analysis.FilesToRunProvider;
+import com.google.devtools.build.lib.analysis.RuleContext;
 import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
-import com.google.devtools.build.lib.packages.BuiltinProvider;
-import com.google.devtools.build.lib.packages.NativeInfo;
+import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.collect.nestedset.Depset;
+import com.google.devtools.build.lib.collect.nestedset.Depset.ElementType;
+import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
+import com.google.devtools.build.lib.packages.StarlarkInfo;
+import com.google.devtools.build.lib.packages.StarlarkProvider;
+import com.google.devtools.build.lib.packages.StarlarkProviderIdentifier;
+import java.util.LinkedHashMap;
+import java.util.Map;
 import javax.annotation.Nullable;
-import net.starlark.java.annot.StarlarkBuiltin;
-import net.starlark.java.annot.StarlarkMethod;
+import net.starlark.java.eval.EvalException;
+import net.starlark.java.eval.NoneType;
+import net.starlark.java.eval.Starlark;
 import net.starlark.java.eval.StarlarkList;
+import net.starlark.java.syntax.Location;
 
 // Note: AutoValue v1.4-rc1 has AutoValue.CopyAnnotations which makes it work with Starlark. No need
 // to un-AutoValue this class to expose it to Starlark.
@@ -32,42 +42,23 @@
  * rules.
  */
 @AutoValue
-public abstract class ProtoLangToolchainProvider extends NativeInfo {
+public abstract class ProtoLangToolchainProvider {
   public static final String PROVIDER_NAME = "ProtoLangToolchainInfo";
-  public static final Provider PROVIDER = new Provider();
+  public static final StarlarkProvider.Key starlarkProtoLangToolchainKey =
+      new StarlarkProvider.Key(
+          Label.parseAbsoluteUnchecked("@_builtins//:common/proto/proto_common.bzl"),
+          PROVIDER_NAME);
+  public static final StarlarkProviderIdentifier PROVIDER_ID =
+      StarlarkProviderIdentifier.forKey(starlarkProtoLangToolchainKey);
 
-  /** Provider class for {@link ProtoLangToolchainProvider} objects. */
-  @StarlarkBuiltin(name = "Provider", documented = false, doc = "")
-  public static class Provider extends BuiltinProvider<ProtoLangToolchainProvider> {
-    public Provider() {
-      super(PROVIDER_NAME, ProtoLangToolchainProvider.class);
-    }
-  }
-
-  @Override
-  public Provider getProvider() {
-    return PROVIDER;
-  }
-
-  @StarlarkMethod(
-      name = "out_replacement_format_flag",
-      doc = "Format string used when passing output to the plugin used by proto compiler.",
-      structField = true)
+  // Format string used when passing output to the plugin used by proto compiler.
   public abstract String outReplacementFormatFlag();
 
-  @StarlarkMethod(
-      name = "plugin_format_flag",
-      doc = "Format string used when passing plugin to proto compiler.",
-      structField = true,
-      allowReturnNones = true)
+  // Format string used when passing plugin to proto compiler.
   @Nullable
   public abstract String pluginFormatFlag();
 
-  @StarlarkMethod(
-      name = "plugin",
-      doc = "Proto compiler plugin.",
-      structField = true,
-      allowReturnNones = true)
+  // Proto compiler plugin.
   @Nullable
   public abstract FilesToRunProvider pluginExecutable();
 
@@ -78,38 +69,26 @@
    * Returns a list of {@link ProtoSource}s that are already provided by the protobuf runtime (i.e.
    * for which {@code <lang>_proto_library} should not generate bindings.
    */
-  @StarlarkMethod(
-      name = "provided_proto_sources",
-      doc = "Proto sources provided by the toolchain.",
-      structField = true)
+  // Proto sources provided by the toolchain.
   public abstract ImmutableList<ProtoSource> providedProtoSources();
 
-  @StarlarkMethod(name = "proto_compiler", doc = "Proto compiler.", structField = true)
+  // Proto compiler.
   public abstract FilesToRunProvider protoc();
 
-  @StarlarkMethod(
-      name = "protoc_opts",
-      doc = "Options to pass to proto compiler.",
-      structField = true)
+  // Options to pass to proto compiler.
   public StarlarkList<String> protocOptsForStarlark() {
     return StarlarkList.immutableCopyOf(protocOpts());
   }
 
   public abstract ImmutableList<String> protocOpts();
 
-  @StarlarkMethod(
-      name = "progress_message",
-      doc = "Progress message to set on the proto compiler action.",
-      structField = true)
+  // Progress message to set on the proto compiler action.
   public abstract String progressMessage();
 
-  @StarlarkMethod(
-      name = "mnemonic",
-      doc = "Mnemonic to set on the proto compiler action.",
-      structField = true)
+  // Mnemonic to set on the proto compiler action.
   public abstract String mnemonic();
 
-  public static ProtoLangToolchainProvider create(
+  public static StarlarkInfo create(
       String outReplacementFormatFlag,
       String pluginFormatFlag,
       FilesToRunProvider pluginExecutable,
@@ -119,15 +98,93 @@
       ImmutableList<String> protocOpts,
       String progressMessage,
       String mnemonic) {
-    return new AutoValue_ProtoLangToolchainProvider(
-        outReplacementFormatFlag,
-        pluginFormatFlag,
-        pluginExecutable,
-        runtime,
-        providedProtoSources,
-        protoc,
-        protocOpts,
-        progressMessage,
-        mnemonic);
+
+    NestedSetBuilder<ProtoSource> providedProtoSourcesSet = NestedSetBuilder.stableOrder();
+    providedProtoSources.forEach(providedProtoSourcesSet::add);
+    NestedSetBuilder<String> protocOptsSet = NestedSetBuilder.stableOrder();
+    protocOpts.forEach(protocOptsSet::add);
+
+    Map<String, Object> m = new LinkedHashMap<>();
+    m.put("plugin", pluginExecutable == null ? Starlark.NONE : pluginExecutable);
+    m.put("plugin_format_flag", pluginFormatFlag);
+    m.put("proto_compiler", protoc == null ? Starlark.NONE : protoc);
+    m.put(
+        "provided_proto_sources",
+        Depset.of(ElementType.of(ProtoSource.class), providedProtoSourcesSet.build()));
+    m.put("protoc_opts", Depset.of(ElementType.of(ProtoSource.class), protocOptsSet.build()));
+    m.put("out_replacement_format_flag", outReplacementFormatFlag);
+    m.put("progress_message", progressMessage);
+    m.put("mnemonic", mnemonic);
+    m.put("plugin", pluginExecutable == null ? Starlark.NONE : pluginExecutable);
+    m.put("runtime", runtime == null ? Starlark.NONE : runtime);
+
+    StarlarkProvider.Builder builder =
+        StarlarkProvider.builder(
+            Location.fromFileLineColumn(protoc.getExecutable().getFilename(), 0, 0));
+    builder.setExported(starlarkProtoLangToolchainKey);
+
+    return StarlarkInfo.create(builder.build(), m, Location.BUILTIN);
+  }
+
+  private static ImmutableList<ProtoLangToolchainProvider> getToolchains(
+      RuleContext ruleContext, String attributeName) {
+    ImmutableList.Builder<ProtoLangToolchainProvider> result = ImmutableList.builder();
+    for (TransitiveInfoCollection prerequisite : ruleContext.getPrerequisites(attributeName)) {
+      ProtoLangToolchainProvider toolchain = get(prerequisite);
+      if (toolchain != null) {
+        result.add(toolchain);
+      }
+    }
+    return result.build();
+  }
+
+  public static ProtoLangToolchainProvider get(RuleContext ruleContext, String attributeName) {
+    return getToolchains(ruleContext, attributeName).stream().findFirst().orElse(null);
+  }
+
+  public static ProtoLangToolchainProvider get(TransitiveInfoCollection prerequisite) {
+    StarlarkInfo provider = (StarlarkInfo) prerequisite.get(starlarkProtoLangToolchainKey);
+    return wrapStarlarkProviderWithNativeProvider(provider);
+  }
+
+  public static StarlarkInfo getStarlarkProvider(RuleContext ruleContext, String attributeName) {
+    for (TransitiveInfoCollection prerequisite : ruleContext.getPrerequisites(attributeName)) {
+      StarlarkInfo provider = (StarlarkInfo) prerequisite.get(starlarkProtoLangToolchainKey);
+      if (provider != null) {
+        return provider;
+      }
+    }
+    return null;
+  }
+
+  public static StarlarkInfo getStarlarkProvider(TransitiveInfoCollection prerequisite) {
+    return (StarlarkInfo) prerequisite.get(starlarkProtoLangToolchainKey);
+  }
+
+  @SuppressWarnings("unchecked")
+  private static ProtoLangToolchainProvider wrapStarlarkProviderWithNativeProvider(
+      StarlarkInfo provider) {
+    if (provider != null) {
+      try {
+        return new AutoValue_ProtoLangToolchainProvider(
+            provider.getValue("out_replacement_format_flag", String.class),
+            provider.getValue("plugin_format_flag", String.class),
+            provider.getValue("plugin") instanceof NoneType
+                ? null
+                : provider.getValue("plugin", FilesToRunProvider.class),
+            provider.getValue("runtime") instanceof NoneType
+                ? null
+                : provider.getValue("runtime", TransitiveInfoCollection.class),
+            ImmutableList.copyOf(
+                (StarlarkList<ProtoSource>) provider.getValue("provided_proto_sources")),
+            provider.getValue("proto_compiler", FilesToRunProvider.class),
+            ImmutableList.copyOf((StarlarkList<String>) provider.getValue("protoc_opts")),
+            provider.getValue("progress_message", String.class),
+            provider.getValue("mnemonic", String.class));
+      } catch (EvalException e) {
+        return null;
+      }
+    }
+    return null;
   }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchainRule.java b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchainRule.java
index 0d4ba14..0682ed3 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchainRule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchainRule.java
@@ -116,7 +116,6 @@
                 .exec()
                 .value(PROTO_COMPILER))
         .requiresConfigurationFragments(ProtoConfiguration.class)
-        .advertiseStarlarkProvider(ProtoLangToolchainProvider.PROVIDER.id())
         .removeAttribute("data")
         .removeAttribute("deps")
         .build();
diff --git a/src/main/starlark/builtins_bzl/common/exports.bzl b/src/main/starlark/builtins_bzl/common/exports.bzl
index 954036f..ad07ebe 100755
--- a/src/main/starlark/builtins_bzl/common/exports.bzl
+++ b/src/main/starlark/builtins_bzl/common/exports.bzl
@@ -55,7 +55,7 @@
     "+cc_binary": cc_binary,
     "+cc_test": cc_test,
     "-cc_library": cc_library,
-    "-proto_lang_toolchain": proto_lang_toolchain,
+    "+proto_lang_toolchain": proto_lang_toolchain,
 }
 
 # A list of Starlark functions callable from native rules implementation.
diff --git a/src/main/starlark/builtins_bzl/common/java/proto/java_proto_library.bzl b/src/main/starlark/builtins_bzl/common/java/proto/java_proto_library.bzl
index 1f3b26b..3e8d40b 100644
--- a/src/main/starlark/builtins_bzl/common/java/proto/java_proto_library.bzl
+++ b/src/main/starlark/builtins_bzl/common/java/proto/java_proto_library.bzl
@@ -15,8 +15,7 @@
 """The implementation of the `java_proto_library` rule and its aspect."""
 
 load(":common/java/java_semantics.bzl", "semantics")
-load(":common/proto/proto_common.bzl", proto_common = "proto_common_do_not_use")
-load(":common/proto/providers.bzl", "ProtoLangToolchainInfo")
+load(":common/proto/proto_common.bzl", "ProtoLangToolchainInfo", proto_common = "proto_common_do_not_use")
 
 java_common = _builtins.toplevel.java_common
 JavaInfo = _builtins.toplevel.JavaInfo
diff --git a/src/main/starlark/builtins_bzl/common/proto/proto_common.bzl b/src/main/starlark/builtins_bzl/common/proto/proto_common.bzl
index c7710cd..d966725 100644
--- a/src/main/starlark/builtins_bzl/common/proto/proto_common.bzl
+++ b/src/main/starlark/builtins_bzl/common/proto/proto_common.bzl
@@ -12,9 +12,22 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""
-Definition of proto_common module.
-"""
+"""Definition of proto_common module, together with bazel providers for proto rules."""
+
+ProtoLangToolchainInfo = provider(
+    doc = "Specifies how to generate language-specific code from .proto files. Used by LANG_proto_library rules.",
+    fields = dict(
+        out_replacement_format_flag = "(str) Format string used when passing output to the plugin used by proto compiler.",
+        plugin_format_flag = "(str) Format string used when passing plugin to proto compiler.",
+        plugin = "(FilesToRunProvider) Proto compiler plugin.",
+        runtime = "(Target) Runtime.",
+        provided_proto_sources = "(list[ProtoSource]) Proto sources provided by the toolchain.",
+        proto_compiler = "(FilesToRunProvider) Proto compiler.",
+        protoc_opts = "(list[str]) Options to pass to proto compiler.",
+        progress_message = "(str) Progress message to set on the proto compiler action.",
+        mnemonic = "(str) Mnemonic to set on the proto compiler action.",
+    ),
+)
 
 def _create_proto_compile_action(
         ctx,
@@ -287,5 +300,5 @@
     declare_generated_files = _declare_generated_files,
     experimental_should_generate_code = _experimental_should_generate_code,
     experimental_filter_sources = _experimental_filter_sources,
-    ProtoLangToolchainInfo = _builtins.internal.ProtoLangToolchainInfo,
+    ProtoLangToolchainInfo = ProtoLangToolchainInfo,
 )
diff --git a/src/main/starlark/builtins_bzl/common/proto/proto_lang_toolchain.bzl b/src/main/starlark/builtins_bzl/common/proto/proto_lang_toolchain.bzl
index c38068d..8e7023d 100644
--- a/src/main/starlark/builtins_bzl/common/proto/proto_lang_toolchain.bzl
+++ b/src/main/starlark/builtins_bzl/common/proto/proto_lang_toolchain.bzl
@@ -14,7 +14,7 @@
 
 """A Starlark implementation of the proto_lang_toolchain rule."""
 
-load(":common/proto/providers.bzl", "ProtoLangToolchainInfo")
+load(":common/proto/proto_common.bzl", "ProtoLangToolchainInfo")
 load(":common/proto/proto_semantics.bzl", "semantics")
 load(":common/rule_util.bzl", "merge_attrs")
 
diff --git a/src/main/starlark/builtins_bzl/common/proto/providers.bzl b/src/main/starlark/builtins_bzl/common/proto/providers.bzl
deleted file mode 100644
index aba5fe0..0000000
--- a/src/main/starlark/builtins_bzl/common/proto/providers.bzl
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright 2021 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.
-
-"""Bazel providers for proto rules."""
-
-ProtoLangToolchainInfo = provider(
-    doc = "Specifies how to generate language-specific code from .proto files. Used by LANG_proto_library rules.",
-    fields = dict(
-        out_replacement_format_flag = "(str) Format string used when passing output to the plugin used by proto compiler.",
-        plugin_format_flag = "(str) Format string used when passing plugin to proto compiler.",
-        plugin = "(FilesToRunProvider) Proto compiler plugin.",
-        runtime = "(Target) Runtime.",
-        provided_proto_sources = "(list[ProtoSource]) Proto sources provided by the toolchain.",
-        proto_compiler = "(FilesToRunProvider) Proto compiler.",
-        protoc_opts = "(list[str]) Options to pass to proto compiler.",
-        progress_message = "(str) Progress message to set on the proto compiler action.",
-        mnemonic = "(str) Mnemonic to set on the proto compiler action.",
-    ),
-)
diff --git a/src/test/java/com/google/devtools/build/lib/rules/proto/BUILD b/src/test/java/com/google/devtools/build/lib/rules/proto/BUILD
index 5602a5b..5c600ff 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/proto/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/rules/proto/BUILD
@@ -39,6 +39,7 @@
     deps = [
         "//src/main/java/com/google/devtools/build/lib/analysis:transitive_info_collection",
         "//src/main/java/com/google/devtools/build/lib/cmdline",
+        "//src/main/java/com/google/devtools/build/lib/packages",
         "//src/main/java/com/google/devtools/build/lib/rules/proto",
         "//src/test/java/com/google/devtools/build/lib/analysis/util",
         "//src/test/java/com/google/devtools/build/lib/packages:testutil",
@@ -50,25 +51,6 @@
 )
 
 java_test(
-    name = "StarlarkProtoLangToolchainTest",
-    srcs = ["StarlarkProtoLangToolchainTest.java"],
-    deps = [
-        ":ProtoLangToolchainTest",
-        "//src/main/java/com/google/devtools/build/lib/analysis:analysis_cluster",
-        "//src/main/java/com/google/devtools/build/lib/analysis:transitive_info_collection",
-        "//src/main/java/com/google/devtools/build/lib/cmdline",
-        "//src/main/java/com/google/devtools/build/lib/packages",
-        "//src/main/java/com/google/devtools/build/lib/rules/proto",
-        "//src/main/java/net/starlark/java/eval",
-        "//src/test/java/com/google/devtools/build/lib/analysis/util",
-        "//src/test/java/com/google/devtools/build/lib/testutil:TestConstants",
-        "//third_party:guava",
-        "//third_party:junit4",
-        "//third_party:truth",
-    ],
-)
-
-java_test(
     name = "BazelProtoLibraryTest",
     srcs = ["BazelProtoLibraryTest.java"],
     deps = [
diff --git a/src/test/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchainTest.java b/src/test/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchainTest.java
index 8126f30..6d6aaf9 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchainTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/proto/ProtoLangToolchainTest.java
@@ -22,6 +22,9 @@
 import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
 import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
 import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
+import com.google.devtools.build.lib.packages.Provider;
+import com.google.devtools.build.lib.packages.StarlarkProvider;
 import com.google.devtools.build.lib.packages.util.MockProtoSupport;
 import com.google.devtools.build.lib.testutil.TestConstants;
 import org.junit.Before;
@@ -32,12 +35,6 @@
 /** Unit tests for {@code proto_lang_toolchain}. */
 @RunWith(JUnit4.class)
 public class ProtoLangToolchainTest extends BuildViewTestCase {
-
-  @Before
-  public void setupStarlarkRule() throws Exception {
-    setBuildLanguageOptions("--experimental_builtins_injection_override=-proto_lang_toolchain");
-  }
-
   @Before
   public void setUp() throws Exception {
     MockProtoSupport.setupWorkspace(scratch);
@@ -46,6 +43,12 @@
     invalidatePackages();
   }
 
+  Provider.Key getStarlarkProtoLangToolchainInfoKey() throws LabelSyntaxException {
+    return new StarlarkProvider.Key(
+        Label.parseAbsolute("@_builtins//:common/proto/proto_common.bzl", ImmutableMap.of()),
+        "ProtoLangToolchainInfo");
+  }
+
   private void validateProtoLangToolchain(ProtoLangToolchainProvider toolchain) throws Exception {
     assertThat(toolchain.outReplacementFormatFlag()).isEqualTo("cmd-line:%s");
     assertThat(toolchain.pluginFormatFlag()).isEqualTo("--plugin=%s");
@@ -57,14 +60,16 @@
         .isEqualTo(Label.parseAbsolute("//third_party/x:runtime", ImmutableMap.of()));
 
     assertThat(toolchain.protocOpts()).containsExactly("--myflag");
-    Label protoc = Label.parseAbsoluteUnchecked(ProtoConstants.DEFAULT_PROTOC_LABEL);
-    assertThat(toolchain.protoc().getExecutable().prettyPrint())
-        .isEqualTo(protoc.toPathFragment().getPathString());
 
     assertThat(toolchain.progressMessage()).isEqualTo("Progress Message %{label}");
     assertThat(toolchain.mnemonic()).isEqualTo("MyMnemonic");
   }
 
+  private void validateProtoCompiler(ProtoLangToolchainProvider toolchain, Label protoCompiler) {
+    assertThat(toolchain.protoc().getExecutable().prettyPrint())
+        .isEqualTo(protoCompiler.toPathFragment().getPathString());
+  }
+
   @Test
   public void protoToolchain() throws Exception {
     scratch.file(
@@ -86,15 +91,52 @@
         "    plugin_format_flag = '--plugin=%s',",
         "    plugin = '//third_party/x:plugin',",
         "    runtime = '//third_party/x:runtime',",
-        "    blacklisted_protos = ['//third_party/x:denied'],",
         "    progress_message = 'Progress Message %{label}',",
         "    mnemonic = 'MyMnemonic',",
         ")");
 
     update(ImmutableList.of("//foo:toolchain"), false, 1, true, new EventBus());
+    ProtoLangToolchainProvider toolchain =
+        ProtoLangToolchainProvider.get(getConfiguredTarget("//foo:toolchain"));
+    Label protoc = Label.parseAbsoluteUnchecked(ProtoConstants.DEFAULT_PROTOC_LABEL);
 
-    validateProtoLangToolchain(
-        getConfiguredTarget("//foo:toolchain").get(ProtoLangToolchainProvider.PROVIDER));
+    validateProtoLangToolchain(toolchain);
+    validateProtoCompiler(toolchain, protoc);
+  }
+
+  @Test
+  public void protoToolchain_setProtoCompiler() throws Exception {
+    scratch.file(
+        "third_party/x/BUILD",
+        "licenses(['unencumbered'])",
+        "cc_binary(name = 'plugin', srcs = ['plugin.cc'])",
+        "cc_library(name = 'runtime', srcs = ['runtime.cc'])",
+        "filegroup(name = 'descriptors', srcs = ['metadata.proto', 'descriptor.proto'])",
+        "filegroup(name = 'any', srcs = ['any.proto'])",
+        "proto_library(name = 'denied', srcs = [':descriptors', ':any'])",
+        "cc_binary(name = 'compiler')");
+
+    scratch.file(
+        "foo/BUILD",
+        TestConstants.LOAD_PROTO_LANG_TOOLCHAIN,
+        "licenses(['unencumbered'])",
+        "proto_lang_toolchain(",
+        "    name = 'toolchain',",
+        "    command_line = 'cmd-line:$(OUT)',",
+        "    plugin_format_flag = '--plugin=%s',",
+        "    plugin = '//third_party/x:plugin',",
+        "    runtime = '//third_party/x:runtime',",
+        "    progress_message = 'Progress Message %{label}',",
+        "    mnemonic = 'MyMnemonic',",
+        "    proto_compiler = '//third_party/x:compiler',",
+        ")");
+
+    ProtoLangToolchainProvider toolchain =
+        ProtoLangToolchainProvider.get(getConfiguredTarget("//foo:toolchain"));
+    Label protoc = Label.parseAbsoluteUnchecked("//third_party/x:compiler");
+
+    validateProtoLangToolchain(toolchain);
+    validateProtoCompiler(toolchain, protoc);
   }
 
   @Test
@@ -117,15 +159,17 @@
         "    plugin_format_flag = '--plugin=%s',",
         "    plugin = '//third_party/x:plugin',",
         "    runtime = '//third_party/x:runtime',",
-        "    blacklisted_protos = ['//third_party/x:descriptors', '//third_party/x:any'],",
         "    progress_message = 'Progress Message %{label}',",
         "    mnemonic = 'MyMnemonic',",
         ")");
 
     update(ImmutableList.of("//foo:toolchain"), false, 1, true, new EventBus());
+    ProtoLangToolchainProvider toolchain =
+        ProtoLangToolchainProvider.get(getConfiguredTarget("//foo:toolchain"));
+    Label protoc = Label.parseAbsoluteUnchecked(ProtoConstants.DEFAULT_PROTOC_LABEL);
 
-    validateProtoLangToolchain(
-        getConfiguredTarget("//foo:toolchain").get(ProtoLangToolchainProvider.PROVIDER));
+    validateProtoLangToolchain(toolchain);
+    validateProtoCompiler(toolchain, protoc);
   }
 
   @Test
@@ -148,15 +192,17 @@
         "    plugin_format_flag = '--plugin=%s',",
         "    plugin = '//third_party/x:plugin',",
         "    runtime = '//third_party/x:runtime',",
-        "    blacklisted_protos = ['//third_party/x:any'],",
         "    progress_message = 'Progress Message %{label}',",
         "    mnemonic = 'MyMnemonic',",
         ")");
 
     update(ImmutableList.of("//foo:toolchain"), false, 1, true, new EventBus());
+    ProtoLangToolchainProvider toolchain =
+        ProtoLangToolchainProvider.get(getConfiguredTarget("//foo:toolchain"));
+    Label protoc = Label.parseAbsoluteUnchecked(ProtoConstants.DEFAULT_PROTOC_LABEL);
 
-    validateProtoLangToolchain(
-        getConfiguredTarget("//foo:toolchain").get(ProtoLangToolchainProvider.PROVIDER));
+    validateProtoLangToolchain(toolchain);
+    validateProtoCompiler(toolchain, protoc);
   }
 
   @Test
@@ -170,9 +216,8 @@
         ")");
 
     update(ImmutableList.of("//foo:toolchain"), false, 1, true, new EventBus());
-
     ProtoLangToolchainProvider toolchain =
-        getConfiguredTarget("//foo:toolchain").get(ProtoLangToolchainProvider.PROVIDER);
+        ProtoLangToolchainProvider.get(getConfiguredTarget("//foo:toolchain"));
 
     assertThat(toolchain.pluginExecutable()).isNull();
     assertThat(toolchain.runtime()).isNull();
diff --git a/src/test/java/com/google/devtools/build/lib/rules/proto/StarlarkProtoLangToolchainTest.java b/src/test/java/com/google/devtools/build/lib/rules/proto/StarlarkProtoLangToolchainTest.java
deleted file mode 100644
index 9bd9d8b..0000000
--- a/src/test/java/com/google/devtools/build/lib/rules/proto/StarlarkProtoLangToolchainTest.java
+++ /dev/null
@@ -1,243 +0,0 @@
-// Copyright 2016 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.proto;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.eventbus.EventBus;
-import com.google.devtools.build.lib.analysis.FilesToRunProvider;
-import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
-import com.google.devtools.build.lib.cmdline.Label;
-import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
-import com.google.devtools.build.lib.packages.Provider;
-import com.google.devtools.build.lib.packages.StarlarkInfo;
-import com.google.devtools.build.lib.packages.StarlarkProvider;
-import com.google.devtools.build.lib.testutil.TestConstants;
-import net.starlark.java.eval.Starlark;
-import net.starlark.java.eval.StarlarkList;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** Unit tests for {@code proto_lang_toolchain}. */
-@RunWith(JUnit4.class)
-public class StarlarkProtoLangToolchainTest extends ProtoLangToolchainTest {
-
-  @Override
-  @Before
-  public void setupStarlarkRule() throws Exception {
-    setBuildLanguageOptions("--experimental_builtins_injection_override=+proto_lang_toolchain");
-  }
-
-  Provider.Key getStarlarkProtoLangToolchainInfoKey() throws LabelSyntaxException {
-    return new StarlarkProvider.Key(
-        Label.parseAbsolute("@_builtins//:common/proto/providers.bzl", ImmutableMap.of()),
-        "ProtoLangToolchainInfo");
-  }
-
-  @SuppressWarnings("unchecked")
-  private void validateStarlarkProtoLangToolchain(StarlarkInfo toolchain) throws Exception {
-    assertThat(toolchain.getValue("out_replacement_format_flag")).isEqualTo("cmd-line:%s");
-    assertThat(toolchain.getValue("plugin_format_flag")).isEqualTo("--plugin=%s");
-    assertThat(toolchain.getValue("progress_message")).isEqualTo("Progress Message %{label}");
-    assertThat(toolchain.getValue("mnemonic")).isEqualTo("MyMnemonic");
-    assertThat(ImmutableList.copyOf((StarlarkList<String>) toolchain.getValue("protoc_opts")))
-        .containsExactly("--myflag");
-    assertThat(
-            ((FilesToRunProvider) toolchain.getValue("plugin"))
-                .getExecutable()
-                .getRootRelativePathString())
-        .isEqualTo("third_party/x/plugin");
-
-    TransitiveInfoCollection runtimes = (TransitiveInfoCollection) toolchain.getValue("runtime");
-    assertThat(runtimes.getLabel())
-        .isEqualTo(Label.parseAbsolute("//third_party/x:runtime", ImmutableMap.of()));
-  }
-
-  private void validateProtoCompiler(StarlarkInfo toolchain, Label protoCompiler) {
-    assertThat(
-            ((FilesToRunProvider) toolchain.getValue("proto_compiler"))
-                .getExecutable()
-                .prettyPrint())
-        .isEqualTo(protoCompiler.toPathFragment().getPathString());
-  }
-
-  @Override
-  @Test
-  public void protoToolchain() throws Exception {
-    scratch.file(
-        "third_party/x/BUILD",
-        "licenses(['unencumbered'])",
-        "cc_binary(name = 'plugin', srcs = ['plugin.cc'])",
-        "cc_library(name = 'runtime', srcs = ['runtime.cc'])",
-        "filegroup(name = 'descriptors', srcs = ['metadata.proto', 'descriptor.proto'])",
-        "filegroup(name = 'any', srcs = ['any.proto'])",
-        "proto_library(name = 'denied', srcs = [':descriptors', ':any'])");
-
-    scratch.file(
-        "foo/BUILD",
-        TestConstants.LOAD_PROTO_LANG_TOOLCHAIN,
-        "licenses(['unencumbered'])",
-        "proto_lang_toolchain(",
-        "    name = 'toolchain',",
-        "    command_line = 'cmd-line:$(OUT)',",
-        "    plugin_format_flag = '--plugin=%s',",
-        "    plugin = '//third_party/x:plugin',",
-        "    runtime = '//third_party/x:runtime',",
-        "    progress_message = 'Progress Message %{label}',",
-        "    mnemonic = 'MyMnemonic',",
-        ")");
-
-    update(ImmutableList.of("//foo:toolchain"), false, 1, true, new EventBus());
-    StarlarkInfo toolchain =
-        (StarlarkInfo)
-            getConfiguredTarget("//foo:toolchain").get(getStarlarkProtoLangToolchainInfoKey());
-    Label protoc = Label.parseAbsoluteUnchecked(ProtoConstants.DEFAULT_PROTOC_LABEL);
-
-    validateStarlarkProtoLangToolchain(toolchain);
-    validateProtoCompiler(toolchain, protoc);
-  }
-
-  @Test
-  public void protoToolchain_setProtoCompiler() throws Exception {
-    scratch.file(
-        "third_party/x/BUILD",
-        "licenses(['unencumbered'])",
-        "cc_binary(name = 'plugin', srcs = ['plugin.cc'])",
-        "cc_library(name = 'runtime', srcs = ['runtime.cc'])",
-        "filegroup(name = 'descriptors', srcs = ['metadata.proto', 'descriptor.proto'])",
-        "filegroup(name = 'any', srcs = ['any.proto'])",
-        "proto_library(name = 'denied', srcs = [':descriptors', ':any'])",
-        "cc_binary(name = 'compiler')");
-
-    scratch.file(
-        "foo/BUILD",
-        TestConstants.LOAD_PROTO_LANG_TOOLCHAIN,
-        "licenses(['unencumbered'])",
-        "proto_lang_toolchain(",
-        "    name = 'toolchain',",
-        "    command_line = 'cmd-line:$(OUT)',",
-        "    plugin_format_flag = '--plugin=%s',",
-        "    plugin = '//third_party/x:plugin',",
-        "    runtime = '//third_party/x:runtime',",
-        "    progress_message = 'Progress Message %{label}',",
-        "    mnemonic = 'MyMnemonic',",
-        "    proto_compiler = '//third_party/x:compiler',",
-        ")");
-
-    StarlarkInfo toolchain =
-        (StarlarkInfo)
-            getConfiguredTarget("//foo:toolchain").get(getStarlarkProtoLangToolchainInfoKey());
-    Label protoc = Label.parseAbsoluteUnchecked("//third_party/x:compiler");
-
-    validateStarlarkProtoLangToolchain(toolchain);
-    validateProtoCompiler(toolchain, protoc);
-  }
-
-  @Override
-  @Test
-  public void protoToolchainBlacklistProtoLibraries() throws Exception {
-    scratch.file(
-        "third_party/x/BUILD",
-        TestConstants.LOAD_PROTO_LIBRARY,
-        "licenses(['unencumbered'])",
-        "cc_binary(name = 'plugin', srcs = ['plugin.cc'])",
-        "cc_library(name = 'runtime', srcs = ['runtime.cc'])",
-        "proto_library(name = 'descriptors', srcs = ['metadata.proto', 'descriptor.proto'])",
-        "proto_library(name = 'any', srcs = ['any.proto'], strip_import_prefix = '/third_party')");
-
-    scratch.file(
-        "foo/BUILD",
-        TestConstants.LOAD_PROTO_LANG_TOOLCHAIN,
-        "proto_lang_toolchain(",
-        "    name = 'toolchain',",
-        "    command_line = 'cmd-line:$(OUT)',",
-        "    plugin_format_flag = '--plugin=%s',",
-        "    plugin = '//third_party/x:plugin',",
-        "    runtime = '//third_party/x:runtime',",
-        "    progress_message = 'Progress Message %{label}',",
-        "    mnemonic = 'MyMnemonic',",
-        ")");
-
-    update(ImmutableList.of("//foo:toolchain"), false, 1, true, new EventBus());
-    StarlarkInfo toolchain =
-        (StarlarkInfo)
-            getConfiguredTarget("//foo:toolchain").get(getStarlarkProtoLangToolchainInfoKey());
-    Label protoc = Label.parseAbsoluteUnchecked(ProtoConstants.DEFAULT_PROTOC_LABEL);
-
-    validateStarlarkProtoLangToolchain(toolchain);
-    validateProtoCompiler(toolchain, protoc);
-  }
-
-  @Override
-  @Test
-  public void protoToolchainBlacklistTransitiveProtos() throws Exception {
-    scratch.file(
-        "third_party/x/BUILD",
-        TestConstants.LOAD_PROTO_LIBRARY,
-        "licenses(['unencumbered'])",
-        "cc_binary(name = 'plugin', srcs = ['plugin.cc'])",
-        "cc_library(name = 'runtime', srcs = ['runtime.cc'])",
-        "proto_library(name = 'descriptors', srcs = ['metadata.proto', 'descriptor.proto'])",
-        "proto_library(name = 'any', srcs = ['any.proto'], deps = [':descriptors'])");
-
-    scratch.file(
-        "foo/BUILD",
-        TestConstants.LOAD_PROTO_LANG_TOOLCHAIN,
-        "proto_lang_toolchain(",
-        "    name = 'toolchain',",
-        "    command_line = 'cmd-line:$(OUT)',",
-        "    plugin_format_flag = '--plugin=%s',",
-        "    plugin = '//third_party/x:plugin',",
-        "    runtime = '//third_party/x:runtime',",
-        "    progress_message = 'Progress Message %{label}',",
-        "    mnemonic = 'MyMnemonic',",
-        ")");
-
-    update(ImmutableList.of("//foo:toolchain"), false, 1, true, new EventBus());
-    StarlarkInfo toolchain =
-        (StarlarkInfo)
-            getConfiguredTarget("//foo:toolchain").get(getStarlarkProtoLangToolchainInfoKey());
-    Label protoc = Label.parseAbsoluteUnchecked(ProtoConstants.DEFAULT_PROTOC_LABEL);
-
-    validateStarlarkProtoLangToolchain(toolchain);
-    validateProtoCompiler(toolchain, protoc);
-  }
-
-  @Override
-  @Test
-  public void optionalFieldsAreEmpty() throws Exception {
-    scratch.file(
-        "foo/BUILD",
-        TestConstants.LOAD_PROTO_LANG_TOOLCHAIN,
-        "proto_lang_toolchain(",
-        "    name = 'toolchain',",
-        "    command_line = 'cmd-line:$(OUT)',",
-        ")");
-
-    update(ImmutableList.of("//foo:toolchain"), false, 1, true, new EventBus());
-
-    StarlarkInfo toolchain =
-        (StarlarkInfo)
-            getConfiguredTarget("//foo:toolchain").get(getStarlarkProtoLangToolchainInfoKey());
-
-    assertThat(toolchain.getValue("plugin")).isEqualTo(Starlark.NONE);
-    assertThat(toolchain.getValue("runtime")).isEqualTo(Starlark.NONE);
-    assertThat(toolchain.getValue("mnemonic")).isEqualTo("GenProto");
-  }
-}