Automated rollback of commit 6d884afa8da1b08288cb0108e8bbf6c22ec63393.

*** Reason for rollback ***

Broke bazel_apple_rules

*** Original change description ***

Make all WithLegacySkylarkName providers declared providers.

RELNOTES: None
PiperOrigin-RevId: 163054821
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/AnalysisUtils.java b/src/main/java/com/google/devtools/build/lib/analysis/AnalysisUtils.java
index a5ad97e..966471c 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/AnalysisUtils.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/AnalysisUtils.java
@@ -14,6 +14,7 @@
 
 package com.google.devtools.build.lib.analysis;
 
+import com.google.common.base.Predicate;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 import com.google.devtools.build.lib.actions.Artifact;
@@ -99,19 +100,15 @@
    */
   public static <S extends TransitiveInfoCollection, C extends TransitiveInfoProvider> Iterable<S>
       filterByProvider(Iterable<S> prerequisites, final Class<C> provider) {
-    return Iterables.filter(prerequisites, target -> target.getProvider(provider) != null);
+    return Iterables.filter(prerequisites, new Predicate<S>() {
+      @Override
+      public boolean apply(S target) {
+        return target.getProvider(provider) != null;
+      }
+    });
   }
 
   /**
-   * Returns the iterable of collections that have the specified provider.
-   */
-  public static <S extends TransitiveInfoCollection, C extends SkylarkClassObject> Iterable<S>
-  filterByProvider(Iterable<S> prerequisites, final NativeClassObjectConstructor<C> provider) {
-    return Iterables.filter(prerequisites, target -> target.get(provider) != null);
-  }
-
-
-  /**
    * Returns the path of the associated manifest file for the path of a Fileset. Works for both
    * exec paths and root relative paths.
    */
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java
index c4afb4f..6bf2ee2 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java
@@ -30,7 +30,6 @@
 import com.google.devtools.build.lib.collect.nestedset.Order;
 import com.google.devtools.build.lib.events.Location;
 import com.google.devtools.build.lib.packages.ClassObjectConstructor;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
 import com.google.devtools.build.lib.packages.SkylarkClassObject;
 import com.google.devtools.build.lib.packages.Target;
 import com.google.devtools.build.lib.packages.TargetUtils;
@@ -213,6 +212,7 @@
   public <T extends TransitiveInfoProvider> RuleConfiguredTargetBuilder addProvider(
       TransitiveInfoProvider provider) {
     providersBuilder.add(provider);
+    maybeAddSkylarkProvider(provider);
     return this;
   }
 
@@ -220,6 +220,9 @@
   public <T extends TransitiveInfoProvider> RuleConfiguredTargetBuilder addProviders(
       Iterable<TransitiveInfoProvider> providers) {
     providersBuilder.addAll(providers);
+    for (TransitiveInfoProvider provider : providers) {
+      maybeAddSkylarkProvider(provider);
+    }
     return this;
   }
 
@@ -247,15 +250,14 @@
     Preconditions.checkNotNull(key);
     Preconditions.checkNotNull(value);
     providersBuilder.put(key, value);
+    maybeAddSkylarkProvider(value);
     return this;
   }
 
-  private <T extends TransitiveInfoProvider> void maybeAddSkylarkLegacyProvider(
-      SkylarkClassObject value) {
-    if (value.getConstructor() instanceof NativeClassObjectConstructor.WithLegacySkylarkName) {
+  protected <T extends TransitiveInfoProvider> void maybeAddSkylarkProvider(T value) {
+    if (value instanceof TransitiveInfoProvider.WithLegacySkylarkName) {
       addSkylarkTransitiveInfo(
-          ((NativeClassObjectConstructor.WithLegacySkylarkName) value.getConstructor())
-              .getSkylarkName(),
+          ((TransitiveInfoProvider.WithLegacySkylarkName) value).getSkylarkName(),
           value);
     }
   }
@@ -326,7 +328,6 @@
     ClassObjectConstructor constructor = provider.getConstructor();
     Preconditions.checkState(constructor.isExported());
     providersBuilder.put(provider);
-    maybeAddSkylarkLegacyProvider(provider);
     return this;
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
index 67613f2..986a93b 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
@@ -902,17 +902,6 @@
   }
 
   /**
-   * Returns all the providers of the specified type that are listed under the specified attribute
-   * of this target in the BUILD file, and that contain the specified provider.
-   */
-  public <C extends SkylarkClassObject>
-  Iterable<? extends TransitiveInfoCollection> getPrerequisitesIf(
-      String attributeName, Mode mode, final NativeClassObjectConstructor<C> classType) {
-    return AnalysisUtils.filterByProvider(getPrerequisites(attributeName, mode), classType);
-  }
-
-
-  /**
    * Returns the prerequisite referred to by the specified attribute. Also checks whether
    * the attribute is marked as executable and that the target referred to can actually be
    * executed.
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoProvider.java b/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoProvider.java
index f2b4919..9ee8933 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoProvider.java
@@ -61,4 +61,18 @@
  */
 public interface TransitiveInfoProvider {
 
+  /**
+   * Implement this to mark that a native provider should be exported with
+   * certain name to Skylark.
+   * Broken: only works for rules, not for aspects.
+   * DO NOT USE FOR NEW CODE!
+   *
+   * Use native declared providers
+   * ({@link com.google.devtools.build.lib.packages.NativeClassObjectConstructor}) to
+   * expose providers to both native and Skylark code.
+   */
+  @Deprecated
+  interface WithLegacySkylarkName {
+    String getSkylarkName();
+  }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/packages/NativeClassObjectConstructor.java b/src/main/java/com/google/devtools/build/lib/packages/NativeClassObjectConstructor.java
index 8cb97c3..935e004 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/NativeClassObjectConstructor.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/NativeClassObjectConstructor.java
@@ -57,21 +57,6 @@
   }
 
   /**
-   * Implement this to mark that a native provider should be exported with
-   * certain name to Skylark.
-   * Broken: only works for rules, not for aspects.
-   * DO NOT USE FOR NEW CODE!
-   *
-   * Use native declared providers
-   * ({@link NativeClassObjectConstructor}) to
-   * expose providers to both native and Skylark code.
-   */
-  @Deprecated
-  public static interface WithLegacySkylarkName {
-    String getSkylarkName();
-  }
-
-  /**
    * A constructor for default {@code struct}s.
    *
    * <p>Singleton, instance is {@link #STRUCT}.
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleConfiguredTargetUtil.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleConfiguredTargetUtil.java
index 8d50183..3113a4c 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleConfiguredTargetUtil.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleConfiguredTargetUtil.java
@@ -26,6 +26,7 @@
 import com.google.devtools.build.lib.analysis.RunfilesProvider;
 import com.google.devtools.build.lib.analysis.RunfilesSupport;
 import com.google.devtools.build.lib.analysis.SkylarkProviderValidationUtil;
+import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
 import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
 import com.google.devtools.build.lib.events.Location;
@@ -349,8 +350,9 @@
         SkylarkClassObject insStruct =
             cast("instrumented_files", oldStyleProviders, SkylarkClassObject.class, loc);
         addInstrumentedFiles(insStruct, ruleContext, builder);
-      } else if (isNativeDeclaredProviderWithLegacySkylarkName(oldStyleProviders.getValue(key))) {
-        builder.addNativeDeclaredProvider((SkylarkClassObject) oldStyleProviders.getValue(key));
+      } else if (oldStyleProviders.getValue(key)
+          instanceof TransitiveInfoProvider.WithLegacySkylarkName) {
+        builder.addProvider((TransitiveInfoProvider) oldStyleProviders.getValue(key));
       } else if (!key.equals("providers")) {
         // We handled providers already.
         builder.addSkylarkTransitiveInfo(key, oldStyleProviders.getValue(key), loc);
@@ -358,14 +360,6 @@
     }
   }
 
-  private static boolean isNativeDeclaredProviderWithLegacySkylarkName(Object value) {
-    if (!(value instanceof SkylarkClassObject)) {
-      return false;
-    }
-    return ((SkylarkClassObject) value).getConstructor()
-        instanceof NativeClassObjectConstructor.WithLegacySkylarkName;
-  }
-
   /**
    * Parses keys of (not necessarily a default) provider. If it is an actual default provider,
    * throws an {@link EvalException} if there are unknown keys.
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinary.java
index 4028dc4..d296905 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinary.java
@@ -121,7 +121,7 @@
     ApplePlatform platform = appleConfiguration.getMultiArchPlatform(platformType);
     ImmutableListMultimap<BuildConfiguration, ObjcProvider> configurationToNonPropagatedObjcMap =
         ruleContext.getPrerequisitesByConfiguration(
-            "non_propagated_deps", Mode.SPLIT, ObjcProvider.SKYLARK_CONSTRUCTOR);
+            "non_propagated_deps", Mode.SPLIT, ObjcProvider.class);
     ImmutableListMultimap<BuildConfiguration, TransitiveInfoCollection> configToDepsCollectionMap =
         ruleContext.getPrerequisitesByConfiguration("deps", Mode.SPLIT);
 
@@ -165,7 +165,7 @@
 
     ObjcProvider objcProvider = objcProviderBuilder.build();
     // TODO(cparsons): Stop propagating ObjcProvider directly from this rule.
-    targetBuilder.addNativeDeclaredProvider(objcProvider);
+    targetBuilder.addProvider(ObjcProvider.class, objcProvider);
 
     switch (getBinaryType(ruleContext)) {
       case EXECUTABLE:
@@ -266,8 +266,7 @@
     }
 
     ObjcProvider bundleLoaderObjcProvider =
-        ruleContext.getPrerequisite(
-            BUNDLE_LOADER_ATTR_NAME, Mode.TARGET, ObjcProvider.SKYLARK_CONSTRUCTOR);
+        ruleContext.getPrerequisite(BUNDLE_LOADER_ATTR_NAME, Mode.TARGET, ObjcProvider.class);
 
     if (bundleLoaderObjcProvider != null) {
       dylibProviders.add(bundleLoaderObjcProvider);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibrary.java
index 81e0975..49575aa 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibrary.java
@@ -81,7 +81,7 @@
         ruleContext.getPrerequisitesByConfiguration("deps", Mode.SPLIT);
     ImmutableListMultimap<BuildConfiguration, ObjcProvider> configToObjcAvoidDepsMap =
         ruleContext.getPrerequisitesByConfiguration(AppleStaticLibraryRule.AVOID_DEPS_ATTR_NAME,
-            Mode.SPLIT, ObjcProvider.SKYLARK_CONSTRUCTOR);
+            Mode.SPLIT, ObjcProvider.class);
     ImmutableListMultimap<BuildConfiguration, CcLinkParamsProvider> configToCcAvoidDepsMap =
         ruleContext.getPrerequisitesByConfiguration(AppleStaticLibraryRule.AVOID_DEPS_ATTR_NAME,
             Mode.SPLIT, CcLinkParamsProvider.CC_LINK_PARAMS);
@@ -181,7 +181,7 @@
 
     targetBuilder
         // TODO(cparsons): Remove ObjcProvider as a direct provider.
-        .addNativeDeclaredProvider(objcProvider)
+        .addProvider(ObjcProvider.class, objcProvider)
         .addNativeDeclaredProvider(
             new AppleStaticLibraryProvider(
                 ruleIntermediateArtifacts.combinedArchitectureArchive(),
@@ -215,7 +215,7 @@
         .addDefines(ruleContext.getTokenizedStringListAttr("defines"))
         .addDeps(propagatedDeps)
         .addDepObjcProviders(
-            ruleContext.getPrerequisites("bundles", Mode.TARGET, ObjcProvider.SKYLARK_CONSTRUCTOR))
+            ruleContext.getPrerequisites("bundles", Mode.TARGET, ObjcProvider.class))
         .addDepObjcProviders(protosObjcProvider.asSet())
         .setIntermediateArtifacts(intermediateArtifacts)
         .setAlwayslink(false)
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibraryRule.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibraryRule.java
index 20bc665..cff1acd 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibraryRule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibraryRule.java
@@ -18,9 +18,11 @@
 import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST;
 import static com.google.devtools.build.lib.packages.ImplicitOutputsFunction.fromTemplates;
 
+import com.google.common.collect.ImmutableList;
 import com.google.devtools.build.lib.analysis.BaseRuleClasses;
 import com.google.devtools.build.lib.analysis.RuleDefinition;
 import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
+import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
 import com.google.devtools.build.lib.packages.ImplicitOutputsFunction;
 import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.SafeImplicitOutputsFunction;
 import com.google.devtools.build.lib.packages.RuleClass;
@@ -81,7 +83,8 @@
             attr(AVOID_DEPS_ATTR_NAME, LABEL_LIST)
                 .direct_compile_time_input()
                 .allowedRuleClasses(ObjcRuleClasses.CompilingRule.ALLOWED_CC_DEPS_RULE_CLASSES)
-                .mandatoryProviders(ObjcProvider.SKYLARK_CONSTRUCTOR.id())
+                .mandatoryNativeProviders(
+                    ImmutableList.<Class<? extends TransitiveInfoProvider>>of(ObjcProvider.class))
                 .cfg(splitTransitionProvider)
                 .allowedFileTypes()
                 .aspect(objcProtoAspect))
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStubBinary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStubBinary.java
index 6ef4b6a..00c92f4 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStubBinary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStubBinary.java
@@ -111,8 +111,7 @@
 
     ApplePlatform platform = appleConfiguration.getMultiArchPlatform(platformType);
     ImmutableListMultimap<BuildConfiguration, ObjcProvider> configurationToDepsMap =
-        ruleContext.getPrerequisitesByConfiguration(
-            "deps", Mode.SPLIT, ObjcProvider.SKYLARK_CONSTRUCTOR);
+        ruleContext.getPrerequisitesByConfiguration("deps", Mode.SPLIT, ObjcProvider.class);
 
     Artifact outputArtifact =
         ObjcRuleClasses.intermediateArtifacts(ruleContext).combinedArchitectureBinary();
@@ -132,7 +131,7 @@
 
     ObjcProvider objcProvider = objcProviderBuilder.build();
     // TODO(cparsons): Stop propagating ObjcProvider directly from this rule.
-    targetBuilder.addNativeDeclaredProvider(objcProvider);
+    targetBuilder.addProvider(ObjcProvider.class, objcProvider);
 
     targetBuilder.addNativeDeclaredProvider(
         new AppleExecutableBinaryProvider(outputArtifact, objcProvider));
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStubBinaryRule.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStubBinaryRule.java
index 575f001..f2e2c59 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStubBinaryRule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStubBinaryRule.java
@@ -18,9 +18,11 @@
 import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST;
 import static com.google.devtools.build.lib.syntax.Type.STRING;
 
+import com.google.common.collect.ImmutableList;
 import com.google.devtools.build.lib.analysis.BaseRuleClasses;
 import com.google.devtools.build.lib.analysis.RuleDefinition;
 import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
+import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
 import com.google.devtools.build.lib.packages.ImplicitOutputsFunction;
 import com.google.devtools.build.lib.packages.RuleClass;
 import com.google.devtools.build.lib.packages.RuleClass.Builder;
@@ -49,7 +51,8 @@
         .add(
             attr("deps", LABEL_LIST)
                 .direct_compile_time_input()
-                .mandatoryProviders(ObjcProvider.SKYLARK_CONSTRUCTOR.id())
+                .mandatoryNativeProviders(
+                    ImmutableList.<Class<? extends TransitiveInfoProvider>>of(ObjcProvider.class))
                 .allowedFileTypes()
                 .cfg(splitTransitionProvider))
         /*<!-- #BLAZE_RULE(apple_stub_binary).IMPLICIT_OUTPUTS -->
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java b/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java
index b78dc3d..79ae789 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java
@@ -183,7 +183,7 @@
 
     RuleConfiguredTargetBuilder targetBuilder =
         ObjcRuleClasses.ruleConfiguredTarget(ruleContext, filesToBuild.build())
-            .addNativeDeclaredProvider(objcProvider)
+            .addProvider(ObjcProvider.class, objcProvider)
             .addNativeDeclaredProvider(objcProvider)
             .addProvider(
                 InstrumentedFilesProvider.class,
@@ -193,7 +193,7 @@
     if (xcTestAppProvider.isPresent()) {
       // TODO(bazel-team): Stop exporting an XcTestAppProvider once objc_binary no longer creates an
       // application bundle.
-      targetBuilder.addNativeDeclaredProvider(xcTestAppProvider.get());
+      targetBuilder.addProvider(XcTestAppProvider.class, xcTestAppProvider.get());
     }
     if (maybeRunfilesSupport.isPresent()) {
       RunfilesSupport runfilesSupport = maybeRunfilesSupport.get();
@@ -230,7 +230,7 @@
             .addDepObjcProviders(protosObjcProvider.asSet())
             .addNonPropagatedDepObjcProviders(
                 ruleContext.getPrerequisites(
-                    "non_propagated_deps", Mode.TARGET, ObjcProvider.SKYLARK_CONSTRUCTOR))
+                    "non_propagated_deps", Mode.TARGET, ObjcProvider.class))
             .setIntermediateArtifacts(intermediateArtifacts)
             .setAlwayslink(false)
             .setHasModuleMap()
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationAttributes.java b/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationAttributes.java
index aafd755..01d25fb 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationAttributes.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationAttributes.java
@@ -269,15 +269,14 @@
         // missing, its private headers will be treated as public!
         if (ruleContext.attributes().has("deps", BuildType.LABEL_LIST)) {
           Iterable<ObjcProvider> providers =
-              ruleContext.getPrerequisites("deps", Mode.TARGET, ObjcProvider.SKYLARK_CONSTRUCTOR);
+              ruleContext.getPrerequisites("deps", Mode.TARGET, ObjcProvider.class);
           for (ObjcProvider provider : providers) {
             moduleMaps.addTransitive(provider.get(TOP_LEVEL_MODULE_MAP));
           }
         }
         if (ruleContext.attributes().has("non_propagated_deps", BuildType.LABEL_LIST)) {
           Iterable<ObjcProvider> providers =
-              ruleContext.getPrerequisites(
-                  "non_propagated_deps", Mode.TARGET, ObjcProvider.SKYLARK_CONSTRUCTOR);
+              ruleContext.getPrerequisites("non_propagated_deps", Mode.TARGET, ObjcProvider.class);
           for (ObjcProvider provider : providers) {
             moduleMaps.addTransitive(provider.get(TOP_LEVEL_MODULE_MAP));
           }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java
index c2ac087..7e49b8e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java
@@ -1098,7 +1098,7 @@
       Artifact dummyArchive =
           Iterables.getOnlyElement(
               ruleContext
-                  .getPrerequisite("$dummy_lib", Mode.TARGET, ObjcProvider.SKYLARK_CONSTRUCTOR)
+                  .getPrerequisite("$dummy_lib", Mode.TARGET, ObjcProvider.class)
                   .get(LIBRARY));
 
       CustomCommandLine commandLine =
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IosApplication.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IosApplication.java
index cd418a3..4af8cee 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/IosApplication.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IosApplication.java
@@ -60,7 +60,7 @@
   @Override
   protected void validateAttributes(RuleContext ruleContext) {
     Iterable<ObjcProvider> extensionProviders = ruleContext.getPrerequisites(
-        "extensions", Mode.TARGET, ObjcProvider.SKYLARK_CONSTRUCTOR);
+        "extensions", Mode.TARGET, ObjcProvider.class);
     if (hasMoreThanOneWatchExtension(extensionProviders, Flag.HAS_WATCH1_EXTENSION)
         || hasMoreThanOneWatchExtension(extensionProviders, Flag.HAS_WATCH2_EXTENSION)) {
       ruleContext.attributeError("extensions", "An iOS application can contain exactly one "
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java
index 908020b..d1ddc21 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java
@@ -268,7 +268,7 @@
             .addDepObjcProviders(protosObjcProvider.asSet())
             .addNonPropagatedDepObjcProviders(
                 ruleContext.getPrerequisites(
-                    "non_propagated_deps", Mode.TARGET, ObjcProvider.SKYLARK_CONSTRUCTOR))
+                    "non_propagated_deps", Mode.TARGET, ObjcProvider.class))
             .setIntermediateArtifacts(ObjcRuleClasses.intermediateArtifacts(ruleContext))
             .setHasModuleMap();
 
@@ -283,8 +283,7 @@
     ObjcConfiguration config = ruleContext.getFragment(ObjcConfiguration.class);
     if (config.runMemleaks()) {
       builder.addDepObjcProviders(
-          ruleContext.getPrerequisites(
-              MEMLEAKS_DEP_ATTR, Mode.TARGET, ObjcProvider.SKYLARK_CONSTRUCTOR));
+          ruleContext.getPrerequisites(MEMLEAKS_DEP_ATTR, Mode.TARGET, ObjcProvider.class));
     }
 
     return builder.build();
@@ -296,7 +295,6 @@
 
   /** Returns the {@link XcTestAppProvider} of the {@code xctest_app} attribute. */
   protected static XcTestAppProvider xcTestAppProvider(RuleContext ruleContext) {
-    return ruleContext.getPrerequisite(
-        XCTEST_APP_ATTR, Mode.TARGET, XcTestAppProvider.SKYLARK_CONSTRUCTOR);
+    return ruleContext.getPrerequisite(XCTEST_APP_ATTR, Mode.TARGET, XcTestAppProvider.class);
   }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IosTestRule.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IosTestRule.java
index 78aaba6..55bfea6 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/IosTestRule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IosTestRule.java
@@ -21,9 +21,11 @@
 import static com.google.devtools.build.lib.syntax.Type.BOOLEAN;
 import static com.google.devtools.build.lib.syntax.Type.STRING_LIST;
 
+import com.google.common.collect.ImmutableList;
 import com.google.devtools.build.lib.analysis.BaseRuleClasses;
 import com.google.devtools.build.lib.analysis.RuleDefinition;
 import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
+import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
 import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
 import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.packages.Attribute.ComputedDefault;
@@ -90,7 +92,9 @@
                       }
                     })
                 .allowedFileTypes()
-                .mandatoryProviders(XcTestAppProvider.SKYLARK_CONSTRUCTOR.id()))
+                .mandatoryNativeProviders(
+                    ImmutableList.<Class<? extends TransitiveInfoProvider>>of(
+                        XcTestAppProvider.class)))
         .override(
             attr(BundlingRule.INFOPLIST_ATTR, LABEL)
                 .value(
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 61e99ec..219eaa5 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
@@ -304,7 +304,7 @@
     return builder
         .addProvider(
             exportedJ2ObjcMappingFileProvider(base, ruleContext, directJ2ObjcMappingFileProvider))
-        .addNativeDeclaredProvider(common.getObjcProvider())
+        .addProvider(common.getObjcProvider())
         .build();
   }
 
@@ -806,7 +806,7 @@
         builder.addDepObjcProviders(ruleContext.getPrerequisites(
             dependentAttribute.getName(),
             dependentAttribute.getAccessMode(),
-            ObjcProvider.SKYLARK_CONSTRUCTOR));
+            ObjcProvider.class));
       }
     }
 
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibrary.java
index 810ce01..e1537d0 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibrary.java
@@ -72,13 +72,12 @@
         .build();
 
     Iterable<ObjcProvider> jreDeps =
-        ruleContext.getPrerequisites("jre_deps", Mode.TARGET, ObjcProvider.SKYLARK_CONSTRUCTOR);
+        ruleContext.getPrerequisites("jre_deps", Mode.TARGET, ObjcProvider.class);
     ObjcProvider.Builder objcProviderBuilder =
         new ObjcProvider.Builder()
             .addTransitiveAndPropagate(jreDeps)
             .addTransitiveAndPropagate(
-                ruleContext.getPrerequisites(
-                    "deps", Mode.TARGET, ObjcProvider.SKYLARK_CONSTRUCTOR));
+                ruleContext.getPrerequisites("deps", Mode.TARGET, ObjcProvider.class));
     for (ObjcProvider prereq : jreDeps) {
       objcProviderBuilder.addTransitiveAndPropagate(JRE_LIBRARY, prereq.get(LIBRARY));
     }
@@ -110,6 +109,7 @@
         .add(RunfilesProvider.class, RunfilesProvider.EMPTY)
         .addProvider(J2ObjcEntryClassProvider.class, j2ObjcEntryClassProvider)
         .addProvider(J2ObjcMappingFileProvider.class, j2ObjcMappingFileProvider)
+        .addProvider(ObjcProvider.class, objcProvider)
         .addNativeDeclaredProvider(objcProvider)
         .build();
   }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/MultiArchBinarySupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/MultiArchBinarySupport.java
index dd78199..9305e8e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/MultiArchBinarySupport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/MultiArchBinarySupport.java
@@ -258,8 +258,7 @@
       Iterable<ObjcProvider> additionalDepProviders =
           Iterables.concat(
               dylibObjcProviders,
-              ruleContext.getPrerequisites("bundles", Mode.TARGET,
-                  ObjcProvider.SKYLARK_CONSTRUCTOR),
+              ruleContext.getPrerequisites("bundles", Mode.TARGET, ObjcProvider.class),
               protosObjcProvider.asSet());
 
       ObjcCommon common =
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundle.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundle.java
index 9888805..dd7eda8 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundle.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundle.java
@@ -45,6 +45,7 @@
 
     NestedSet<Artifact> filesToBuild = NestedSetBuilder.emptySet(STABLE_ORDER);
     return ObjcRuleClasses.ruleConfiguredTarget(ruleContext, filesToBuild)
+        .addProvider(ObjcProvider.class, common.getObjcProvider())
         .addNativeDeclaredProvider(common.getObjcProvider())
         .build();
   }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java
index c341593..aa6d9b3 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java
@@ -75,6 +75,7 @@
         .build();
 
     return ObjcRuleClasses.ruleConfiguredTarget(ruleContext, filesToBuild.build())
+        .addProvider(ObjcProvider.class, nestedBundleProvider)
         .addNativeDeclaredProvider(nestedBundleProvider)
         .build();
   }
@@ -112,7 +113,7 @@
     return new ObjcCommon.Builder(ruleContext)
         .setResourceAttributes(new ResourceAttributes(ruleContext))
         .addDepObjcProviders(
-            ruleContext.getPrerequisites("bundles", Mode.TARGET, ObjcProvider.SKYLARK_CONSTRUCTOR))
+            ruleContext.getPrerequisites("bundles", Mode.TARGET, ObjcProvider.class))
         .setIntermediateArtifacts(ObjcRuleClasses.intermediateArtifacts(ruleContext))
         .build();
   }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java
index 55ac6df..443144b 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java
@@ -67,8 +67,6 @@
 import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
 import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
 import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
 import com.google.devtools.build.lib.rules.apple.AppleToolchain;
 import com.google.devtools.build.lib.rules.cpp.CcLinkParams;
 import com.google.devtools.build.lib.rules.cpp.CcLinkParamsProvider;
@@ -259,7 +257,7 @@
           ImmutableList.<CcLinkParamsProvider>builder();
 
       for (TransitiveInfoCollection dep : deps) {
-        addAnyProviders(propagatedObjcDeps, dep, ObjcProvider.SKYLARK_CONSTRUCTOR);
+        addAnyProviders(propagatedObjcDeps, dep, ObjcProvider.class);
         addAnyProviders(cppDeps, dep, CppCompilationContext.class);
         if (isCcLibrary(dep)) {
           cppDepLinkParams.add(dep.get(CcLinkParamsProvider.CC_LINK_PARAMS));
@@ -281,7 +279,7 @@
           ImmutableList.<ObjcProvider>builder();
 
       for (TransitiveInfoCollection dep : runtimeDeps) {
-        addAnyProviders(propagatedDeps, dep, ObjcProvider.SKYLARK_CONSTRUCTOR);
+        addAnyProviders(propagatedDeps, dep, ObjcProvider.class);
       }
       this.runtimeDepObjcProviders = Iterables.concat(
           this.runtimeDepObjcProviders, propagatedDeps.build());
@@ -292,25 +290,12 @@
         ImmutableList.Builder<T> listBuilder,
         TransitiveInfoCollection collection,
         Class<T> providerClass) {
-      T provider = collection.getProvider(providerClass);
-      if (provider != null) {
-        listBuilder.add(provider);
+      if (collection.getProvider(providerClass) != null) {
+        listBuilder.add(collection.getProvider(providerClass));
       }
       return listBuilder;
     }
 
-    private <T extends SkylarkClassObject> ImmutableList.Builder<T> addAnyProviders(
-        ImmutableList.Builder<T> listBuilder,
-        TransitiveInfoCollection collection,
-        NativeClassObjectConstructor<T> providerClass) {
-      T provider = collection.get(providerClass);
-      if (provider != null) {
-        listBuilder.add(provider);
-      }
-      return listBuilder;
-    }
-
-
     /**
      * Add providers which will be exposed both to the declaring rule and to any dependers on the
      * declaring rule.
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcFramework.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcFramework.java
index 701856b..e11a01e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcFramework.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcFramework.java
@@ -68,6 +68,7 @@
             NestedSetBuilder.<Artifact>linkOrder().addAll(frameworkImports).build());
     NestedSet<Artifact> filesToBuild = NestedSetBuilder.emptySet(STABLE_ORDER);
     return ObjcRuleClasses.ruleConfiguredTarget(ruleContext, filesToBuild)
+        .addProvider(ObjcProvider.class, objcProvider)
         .addNativeDeclaredProvider(objcProvider)
         .addNativeDeclaredProvider(frameworkProvider)
         .build();
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcImport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcImport.java
index a1253f0..37c8cb6 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcImport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcImport.java
@@ -42,8 +42,7 @@
             .addExtraImportLibraries(
                 ruleContext.getPrerequisiteArtifacts("archives", Mode.TARGET).list())
             .addDepObjcProviders(
-                ruleContext.getPrerequisites(
-                    "bundles", Mode.TARGET, ObjcProvider.SKYLARK_CONSTRUCTOR))
+                ruleContext.getPrerequisites("bundles", Mode.TARGET, ObjcProvider.class))
             .build();
 
     NestedSetBuilder<Artifact> filesToBuild = NestedSetBuilder.stableOrder();
@@ -65,6 +64,7 @@
     new ResourceSupport(ruleContext).validateAttributes();
 
     return ObjcRuleClasses.ruleConfiguredTarget(ruleContext, filesToBuild.build())
+        .addProvider(ObjcProvider.class, common.getObjcProvider())
         .addNativeDeclaredProvider(common.getObjcProvider())
         .build();
   }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java
index c45c378..814e3717 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java
@@ -46,10 +46,9 @@
         .addDeps(ruleContext.getPrerequisites("deps", Mode.TARGET))
         .addRuntimeDeps(ruleContext.getPrerequisites("runtime_deps", Mode.TARGET))
         .addDepObjcProviders(
-            ruleContext.getPrerequisites("bundles", Mode.TARGET, ObjcProvider.SKYLARK_CONSTRUCTOR))
+            ruleContext.getPrerequisites("bundles", Mode.TARGET, ObjcProvider.class))
         .addNonPropagatedDepObjcProviders(
-            ruleContext.getPrerequisites(
-                "non_propagated_deps", Mode.TARGET, ObjcProvider.SKYLARK_CONSTRUCTOR))
+            ruleContext.getPrerequisites("non_propagated_deps", Mode.TARGET, ObjcProvider.class))
         .setIntermediateArtifacts(ObjcRuleClasses.intermediateArtifacts(ruleContext))
         .setAlwayslink(ruleContext.attributes().get("alwayslink", Type.BOOLEAN))
         .setHasModuleMap()
@@ -90,6 +89,7 @@
           J2ObjcEntryClassProvider.class)).build();
 
     return ObjcRuleClasses.ruleConfiguredTarget(ruleContext, filesToBuild.build())
+        .addProvider(ObjcProvider.class, common.getObjcProvider())
         .addNativeDeclaredProvider(common.getObjcProvider())
         .addProvider(J2ObjcEntryClassProvider.class, j2ObjcEntryClassProvider)
         .addProvider(J2ObjcMappingFileProvider.class, j2ObjcMappingFileProvider)
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoAspect.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoAspect.java
index b386e9b..4b9143e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoAspect.java
@@ -98,7 +98,7 @@
       // (i.e. objc_binary) don't have to depend on it.
       ObjcProvider protobufObjcProvider =
           ruleContext.getPrerequisite(
-              ObjcRuleClasses.PROTO_LIB_ATTR, Mode.TARGET, ObjcProvider.SKYLARK_CONSTRUCTOR);
+              ObjcRuleClasses.PROTO_LIB_ATTR, Mode.TARGET, ObjcProvider.class);
       aspectObjcProtoProvider.addProtobufHeaders(protobufObjcProvider.get(ObjcProvider.HEADER));
       aspectObjcProtoProvider.addProtobufHeaderSearchPaths(
           protobufObjcProvider.get(ObjcProvider.INCLUDE));
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibrary.java
index ae0d22b..64bdc18 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibrary.java
@@ -14,6 +14,7 @@
 
 package com.google.devtools.build.lib.rules.objc;
 
+
 import com.google.common.collect.Iterables;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.analysis.ConfiguredTarget;
@@ -66,6 +67,7 @@
             .addFilesToBuild(filesToBuild);
 
     return ObjcRuleClasses.ruleConfiguredTarget(ruleContext, filesToBuild.build())
+        .addProvider(ObjcProvider.class, protoSupport.getObjcProvider().get())
         .addNativeDeclaredProvider(protoSupport.getObjcProvider().get())
         .build();
   }
@@ -108,7 +110,7 @@
             .addFilesToBuild(filesToBuild);
 
     return ObjcRuleClasses.ruleConfiguredTarget(ruleContext, filesToBuild.build())
-        .addNativeDeclaredProvider(protoSupport.getObjcProvider())
+        .addProvider(ObjcProvider.class, protoSupport.getObjcProvider())
         .build();
   }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java
index 4a2081c..dfe934a 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java
@@ -25,12 +25,12 @@
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
 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.packages.NativeClassObjectConstructor;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor.WithLegacySkylarkName;
 import com.google.devtools.build.lib.packages.SkylarkClassObject;
 import com.google.devtools.build.lib.rules.cpp.CcLinkParamsProvider;
 import com.google.devtools.build.lib.rules.cpp.CppModuleMap;
@@ -55,11 +55,17 @@
   category = SkylarkModuleCategory.PROVIDER,
   doc = "A provider for compilation and linking of objc."
 )
-public final class ObjcProvider extends SkylarkClassObject {
+public final class ObjcProvider extends SkylarkClassObject
+    implements TransitiveInfoProvider, TransitiveInfoProvider.WithLegacySkylarkName {
 
   /** Skylark name for the ObjcProvider. */
   public static final String SKYLARK_NAME = "objc";
 
+  @Override
+  public String getSkylarkName() {
+    return SKYLARK_NAME;
+  }
+
   /**
    * Represents one of the things this provider can provide transitively. Things are provided as
    * {@link NestedSet}s of type E.
@@ -500,7 +506,12 @@
 
   /** Skylark constructor and identifier for ObjcProvider. */
   public static final NativeClassObjectConstructor<ObjcProvider> SKYLARK_CONSTRUCTOR =
-      new Constructor();
+      new NativeClassObjectConstructor<ObjcProvider>(ObjcProvider.class, SKYLARK_NAME) {
+        @Override
+        public String getErrorMessageFormatForInstances() {
+          return "ObjcProvider field %s could not be instantiated";
+        }
+      };
 
   private ObjcProvider(
       ImmutableMap<Key<?>, NestedSet<?>> items,
@@ -987,22 +998,4 @@
       return new ObjcProvider(propagated, nonPropagated, strictDependency, skylarkFields.build());
     }
   }
-
-  private static class Constructor
-      extends NativeClassObjectConstructor<ObjcProvider>
-      implements WithLegacySkylarkName {
-    public Constructor() {
-      super(ObjcProvider.class, ObjcProvider.SKYLARK_NAME);
-    }
-
-    @Override
-    public String getSkylarkName() {
-      return SKYLARK_NAME;
-    }
-
-    @Override
-    public String getErrorMessageFormatForInstances() {
-      return "ObjcProvider field %s could not be instantiated";
-    }
-  }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java
index a1138a2..411a795 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java
@@ -36,6 +36,7 @@
 import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
 import com.google.devtools.build.lib.analysis.Runfiles;
 import com.google.devtools.build.lib.analysis.RunfilesProvider;
+import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
 import com.google.devtools.build.lib.analysis.actions.SpawnAction;
 import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
 import com.google.devtools.build.lib.cmdline.Label;
@@ -672,8 +673,9 @@
               attr("deps", LABEL_LIST)
                   .direct_compile_time_input()
                   .allowedRuleClasses(ALLOWED_CC_DEPS_RULE_CLASSES)
-                  .mandatoryProviders(ObjcProvider.SKYLARK_CONSTRUCTOR.id())
-          .allowedFileTypes())
+                  .mandatoryNativeProviders(
+                      ImmutableList.<Class<? extends TransitiveInfoProvider>>of(ObjcProvider.class))
+                  .allowedFileTypes())
           /* <!-- #BLAZE_RULE($objc_compiling_rule).ATTRIBUTE(runtime_deps) -->
           The list of framework targets that are late loaded at runtime.  They are included in the
           app bundle but not linked against at build time.
@@ -695,7 +697,8 @@
               attr("non_propagated_deps", LABEL_LIST)
                   .direct_compile_time_input()
                   .allowedRuleClasses(ALLOWED_CC_DEPS_RULE_CLASSES)
-                  .mandatoryProviders(ObjcProvider.SKYLARK_CONSTRUCTOR.id())
+                  .mandatoryNativeProviders(
+                      ImmutableList.<Class<? extends TransitiveInfoProvider>>of(ObjcProvider.class))
                   .allowedFileTypes())
           /* <!-- #BLAZE_RULE($objc_compiling_rule).ATTRIBUTE(defines) -->
           Extra <code>-D</code> flags to pass to the compiler. They should be in
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ProtobufSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ProtobufSupport.java
index 9038e68..053cd56 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ProtobufSupport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ProtobufSupport.java
@@ -392,7 +392,7 @@
     } else {
       commonBuilder.addDepObjcProviders(
           ruleContext.getPrerequisites(
-              ObjcRuleClasses.PROTO_LIB_ATTR, Mode.TARGET, ObjcProvider.SKYLARK_CONSTRUCTOR));
+              ObjcRuleClasses.PROTO_LIB_ATTR, Mode.TARGET, ObjcProvider.class));
     }
     return commonBuilder.build();
   }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ProtocolBuffers2Support.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ProtocolBuffers2Support.java
index 343aa82..8139368 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ProtocolBuffers2Support.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ProtocolBuffers2Support.java
@@ -127,7 +127,7 @@
         .addIncludes(getIncludes())
         .addDepObjcProviders(
             ruleContext.getPrerequisites(
-                ObjcRuleClasses.PROTO_LIB_ATTR, Mode.TARGET, ObjcProvider.SKYLARK_CONSTRUCTOR))
+                ObjcRuleClasses.PROTO_LIB_ATTR, Mode.TARGET, ObjcProvider.class))
         .build();
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java
index a6d32b3..6aa8f48 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java
@@ -1174,8 +1174,7 @@
       }
 
       for (ObjcProvider provider
-          : ruleContext.getPrerequisites(
-              "binary", Mode.DONT_CHECK, ObjcProvider.SKYLARK_CONSTRUCTOR)) {
+          : ruleContext.getPrerequisites("binary", Mode.DONT_CHECK, ObjcProvider.class)) {
         if (!provider.get(ObjcProvider.MULTI_ARCH_LINKED_BINARIES).isEmpty()) {
           return Iterables.getOnlyElement(provider.get(ObjcProvider.MULTI_ARCH_LINKED_BINARIES));
         }
@@ -1190,8 +1189,7 @@
 
       NestedSetBuilder<Artifact> linkedBinaries = NestedSetBuilder.stableOrder();
       for (ObjcProvider provider
-          : ruleContext.getPrerequisites(
-              "binary", Mode.DONT_CHECK, ObjcProvider.SKYLARK_CONSTRUCTOR)) {
+          : ruleContext.getPrerequisites("binary", Mode.DONT_CHECK, ObjcProvider.class)) {
         linkedBinaries.addTransitive(provider.get(ObjcProvider.LINKED_BINARY));
       }
 
@@ -1269,7 +1267,7 @@
       if (ruleContext.attributes().has("binary", BuildType.LABEL)) {
         for (TransitiveInfoCollection prerequisite
             : ruleContext.getPrerequisites("binary", Mode.DONT_CHECK)) {
-          ObjcProvider prerequisiteProvider =  prerequisite.get(ObjcProvider.SKYLARK_CONSTRUCTOR);
+          ObjcProvider prerequisiteProvider =  prerequisite.getProvider(ObjcProvider.class);
           if (prerequisiteProvider != null) {
             Artifact sourceArtifact = Iterables.getOnlyElement(prerequisiteProvider.get(key), null);
             if (sourceArtifact != null) {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingTargetFactory.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingTargetFactory.java
index dc5962b..53820e6 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingTargetFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingTargetFactory.java
@@ -80,7 +80,7 @@
 
     RuleConfiguredTargetBuilder targetBuilder =
         ObjcRuleClasses.ruleConfiguredTarget(ruleContext, filesToBuild.build())
-            .addNativeDeclaredProvider(releaseBundlingSupport.xcTestAppProvider())
+            .addProvider(XcTestAppProvider.class, releaseBundlingSupport.xcTestAppProvider())
             .addProvider(
                 InstrumentedFilesProvider.class,
                 InstrumentedFilesCollector.forward(ruleContext, "binary"));
@@ -88,6 +88,7 @@
     ObjcProvider exposedObjcProvider = exposedObjcProvider(ruleContext, releaseBundlingSupport);
     if (exposedObjcProvider != null) {
       targetBuilder
+          .addProvider(ObjcProvider.class, exposedObjcProvider)
           .addNativeDeclaredProvider(exposedObjcProvider);
     }
 
@@ -142,7 +143,7 @@
     for (Attribute attribute : dependencyAttributes) {
       builder.addDepObjcProviders(
           ruleContext.getPrerequisites(
-              attribute.getName(), attribute.getAccessMode(), ObjcProvider.SKYLARK_CONSTRUCTOR));
+              attribute.getName(), attribute.getAccessMode(), ObjcProvider.class));
     }
     return builder.build();
   }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/XcTestAppProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/XcTestAppProvider.java
index a0a306f..051bcd5 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/XcTestAppProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/XcTestAppProvider.java
@@ -16,9 +16,9 @@
 
 import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
 import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor.WithLegacySkylarkName;
 import com.google.devtools.build.lib.packages.SkylarkClassObject;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
@@ -33,21 +33,33 @@
       "Deprecated. A provider for XCTest apps for testing. This is a legacy provider and should "
           + "not be used."
 )
-public final class XcTestAppProvider extends SkylarkClassObject {
+public final class XcTestAppProvider extends SkylarkClassObject
+    implements TransitiveInfoProvider, TransitiveInfoProvider.WithLegacySkylarkName {
   /**
    * The skylark struct key name for a rule implementation to use when exporting an ObjcProvider.
    */
   public static final String XCTEST_APP_SKYLARK_PROVIDER_NAME = "xctest_app";
 
-  public static final NativeClassObjectConstructor<XcTestAppProvider> SKYLARK_CONSTRUCTOR =
-      new Constructor();
+  @Override
+  public String getSkylarkName() {
+    return XCTEST_APP_SKYLARK_PROVIDER_NAME;
+  }
+
+  private static final NativeClassObjectConstructor<XcTestAppProvider> XCTEST_APP_PROVIDER =
+      new NativeClassObjectConstructor<XcTestAppProvider>(
+          XcTestAppProvider.class, "xctest_app_provider") {
+        @Override
+        public String getErrorMessageFormatForInstances() {
+          return "XcTestAppProvider field %s could not be instantiated";
+        }
+      };
 
   private final Artifact bundleLoader;
   private final Artifact ipa;
   private final ObjcProvider objcProvider;
 
   XcTestAppProvider(Artifact bundleLoader, Artifact ipa, ObjcProvider objcProvider) {
-    super(SKYLARK_CONSTRUCTOR, getSkylarkFields(bundleLoader, ipa, objcProvider));
+    super(XCTEST_APP_PROVIDER, getSkylarkFields(bundleLoader, ipa, objcProvider));
     this.bundleLoader = Preconditions.checkNotNull(bundleLoader);
     this.ipa = Preconditions.checkNotNull(ipa);
     this.objcProvider = Preconditions.checkNotNull(objcProvider);
@@ -84,23 +96,4 @@
         .put("objc", objcProvider)
         .build();
   }
-
-  private static class Constructor
-      extends NativeClassObjectConstructor<XcTestAppProvider>
-      implements WithLegacySkylarkName {
-
-    private Constructor() {
-      super(XcTestAppProvider.class, "xctest_app_provider");
-    }
-
-    @Override
-    public String getSkylarkName() {
-      return XCTEST_APP_SKYLARK_PROVIDER_NAME;
-    }
-
-    @Override
-    public String getErrorMessageFormatForInstances() {
-      return "XcTestAppProvider field %s could not be instantiated";
-    }
-  }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/BazelJ2ObjcLibraryTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/BazelJ2ObjcLibraryTest.java
index a7b9e1e..4c562df 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/objc/BazelJ2ObjcLibraryTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/objc/BazelJ2ObjcLibraryTest.java
@@ -51,7 +51,7 @@
   public void testJ2ObjCInformationExportedFromJ2ObjcLibrary() throws Exception {
     ConfiguredTarget j2objcLibraryTarget = getConfiguredTarget(
         "//java/com/google/dummy/test:transpile");
-    ObjcProvider provider = j2objcLibraryTarget.get(ObjcProvider.SKYLARK_CONSTRUCTOR);
+    ObjcProvider provider = j2objcLibraryTarget.getProvider(ObjcProvider.class);
     assertThat(Artifact.toRootRelativePaths(provider.get(ObjcProvider.LIBRARY))).containsExactly(
         "third_party/java/j2objc/libjre_core_lib.a",
         "java/com/google/dummy/test/libtest_j2objc.a");
@@ -85,7 +85,7 @@
         "    deps = ['test'])");
 
     ConfiguredTarget target = getConfiguredTarget("//java/com/google/test:transpile");
-    ObjcProvider provider = target.get(ObjcProvider.SKYLARK_CONSTRUCTOR);
+    ObjcProvider provider = target.getProvider(ObjcProvider.class);
     String genfilesFragment = target.getConfiguration().getGenfilesFragment().toString();
     assertThat(Artifact.toRootRelativePaths(provider.get(ObjcProvider.LIBRARY))).containsExactly(
         "third_party/java/j2objc/libjre_core_lib.a",
@@ -124,7 +124,7 @@
 
     ConfiguredTarget j2objcLibraryTarget = getConfiguredTarget(
         "//java/com/google/dummy/test/proto:transpile");
-    ObjcProvider provider = j2objcLibraryTarget.get(ObjcProvider.SKYLARK_CONSTRUCTOR);
+    ObjcProvider provider = j2objcLibraryTarget.getProvider(ObjcProvider.class);
     assertThat(Artifact.toRootRelativePaths(provider.get(ObjcProvider.LIBRARY))).containsExactly(
         "third_party/java/j2objc/libjre_core_lib.a",
         "third_party/java/j2objc/libproto_runtime.a",
@@ -220,7 +220,7 @@
     Artifact classMappingFile = getGenfilesArtifact("test.clsmap.properties", test);
     assertThat(provider.getClassMappingFiles()).containsExactly(classMappingFile);
 
-    ObjcProvider objcProvider = target.get(ObjcProvider.SKYLARK_CONSTRUCTOR);
+    ObjcProvider objcProvider = target.getProvider(ObjcProvider.class);
     Artifact headerFile = getGenfilesArtifact("test.j2objc.pb.h", test);
     Artifact sourceFile = getGenfilesArtifact("test.j2objc.pb.m", test);
     assertThat(objcProvider.get(ObjcProvider.HEADER)).contains(headerFile);
@@ -285,7 +285,7 @@
   public void testExplicitJreDeps() throws Exception {
     ConfiguredTarget j2objcLibraryTarget = getConfiguredTarget(
         "//java/com/google/dummy/test:transpile");
-    ObjcProvider provider = j2objcLibraryTarget.get(ObjcProvider.SKYLARK_CONSTRUCTOR);
+    ObjcProvider provider = j2objcLibraryTarget.getProvider(ObjcProvider.class);
     // jre_io_lib and jre_emul_lib should be excluded.
     assertThat(Artifact.toRootRelativePaths(provider.get(ObjcProvider.LIBRARY))).containsExactly(
         "third_party/java/j2objc/libjre_core_lib.a",
@@ -306,7 +306,7 @@
         ")");
 
     ConfiguredTarget target = getJ2ObjCAspectConfiguredTarget("//java/com/google/transpile:dummy");
-    ObjcProvider provider = target.get(ObjcProvider.SKYLARK_CONSTRUCTOR);
+    ObjcProvider provider = target.getProvider(ObjcProvider.class);
     Artifact srcJarSources = getFirstArtifactEndingWith(
         provider.get(ObjcProvider.SOURCE), "source_files");
     Artifact srcJarHeaders = getFirstArtifactEndingWith(
@@ -325,7 +325,7 @@
     addSimpleJ2ObjcLibraryWithJavaPlugin();
     ConfiguredTarget j2objcLibraryTarget =
         getConfiguredTarget("//java/com/google/app/test:transpile");
-    ObjcProvider provider = j2objcLibraryTarget.get(ObjcProvider.SKYLARK_CONSTRUCTOR);
+    ObjcProvider provider = j2objcLibraryTarget.getProvider(ObjcProvider.class);
     Artifact headers =
         getFirstArtifactEndingWith(provider.get(ObjcProvider.HEADER), "header_files");
     Artifact sources =
@@ -500,7 +500,7 @@
   protected Artifact j2objcArchive(String j2objcLibraryTarget, String javaTargetName)
       throws Exception {
     ConfiguredTarget target = getConfiguredTarget(j2objcLibraryTarget);
-    ObjcProvider provider = target.get(ObjcProvider.SKYLARK_CONSTRUCTOR);
+    ObjcProvider provider = target.getProvider(ObjcProvider.class);
     String archiveName = String.format("lib%s_j2objc.a", javaTargetName);
     return getFirstArtifactEndingWith(provider.get(ObjcProvider.LIBRARY), archiveName);
   }
@@ -518,7 +518,7 @@
 
     ConfiguredTarget objcTarget = getConfiguredTarget("//app:lib");
 
-    ObjcProvider provider = objcTarget.get(ObjcProvider.SKYLARK_CONSTRUCTOR);
+    ObjcProvider provider = objcTarget.getProvider(ObjcProvider.class);
     assertThat(Artifact.toRootRelativePaths(provider.get(ObjcProvider.LIBRARY)))
         .containsExactly(
             "third_party/java/j2objc/libjre_core_lib.a",
@@ -559,7 +559,7 @@
 
     ConfiguredTarget objcTarget = getConfiguredTarget("//app:lib");
 
-    ObjcProvider provider = objcTarget.get(ObjcProvider.SKYLARK_CONSTRUCTOR);
+    ObjcProvider provider = objcTarget.getProvider(ObjcProvider.class);
     assertThat(Artifact.toRootRelativePaths(provider.get(ObjcProvider.LIBRARY)))
         .containsExactly(
             "third_party/java/j2objc/libjre_core_lib.a",
@@ -659,7 +659,7 @@
 
     ConfiguredTarget target = getJ2ObjCAspectConfiguredTarget("//java/com/google/transpile:dummy");
 
-    ObjcProvider provider = target.get(ObjcProvider.SKYLARK_CONSTRUCTOR);
+    ObjcProvider provider = target.getProvider(ObjcProvider.class);
     Artifact moduleMap =
         getFirstArtifactEndingWith(
             provider.get(ObjcProvider.MODULE_MAP), "dummy.modulemaps/module.modulemap");
@@ -696,7 +696,7 @@
     addSimpleJ2ObjcLibraryWithJavaPlugin();
     ConfiguredTarget j2objcLibraryTarget =
         getConfiguredTarget("//java/com/google/app/test:transpile");
-    ObjcProvider provider = j2objcLibraryTarget.get(ObjcProvider.SKYLARK_CONSTRUCTOR);
+    ObjcProvider provider = j2objcLibraryTarget.getProvider(ObjcProvider.class);
     Artifact moduleMap =
         getFirstArtifactEndingWith(
             provider.get(ObjcProvider.MODULE_MAP), "test.modulemaps/module.modulemap");
diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/IosApplicationTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/IosApplicationTest.java
index 01e54dd..2f718f3 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/objc/IosApplicationTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/objc/IosApplicationTest.java
@@ -116,8 +116,7 @@
         ")");
     RuleContext ruleContext = getRuleContext(getConfiguredTarget("//x:x"));
     ImmutableListMultimap<BuildConfiguration, ObjcProvider> prereqByConfig =
-        ruleContext.getPrerequisitesByConfiguration(
-            "binary", Mode.SPLIT, ObjcProvider.SKYLARK_CONSTRUCTOR);
+        ruleContext.getPrerequisitesByConfiguration("binary", Mode.SPLIT, ObjcProvider.class);
     List<String> childCpus = Lists.transform(prereqByConfig.keySet().asList(),
         new Function<BuildConfiguration, String>() {
           @Override
diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/IosTestTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/IosTestTest.java
index f33a9e6..8427e72 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/objc/IosTestTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/objc/IosTestTest.java
@@ -1092,7 +1092,7 @@
 
     ObjcProvider appProvider =
         getConfiguredTarget("//test:protos_app")
-            .get(XcTestAppProvider.SKYLARK_CONSTRUCTOR)
+            .getProvider(XcTestAppProvider.class)
             .getObjcProvider();
     ConfiguredTarget binTarget = getConfiguredTarget("//test:protos_bin");
     Artifact protoHeader =
diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/LegacyObjcLibraryTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/LegacyObjcLibraryTest.java
index abbae40..40fa356 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/objc/LegacyObjcLibraryTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/objc/LegacyObjcLibraryTest.java
@@ -108,7 +108,7 @@
             .addAll(FASTBUILD_COPTS)
             .addAll(
                 iquoteArgs(
-                    getConfiguredTarget("//objc:lib").get(ObjcProvider.SKYLARK_CONSTRUCTOR),
+                    getConfiguredTarget("//objc:lib").getProvider(ObjcProvider.class),
                     getTargetConfiguration()))
             .build();
 
@@ -170,7 +170,7 @@
             .addAll(FASTBUILD_COPTS)
             .addAll(
                 iquoteArgs(
-                    getConfiguredTarget("//objc:lib").get(ObjcProvider.SKYLARK_CONSTRUCTOR),
+                    getConfiguredTarget("//objc:lib").getProvider(ObjcProvider.class),
                     getTargetConfiguration()))
             .build();
 
@@ -249,7 +249,7 @@
                 .addAll(FASTBUILD_COPTS)
                 .addAll(
                     iquoteArgs(
-                        getConfiguredTarget("//objc:lib").get(ObjcProvider.SKYLARK_CONSTRUCTOR),
+                        getConfiguredTarget("//objc:lib").getProvider(ObjcProvider.class),
                         getAppleCrosstoolConfiguration()))
                 .add("-include", "objc/some.pch")
                 .add("-fobjc-arc")
@@ -295,7 +295,7 @@
                 .addAll(FASTBUILD_COPTS)
                 .addAll(
                     iquoteArgs(
-                        getConfiguredTarget("//objc:lib").get(ObjcProvider.SKYLARK_CONSTRUCTOR),
+                        getConfiguredTarget("//objc:lib").getProvider(ObjcProvider.class),
                         getTargetConfiguration()))
                 .add("-fobjc-arc")
                 .add("-Ifoo")
diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/LegacyObjcProtoLibraryTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/LegacyObjcProtoLibraryTest.java
index a7258a4..dc45294 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/objc/LegacyObjcProtoLibraryTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/objc/LegacyObjcProtoLibraryTest.java
@@ -79,7 +79,7 @@
                 .addAll(FASTBUILD_COPTS)
                 .addAll(
                     LegacyObjcLibraryTest.iquoteArgs(
-                        target.get(ObjcProvider.SKYLARK_CONSTRUCTOR), getTargetConfiguration()))
+                        target.getProvider(ObjcProvider.class), getTargetConfiguration()))
                 .add("-I")
                 .add(sourceFile.getExecPath().getParentDirectory().getParentDirectory().toString())
                 .add("-fno-objc-arc")
diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcLibraryTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcLibraryTest.java
index 9e2d0c0..5b71555 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcLibraryTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcLibraryTest.java
@@ -51,7 +51,6 @@
 import com.google.devtools.build.lib.rules.cpp.CppCompileAction;
 import com.google.devtools.build.lib.rules.cpp.CppModuleMapAction;
 import com.google.devtools.build.lib.rules.objc.ObjcCommandLineOptions.ObjcCrosstoolMode;
-import com.google.devtools.build.lib.rules.objc.ObjcProvider.Key;
 import com.google.devtools.build.lib.vfs.PathFragment;
 import com.google.devtools.common.options.OptionsParsingException;
 import java.util.Collections;
@@ -332,9 +331,9 @@
             .setAndCreateFiles("hdrs", "d.h", "e.m")
             .setList("deps", "//objc:lib")
             .write();
-    assertThat(getArifactPaths(target, HEADER))
+    assertThat(Artifact.toRootRelativePaths(target.getProvider(ObjcProvider.class).get(HEADER)))
         .containsExactly("objc/a.h", "objc/b.h", "objc/f.m");
-    assertThat(getArifactPaths(depender, HEADER))
+    assertThat(Artifact.toRootRelativePaths(depender.getProvider(ObjcProvider.class).get(HEADER)))
         .containsExactly("objc/a.h", "objc/b.h", "objc/f.m", "objc2/d.h", "objc2/e.m");
   }
 
@@ -357,9 +356,11 @@
             .setList("non_propagated_deps", "//objc2:lib")
             .write();
 
-    assertThat(getArifactPaths(target, HEADER))
+    assertThat(Artifact.toRootRelativePaths(target.getProvider(ObjcProvider.class).get(HEADER)))
         .containsExactly("objc/a.h", "objc/b.h");
-    assertThat(getArifactPaths(transitiveDepender, HEADER))
+    assertThat(
+            Artifact.toRootRelativePaths(
+                transitiveDepender.getProvider(ObjcProvider.class).get(HEADER)))
         .containsExactly("objc2/c.h", "objc2/d.h", "objc3/e.h", "objc3/f.h");
   }
 
@@ -1025,20 +1026,16 @@
             .setAndCreateFiles("hdrs", "c.h", "d.h")
             .setList("deps", "//objc:lib")
             .write();
-    assertThat(getArifactPaths(target, LIBRARY)).containsExactly("objc/liblib.a");
-    assertThat(getArifactPaths(depender, LIBRARY)).containsExactly(
-        "objc/liblib.a", "objc2/liblib.a");
-    assertThat(getArifactPaths(target, HEADER))
+    assertThat(Artifact.toRootRelativePaths(target.getProvider(ObjcProvider.class).get(LIBRARY)))
+        .containsExactly("objc/liblib.a");
+    assertThat(Artifact.toRootRelativePaths(depender.getProvider(ObjcProvider.class).get(LIBRARY)))
+        .containsExactly("objc/liblib.a", "objc2/liblib.a");
+    assertThat(Artifact.toRootRelativePaths(target.getProvider(ObjcProvider.class).get(HEADER)))
         .containsExactly("objc/a.h", "objc/b.h");
-    assertThat(getArifactPaths(depender, HEADER))
+    assertThat(Artifact.toRootRelativePaths(depender.getProvider(ObjcProvider.class).get(HEADER)))
         .containsExactly("objc/a.h", "objc/b.h", "objc2/c.h", "objc2/d.h");
   }
 
-  private Iterable<String> getArifactPaths(ConfiguredTarget target, Key<Artifact> artifactKey) {
-    return Artifact.toRootRelativePaths(
-        target.get(ObjcProvider.SKYLARK_CONSTRUCTOR).get(artifactKey));
-  }
-
   @Test
   public void testWeakSdkFrameworks_objcProvider() throws Exception {
     createLibraryTargetWriter("//base_lib:lib")
diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcRuleTestCase.java b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcRuleTestCase.java
index 8116e34..9ae12ff 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcRuleTestCase.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcRuleTestCase.java
@@ -1072,7 +1072,7 @@
   }
 
   protected ObjcProvider providerForTarget(String label) throws Exception {
-    return getConfiguredTarget(label).get(ObjcProvider.SKYLARK_CONSTRUCTOR);
+    return getConfiguredTarget(label).getProvider(ObjcProvider.class);
   }
 
   protected CommandAction archiveAction(String label) throws Exception {
@@ -1171,7 +1171,7 @@
         "includes", "['incdir']");
     ObjcProvider provider =
         getConfiguredTarget("//x:x", getAppleCrosstoolConfiguration())
-            .get(ObjcProvider.SKYLARK_CONSTRUCTOR);
+            .getProvider(ObjcProvider.class);
     assertThat(provider.get(HEADER)).containsExactly(getSourceArtifact("x/a.h"));
     assertThat(provider.get(INCLUDE))
         .containsExactly(
diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcSkylarkTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcSkylarkTest.java
index 11d3633..2cfdbad 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcSkylarkTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcSkylarkTest.java
@@ -209,7 +209,7 @@
         ")");
 
     ConfiguredTarget binaryTarget = getConfiguredTarget("//examples/apple_skylark:bin");
-    ObjcProvider objcProvider = binaryTarget.get(ObjcProvider.SKYLARK_CONSTRUCTOR);
+    ObjcProvider objcProvider = binaryTarget.getProvider(ObjcProvider.class);
 
     assertThat(Artifact.toRootRelativePaths(objcProvider.get(ObjcProvider.LIBRARY)))
         .contains("examples/apple_skylark/liblib.a");
@@ -246,7 +246,7 @@
         ")");
 
     ConfiguredTarget binaryTarget = getConfiguredTarget("//examples/apple_skylark:bin");
-    ObjcProvider objcProvider = binaryTarget.get(ObjcProvider.SKYLARK_CONSTRUCTOR);
+    ObjcProvider objcProvider = binaryTarget.getProvider(ObjcProvider.class);
 
     assertThat(objcProvider.get(ObjcProvider.DEFINE)).contains("mock_define");
   }
@@ -689,11 +689,11 @@
             "   return struct(objc=created_provider)");
 
     Iterable<String> foundLinkopts =
-        skylarkTarget.get(ObjcProvider.SKYLARK_CONSTRUCTOR).get(ObjcProvider.LINKOPT);
+        skylarkTarget.getProvider(ObjcProvider.class).get(ObjcProvider.LINKOPT);
     Iterable<String> foundDefines =
-        skylarkTarget.get(ObjcProvider.SKYLARK_CONSTRUCTOR).get(ObjcProvider.DEFINE);
+        skylarkTarget.getProvider(ObjcProvider.class).get(ObjcProvider.DEFINE);
     boolean usesSwift =
-        skylarkTarget.get(ObjcProvider.SKYLARK_CONSTRUCTOR).is(ObjcProvider.Flag.USES_SWIFT);
+        skylarkTarget.getProvider(ObjcProvider.class).is(ObjcProvider.Flag.USES_SWIFT);
 
     assertThat(foundLinkopts).containsExactly("somelinkopt");
     assertThat(foundDefines).containsExactly("define1", "define2");
@@ -712,7 +712,7 @@
             "   return struct(objc=created_provider)");
 
     Iterable<Artifact> foundLinkInputs =
-        skylarkTarget.get(ObjcProvider.SKYLARK_CONSTRUCTOR).get(ObjcProvider.LINK_INPUTS);
+        skylarkTarget.getProvider(ObjcProvider.class).get(ObjcProvider.LINK_INPUTS);
     assertThat(ActionsTestUtil.baseArtifactNames(foundLinkInputs)).contains("foo.ast");
   }
 
@@ -724,7 +724,7 @@
             "   return struct(objc=created_provider)");
 
     boolean usesSwift =
-        skylarkTarget.get(ObjcProvider.SKYLARK_CONSTRUCTOR).is(ObjcProvider.Flag.USES_SWIFT);
+        skylarkTarget.getProvider(ObjcProvider.class).is(ObjcProvider.Flag.USES_SWIFT);
 
     assertThat(usesSwift).isTrue();
   }
@@ -739,7 +739,7 @@
             "   return struct(objc=created_provider)");
 
     Iterable<PathFragment> foundIncludes =
-        skylarkTarget.get(ObjcProvider.SKYLARK_CONSTRUCTOR).get(ObjcProvider.INCLUDE);
+        skylarkTarget.getProvider(ObjcProvider.class).get(ObjcProvider.INCLUDE);
 
     assertThat(foundIncludes)
         .containsExactly(
@@ -760,7 +760,7 @@
             "(include=propagated_includes, direct_dep_providers=[strict_provider])",
             "   return struct(objc=created_provider)");
 
-    ObjcProvider skylarkProvider = skylarkTarget.get(ObjcProvider.SKYLARK_CONSTRUCTOR);
+    ObjcProvider skylarkProvider = skylarkTarget.getProvider(ObjcProvider.class);
     ObjcProvider skylarkProviderDirectDepender =
         new ObjcProvider.Builder().addTransitiveAndPropagate(skylarkProvider).build();
     ObjcProvider skylarkProviderIndirectDepender = 
@@ -785,7 +785,7 @@
             "   return struct(objc=created_provider)");
 
     Iterable<String> foundStrings =
-        skylarkTarget.get(ObjcProvider.SKYLARK_CONSTRUCTOR).get(ObjcProvider.DEFINE);
+        skylarkTarget.getProvider(ObjcProvider.class).get(ObjcProvider.DEFINE);
 
     assertThat(foundStrings).containsExactly("define_from_dep", "define_from_impl");
   }
@@ -1130,7 +1130,7 @@
 
     ConfiguredTarget skylarkTarget = getConfiguredTarget("//examples/apple_skylark:my_target");
 
-    XcTestAppProvider xcTestAppProvider = skylarkTarget.get(XcTestAppProvider.SKYLARK_CONSTRUCTOR);
+    XcTestAppProvider xcTestAppProvider = skylarkTarget.getProvider(XcTestAppProvider.class);
 
     assertThat(xcTestAppProvider.getBundleLoader().getRootRelativePathString())
         .isEqualTo("examples/rule/test_artifact");
@@ -1243,7 +1243,7 @@
         ")");
 
     ConfiguredTarget skylarkTarget = getConfiguredTarget("//examples/apple_skylark:my_target");
-    assertThat(skylarkTarget.get(ObjcProvider.SKYLARK_CONSTRUCTOR)).isNotNull();
+    assertThat(skylarkTarget.getProvider(ObjcProvider.class)).isNotNull();
   }
 
   private void checkSkylarkRunMemleaksWithExpectedValue(boolean expectedValue) throws Exception {