Better names for declared providers-related classes.

Follows
https://docs.google.com/document/d/1aAIVWvHPERDz2cv_PCFGwr8dvh5FcAkENFoRsNS4clk/.

RELNOTES: None.
PiperOrigin-RevId: 163728291
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/AbstractConfiguredTarget.java b/src/main/java/com/google/devtools/build/lib/analysis/AbstractConfiguredTarget.java
index a998570..235dc37 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/AbstractConfiguredTarget.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/AbstractConfiguredTarget.java
@@ -22,9 +22,9 @@
 import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
 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.Info;
 import com.google.devtools.build.lib.packages.PackageSpecification;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Provider;
 import com.google.devtools.build.lib.packages.Target;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
 import com.google.devtools.build.lib.syntax.ClassObject;
@@ -113,12 +113,12 @@
 
   @Override
   public final Object getIndex(Object key, Location loc) throws EvalException {
-    if (!(key instanceof ClassObjectConstructor)) {
+    if (!(key instanceof Provider)) {
       throw new EvalException(loc, String.format(
           "Type Target only supports indexing by object constructors, got %s instead",
           EvalUtils.getDataTypeName(key)));
     }
-    ClassObjectConstructor constructor = (ClassObjectConstructor) key;
+    Provider constructor = (Provider) key;
     Object declaredProvider = get(constructor.getKey());
     if (declaredProvider != null) {
       return declaredProvider;
@@ -133,12 +133,12 @@
 
   @Override
   public boolean containsKey(Object key, Location loc) throws EvalException {
-    if (!(key instanceof ClassObjectConstructor)) {
+    if (!(key instanceof Provider)) {
       throw new EvalException(loc, String.format(
           "Type Target only supports querying by object constructors, got %s instead",
           EvalUtils.getDataTypeName(key)));
     }
-    return get(((ClassObjectConstructor) key).getKey()) != null;
+    return get(((Provider) key).getKey()) != null;
   }
 
   @Override
@@ -180,7 +180,7 @@
   /** Returns a declared provider provided by this target. Only meant to use from Skylark. */
   @Nullable
   @Override
-  public final SkylarkClassObject get(ClassObjectConstructor.Key providerKey) {
+  public final Info get(Provider.Key providerKey) {
     if (providerKey.equals(DefaultProvider.SKYLARK_CONSTRUCTOR.getKey())) {
       return getDefaultProvider();
     }
@@ -189,8 +189,7 @@
 
   /** Implement in subclasses to get a skylark provider for a given {@code providerKey}. */
   @Nullable
-  protected abstract SkylarkClassObject rawGetSkylarkProvider(
-      ClassObjectConstructor.Key providerKey);
+  protected abstract Info rawGetSkylarkProvider(Provider.Key providerKey);
 
   /**
    * Returns a value provided by this target. Only meant to use from Skylark.
@@ -212,7 +211,6 @@
       default:
         return rawGetSkylarkProvider(providerKey);
     }
-
   }
 
   /** Implement in subclasses to get a skylark provider for a given {@code providerKey}. */
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ActionsProvider.java b/src/main/java/com/google/devtools/build/lib/analysis/ActionsProvider.java
index 8eb0f27..90441ee 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/ActionsProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/ActionsProvider.java
@@ -16,8 +16,8 @@
 import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.actions.ActionAnalysisMetadata;
 import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -28,13 +28,11 @@
 public final class ActionsProvider {
 
   /** The Actions provider type itself. */
-  public static final NativeClassObjectConstructor<SkylarkClassObject> SKYLARK_CONSTRUCTOR =
-      new NativeClassObjectConstructor<SkylarkClassObject>(SkylarkClassObject.class, "Actions") {};
+  public static final NativeProvider<Info> SKYLARK_CONSTRUCTOR =
+      new NativeProvider<Info>(Info.class, "Actions") {};
 
-  /**
-   * Factory method for creating instances of the Actions provider.
-   */
-  public static SkylarkClassObject create(Iterable<ActionAnalysisMetadata> actions) {
+  /** Factory method for creating instances of the Actions provider. */
+  public static Info create(Iterable<ActionAnalysisMetadata> actions) {
     Map<Artifact, ActionAnalysisMetadata> map = new HashMap<>();
     for (ActionAnalysisMetadata action : actions) {
       for (Artifact artifact : action.getOutputs()) {
@@ -46,6 +44,6 @@
       }
     }
     ImmutableMap<String, Object> fields = ImmutableMap.<String, Object>of("by_file", map);
-    return new SkylarkClassObject(SKYLARK_CONSTRUCTOR, fields);
+    return new Info(SKYLARK_CONSTRUCTOR, fields);
   }
 }
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..c9462d2 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
@@ -24,8 +24,8 @@
 import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
 import com.google.devtools.build.lib.collect.nestedset.Order;
 import com.google.devtools.build.lib.packages.BuildType;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 import com.google.devtools.build.lib.packages.TriState;
 import com.google.devtools.build.lib.vfs.PathFragment;
 
@@ -81,9 +81,9 @@
    * Returns the list of declared providers (native and Skylark) of the specified Skylark key from a
    * set of transitive info collections.
    */
-  public static <T extends SkylarkClassObject> Iterable<T> getProviders(
+  public static <T extends Info> Iterable<T> getProviders(
       Iterable<? extends TransitiveInfoCollection> prerequisites,
-      final NativeClassObjectConstructor<T> skylarkKey) {
+      final NativeProvider<T> skylarkKey) {
     ImmutableList.Builder<T> result = ImmutableList.builder();
     for (TransitiveInfoCollection prerequisite : prerequisites) {
       T prerequisiteProvider = prerequisite.get(skylarkKey);
@@ -102,11 +102,9 @@
     return Iterables.filter(prerequisites, target -> 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) {
+  /** Returns the iterable of collections that have the specified provider. */
+  public static <S extends TransitiveInfoCollection, C extends Info> Iterable<S> filterByProvider(
+      Iterable<S> prerequisites, final NativeProvider<C> provider) {
     return Iterables.filter(prerequisites, target -> target.get(provider) != null);
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredAspect.java b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredAspect.java
index 4e0c62b..23df295 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredAspect.java
@@ -28,8 +28,8 @@
 import com.google.devtools.build.lib.packages.AspectClass;
 import com.google.devtools.build.lib.packages.AspectDescriptor;
 import com.google.devtools.build.lib.packages.AspectParameters;
-import com.google.devtools.build.lib.packages.ClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.Provider;
 import com.google.devtools.build.lib.packages.SkylarkProviderIdentifier;
 import com.google.devtools.build.lib.syntax.EvalException;
 import com.google.devtools.build.lib.util.Preconditions;
@@ -97,7 +97,7 @@
     }
   }
 
-  public SkylarkClassObject get(ClassObjectConstructor.Key key) {
+  public Info get(Provider.Key key) {
     return providers.getProvider(key);
   }
 
@@ -205,9 +205,9 @@
       return this;
     }
 
-    public Builder addSkylarkDeclaredProvider(SkylarkClassObject declaredProvider, Location loc)
+    public Builder addSkylarkDeclaredProvider(Info declaredProvider, Location loc)
         throws EvalException {
-      ClassObjectConstructor constructor = declaredProvider.getConstructor();
+      Provider constructor = declaredProvider.getProvider();
       if (!constructor.isExported()) {
         throw new EvalException(
             constructor.getLocation(), "All providers must be top level values");
@@ -216,12 +216,12 @@
       return this;
     }
 
-    private void addDeclaredProvider(SkylarkClassObject declaredProvider) {
+    private void addDeclaredProvider(Info declaredProvider) {
       providers.put(declaredProvider);
     }
 
-    public Builder addNativeDeclaredProvider(SkylarkClassObject declaredProvider) {
-      ClassObjectConstructor constructor = declaredProvider.getConstructor();
+    public Builder addNativeDeclaredProvider(Info declaredProvider) {
+      Provider constructor = declaredProvider.getProvider();
       Preconditions.checkState(constructor.isExported());
       addDeclaredProvider(declaredProvider);
       return this;
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/DefaultProvider.java b/src/main/java/com/google/devtools/build/lib/analysis/DefaultProvider.java
index ab0722c..26ba931 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/DefaultProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/DefaultProvider.java
@@ -19,16 +19,16 @@
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
 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.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
+import com.google.devtools.build.lib.packages.Provider;
 import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicReference;
 
 /** DefaultProvider is provided by all targets implicitly and contains all standard fields. */
 @Immutable
-public final class DefaultProvider extends SkylarkClassObject {
+public final class DefaultProvider extends Info {
 
   // Accessors for Skylark
   private static final String DATA_RUNFILES_FIELD = "data_runfiles";
@@ -47,18 +47,18 @@
   private final AtomicReference<SkylarkNestedSet> files = new AtomicReference<>();
 
   public static final String SKYLARK_NAME = "DefaultInfo";
-  public static final ClassObjectConstructor SKYLARK_CONSTRUCTOR =
-      new NativeClassObjectConstructor<SkylarkClassObject>(SkylarkClassObject.class, SKYLARK_NAME) {
+  public static final Provider SKYLARK_CONSTRUCTOR =
+      new NativeProvider<Info>(Info.class, SKYLARK_NAME) {
         @Override
-        protected SkylarkClassObject createInstanceFromSkylark(Object[] args, Location loc) {
+        protected Info createInstanceFromSkylark(Object[] args, Location loc) {
           @SuppressWarnings("unchecked")
           Map<String, Object> kwargs = (Map<String, Object>) args[0];
-          return new SkylarkClassObject(this, kwargs, loc);
+          return new Info(this, kwargs, loc);
         }
       };
 
   private DefaultProvider(
-      ClassObjectConstructor constructor,
+      Provider constructor,
       RunfilesProvider runfilesProvider,
       FileProvider fileProvider,
       FilesToRunProvider filesToRunProvider) {
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/EnvironmentGroupConfiguredTarget.java b/src/main/java/com/google/devtools/build/lib/analysis/EnvironmentGroupConfiguredTarget.java
index 83a9266..358a40d 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/EnvironmentGroupConfiguredTarget.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/EnvironmentGroupConfiguredTarget.java
@@ -14,9 +14,9 @@
 
 package com.google.devtools.build.lib.analysis;
 
-import com.google.devtools.build.lib.packages.ClassObjectConstructor;
 import com.google.devtools.build.lib.packages.EnvironmentGroup;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.Provider;
 import com.google.devtools.build.lib.util.Preconditions;
 
 /**
@@ -35,7 +35,7 @@
   }
 
   @Override
-  protected SkylarkClassObject rawGetSkylarkProvider(ClassObjectConstructor.Key providerKey) {
+  protected Info rawGetSkylarkProvider(Provider.Key providerKey) {
     return null;
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/FileConfiguredTarget.java b/src/main/java/com/google/devtools/build/lib/analysis/FileConfiguredTarget.java
index 0659bb8..2c1ed08 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/FileConfiguredTarget.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/FileConfiguredTarget.java
@@ -18,9 +18,9 @@
 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.packages.ClassObjectConstructor;
 import com.google.devtools.build.lib.packages.FileTarget;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.Provider;
 import com.google.devtools.build.lib.rules.fileset.FilesetProvider;
 import com.google.devtools.build.lib.rules.test.InstrumentedFilesProvider;
 import com.google.devtools.build.lib.util.FileType;
@@ -81,7 +81,7 @@
   }
 
   @Override
-  protected SkylarkClassObject rawGetSkylarkProvider(ClassObjectConstructor.Key providerKey) {
+  protected Info rawGetSkylarkProvider(Provider.Key providerKey) {
     return providers.getProvider(providerKey);
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/MergedConfiguredTarget.java b/src/main/java/com/google/devtools/build/lib/analysis/MergedConfiguredTarget.java
index ec5a58f..de8dbd8 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/MergedConfiguredTarget.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/MergedConfiguredTarget.java
@@ -15,9 +15,9 @@
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
-import com.google.devtools.build.lib.packages.ClassObjectConstructor;
-import com.google.devtools.build.lib.packages.ClassObjectConstructor.Key;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.Provider;
+import com.google.devtools.build.lib.packages.Provider.Key;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
 import java.util.ArrayList;
 import java.util.List;
@@ -76,8 +76,8 @@
   }
 
   @Override
-  protected SkylarkClassObject rawGetSkylarkProvider(ClassObjectConstructor.Key providerKey) {
-    SkylarkClassObject provider = providers.getProvider(providerKey);
+  protected Info rawGetSkylarkProvider(Provider.Key providerKey) {
+    Info provider = providers.getProvider(providerKey);
     if (provider == null) {
       provider = base.get(providerKey);
     }
@@ -142,12 +142,12 @@
             throw new DuplicateException("Provider " + legacyId + " provided twice");
           }
           aspectProviders.put(legacyId, providers.getProviderInstanceAt(i));
-        } else if (providerKey instanceof ClassObjectConstructor.Key) {
-          ClassObjectConstructor.Key key = (Key) providerKey;
+        } else if (providerKey instanceof Provider.Key) {
+          Provider.Key key = (Key) providerKey;
           if (base.get(key) != null || aspectProviders.contains(key)) {
             throw new DuplicateException("Provider " + key + " provided twice");
           }
-          aspectProviders.put((SkylarkClassObject) providers.getProviderInstanceAt(i));
+          aspectProviders.put((Info) providers.getProviderInstanceAt(i));
         }
       }
     }
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/OutputGroupProvider.java b/src/main/java/com/google/devtools/build/lib/analysis/OutputGroupProvider.java
index 9557410..c53ef44 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/OutputGroupProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/OutputGroupProvider.java
@@ -28,8 +28,8 @@
 import com.google.devtools.build.lib.collect.nestedset.Order;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
 import com.google.devtools.build.lib.events.Location;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 import com.google.devtools.build.lib.rules.SkylarkRuleConfiguredTargetUtil;
 import com.google.devtools.build.lib.syntax.EvalException;
 import com.google.devtools.build.lib.syntax.EvalUtils;
@@ -48,8 +48,8 @@
  * built when the target is mentioned on the command line (as opposed to being always built, like
  * {@link com.google.devtools.build.lib.analysis.FileProvider})
  *
- * <p>The artifacts are grouped into "output groups". Which output groups are built is controlled
- * by the {@code --output_groups} undocumented command line option, which in turn is added to the
+ * <p>The artifacts are grouped into "output groups". Which output groups are built is controlled by
+ * the {@code --output_groups} undocumented command line option, which in turn is added to the
  * command line at the discretion of the build command being run.
  *
  * <p>Output groups starting with an underscore are "not important". This means that artifacts built
@@ -57,12 +57,10 @@
  * not mentioned on the output.
  */
 @Immutable
-public final class OutputGroupProvider extends SkylarkClassObject
-    implements SkylarkIndexable, Iterable<String> {
+public final class OutputGroupProvider extends Info implements SkylarkIndexable, Iterable<String> {
   public static final String SKYLARK_NAME = "output_groups";
 
-  public static NativeClassObjectConstructor<OutputGroupProvider> SKYLARK_CONSTRUCTOR =
-      new Constructor();
+  public static NativeProvider<OutputGroupProvider> SKYLARK_CONSTRUCTOR = new Constructor();
 
   /**
    * Prefix for output groups that are not reported to the user on the terminal output of Blaze when
@@ -258,7 +256,7 @@
   }
 
   /** A constructor callable from Skylark for OutputGroupProvider. */
-  private static class Constructor extends NativeClassObjectConstructor<OutputGroupProvider> {
+  private static class Constructor extends NativeProvider<OutputGroupProvider> {
 
     private Constructor() {
       super(OutputGroupProvider.class, "OutputGroupInfo");
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/PackageGroupConfiguredTarget.java b/src/main/java/com/google/devtools/build/lib/analysis/PackageGroupConfiguredTarget.java
index e0516dc..4085f63 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/PackageGroupConfiguredTarget.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/PackageGroupConfiguredTarget.java
@@ -20,10 +20,10 @@
 import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
 import com.google.devtools.build.lib.collect.nestedset.Order;
 import com.google.devtools.build.lib.events.Event;
-import com.google.devtools.build.lib.packages.ClassObjectConstructor;
+import com.google.devtools.build.lib.packages.Info;
 import com.google.devtools.build.lib.packages.PackageGroup;
 import com.google.devtools.build.lib.packages.PackageSpecification;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Provider;
 import com.google.devtools.build.lib.util.Preconditions;
 
 /**
@@ -81,7 +81,7 @@
   }
 
   @Override
-  protected SkylarkClassObject rawGetSkylarkProvider(ClassObjectConstructor.Key providerKey) {
+  protected Info rawGetSkylarkProvider(Provider.Key providerKey) {
     return null;
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTarget.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTarget.java
index 8f6b61c..028c8c5 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTarget.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTarget.java
@@ -17,10 +17,10 @@
 import com.google.devtools.build.lib.analysis.config.ConfigMatchingProvider;
 import com.google.devtools.build.lib.analysis.config.RunUnder;
 import com.google.devtools.build.lib.cmdline.Label;
-import com.google.devtools.build.lib.packages.ClassObjectConstructor;
+import com.google.devtools.build.lib.packages.Info;
 import com.google.devtools.build.lib.packages.OutputFile;
+import com.google.devtools.build.lib.packages.Provider;
 import com.google.devtools.build.lib.packages.Rule;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
 import com.google.devtools.build.lib.rules.SkylarkApiProvider;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
 import com.google.devtools.build.lib.syntax.Printer;
@@ -129,7 +129,7 @@
   }
 
   @Override
-  protected SkylarkClassObject rawGetSkylarkProvider(ClassObjectConstructor.Key providerKey) {
+  protected Info rawGetSkylarkProvider(Provider.Key providerKey) {
     return providers.getProvider(providerKey);
   }
 
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 8216468..fc7bcf6 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
@@ -29,9 +29,9 @@
 import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
 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.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
+import com.google.devtools.build.lib.packages.Provider;
 import com.google.devtools.build.lib.packages.Target;
 import com.google.devtools.build.lib.packages.TargetUtils;
 import com.google.devtools.build.lib.rules.test.ExecutionInfoProvider;
@@ -250,13 +250,10 @@
     return this;
   }
 
-  private <T extends TransitiveInfoProvider> void maybeAddSkylarkLegacyProvider(
-      SkylarkClassObject value) {
-    if (value.getConstructor() instanceof NativeClassObjectConstructor.WithLegacySkylarkName) {
+  private <T extends TransitiveInfoProvider> void maybeAddSkylarkLegacyProvider(Info value) {
+    if (value.getProvider() instanceof NativeProvider.WithLegacySkylarkName) {
       addSkylarkTransitiveInfo(
-          ((NativeClassObjectConstructor.WithLegacySkylarkName) value.getConstructor())
-              .getSkylarkName(),
-          value);
+          ((NativeProvider.WithLegacySkylarkName) value.getProvider()).getSkylarkName(), value);
     }
   }
 
@@ -273,18 +270,17 @@
   }
 
   /**
-   * Adds a "declared provider" defined in Skylark to the rule.
-   * Use this method for declared providers defined in Skyark.
+   * Adds a "declared provider" defined in Skylark to the rule. Use this method for declared
+   * providers defined in Skyark.
    *
-   * Has special handling for {@link OutputGroupProvider}: that provider is not added
-   * from Skylark directly, instead its outpuyt groups are added.
+   * <p>Has special handling for {@link OutputGroupProvider}: that provider is not added from
+   * Skylark directly, instead its outpuyt groups are added.
    *
-   * Use {@link #addNativeDeclaredProvider(SkylarkClassObject)} in definitions of
-   * native rules.
+   * <p>Use {@link #addNativeDeclaredProvider(Info)} in definitions of native rules.
    */
-  public RuleConfiguredTargetBuilder addSkylarkDeclaredProvider(
-      SkylarkClassObject provider, Location loc) throws EvalException {
-    ClassObjectConstructor constructor = provider.getConstructor();
+  public RuleConfiguredTargetBuilder addSkylarkDeclaredProvider(Info provider, Location loc)
+      throws EvalException {
+    Provider constructor = provider.getProvider();
     if (!constructor.isExported()) {
       throw new EvalException(constructor.getLocation(),
           "All providers must be top level values");
@@ -304,26 +300,23 @@
    * Adds "declared providers" defined in native code to the rule. Use this method for declared
    * providers in definitions of native rules.
    *
-   * <p>Use {@link #addSkylarkDeclaredProvider(SkylarkClassObject, Location)} for Skylark rule
-   * implementations.
+   * <p>Use {@link #addSkylarkDeclaredProvider(Info, Location)} for Skylark rule implementations.
    */
-  public RuleConfiguredTargetBuilder addNativeDeclaredProviders(
-      Iterable<SkylarkClassObject> providers) {
-    for (SkylarkClassObject provider : providers) {
+  public RuleConfiguredTargetBuilder addNativeDeclaredProviders(Iterable<Info> providers) {
+    for (Info provider : providers) {
       addNativeDeclaredProvider(provider);
     }
     return this;
   }
 
   /**
-   * Adds a "declared provider" defined in native code to the rule.
-   * Use this method for declared providers in definitions of native rules.
+   * Adds a "declared provider" defined in native code to the rule. Use this method for declared
+   * providers in definitions of native rules.
    *
-   * Use {@link #addSkylarkDeclaredProvider(SkylarkClassObject, Location)}
-   * for Skylark rule implementations.
+   * <p>Use {@link #addSkylarkDeclaredProvider(Info, Location)} for Skylark rule implementations.
    */
-  public RuleConfiguredTargetBuilder addNativeDeclaredProvider(SkylarkClassObject provider) {
-    ClassObjectConstructor constructor = provider.getConstructor();
+  public RuleConfiguredTargetBuilder addNativeDeclaredProvider(Info provider) {
+    Provider constructor = provider.getProvider();
     Preconditions.checkState(constructor.isExported());
     providersBuilder.put(provider);
     maybeAddSkylarkLegacyProvider(provider);
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 cd7b72b..de978e0 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
@@ -64,8 +64,9 @@
 import com.google.devtools.build.lib.packages.FileTarget;
 import com.google.devtools.build.lib.packages.FilesetEntry;
 import com.google.devtools.build.lib.packages.ImplicitOutputsFunction;
+import com.google.devtools.build.lib.packages.Info;
 import com.google.devtools.build.lib.packages.InputFile;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
+import com.google.devtools.build.lib.packages.NativeProvider;
 import com.google.devtools.build.lib.packages.OutputFile;
 import com.google.devtools.build.lib.packages.PackageSpecification;
 import com.google.devtools.build.lib.packages.RawAttributeMapper;
@@ -74,7 +75,6 @@
 import com.google.devtools.build.lib.packages.RuleClass;
 import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
 import com.google.devtools.build.lib.packages.RuleErrorConsumer;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
 import com.google.devtools.build.lib.packages.Target;
 import com.google.devtools.build.lib.packages.TargetUtils;
 import com.google.devtools.build.lib.rules.AliasProvider;
@@ -717,9 +717,7 @@
       checkAttribute(attributeName, Mode.SPLIT);
       Map<Optional<String>, ? extends List<? extends TransitiveInfoCollection>> map =
           getSplitPrerequisites(attributeName);
-      return map.isEmpty()
-          ? ImmutableList.of()
-          : map.entrySet().iterator().next().getValue();
+      return map.isEmpty() ? ImmutableList.of() : map.entrySet().iterator().next().getValue();
     }
 
     checkAttribute(attributeName, mode);
@@ -820,13 +818,13 @@
   }
 
   /**
-   * For a given attribute, returns all declared provider provided by targets
-   * of that attribute. Each declared provider is keyed by the
-   * {@link BuildConfiguration} under which the provider was created.
+   * For a given attribute, returns all declared provider provided by targets of that attribute.
+   * Each declared provider is keyed by the {@link BuildConfiguration} under which the provider was
+   * created.
    */
-  public <C extends SkylarkClassObject> ImmutableListMultimap<BuildConfiguration, C>
-  getPrerequisitesByConfiguration(String attributeName, Mode mode,
-      final NativeClassObjectConstructor<C> provider) {
+  public <C extends Info>
+      ImmutableListMultimap<BuildConfiguration, C> getPrerequisitesByConfiguration(
+          String attributeName, Mode mode, final NativeProvider<C> provider) {
     List<? extends TransitiveInfoCollection> transitiveInfoCollections =
         getPrerequisites(attributeName, mode);
 
@@ -873,8 +871,8 @@
    * Returns all the declared providers (native and Skylark) for the specified constructor under the
    * specified attribute of this target in the BUILD file.
    */
-  public <T extends SkylarkClassObject> Iterable<T> getPrerequisites(
-      String attributeName, Mode mode, final NativeClassObjectConstructor<T> skylarkKey) {
+  public <T extends Info> Iterable<T> getPrerequisites(
+      String attributeName, Mode mode, final NativeProvider<T> skylarkKey) {
     return AnalysisUtils.getProviders(getPrerequisites(attributeName, mode), skylarkKey);
   }
 
@@ -884,8 +882,8 @@
    * TransitiveInfoCollection under the specified attribute.
    */
   @Nullable
-  public <T extends SkylarkClassObject> T getPrerequisite(
-      String attributeName, Mode mode, final NativeClassObjectConstructor<T> skylarkKey) {
+  public <T extends Info> T getPrerequisite(
+      String attributeName, Mode mode, final NativeProvider<T> skylarkKey) {
     TransitiveInfoCollection prerequisite = getPrerequisite(attributeName, mode);
     return prerequisite == null ? null : prerequisite.get(skylarkKey);
   }
@@ -904,9 +902,8 @@
    * 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) {
+  public <C extends Info> Iterable<? extends TransitiveInfoCollection> getPrerequisitesIf(
+      String attributeName, Mode mode, final NativeProvider<C> classType) {
     return AnalysisUtils.filterByProvider(getPrerequisites(attributeName, mode), classType);
   }
 
@@ -1978,8 +1975,8 @@
     }
 
     /**
-     * Because some rules still have to use allowedRuleClasses to do rule dependency validation.
-     * A dependency is valid if it is from a rule in allowedRuledClasses, OR if all of the providers
+     * Because some rules still have to use allowedRuleClasses to do rule dependency validation. A
+     * dependency is valid if it is from a rule in allowedRuledClasses, OR if all of the providers
      * in requiredProviders are provided by the target.
      */
     private void validateRuleDependency(ConfiguredTarget prerequisite, Attribute attribute) {
@@ -1993,8 +1990,7 @@
         return;
       }
 
-      if (checkRuleDependencyMandatoryProviders(prerequisite, attribute,
-          unfulfilledRequirements)) {
+      if (checkRuleDependencyMandatoryProviders(prerequisite, attribute, unfulfilledRequirements)) {
         return;
       }
 
@@ -2005,14 +2001,13 @@
       }
     }
 
-    /**
-     * Check if prerequisite should be allowed based on its rule class.
-     */
-    private boolean checkRuleDependencyClass(ConfiguredTarget prerequisite, Attribute attribute,
-        Set<String> unfulfilledRequirements) {
+    /** Check if prerequisite should be allowed based on its rule class. */
+    private boolean checkRuleDependencyClass(
+        ConfiguredTarget prerequisite, Attribute attribute, Set<String> unfulfilledRequirements) {
       if (attribute.getAllowedRuleClassesPredicate() != Predicates.<RuleClass>alwaysTrue()) {
-        if (attribute.getAllowedRuleClassesPredicate().apply(
-            ((Rule) prerequisite.getTarget()).getRuleClassObject())) {
+        if (attribute
+            .getAllowedRuleClassesPredicate()
+            .apply(((Rule) prerequisite.getTarget()).getRuleClassObject())) {
           // prerequisite has an allowed rule class => accept.
           return true;
         }
@@ -2031,16 +2026,21 @@
     /**
      * Check if prerequisite should be allowed with warning based on its rule class.
      *
-     * If yes, also issues said warning.
+     * <p>If yes, also issues said warning.
      */
-    private boolean checkRuleDependencyClassWarnings(ConfiguredTarget prerequisite,
-        Attribute attribute) {
-      if (attribute.getAllowedRuleClassesWarningPredicate().apply(
-          ((Rule) prerequisite.getTarget()).getRuleClassObject())) {
+    private boolean checkRuleDependencyClassWarnings(
+        ConfiguredTarget prerequisite, Attribute attribute) {
+      if (attribute
+          .getAllowedRuleClassesWarningPredicate()
+          .apply(((Rule) prerequisite.getTarget()).getRuleClassObject())) {
         Predicate<RuleClass> allowedRuleClasses = attribute.getAllowedRuleClassesPredicate();
-        reportBadPrerequisite(attribute, prerequisite.getTarget().getTargetKind(), prerequisite,
+        reportBadPrerequisite(
+            attribute,
+            prerequisite.getTarget().getTargetKind(),
+            prerequisite,
             allowedRuleClasses == Predicates.<RuleClass>alwaysTrue()
-                ? null : "expected " + allowedRuleClasses,
+                ? null
+                : "expected " + allowedRuleClasses,
             true);
         // prerequisite has a rule class allowed with a warning => accept, emitting a warning.
         return true;
@@ -2048,12 +2048,9 @@
       return false;
     }
 
-    /**
-     * Check if prerequisite should be allowed based on required providers on
-     * the attribute.
-     */
-    private boolean checkRuleDependencyMandatoryProviders(ConfiguredTarget prerequisite,
-        Attribute attribute, Set<String> unfulfilledRequirements) {
+    /** Check if prerequisite should be allowed based on required providers on the attribute. */
+    private boolean checkRuleDependencyMandatoryProviders(
+        ConfiguredTarget prerequisite, Attribute attribute, Set<String> unfulfilledRequirements) {
       RequiredProviders requiredProviders = attribute.getRequiredProviders();
 
       if (requiredProviders.acceptsAny()) {
@@ -2066,7 +2063,8 @@
       }
 
       unfulfilledRequirements.add(
-          String.format("'%s' does not have mandatory providers: %s",
+          String.format(
+              "'%s' does not have mandatory providers: %s",
               prerequisite.getLabel(),
               prerequisite.missingProviders(requiredProviders).getDescription()));
 
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/SkylarkProviderCollection.java b/src/main/java/com/google/devtools/build/lib/analysis/SkylarkProviderCollection.java
index cbe80a6..2187da0 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/SkylarkProviderCollection.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/SkylarkProviderCollection.java
@@ -14,9 +14,9 @@
 
 package com.google.devtools.build.lib.analysis;
 
-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.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
+import com.google.devtools.build.lib.packages.Provider;
 import com.google.devtools.build.lib.packages.SkylarkProviderIdentifier;
 import javax.annotation.Nullable;
 
@@ -36,18 +36,18 @@
   /**
    * Returns the declared provider requested, or null, if the information is not found.
    *
-   * Use {@link #get(NativeClassObjectConstructor)} for native providers.
+   * <p>Use {@link #get(NativeProvider)} for native providers.
    */
   @Nullable
-  SkylarkClassObject get(ClassObjectConstructor.Key providerKey);
+  Info get(Provider.Key providerKey);
 
   /**
    * Returns the native declared provider requested, or null, if the information is not found.
    *
-   * Type-safe version of {@link #get(ClassObjectConstructor.Key)} for native providers.
+   * <p>Type-safe version of {@link #get(Provider.Key)} for native providers.
    */
   @Nullable
-  default <T extends SkylarkClassObject> T get(NativeClassObjectConstructor<T> provider) {
+  default <T extends Info> T get(NativeProvider<T> provider) {
     return provider.getValueClass().cast(get(provider.getKey()));
   }
 
@@ -55,9 +55,8 @@
    * Returns the provider defined in Skylark, or null, if the information is not found. The
    * transitive information has to have been added using the Skylark framework.
    *
-   * <p>This method dispatches to either {@link #get(ClassObjectConstructor.Key)} or {@link
-   * #get(String)} depending on whether {@link SkylarkProviderIdentifier} is for legacy or for
-   * declared provider.
+   * <p>This method dispatches to either {@link #get(Provider.Key)} or {@link #get(String)}
+   * depending on whether {@link SkylarkProviderIdentifier} is for legacy or for declared provider.
    */
   @Nullable
   default Object get(SkylarkProviderIdentifier id) {
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoCollection.java b/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoCollection.java
index 23c2238..b3b4894 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoCollection.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoCollection.java
@@ -87,22 +87,18 @@
   default boolean satisfies(RequiredProviders providers) {
     return providers.isSatisfiedBy(
         aClass -> getProvider(aClass.asSubclass(TransitiveInfoProvider.class)) != null,
-        id -> this.get(id) != null
-    );
+        id -> this.get(id) != null);
   }
 
   /**
-   * Returns providers that this {@link TransitiveInfoCollection} misses from
-   * a given {@link RequiredProviders}.
+   * Returns providers that this {@link TransitiveInfoCollection} misses from a given {@link
+   * RequiredProviders}.
    *
-   * If none are missing, returns {@link RequiredProviders} that accept any set
-   * of providers.
+   * <p>If none are missing, returns {@link RequiredProviders} that accept any set of providers.
    */
   default RequiredProviders missingProviders(RequiredProviders providers) {
     return providers.getMissing(
         aClass -> getProvider(aClass.asSubclass(TransitiveInfoProvider.class)) != null,
-        id -> this.get(id) != null
-    );
+        id -> this.get(id) != null);
   }
-
 }
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoProviderMap.java b/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoProviderMap.java
index d8fa9ae..9d83702 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoProviderMap.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoProviderMap.java
@@ -14,26 +14,26 @@
 
 package com.google.devtools.build.lib.analysis;
 
-import com.google.devtools.build.lib.packages.ClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.Provider;
 import com.google.devtools.build.lib.packages.SkylarkProviderIdentifier;
 import javax.annotation.Nullable;
 import javax.annotation.concurrent.Immutable;
 
 /**
- * Provides a mapping between an identifier for transitive information and its instance.
- * (between provider identifier and provider instance)
+ * Provides a mapping between an identifier for transitive information and its instance. (between
+ * provider identifier and provider instance)
  *
- * We have three kinds of provider identifiers:
+ * <p>We have three kinds of provider identifiers:
+ *
  * <ul>
- *   <li>Declared providers. They are exposed to Skylark and identified by
- *   {@link ClassObjectConstructor.Key}. Provider instances are {@link SkylarkClassObject}s.</li>
- *   <li>Native providers. They are identified by their {@link Class} and their instances
- *   are instances of that class. They should implement {@link TransitiveInfoProvider} marker
- *   interface.
- *   </li>
- *   <li>Legacy Skylark providers (deprecated). They are identified by simple strings,
- *   and their instances are more-less random objects.</li>
+ *   <li>Declared providers. They are exposed to Skylark and identified by {@link Provider.Key}.
+ *       Provider instances are {@link Info}s.
+ *   <li>Native providers. They are identified by their {@link Class} and their instances are
+ *       instances of that class. They should implement {@link TransitiveInfoProvider} marker
+ *       interface.
+ *   <li>Legacy Skylark providers (deprecated). They are identified by simple strings, and their
+ *       instances are more-less random objects.
  * </ul>
  */
 @Immutable
@@ -43,11 +43,11 @@
   <P extends TransitiveInfoProvider> P getProvider(Class<P> providerClass);
 
   /**
-   * Returns the instance of declared provider with the given {@code key},
-   * or {@code null} if not present.
+   * Returns the instance of declared provider with the given {@code key}, or {@code null} if not
+   * present.
    */
   @Nullable
-  SkylarkClassObject getProvider(ClassObjectConstructor.Key key);
+  Info getProvider(Provider.Key key);
 
   /**
    * Returns the instance of a legacy Skylark  with the given name, or {@code null} if not present.
@@ -80,10 +80,11 @@
 
   /**
    * Return value is one of:
+   *
    * <ul>
-   *   <li>{@code Class<? extends TransitiveInfoProvider>}</li>
-   *   <li>String</li>
-   *   <li>{@link ClassObjectConstructor.Key}</li>
+   *   <li>{@code Class<? extends TransitiveInfoProvider>}
+   *   <li>String
+   *   <li>{@link Provider.Key}
    * </ul>
    *
    * Low-level method, use with care.
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoProviderMapBuilder.java b/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoProviderMapBuilder.java
index f46689c..4f1b753 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoProviderMapBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoProviderMapBuilder.java
@@ -14,8 +14,8 @@
 
 package com.google.devtools.build.lib.analysis;
 
-import com.google.devtools.build.lib.packages.ClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.Provider;
 import com.google.devtools.build.lib.util.Preconditions;
 import java.util.Arrays;
 import java.util.LinkedHashMap;
@@ -39,7 +39,7 @@
     return providers.containsKey(legacyId);
   }
 
-  public boolean contains(ClassObjectConstructor.Key key) {
+  public boolean contains(Provider.Key key) {
     return providers.containsKey(key);
   }
 
@@ -48,9 +48,8 @@
       Class<? extends T> providerClass, T provider) {
     Preconditions.checkNotNull(providerClass);
     Preconditions.checkNotNull(provider);
-    Preconditions.checkState(!(provider instanceof SkylarkClassObject),
-        "Expose %s as native declared provider",
-        providerClass);
+    Preconditions.checkState(
+        !(provider instanceof Info), "Expose %s as native declared provider", providerClass);
 
     // TODO(arielb): throw an exception if the providerClass is already present?
     // This is enforced by aspects but RuleConfiguredTarget presents violations
@@ -59,13 +58,13 @@
     return this;
   }
 
-  public TransitiveInfoProviderMapBuilder put(SkylarkClassObject classObject) {
+  public TransitiveInfoProviderMapBuilder put(Info classObject) {
     Preconditions.checkNotNull(classObject);
     Preconditions.checkState(!(classObject instanceof TransitiveInfoProvider),
         "Declared provider %s should not implement TransitiveInfoProvider",
         classObject.getClass());
 
-    providers.put(classObject.getConstructor().getKey(), classObject);
+    providers.put(classObject.getProvider().getKey(), classObject);
     return this;
   }
 
@@ -105,8 +104,8 @@
   }
 
   @Nullable
-  public SkylarkClassObject getProvider(ClassObjectConstructor.Key key) {
-    return (SkylarkClassObject) providers.get(key);
+  public Info getProvider(Provider.Key key) {
+    return (Info) providers.get(key);
   }
 
   public TransitiveInfoProviderMap build() {
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoProviderMapImpl.java b/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoProviderMapImpl.java
index b0ba583..b43129d 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoProviderMapImpl.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoProviderMapImpl.java
@@ -15,8 +15,8 @@
 package com.google.devtools.build.lib.analysis;
 
 import com.google.devtools.build.lib.collect.ImmutableSharedKeyMap;
-import com.google.devtools.build.lib.packages.ClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.Provider;
 import java.util.Map;
 import javax.annotation.Nullable;
 
@@ -43,8 +43,8 @@
 
   @Nullable
   @Override
-  public SkylarkClassObject getProvider(ClassObjectConstructor.Key key) {
-    return (SkylarkClassObject) get(key);
+  public Info getProvider(Provider.Key key) {
+    return (Info) get(key);
   }
 
   @Nullable
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/platform/ConstraintSettingInfo.java b/src/main/java/com/google/devtools/build/lib/analysis/platform/ConstraintSettingInfo.java
index 6020817..e790180 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/platform/ConstraintSettingInfo.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/platform/ConstraintSettingInfo.java
@@ -19,8 +19,8 @@
 import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
 import com.google.devtools.build.lib.events.Location;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
@@ -35,7 +35,7 @@
   category = SkylarkModuleCategory.PROVIDER
 )
 @Immutable
-public class ConstraintSettingInfo extends SkylarkClassObject {
+public class ConstraintSettingInfo extends Info {
 
   /** Name used in Skylark for accessing this provider. */
   public static final String SKYLARK_NAME = "ConstraintSettingInfo";
@@ -53,8 +53,8 @@
           /*types=*/ ImmutableList.<SkylarkType>of(SkylarkType.of(Label.class)));
 
   /** Skylark constructor and identifier for this provider. */
-  public static final NativeClassObjectConstructor<ConstraintSettingInfo> SKYLARK_CONSTRUCTOR =
-      new NativeClassObjectConstructor<ConstraintSettingInfo>(
+  public static final NativeProvider<ConstraintSettingInfo> SKYLARK_CONSTRUCTOR =
+      new NativeProvider<ConstraintSettingInfo>(
           ConstraintSettingInfo.class, SKYLARK_NAME, SIGNATURE) {
         @Override
         protected ConstraintSettingInfo createInstanceFromSkylark(Object[] args, Location loc)
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/platform/ConstraintValueInfo.java b/src/main/java/com/google/devtools/build/lib/analysis/platform/ConstraintValueInfo.java
index 9cd1fac..53d8ae1 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/platform/ConstraintValueInfo.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/platform/ConstraintValueInfo.java
@@ -19,8 +19,8 @@
 import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
 import com.google.devtools.build.lib.events.Location;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
@@ -35,7 +35,7 @@
   category = SkylarkModuleCategory.PROVIDER
 )
 @Immutable
-public class ConstraintValueInfo extends SkylarkClassObject {
+public class ConstraintValueInfo extends Info {
 
   /** Name used in Skylark for accessing this provider. */
   public static final String SKYLARK_NAME = "ConstraintValueInfo";
@@ -55,9 +55,8 @@
               SkylarkType.of(Label.class), SkylarkType.of(ConstraintSettingInfo.class)));
 
   /** Skylark constructor and identifier for this provider. */
-  public static final NativeClassObjectConstructor<ConstraintValueInfo> SKYLARK_CONSTRUCTOR =
-      new NativeClassObjectConstructor<ConstraintValueInfo>(
-          ConstraintValueInfo.class, SKYLARK_NAME, SIGNATURE) {
+  public static final NativeProvider<ConstraintValueInfo> SKYLARK_CONSTRUCTOR =
+      new NativeProvider<ConstraintValueInfo>(ConstraintValueInfo.class, SKYLARK_NAME, SIGNATURE) {
         @Override
         protected ConstraintValueInfo createInstanceFromSkylark(Object[] args, Location loc)
             throws EvalException {
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/platform/PlatformInfo.java b/src/main/java/com/google/devtools/build/lib/analysis/platform/PlatformInfo.java
index 9e5c917..8d8b669 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/platform/PlatformInfo.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/platform/PlatformInfo.java
@@ -22,8 +22,8 @@
 import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
 import com.google.devtools.build.lib.events.Location;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
@@ -44,7 +44,7 @@
   category = SkylarkModuleCategory.PROVIDER
 )
 @Immutable
-public class PlatformInfo extends SkylarkClassObject {
+public class PlatformInfo extends Info {
 
   /** Name used in Skylark for accessing this provider. */
   public static final String SKYLARK_NAME = "PlatformInfo";
@@ -66,8 +66,8 @@
                   SkylarkType.LIST, SkylarkType.of(ConstraintValueInfo.class))));
 
   /** Skylark constructor and identifier for this provider. */
-  public static final NativeClassObjectConstructor<PlatformInfo> SKYLARK_CONSTRUCTOR =
-      new NativeClassObjectConstructor<PlatformInfo>(PlatformInfo.class, SKYLARK_NAME, SIGNATURE) {
+  public static final NativeProvider<PlatformInfo> SKYLARK_CONSTRUCTOR =
+      new NativeProvider<PlatformInfo>(PlatformInfo.class, SKYLARK_NAME, SIGNATURE) {
         @Override
         protected PlatformInfo createInstanceFromSkylark(Object[] args, Location loc)
             throws EvalException {
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/platform/ToolchainInfo.java b/src/main/java/com/google/devtools/build/lib/analysis/platform/ToolchainInfo.java
index d8d1282..dcdde46 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/platform/ToolchainInfo.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/platform/ToolchainInfo.java
@@ -18,8 +18,8 @@
 import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
 import com.google.devtools.build.lib.events.Location;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
 import com.google.devtools.build.lib.syntax.EvalException;
@@ -38,7 +38,7 @@
   category = SkylarkModuleCategory.PROVIDER
 )
 @Immutable
-public class ToolchainInfo extends SkylarkClassObject {
+public class ToolchainInfo extends Info {
 
   /** Name used in Skylark for accessing this provider. */
   public static final String SKYLARK_NAME = "ToolchainInfo";
@@ -56,9 +56,8 @@
           /*types=*/ ImmutableList.<SkylarkType>of(SkylarkType.DICT));
 
   /** Skylark constructor and identifier for this provider. */
-  public static final NativeClassObjectConstructor<ToolchainInfo> SKYLARK_CONSTRUCTOR =
-      new NativeClassObjectConstructor<ToolchainInfo>(
-          ToolchainInfo.class, SKYLARK_NAME, SIGNATURE) {
+  public static final NativeProvider<ToolchainInfo> SKYLARK_CONSTRUCTOR =
+      new NativeProvider<ToolchainInfo>(ToolchainInfo.class, SKYLARK_NAME, SIGNATURE) {
         @Override
         protected ToolchainInfo createInstanceFromSkylark(Object[] args, Location loc)
             throws EvalException {
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java
index 51e48c1..7f3f014 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java
@@ -27,9 +27,9 @@
 import com.google.devtools.build.lib.events.Location;
 import com.google.devtools.build.lib.events.Reporter;
 import com.google.devtools.build.lib.packages.Attribute;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 import com.google.devtools.build.lib.packages.Rule;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
 import com.google.devtools.build.lib.rules.repository.RepositoryFunction;
 import com.google.devtools.build.lib.rules.repository.RepositoryFunction.RepositoryFunctionException;
 import com.google.devtools.build.lib.rules.repository.WorkspaceAttributeMapper;
@@ -78,7 +78,7 @@
 
   private final Rule rule;
   private final Path outputDirectory;
-  private final SkylarkClassObject attrObject;
+  private final Info attrObject;
   private final SkylarkOS osObject;
   private final Environment env;
   private final HttpDownloader httpDownloader;
@@ -110,8 +110,7 @@
                 : SkylarkType.convertToSkylark(val, null));
       }
     }
-    attrObject = NativeClassObjectConstructor.STRUCT.create(
-        attrBuilder.build(), "No such attribute '%s'");
+    attrObject = NativeProvider.STRUCT.create(attrBuilder.build(), "No such attribute '%s'");
   }
 
   @SkylarkCallable(
@@ -130,7 +129,7 @@
         "A struct to access the values of the attributes. The values are provided by "
             + "the user (if not, a default value is used)."
   )
-  public SkylarkClassObject getAttr() {
+  public Info getAttr() {
     return attrObject;
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelPrerequisiteValidator.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelPrerequisiteValidator.java
index 4c9454e..f1d7dff 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelPrerequisiteValidator.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelPrerequisiteValidator.java
@@ -75,9 +75,8 @@
     }
 
     if (prerequisiteTarget instanceof PackageGroup) {
-      RequiredProviders requiredProviders = RawAttributeMapper.of(rule)
-          .getAttributeDefinition(attrName)
-          .getRequiredProviders();
+      RequiredProviders requiredProviders =
+          RawAttributeMapper.of(rule).getAttributeDefinition(attrName).getRequiredProviders();
       boolean containsPackageSpecificationProvider =
           requiredProviders.getDescription().contains("PackageSpecificationProvider");
       // TODO(plf): Add the PackageSpecificationProvider to the 'visibility' attribute.
diff --git a/src/main/java/com/google/devtools/build/lib/packages/AdvertisedProviderSet.java b/src/main/java/com/google/devtools/build/lib/packages/AdvertisedProviderSet.java
index 1f1ddd6..3f8686b 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/AdvertisedProviderSet.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/AdvertisedProviderSet.java
@@ -164,7 +164,7 @@
       return this;
     }
 
-    public Builder addSkylark(ClassObjectConstructor.Key id) {
+    public Builder addSkylark(Provider.Key id) {
       skylarkProviders.add(SkylarkProviderIdentifier.forKey(id));
       return this;
     }
diff --git a/src/main/java/com/google/devtools/build/lib/packages/Attribute.java b/src/main/java/com/google/devtools/build/lib/packages/Attribute.java
index 7114040..bd36056 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/Attribute.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/Attribute.java
@@ -950,18 +950,18 @@
 
     /**
      * If this is a label or label-list attribute, then this sets the allowed rule types with
-     * warning for the labels occurring in the attribute. This must be a disjoint set from
-     * {@link #allowedRuleClasses}.
+     * warning for the labels occurring in the attribute. This must be a disjoint set from {@link
+     * #allowedRuleClasses}.
      *
      * <p>If the attribute contains Labels of any other rule type (other than this or those set in
-     * allowedRuleClasses()) and they fulfill {@link #getRequiredProviders()}}, the build
-     * continues without error. Else the build fails during analysis.
+     * allowedRuleClasses()) and they fulfill {@link #getRequiredProviders()}}, the build continues
+     * without error. Else the build fails during analysis.
      *
-     * <p>If neither this nor {@link #allowedRuleClassesForLabels} is set, only rules that
-     * fulfill {@link #getRequiredProviders()} build without error.
+     * <p>If neither this nor {@link #allowedRuleClassesForLabels} is set, only rules that fulfill
+     * {@link #getRequiredProviders()} build without error.
      *
-     * <p>This only works on a per-target basis, not on a per-file basis; with other words, it
-     * works for 'deps' attributes, but not 'srcs' attributes.
+     * <p>This only works on a per-target basis, not on a per-file basis; with other words, it works
+     * for 'deps' attributes, but not 'srcs' attributes.
      */
     public Builder<TYPE> allowedRuleClassesWithWarning(String... allowedRuleClasses) {
       return allowedRuleClassesWithWarning(ImmutableSet.copyOf(allowedRuleClasses));
@@ -1514,7 +1514,7 @@
     private Object invokeCallback(Map<String, Object> attrValues)
         throws EvalException, InterruptedException {
       ClassObject attrs =
-          NativeClassObjectConstructor.STRUCT.create(
+          NativeProvider.STRUCT.create(
               attrValues, "No such regular (non computed) attribute '%s'.");
       Object result = callback.call(attrs);
       try {
@@ -1792,19 +1792,16 @@
   private final ImmutableList<RuleAspect<?>> aspects;
 
   /**
-   * Constructs a rule attribute with the specified name, type and default
-   * value.
+   * Constructs a rule attribute with the specified name, type and default value.
    *
    * @param name the name of the attribute
    * @param type the type of the attribute
-   * @param defaultValue the default value to use for this attribute if none is
-   *        specified in rule declaration in the BUILD file. Must be null, or of
-   *        type "type". May be an instance of ComputedDefault, in which case
-   *        its getDefault() method must return an instance of "type", or null.
-   *        Must be immutable.
-   * @param configTransition the configuration transition for this attribute
-   *        (which must be of type LABEL, LABEL_LIST, NODEP_LABEL or
-   *        NODEP_LABEL_LIST).
+   * @param defaultValue the default value to use for this attribute if none is specified in rule
+   *     declaration in the BUILD file. Must be null, or of type "type". May be an instance of
+   *     ComputedDefault, in which case its getDefault() method must return an instance of "type",
+   *     or null. Must be immutable.
+   * @param configTransition the configuration transition for this attribute (which must be of type
+   *     LABEL, LABEL_LIST, NODEP_LABEL or NODEP_LABEL_LIST).
    */
   private Attribute(
       String name,
diff --git a/src/main/java/com/google/devtools/build/lib/packages/ImplicitOutputsFunction.java b/src/main/java/com/google/devtools/build/lib/packages/ImplicitOutputsFunction.java
index 5250554..ecb9cf8 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/ImplicitOutputsFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/ImplicitOutputsFunction.java
@@ -94,10 +94,11 @@
           attrValues.put(attrName, value == null ? Runtime.NONE : value);
         }
       }
-      ClassObject attrs = NativeClassObjectConstructor.STRUCT.create(
-          attrValues,
-          "Attribute '%s' either doesn't exist "
-          + "or uses a select() (i.e. could have multiple values)");
+      ClassObject attrs =
+          NativeProvider.STRUCT.create(
+              attrValues,
+              "Attribute '%s' either doesn't exist "
+                  + "or uses a select() (i.e. could have multiple values)");
       try {
         ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
         for (Map.Entry<String, String> entry : castMap(callback.call(attrs),
diff --git a/src/main/java/com/google/devtools/build/lib/packages/SkylarkClassObject.java b/src/main/java/com/google/devtools/build/lib/packages/Info.java
similarity index 68%
rename from src/main/java/com/google/devtools/build/lib/packages/SkylarkClassObject.java
rename to src/main/java/com/google/devtools/build/lib/packages/Info.java
index fa84c3e..059c55e 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/SkylarkClassObject.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/Info.java
@@ -21,7 +21,6 @@
 import com.google.common.collect.Sets;
 import com.google.common.collect.Sets.SetView;
 import com.google.devtools.build.lib.events.Location;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor.StructConstructor;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
@@ -40,7 +39,7 @@
 import java.util.Map;
 import javax.annotation.Nullable;
 
-/** An implementation class of ClassObject for structs created in Skylark code. */
+/** Represents information provided by a {@link Provider}. */
 @SkylarkModule(
   name = "struct",
   category = SkylarkModuleCategory.BUILTIN,
@@ -49,53 +48,48 @@
           + "See the global <a href=\"globals.html#struct\">struct</a> function "
           + "for more details."
 )
-public class SkylarkClassObject implements ClassObject, SkylarkValue, Concatable, Serializable {
-  private final ClassObjectConstructor constructor;
+public class Info implements ClassObject, SkylarkValue, Concatable, Serializable {
+  private final Provider provider;
   private final ImmutableMap<String, Object> values;
   private final Location creationLoc;
   private final String errorMessage;
 
   /** Creates an empty struct with a given location. */
-  public SkylarkClassObject(ClassObjectConstructor constructor, Location location) {
-    this.constructor = constructor;
+  public Info(Provider provider, Location location) {
+    this.provider = provider;
     this.values = ImmutableMap.of();
     this.creationLoc = location;
-    this.errorMessage = constructor.getErrorMessageFormatForInstances();
+    this.errorMessage = provider.getErrorMessageFormatForInstances();
   }
 
-  /**
-   * Creates a built-in struct (i.e. without creation loc).
-   */
-  public SkylarkClassObject(ClassObjectConstructor constructor,
-      Map<String, Object> values) {
-    this.constructor = constructor;
+  /** Creates a built-in struct (i.e. without creation loc). */
+  public Info(Provider provider, Map<String, Object> values) {
+    this.provider = provider;
     this.values = copyValues(values);
     this.creationLoc = null;
-    this.errorMessage = constructor.getErrorMessageFormatForInstances();
+    this.errorMessage = provider.getErrorMessageFormatForInstances();
   }
 
   /**
    * Creates a built-in struct (i.e. without creation loc).
    *
-   * Allows to supply a specific error message.
-   * Only used in {@link StructConstructor#create(Map, String)}
-   * If you need to override an error message, preferred way is to create a specific
-   * {@link NativeClassObjectConstructor}.
+   * <p>Allows to supply a specific error message. Only used in
+   * {@link com.google.devtools.build.lib.packages.NativeProvider.StructConstructor#create(Map,
+   * String)} If you need to override an error message, preferred way is to create a specific {@link
+   * NativeProvider}.
    */
-  SkylarkClassObject(ClassObjectConstructor constructor,
-      Map<String, Object> values, String errorMessage) {
-    this.constructor = constructor;
+  Info(Provider provider, Map<String, Object> values, String errorMessage) {
+    this.provider = provider;
     this.values = copyValues(values);
     this.creationLoc = null;
     this.errorMessage = Preconditions.checkNotNull(errorMessage);
   }
 
-  public SkylarkClassObject(ClassObjectConstructor constructor,
-      Map<String, Object> values, Location creationLoc) {
-    this.constructor = constructor;
+  public Info(Provider provider, Map<String, Object> values, Location creationLoc) {
+    this.provider = provider;
     this.values = copyValues(values);
     this.creationLoc = Preconditions.checkNotNull(creationLoc);
-    this.errorMessage = constructor.getErrorMessageFormatForInstances();
+    this.errorMessage = provider.getErrorMessageFormatForInstances();
   }
 
   // Ensure that values are all acceptable to Skylark before to stuff them in a ClassObject
@@ -117,9 +111,7 @@
     return values.containsKey(name);
   }
 
-  /**
-   *  Returns a value and try to cast it into specified type
-   */
+  /** Returns a value and try to cast it into specified type */
   public <TYPE> TYPE getValue(String key, Class<TYPE> type) throws EvalException {
     Object obj = values.get(key);
     if (obj == null) {
@@ -135,17 +127,16 @@
   }
 
   public Location getCreationLoc() {
-    return Preconditions.checkNotNull(creationLoc,
-        "This struct was not created in a Skylark code");
+    return Preconditions.checkNotNull(creationLoc, "This struct was not created in a Skylark code");
   }
 
   @Override
   public Concatter getConcatter() {
     return StructConcatter.INSTANCE;
   }
-  
-  public ClassObjectConstructor getConstructor() {
-    return constructor;
+
+  public Provider getProvider() {
+    return provider;
   }
 
   @Nullable
@@ -159,27 +150,25 @@
     private StructConcatter() {}
 
     @Override
-    public SkylarkClassObject concat(
-        Concatable left, Concatable right, Location loc) throws EvalException {
-      SkylarkClassObject lval = (SkylarkClassObject) left;
-      SkylarkClassObject rval = (SkylarkClassObject) right;
-      if (!lval.constructor.equals(rval.constructor)) {
-        throw new EvalException(loc,
-            String.format("Cannot concat %s with %s",
-                lval.constructor.getPrintableName(),
-                rval.constructor.getPrintableName()));
+    public Info concat(Concatable left, Concatable right, Location loc) throws EvalException {
+      Info lval = (Info) left;
+      Info rval = (Info) right;
+      if (!lval.provider.equals(rval.provider)) {
+        throw new EvalException(
+            loc,
+            String.format(
+                "Cannot concat %s with %s",
+                lval.provider.getPrintableName(), rval.provider.getPrintableName()));
       }
-      SetView<String> commonFields = Sets
-          .intersection(lval.values.keySet(), rval.values.keySet());
+      SetView<String> commonFields = Sets.intersection(lval.values.keySet(), rval.values.keySet());
       if (!commonFields.isEmpty()) {
-        throw new EvalException(loc, "Cannot concat structs with common field(s): "
-            + Joiner.on(",").join(commonFields));
+        throw new EvalException(
+            loc,
+            "Cannot concat structs with common field(s): " + Joiner.on(",").join(commonFields));
       }
-      return new SkylarkClassObject(lval.constructor,
-          ImmutableMap.<String, Object>builder()
-              .putAll(lval.values)
-              .putAll(rval.values)
-              .build(),
+      return new Info(
+          lval.provider,
+          ImmutableMap.<String, Object>builder().putAll(lval.values).putAll(rval.values).build(),
           loc);
     }
   }
@@ -194,8 +183,8 @@
 
   @Override
   public boolean isImmutable() {
-    // If the constructor is not yet exported the hash code of the object is subject to change
-    if (!constructor.isExported()) {
+    // If the provider is not yet exported the hash code of the object is subject to change
+    if (!provider.isExported()) {
       return false;
     }
     for (Object item : values.values()) {
@@ -208,14 +197,14 @@
 
   @Override
   public boolean equals(Object otherObject) {
-    if (!(otherObject instanceof SkylarkClassObject)) {
+    if (!(otherObject instanceof Info)) {
       return false;
     }
-    SkylarkClassObject other = (SkylarkClassObject) otherObject;
+    Info other = (Info) otherObject;
     if (this == other) {
       return true;
     }
-    if (!this.constructor.equals(other.constructor)) {
+    if (!this.provider.equals(other.provider)) {
       return false;
     }
     // Compare objects' keys and values
@@ -235,7 +224,7 @@
     List<String> keys = new ArrayList<>(getKeys());
     Collections.sort(keys);
     List<Object> objectsToHash = new ArrayList<>();
-    objectsToHash.add(constructor);
+    objectsToHash.add(provider);
     for (String key : keys) {
       objectsToHash.add(key);
       objectsToHash.add(getValue(key));
@@ -267,7 +256,7 @@
   @Override
   public void reprLegacy(SkylarkPrinter printer) {
     boolean first = true;
-    printer.append(constructor.getPrintableName());
+    printer.append(provider.getPrintableName());
     printer.append("(");
     // Sort by key to ensure deterministic output.
     for (String key : Ordering.natural().sortedCopy(values.keySet())) {
diff --git a/src/main/java/com/google/devtools/build/lib/packages/NativeClassObjectConstructor.java b/src/main/java/com/google/devtools/build/lib/packages/NativeProvider.java
similarity index 64%
rename from src/main/java/com/google/devtools/build/lib/packages/NativeClassObjectConstructor.java
rename to src/main/java/com/google/devtools/build/lib/packages/NativeProvider.java
index 6bcce0f..f6f7d8e 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/NativeClassObjectConstructor.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/NativeProvider.java
@@ -23,31 +23,27 @@
 import javax.annotation.Nullable;
 
 /**
- * Base class for declared providers {@see ClassObjectConstructor} defined in native code.
+ * Base class for declared providers {@see Provider} defined in native code.
  *
- * <p>Every non-abstract derived class of {@link NativeClassObjectConstructor} corresponds to a
- * single declared provider. This is enforced by final {@link #equals(Object)} and {@link
- * #hashCode()}.
+ * <p>Every non-abstract derived class of {@link NativeProvider} corresponds to a single declared
+ * provider. This is enforced by final {@link #equals(Object)} and {@link #hashCode()}.
  *
  * <p>Typical implementation of a non-constructable from Skylark declared provider is as follows:
  *
  * <pre>
- *     public static final ClassObjectConstructor CC_LINK_PARAMS =
- *       new NativeClassObjectConstructor("link_params") { };
+ *     public static final Provider CC_LINK_PARAMS =
+ *       new NativeProvider("link_params") { };
  * </pre>
  *
  * To allow construction from Skylark and custom construction logic, override {@link
  * #createInstanceFromSkylark(Object[], Location)} (see {@link #STRUCT} for an example.
  */
 @Immutable
-public abstract class NativeClassObjectConstructor<VALUE extends SkylarkClassObject>
-    extends ClassObjectConstructor {
+public abstract class NativeProvider<VALUE extends Info> extends Provider {
   private final NativeKey key;
   private final String errorMessageForInstances;
 
-  /**
-   * "struct" function.
-   */
+  /** "struct" function. */
   public static final StructConstructor STRUCT = new StructConstructor();
 
   private final Class<VALUE> valueClass;
@@ -57,13 +53,11 @@
   }
 
   /**
-   * 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!
+   * 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 mechanism
-   * exclusively to expose providers to both native and Skylark code.
+   * <p>Use native declared providers mechanism exclusively to expose providers to both native and
+   * Skylark code.
    */
   @Deprecated
   public static interface WithLegacySkylarkName {
@@ -75,36 +69,35 @@
    *
    * <p>Singleton, instance is {@link #STRUCT}.
    */
-  public static final class StructConstructor
-      extends NativeClassObjectConstructor<SkylarkClassObject> {
+  public static final class StructConstructor extends NativeProvider<Info> {
     private StructConstructor() {
-      super(SkylarkClassObject.class, "struct");
+      super(Info.class, "struct");
     }
 
     @Override
-    protected SkylarkClassObject createInstanceFromSkylark(Object[] args, Location loc) {
+    protected Info createInstanceFromSkylark(Object[] args, Location loc) {
       @SuppressWarnings("unchecked")
       Map<String, Object> kwargs = (Map<String, Object>) args[0];
-      return new SkylarkClassObject(this, kwargs, loc);
+      return new Info(this, kwargs, loc);
     }
 
-    public SkylarkClassObject create(Map<String, Object> values, String message) {
-      return new SkylarkClassObject(this, values, message);
+    public Info create(Map<String, Object> values, String message) {
+      return new Info(this, values, message);
     }
 
-    public SkylarkClassObject create(Location loc) {
-      return new SkylarkClassObject(this, loc);
+    public Info create(Location loc) {
+      return new Info(this, loc);
     }
   }
 
   private static final FunctionSignature.WithValues<Object, SkylarkType> SIGNATURE =
       FunctionSignature.WithValues.create(FunctionSignature.KWARGS);
 
-  protected NativeClassObjectConstructor(Class<VALUE> clazz, String name) {
+  protected NativeProvider(Class<VALUE> clazz, String name) {
     this(clazz, name, SIGNATURE);
   }
 
-  protected NativeClassObjectConstructor(
+  protected NativeProvider(
       Class<VALUE> valueClass,
       String name,
       FunctionSignature.WithValues<Object, SkylarkType> signature) {
@@ -117,8 +110,8 @@
   /**
    * equals() implements singleton class semantics.
    *
-   * Every non-abstract derived class of {@link NativeClassObjectConstructor}
-   * corresponds to a single declared provider.
+   * <p>Every non-abstract derived class of {@link NativeProvider} corresponds to a single declared
+   * provider.
    */
   @Override
   public final boolean equals(@Nullable Object other) {
@@ -128,8 +121,8 @@
   /**
    * hashCode() implements singleton class semantics.
    *
-   * Every non-abstract derived class of {@link NativeClassObjectConstructor}
-   * corresponds to a single declared provider.
+   * <p>Every non-abstract derived class of {@link NativeProvider} corresponds to a single declared
+   * provider.
    */
   @Override
   public final int hashCode() {
@@ -157,10 +150,9 @@
   }
 
   @Override
-  protected SkylarkClassObject createInstanceFromSkylark(Object[] args, Location loc)
-      throws EvalException {
-    throw new EvalException(loc,
-        String.format("'%s' cannot be constructed from Skylark", getPrintableName()));
+  protected Info createInstanceFromSkylark(Object[] args, Location loc) throws EvalException {
+    throw new EvalException(
+        loc, String.format("'%s' cannot be constructed from Skylark", getPrintableName()));
   }
 
   public static Pair<String, String> getSerializedRepresentationForNativeKey(NativeKey key) {
@@ -169,26 +161,24 @@
 
   public static NativeKey getNativeKeyFromSerializedRepresentation(Pair<String, String> serialized)
       throws ClassNotFoundException {
-    Class<? extends NativeClassObjectConstructor> aClass =
-        Class.forName(serialized.second).asSubclass(NativeClassObjectConstructor.class);
+    Class<? extends NativeProvider> aClass =
+        Class.forName(serialized.second).asSubclass(NativeProvider.class);
     return new NativeKey(serialized.first, aClass);
   }
 
   /**
-   * A serializable representation of {@link NativeClassObjectConstructor}.
+   * A serializable representation of {@link NativeProvider}.
    *
-   * Just a wrapper around its class.
+   * <p>Just a wrapper around its class.
    */
   // todo(vladmos,dslomov): when we allow declared providers in `requiredProviders`,
   // we will need to serialize this somehow.
   @Immutable
   public static final class NativeKey extends Key {
     private final String name;
-    private final Class<? extends NativeClassObjectConstructor> aClass;
+    private final Class<? extends NativeProvider> aClass;
 
-    private NativeKey(
-        String name,
-        Class<? extends NativeClassObjectConstructor> aClass) {
+    private NativeKey(String name, Class<? extends NativeProvider> aClass) {
       this.name = name;
       this.aClass = aClass;
     }
diff --git a/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java b/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
index 1ca18e2..b03acc5 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
@@ -1592,8 +1592,7 @@
         builder.put(function.getName(), function);
       }
     }
-    return NativeClassObjectConstructor.STRUCT.create(
-        builder.build(), "no native function or rule '%s'");
+    return NativeProvider.STRUCT.create(builder.build(), "no native function or rule '%s'");
   }
 
   /** @param fakeEnv specify if we declare no-op functions, or real functions. */
diff --git a/src/main/java/com/google/devtools/build/lib/packages/ClassObjectConstructor.java b/src/main/java/com/google/devtools/build/lib/packages/Provider.java
similarity index 68%
rename from src/main/java/com/google/devtools/build/lib/packages/ClassObjectConstructor.java
rename to src/main/java/com/google/devtools/build/lib/packages/Provider.java
index 2356d71..b497b76 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/ClassObjectConstructor.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/Provider.java
@@ -25,16 +25,16 @@
 import javax.annotation.Nullable;
 
 /**
- * Declared Provider (a constructor for {@link SkylarkClassObject}).
+ * Declared Provider (a constructor for {@link Info}).
  *
- * <p>Declared providers can be declared either natively ({@link NativeClassObjectConstructor} or in
- * Skylark {@link SkylarkClassObjectConstructor}.
+ * <p>Declared providers can be declared either natively ({@link NativeProvider} or in Skylark
+ * {@link SkylarkProvider}.
  *
- * <p>{@link ClassObjectConstructor} serves both as "type identifier" for declared provider
- * instances and as a function that can be called to construct a provider.
+ * <p>{@link Provider} serves both as "type identifier" for declared provider instances and as a
+ * function that can be called to construct a provider.
  *
- * <p>Prefer to use {@link Key} as a serializable identifier of {@link ClassObjectConstructor}. In
- * particular, {@link Key} should be used in all data structures exposed to Skyframe.
+ * <p>Prefer to use {@link Key} as a serializable identifier of {@link Provider}. In particular,
+ * {@link Key} should be used in all data structures exposed to Skyframe.
  */
 @SkylarkModule(
   name = "Provider",
@@ -60,35 +60,29 @@
           + "<a href=\"globals.html#provider\">provider</a> function."
 )
 @Immutable
-public abstract class ClassObjectConstructor extends BaseFunction {
+public abstract class Provider extends BaseFunction {
 
-  protected ClassObjectConstructor(String name,
-      FunctionSignature.WithValues<Object, SkylarkType> signature,
-      Location location) {
+  protected Provider(
+      String name, FunctionSignature.WithValues<Object, SkylarkType> signature, Location location) {
     super(name, signature, location);
   }
 
   /**
-   * Has this {@link ClassObjectConstructor} been exported?
-   * All native constructors are always exported. Skylark constructors are exported
-   * if they are assigned to top-level name in a Skylark module.
+   * Has this {@link Provider} been exported? All native providers are always exported. Skylark
+   * providers are exported if they are assigned to top-level name in a Skylark module.
    */
   public abstract boolean isExported();
 
-  /**
-   * Returns a serializable representation of this constructor.
-   */
+  /** Returns a serializable representation of this {@link Provider}. */
   public abstract Key getKey();
 
-  /**
-   * Returns a name of this constructor that should be used in error messages.
-   */
+  /** Returns a name of this {@link Provider} that should be used in error messages. */
   public abstract String getPrintableName();
 
   /**
    * Returns an error message format for instances.
    *
-   * Must contain one '%s' placeholder for field name.
+   * <p>Must contain one '%s' placeholder for field name.
    */
   public abstract String getErrorMessageFormatForInstances();
 
@@ -104,22 +98,17 @@
   }
 
   /**
-   * Override this method to provide logic that is used to instantiate a declared provider
-   * from Skylark.
+   * Override this method to provide logic that is used to instantiate a declared provider from
+   * Skylark.
    *
-   * This is a method that is called when a constructor {@code c} is invoked as<br>
+   * <p>This is a method that is called when a constructor {@code c} is invoked as<br>
    * {@code c(arg1 = val1, arg2 = val2, ...)}.
    *
-   * @param args an array of argument values sorted as per the signature
-   *          ({@see BaseFunction#call})
+   * @param args an array of argument values sorted as per the signature ({@see BaseFunction#call})
    */
-  protected abstract SkylarkClassObject createInstanceFromSkylark(Object[] args, Location loc)
+  protected abstract Info createInstanceFromSkylark(Object[] args, Location loc)
       throws EvalException;
 
-  /**
-   * A serializable representation of {@link ClassObjectConstructor}.
-   */
-  // todo(vladmos,dslomov): when we allow declared providers in `requiredProviders`,
-  // we will need to serialize this somehow.
+  /** A serializable representation of {@link Provider}. */
   public abstract static class Key {}
 }
diff --git a/src/main/java/com/google/devtools/build/lib/packages/RequiredProviders.java b/src/main/java/com/google/devtools/build/lib/packages/RequiredProviders.java
index e9298bd..5b494b7 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/RequiredProviders.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/RequiredProviders.java
@@ -72,7 +72,8 @@
       }
 
       @Override
-      public boolean satisfies(Predicate<Class<?>> hasNativeProvider,
+      public boolean satisfies(
+          Predicate<Class<?>> hasNativeProvider,
           Predicate<SkylarkProviderIdentifier> hasSkylarkProvider,
           RequiredProviders requiredProviders,
           Builder missingProviders) {
@@ -100,7 +101,8 @@
       }
 
       @Override
-      public boolean satisfies(Predicate<Class<?>> hasNativeProvider,
+      public boolean satisfies(
+          Predicate<Class<?>> hasNativeProvider,
           Predicate<SkylarkProviderIdentifier> hasSkylarkProvider,
           RequiredProviders requiredProviders,
           Builder missingProviders) {
@@ -121,19 +123,23 @@
     /** Accept a dependency that has all providers from one of the sets. */
     RESTRICTED {
       @Override
-      public boolean satisfies(final AdvertisedProviderSet advertisedProviderSet,
-          RequiredProviders requiredProviders, Builder missing) {
+      public boolean satisfies(
+          final AdvertisedProviderSet advertisedProviderSet,
+          RequiredProviders requiredProviders,
+          Builder missing) {
         if (advertisedProviderSet.canHaveAnyProvider()) {
           return true;
         }
         return satisfies(
             advertisedProviderSet.getNativeProviders()::contains,
             advertisedProviderSet.getSkylarkProviders()::contains,
-            requiredProviders, missing);
+            requiredProviders,
+            missing);
       }
 
       @Override
-      public boolean satisfies(Predicate<Class<?>> hasNativeProvider,
+      public boolean satisfies(
+          Predicate<Class<?>> hasNativeProvider,
           Predicate<SkylarkProviderIdentifier> hasSkylarkProvider,
           RequiredProviders requiredProviders,
           Builder missingProviders) {
@@ -145,10 +151,11 @@
           // Collect missing providers
           if (missingProviders != null) {
             missingProviders.addNativeSet(
-                nativeProviderSet.stream().filter(hasNativeProvider.negate())
+                nativeProviderSet
+                    .stream()
+                    .filter(hasNativeProvider.negate())
                     .collect(ImmutableSet.toImmutableSet()));
           }
-
         }
 
         for (ImmutableSet<SkylarkProviderIdentifier> skylarkProviderSet
@@ -159,7 +166,9 @@
           // Collect missing providers
           if (missingProviders != null) {
             missingProviders.addSkylarkSet(
-                skylarkProviderSet.stream().filter(hasSkylarkProvider.negate())
+                skylarkProviderSet
+                    .stream()
+                    .filter(hasSkylarkProvider.negate())
                     .collect(ImmutableSet.toImmutableSet()));
           }
         }
@@ -185,30 +194,28 @@
         describe(result, providers.nativeProviders, Class::getSimpleName);
         describe(result, providers.skylarkProviders, id -> "'" + id.toString() + "'");
         return result.toString();
-
       }
     };
 
     /** Checks if {@code advertisedProviderSet} satisfies these {@code RequiredProviders} */
-    public abstract boolean satisfies(AdvertisedProviderSet advertisedProviderSet,
-        RequiredProviders requiredProviders, Builder missing);
+    public abstract boolean satisfies(
+        AdvertisedProviderSet advertisedProviderSet,
+        RequiredProviders requiredProviders,
+        Builder missing);
 
     /**
-     * Checks if a set of providers encoded by predicates {@code hasNativeProviders}
-     * and {@code hasSkylarkProvider} satisfies these {@code RequiredProviders}
+     * Checks if a set of providers encoded by predicates {@code hasNativeProviders} and {@code
+     * hasSkylarkProvider} satisfies these {@code RequiredProviders}
      */
     abstract boolean satisfies(
         Predicate<Class<?>> hasNativeProvider,
         Predicate<SkylarkProviderIdentifier> hasSkylarkProvider,
         RequiredProviders requiredProviders,
-        @Nullable
-        Builder missingProviders);
+        @Nullable Builder missingProviders);
 
     abstract Builder copyAsBuilder(RequiredProviders providers);
 
-    /**
-     * Returns a string describing the providers that can be presented to the user.
-     */
+    /** Returns a string describing the providers that can be presented to the user. */
     abstract String getDescription(RequiredProviders providers);
   }
 
@@ -228,8 +235,8 @@
   }
 
   /**
-   * Returns providers that are missing. If none are missing, returns
-   * {@code RequiredProviders} that accept anything.
+   * Returns providers that are missing. If none are missing, returns {@code RequiredProviders} that
+   * accept anything.
    */
   public RequiredProviders getMissing(
       Predicate<Class<?>> hasNativeProvider,
@@ -243,8 +250,8 @@
   }
 
   /**
-   * Returns providers that are missing. If none are missing, returns
-   * {@code RequiredProviders} that accept anything.
+   * Returns providers that are missing. If none are missing, returns {@code RequiredProviders} that
+   * accept anything.
    */
   public RequiredProviders getMissing(AdvertisedProviderSet set) {
     Builder builder = acceptAnyBuilder();
@@ -255,10 +262,7 @@
     return builder.build();
   }
 
-
-  /**
-   * Returns true if this {@code RequiredProviders} instance accept any set of providers.
-   */
+  /** Returns true if this {@code RequiredProviders} instance accept any set of providers. */
   public boolean acceptsAny() {
     return constraint.equals(Constraint.ANY);
   }
@@ -278,11 +282,11 @@
     this.skylarkProviders = skylarkProviders;
   }
 
-  /**
-   * Helper method to describe lists of sets of things.
-   */
-  private static <T> void describe(StringBuilder result,
-      ImmutableList<ImmutableSet<T>> listOfSets, Function<T, String> describeOne) {
+  /** Helper method to describe lists of sets of things. */
+  private static <T> void describe(
+      StringBuilder result,
+      ImmutableList<ImmutableSet<T>> listOfSets,
+      Function<T, String> describeOne) {
     Joiner joiner = Joiner.on(", ");
     for (ImmutableSet<T> ids : listOfSets) {
       if (result.length() > 0) {
@@ -294,7 +298,6 @@
     }
   }
 
-
   /**
    * A builder for {@link RequiredProviders} that accepts any dependency
    * unless restriction provider sets are added.
@@ -311,9 +314,7 @@
     return new Builder(true);
   }
 
-  /**
-   * Returns a Builder initialized to the same value as this {@code RequiredProvider}
-   */
+  /** Returns a Builder initialized to the same value as this {@code RequiredProvider} */
   public Builder copyAsBuilder() {
     return constraint.copyAsBuilder(this);
   }
diff --git a/src/main/java/com/google/devtools/build/lib/packages/SkylarkClassObjectConstructor.java b/src/main/java/com/google/devtools/build/lib/packages/SkylarkProvider.java
similarity index 80%
rename from src/main/java/com/google/devtools/build/lib/packages/SkylarkClassObjectConstructor.java
rename to src/main/java/com/google/devtools/build/lib/packages/SkylarkProvider.java
index 8bd6008..ea341b3 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/SkylarkClassObjectConstructor.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/SkylarkProvider.java
@@ -31,40 +31,36 @@
  * <p>This is a result of calling {@code provider()} function from Skylark ({@link
  * com.google.devtools.build.lib.rules.SkylarkRuleClassFunctions#provider}).
  */
-public class SkylarkClassObjectConstructor extends ClassObjectConstructor
-    implements SkylarkExportable {
+public class SkylarkProvider extends Provider implements SkylarkExportable {
 
   private static final FunctionSignature.WithValues<Object, SkylarkType> SIGNATURE =
       FunctionSignature.WithValues.create(FunctionSignature.KWARGS);
 
-  @Nullable
-  private SkylarkKey key;
-  @Nullable
-  private String errorMessageFormatForInstances;
+  @Nullable private SkylarkKey key;
+  @Nullable private String errorMessageFormatForInstances;
 
   private static final String DEFAULT_ERROR_MESSAFE = "Object has no '%s' attribute.";
 
   /**
-   * Creates a Skylark-defined Declared Provider ({@link SkylarkClassObject} constructor).
+   * Creates a Skylark-defined Declared Provider ({@link Info} constructor).
    *
-   * Needs to be exported later.
+   * <p>Needs to be exported later.
    */
-  public SkylarkClassObjectConstructor(String name, Location location) {
+  public SkylarkProvider(String name, Location location) {
     this(name, SIGNATURE, location);
   }
 
-  public SkylarkClassObjectConstructor(
+  public SkylarkProvider(
       String name, FunctionSignature.WithValues<Object, SkylarkType> signature, Location location) {
     super(name, signature, location);
     this.errorMessageFormatForInstances = DEFAULT_ERROR_MESSAFE;
   }
 
   @Override
-  protected SkylarkClassObject createInstanceFromSkylark(Object[] args, Location loc)
-      throws EvalException {
+  protected Info createInstanceFromSkylark(Object[] args, Location loc) throws EvalException {
     @SuppressWarnings("unchecked")
     Map<String, Object> kwargs = (Map<String, Object>) args[0];
-    return new SkylarkClassObject(this, kwargs, loc);
+    return new Info(this, kwargs, loc);
   }
 
   @Override
@@ -92,8 +88,8 @@
   public void export(Label extensionLabel, String exportedName) {
     Preconditions.checkState(!isExported());
     this.key = new SkylarkKey(extensionLabel, exportedName);
-    this.errorMessageFormatForInstances = String.format(
-        "'%s' object has no attribute '%%s'", exportedName);
+    this.errorMessageFormatForInstances =
+        String.format("'%s' object has no attribute '%%s'", exportedName);
   }
 
   @Override
@@ -106,10 +102,10 @@
 
   @Override
   public boolean equals(@Nullable Object otherObject) {
-    if (!(otherObject instanceof  SkylarkClassObjectConstructor)) {
+    if (!(otherObject instanceof SkylarkProvider)) {
       return false;
     }
-    SkylarkClassObjectConstructor other = (SkylarkClassObjectConstructor) otherObject;
+    SkylarkProvider other = (SkylarkProvider) otherObject;
 
     if (this.isExported() && other.isExported()) {
       return this.getKey().equals(other.getKey());
@@ -130,9 +126,8 @@
   }
 
   /**
-   * A serializable representation of Skylark-defined {@link SkylarkClassObjectConstructor}
-   * that uniquely identifies all {@link SkylarkClassObjectConstructor}s that
-   * are exposed to SkyFrame.
+   * A serializable representation of Skylark-defined {@link SkylarkProvider} that uniquely
+   * identifies all {@link SkylarkProvider}s that are exposed to SkyFrame.
    */
   public static class SkylarkKey extends Key {
     private final Label extensionLabel;
diff --git a/src/main/java/com/google/devtools/build/lib/packages/SkylarkProviderIdentifier.java b/src/main/java/com/google/devtools/build/lib/packages/SkylarkProviderIdentifier.java
index d9e663c..34b507a 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/SkylarkProviderIdentifier.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/SkylarkProviderIdentifier.java
@@ -19,21 +19,17 @@
 import javax.annotation.Nullable;
 
 /**
- * A wrapper around Skylark provider identifier,
- * representing either a declared provider ({@see SkylarkClassObjectConstructor})
- * or a "legacy" string identifier.
+ * A wrapper around Skylark provider identifier, representing either a declared provider ({@see
+ * SkylarkProvider}) or a "legacy" string identifier.
  */
 public final class SkylarkProviderIdentifier {
 
   @Nullable
   private final String legacyId;
-  @Nullable
-  private final ClassObjectConstructor.Key key;
+  @Nullable private final Provider.Key key;
 
-  /**
-   * Creates an id for a declared provider with a given key ({@see SkylarkClassObjectConstructor}).
-   */
-  public static SkylarkProviderIdentifier forKey(ClassObjectConstructor.Key key) {
+  /** Creates an id for a declared provider with a given key ({@see SkylarkProvider}). */
+  public static SkylarkProviderIdentifier forKey(Provider.Key key) {
     return new SkylarkProviderIdentifier(key);
   }
 
@@ -49,7 +45,7 @@
     this.key = null;
   }
 
-  private SkylarkProviderIdentifier(ClassObjectConstructor.Key key) {
+  private SkylarkProviderIdentifier(Provider.Key key) {
     this.legacyId = null;
     this.key = key;
   }
@@ -70,10 +66,8 @@
     return legacyId;
   }
 
-  /**
-   * Returns a key identifying the declared provider (only for non-legacy providers).
-   */
-  public ClassObjectConstructor.Key getKey() {
+  /** Returns a key identifying the declared provider (only for non-legacy providers). */
+  public Provider.Key getKey() {
     Preconditions.checkState(!isLegacy(), "Check !isLegacy() first");
     return key;
   }
diff --git a/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactory.java b/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactory.java
index ccb81e1..292ce4d 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactory.java
@@ -528,8 +528,7 @@
     }
 
     builder.put("bazel_version", version);
-    return NativeClassObjectConstructor.STRUCT.create(
-        builder.build(), "no native function or rule '%s'");
+    return NativeProvider.STRUCT.create(builder.build(), "no native function or rule '%s'");
   }
 
   static ClassObject newNativeModule(RuleClassProvider ruleClassProvider, String version) {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/AliasConfiguredTarget.java b/src/main/java/com/google/devtools/build/lib/rules/AliasConfiguredTarget.java
index 1dc878f..d6bc200 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/AliasConfiguredTarget.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/AliasConfiguredTarget.java
@@ -24,8 +24,8 @@
 import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
 import com.google.devtools.build.lib.events.Location;
-import com.google.devtools.build.lib.packages.ClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.Provider;
 import com.google.devtools.build.lib.packages.Target;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
 import com.google.devtools.build.lib.syntax.ClassObject;
@@ -79,7 +79,7 @@
 
   @Nullable
   @Override
-  public SkylarkClassObject get(ClassObjectConstructor.Key providerKey) {
+  public Info get(Provider.Key providerKey) {
     return actual.get(providerKey);
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/rules/MakeVariableProvider.java b/src/main/java/com/google/devtools/build/lib/rules/MakeVariableProvider.java
index 2b700f5..f92946e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/MakeVariableProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/MakeVariableProvider.java
@@ -16,20 +16,19 @@
 
 import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
 
 /** Provides access to make variables from the current fragments. */
 @SkylarkModule(name = "MakeVariables", doc = "Make variables exposed by the current target.")
 @Immutable
-public final class MakeVariableProvider extends SkylarkClassObject {
+public final class MakeVariableProvider extends Info {
   public static final String SKYLARK_NAME = "MakeVariableInfo";
 
-  public static final NativeClassObjectConstructor<MakeVariableProvider> SKYLARK_CONSTRUCTOR =
-      new NativeClassObjectConstructor<MakeVariableProvider>(
-          MakeVariableProvider.class, SKYLARK_NAME) {};
+  public static final NativeProvider<MakeVariableProvider> SKYLARK_CONSTRUCTOR =
+      new NativeProvider<MakeVariableProvider>(MakeVariableProvider.class, SKYLARK_NAME) {};
 
   private final ImmutableMap<String, String> makeVariables;
 
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkAttr.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkAttr.java
index c8b1368..1951610 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkAttr.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkAttr.java
@@ -27,7 +27,7 @@
 import com.google.devtools.build.lib.packages.Attribute.SplitTransition;
 import com.google.devtools.build.lib.packages.AttributeValueSource;
 import com.google.devtools.build.lib.packages.BuildType;
-import com.google.devtools.build.lib.packages.ClassObjectConstructor;
+import com.google.devtools.build.lib.packages.Provider;
 import com.google.devtools.build.lib.packages.SkylarkAspect;
 import com.google.devtools.build.lib.packages.SkylarkProviderIdentifier;
 import com.google.devtools.build.lib.skylarkinterface.Param;
@@ -347,7 +347,7 @@
    * a legacy provider name.
    */
   static boolean isProvider(Object o) {
-    return o instanceof String || o instanceof ClassObjectConstructor;
+    return o instanceof String || o instanceof Provider;
   }
 
   /**
@@ -361,8 +361,8 @@
     for (Object obj : list) {
       if (obj instanceof String) {
         result.add(SkylarkProviderIdentifier.forLegacy((String) obj));
-      } else if (obj instanceof ClassObjectConstructor) {
-        ClassObjectConstructor constructor = (ClassObjectConstructor) obj;
+      } else if (obj instanceof Provider) {
+        Provider constructor = (Provider) obj;
         if (!constructor.isExported()) {
           throw new EvalException(location,
               "Providers should be top-level values in extension files that define them.");
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java
index a2cfcb2..b71db3b 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java
@@ -51,14 +51,15 @@
 import com.google.devtools.build.lib.packages.Attribute;
 import com.google.devtools.build.lib.packages.AttributeMap;
 import com.google.devtools.build.lib.packages.AttributeValueSource;
-import com.google.devtools.build.lib.packages.ClassObjectConstructor;
 import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.SkylarkImplicitOutputsFunctionWithCallback;
 import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.SkylarkImplicitOutputsFunctionWithMap;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 import com.google.devtools.build.lib.packages.Package.NameConflictException;
 import com.google.devtools.build.lib.packages.PackageFactory;
 import com.google.devtools.build.lib.packages.PackageFactory.PackageContext;
 import com.google.devtools.build.lib.packages.PredicateWithMessage;
+import com.google.devtools.build.lib.packages.Provider;
 import com.google.devtools.build.lib.packages.RuleClass;
 import com.google.devtools.build.lib.packages.RuleClass.Builder;
 import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType;
@@ -66,9 +67,8 @@
 import com.google.devtools.build.lib.packages.RuleFactory.BuildLangTypedAttributeValuesMap;
 import com.google.devtools.build.lib.packages.RuleFactory.InvalidRuleException;
 import com.google.devtools.build.lib.packages.SkylarkAspect;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
-import com.google.devtools.build.lib.packages.SkylarkClassObjectConstructor;
 import com.google.devtools.build.lib.packages.SkylarkExportable;
+import com.google.devtools.build.lib.packages.SkylarkProvider;
 import com.google.devtools.build.lib.packages.TargetUtils;
 import com.google.devtools.build.lib.packages.TestSize;
 import com.google.devtools.build.lib.rules.SkylarkAttr.Descriptor;
@@ -183,7 +183,7 @@
 
   @SkylarkSignature(
     name = "struct",
-    returnType = SkylarkClassObject.class,
+    returnType = Info.class,
     doc =
         "Creates an immutable struct using the keyword arguments as attributes. It is used to "
             + "group multiple values together. Example:<br>"
@@ -192,11 +192,11 @@
     extraKeywords = @Param(name = "kwargs", doc = "the struct attributes."),
     useLocation = true
   )
-  private static final ClassObjectConstructor struct = NativeClassObjectConstructor.STRUCT;
+  private static final Provider struct = NativeProvider.STRUCT;
 
   @SkylarkSignature(
     name = "DefaultInfo",
-    returnType = ClassObjectConstructor.class,
+    returnType = Provider.class,
     doc =
         "A provider that is provided by every rule, even if it is not returned explicitly. "
             + "A <code>DefaultInfo</code> accepts the following parameters:"
@@ -215,11 +215,11 @@
             + "<li><code>default_runfiles</code></li>"
             + "</ul>"
   )
-  private static final ClassObjectConstructor defaultInfo = DefaultProvider.SKYLARK_CONSTRUCTOR;
+  private static final Provider defaultInfo = DefaultProvider.SKYLARK_CONSTRUCTOR;
 
   @SkylarkSignature(
     name = "OutputGroupInfo",
-    returnType = ClassObjectConstructor.class,
+    returnType = Provider.class,
     doc =
         "Provides information about output groups the rule provides.<br>"
             + "Instantiate this provider with <br>"
@@ -227,31 +227,33 @@
             + "OutputGroupInfo(group1 = &lt;files&gt;, group2 = &lt;files&gt;...)</pre>"
             + "See <a href=\"../rules.html#output-groups\">Output Groups</a> for more information"
   )
-  private static final ClassObjectConstructor outputGroupInfo =
-      OutputGroupProvider.SKYLARK_CONSTRUCTOR;
+  private static final Provider outputGroupInfo = OutputGroupProvider.SKYLARK_CONSTRUCTOR;
 
   // TODO(bazel-team): Move to a "testing" namespace module. Normally we'd pass an objectType
   // to @SkylarkSignature to do this, but that doesn't work here because we're exposing an already-
   // configured BaseFunction, rather than defining a new BuiltinFunction. This should wait for
   // better support from the Skylark/Java interface, or perhaps support for first-class modules.
-  @SkylarkSignature(name = "Actions", returnType = SkylarkClassObjectConstructor.class, doc =
-      "<i>(Note: This is a provider type. Don't instantiate it yourself; use it to retrieve a "
-          + "provider object from a <a href=\"Target.html\">Target</a>.)</i>"
-          + "<br/><br/>"
-          + "Provides access to the <a href=\"Action.html\">actions</a> generated by a rule. There "
-          + "is one field, <code>by_file</code>, which is a dictionary from an output of the rule "
-          + "to its corresponding generating action. "
-          + "<br/><br/>"
-          + "This is designed for testing rules, and should not be accessed outside of test logic. "
-          + "This provider is only available for targets generated by rules that have "
-          + "<a href=\"globals.html#rule._skylark_testable\">_skylark_testable</a> set to "
-          + "<code>True</code>."
+  @SkylarkSignature(
+    name = "Actions",
+    returnType = SkylarkProvider.class,
+    doc =
+        "<i>(Note: This is a provider type. Don't instantiate it yourself; use it to retrieve a "
+            + "provider object from a <a href=\"Target.html\">Target</a>.)</i>"
+            + "<br/><br/>"
+            + "Provides access to the <a href=\"Action.html\">actions</a> generated by a rule. "
+            + "There is one field, <code>by_file</code>, which is a dictionary from an output "
+            + "of the rule to its corresponding generating action. "
+            + "<br/><br/>"
+            + "This is designed for testing rules, and should not be accessed outside "
+            + "of test logic. This provider is only available for targets generated by rules"
+            + " that have <a href=\"globals.html#rule._skylark_testable\">_skylark_testable</a> "
+            + "set to <code>True</code>."
   )
-  private static final ClassObjectConstructor actions = ActionsProvider.SKYLARK_CONSTRUCTOR;
+  private static final Provider actions = ActionsProvider.SKYLARK_CONSTRUCTOR;
 
   @SkylarkSignature(
     name = "provider",
-    returnType = ClassObjectConstructor.class,
+    returnType = Provider.class,
     doc =
         "Creates a declared provider 'constructor'. The return value of this "
             + "function can be used to create \"struct-like\" values. Example:<br>"
@@ -271,8 +273,8 @@
   )
   private static final BuiltinFunction provider =
       new BuiltinFunction("provider") {
-        public ClassObjectConstructor invoke(String doc, Location location) {
-          return new SkylarkClassObjectConstructor(
+        public Provider invoke(String doc, Location location) {
+          return new SkylarkProvider(
               "<no name>", // name is set on export.
               location);
         }
@@ -854,8 +856,7 @@
    * RuleFunction}s etc.
    */
   private static final ImmutableList<Class<? extends SkylarkExportable>> EXPORTABLES =
-      ImmutableList.of(
-          SkylarkClassObjectConstructor.class, SkylarkAspect.class, RuleFunction.class);
+      ImmutableList.of(SkylarkProvider.class, SkylarkAspect.class, RuleFunction.class);
 
   @SkylarkSignature(
     name = "Label",
@@ -963,17 +964,17 @@
             + "# key {\n#   inner_key: 1\n# }\n# key {\n#   inner_key: 2\n# }\n\n"
             + "struct(key=struct(inner_key=struct(inner_inner_key='text'))).to_proto()\n"
             + "# key {\n#    inner_key {\n#     inner_inner_key: \"text\"\n#   }\n# }\n</pre>",
-    objectType = SkylarkClassObject.class,
+    objectType = Info.class,
     returnType = String.class,
     parameters = {
       // TODO(bazel-team): shouldn't we accept any ClassObject?
-      @Param(name = "self", type = SkylarkClassObject.class, doc = "this struct.")
+      @Param(name = "self", type = Info.class, doc = "this struct.")
     },
     useLocation = true
   )
   private static final BuiltinFunction toProto =
       new BuiltinFunction("to_proto") {
-        public String invoke(SkylarkClassObject self, Location loc) throws EvalException {
+        public String invoke(Info self, Location loc) throws EvalException {
           StringBuilder sb = new StringBuilder();
           printProtoTextMessage(self, sb, 0, loc);
           return sb.toString();
@@ -1069,17 +1070,17 @@
             + "# {\"key\":[{\"inner_key\":1},{\"inner_key\":2}]}\n\n"
             + "struct(key=struct(inner_key=struct(inner_inner_key='text'))).to_json()\n"
             + "# {\"key\":{\"inner_key\":{\"inner_inner_key\":\"text\"}}}\n</pre>",
-    objectType = SkylarkClassObject.class,
+    objectType = Info.class,
     returnType = String.class,
     parameters = {
       // TODO(bazel-team): shouldn't we accept any ClassObject?
-      @Param(name = "self", type = SkylarkClassObject.class, doc = "this struct.")
+      @Param(name = "self", type = Info.class, doc = "this struct.")
     },
     useLocation = true
   )
   private static final BuiltinFunction toJson =
       new BuiltinFunction("to_json") {
-        public String invoke(SkylarkClassObject self, Location loc) throws EvalException {
+        public String invoke(Info self, Location loc) throws EvalException {
           StringBuilder sb = new StringBuilder();
           printJson(self, sb, loc, "struct field", null);
           return sb.toString();
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..834cf87 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
@@ -29,9 +29,9 @@
 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;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 import com.google.devtools.build.lib.packages.Rule;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
 import com.google.devtools.build.lib.packages.TargetUtils;
 import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector;
 import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector.InstrumentationSpec;
@@ -103,7 +103,7 @@
 
       if (ruleContext.hasErrors()) {
         return null;
-      } else if (!(target instanceof SkylarkClassObject)
+      } else if (!(target instanceof Info)
           && target != Runtime.NONE
           && !(target instanceof Iterable)) {
         ruleContext.ruleError(
@@ -187,7 +187,7 @@
   }
 
   private static void addInstrumentedFiles(
-      SkylarkClassObject insStruct, RuleContext ruleContext, RuleConfiguredTargetBuilder builder)
+      Info insStruct, RuleContext ruleContext, RuleConfiguredTargetBuilder builder)
       throws EvalException {
     Location insLoc = insStruct.getCreationLoc();
     FileTypeSet fileTypeSet = FileTypeSet.ANY_FILE;
@@ -269,25 +269,25 @@
       RuleContext ruleContext, RuleConfiguredTargetBuilder builder, Object target, Location loc)
       throws EvalException {
 
-    SkylarkClassObject oldStyleProviders = NativeClassObjectConstructor.STRUCT.create(loc);
-    ArrayList<SkylarkClassObject> declaredProviders = new ArrayList<>();
+    Info oldStyleProviders = NativeProvider.STRUCT.create(loc);
+    ArrayList<Info> declaredProviders = new ArrayList<>();
 
-    if (target instanceof SkylarkClassObject) {
+    if (target instanceof Info) {
       // Either an old-style struct or a single declared provider (not in a list)
-      SkylarkClassObject struct = (SkylarkClassObject) target;
+      Info struct = (Info) target;
       // Use the creation location of this struct as a better reference in error messages
       loc = struct.getCreationLoc();
-      if (struct.getConstructor().getKey().equals(NativeClassObjectConstructor.STRUCT.getKey())) {
+      if (struct.getProvider().getKey().equals(NativeProvider.STRUCT.getKey())) {
         // Old-style struct, but it may contain declared providers
         oldStyleProviders = struct;
 
         if (struct.hasKey("providers")) {
           Iterable iterable = cast("providers", struct, Iterable.class, loc);
           for (Object o : iterable) {
-            SkylarkClassObject declaredProvider =
+            Info declaredProvider =
                 SkylarkType.cast(
                     o,
-                    SkylarkClassObject.class,
+                    Info.class,
                     loc,
                     "The value of 'providers' should be a sequence of declared providers");
             declaredProviders.add(declaredProvider);
@@ -300,10 +300,10 @@
     } else if (target instanceof Iterable) {
       // Sequence of declared providers
       for (Object o : (Iterable) target) {
-        SkylarkClassObject declaredProvider =
+        Info declaredProvider =
             SkylarkType.cast(
                 o,
-                SkylarkClassObject.class,
+                Info.class,
                 loc,
                 "A return value of a rule implementation function should be "
                     + "a sequence of declared providers");
@@ -313,9 +313,9 @@
 
     boolean defaultProviderProvidedExplicitly = false;
 
-    for (SkylarkClassObject declaredProvider : declaredProviders) {
+    for (Info declaredProvider : declaredProviders) {
       if (declaredProvider
-          .getConstructor()
+          .getProvider()
           .getKey()
           .equals(DefaultProvider.SKYLARK_CONSTRUCTOR.getKey())) {
         parseDefaultProviderKeys(declaredProvider, ruleContext, builder);
@@ -346,11 +346,10 @@
       } else if (key.equals("output_groups")) {
         addOutputGroups(oldStyleProviders.getValue(key), loc, builder);
       } else if (key.equals("instrumented_files")) {
-        SkylarkClassObject insStruct =
-            cast("instrumented_files", oldStyleProviders, SkylarkClassObject.class, loc);
+        Info insStruct = cast("instrumented_files", oldStyleProviders, Info.class, loc);
         addInstrumentedFiles(insStruct, ruleContext, builder);
       } else if (isNativeDeclaredProviderWithLegacySkylarkName(oldStyleProviders.getValue(key))) {
-        builder.addNativeDeclaredProvider((SkylarkClassObject) oldStyleProviders.getValue(key));
+        builder.addNativeDeclaredProvider((Info) oldStyleProviders.getValue(key));
       } else if (!key.equals("providers")) {
         // We handled providers already.
         builder.addSkylarkTransitiveInfo(key, oldStyleProviders.getValue(key), loc);
@@ -359,11 +358,10 @@
   }
 
   private static boolean isNativeDeclaredProviderWithLegacySkylarkName(Object value) {
-    if (!(value instanceof SkylarkClassObject)) {
+    if (!(value instanceof Info)) {
       return false;
     }
-    return ((SkylarkClassObject) value).getConstructor()
-        instanceof NativeClassObjectConstructor.WithLegacySkylarkName;
+    return ((Info) value).getProvider() instanceof NativeProvider.WithLegacySkylarkName;
   }
 
   /**
@@ -371,7 +369,7 @@
    * throws an {@link EvalException} if there are unknown keys.
    */
   private static void parseDefaultProviderKeys(
-      SkylarkClassObject provider, RuleContext ruleContext, RuleConfiguredTargetBuilder builder)
+      Info provider, RuleContext ruleContext, RuleConfiguredTargetBuilder builder)
       throws EvalException {
     SkylarkNestedSet files = null;
     Runfiles statelessRunfiles = null;
@@ -398,7 +396,7 @@
       } else if (key.equals("executable")) {
         executable = cast("executable", provider, Artifact.class, loc);
       } else if (provider
-          .getConstructor()
+          .getProvider()
           .getKey()
           .equals(DefaultProvider.SKYLARK_CONSTRUCTOR.getKey())) {
         // Custom keys are not allowed for default providers
@@ -473,8 +471,8 @@
     }
 
     if (ruleContext.getRule().getRuleClassObject().isSkylarkTestable()) {
-      SkylarkClassObject actions = ActionsProvider.create(
-          ruleContext.getAnalysisEnvironment().getRegisteredActions());
+      Info actions =
+          ActionsProvider.create(ruleContext.getAnalysisEnvironment().getRegisteredActions());
       builder.addSkylarkDeclaredProvider(actions, loc);
     }
   }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java
index 7590bc3..51dbdf0 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java
@@ -43,14 +43,14 @@
 import com.google.devtools.build.lib.packages.Attribute;
 import com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition;
 import com.google.devtools.build.lib.packages.BuildType;
-import com.google.devtools.build.lib.packages.ClassObjectConstructor;
 import com.google.devtools.build.lib.packages.ImplicitOutputsFunction;
 import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.SkylarkImplicitOutputsFunction;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 import com.google.devtools.build.lib.packages.OutputFile;
 import com.google.devtools.build.lib.packages.Package;
+import com.google.devtools.build.lib.packages.Provider;
 import com.google.devtools.build.lib.packages.RawAttributeMapper;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
 import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector;
 import com.google.devtools.build.lib.rules.test.InstrumentedFilesProvider;
 import com.google.devtools.build.lib.shell.ShellUtils;
@@ -185,11 +185,11 @@
   private SkylarkDict<String, String> makeVariables;
   private SkylarkRuleAttributesCollection attributesCollection;
   private SkylarkRuleAttributesCollection ruleAttributesCollection;
-  private SkylarkClassObject splitAttributes;
+  private Info splitAttributes;
 
   // TODO(bazel-team): we only need this because of the css_binary rule.
   private ImmutableMap<Artifact, Label> artifactsLabelMap;
-  private SkylarkClassObject outputsObject;
+  private Info outputsObject;
 
   /**
    * Creates a new SkylarkRuleContext using ruleContext.
@@ -262,7 +262,7 @@
 
       this.artifactsLabelMap = artifactLabelMapBuilder.build();
       this.outputsObject =
-          NativeClassObjectConstructor.STRUCT.create(
+          NativeProvider.STRUCT.create(
               outputsBuilder,
               "No attribute '%s' in outputs. Make sure you declared a rule output with this name.");
 
@@ -442,7 +442,7 @@
         executableRunfilesbuilder.build());
   }
 
-  private static SkylarkClassObject buildSplitAttributeInfo(
+  private static Info buildSplitAttributeInfo(
       Collection<Attribute> attributes, RuleContext ruleContext) {
 
     ImmutableMap.Builder<String, Object> splitAttrInfos = ImmutableMap.builder();
@@ -482,10 +482,10 @@
       }
     }
 
-    return NativeClassObjectConstructor.STRUCT.create(
+    return NativeProvider.STRUCT.create(
         splitAttrInfos.build(),
         "No attribute '%s' in split_attr. Make sure that this attribute is defined with a "
-          + "split configuration.");
+            + "split configuration.");
   }
 
   @SkylarkModule(
@@ -495,10 +495,10 @@
   )
   private static class SkylarkRuleAttributesCollection implements SkylarkValue {
     private final SkylarkRuleContext skylarkRuleContext;
-    private final SkylarkClassObject attrObject;
-    private final SkylarkClassObject executableObject;
-    private final SkylarkClassObject fileObject;
-    private final SkylarkClassObject filesObject;
+    private final Info attrObject;
+    private final Info executableObject;
+    private final Info fileObject;
+    private final Info filesObject;
     private final ImmutableMap<Artifact, FilesToRunProvider> executableRunfilesMap;
     private final String ruleClassName;
 
@@ -512,21 +512,21 @@
       this.skylarkRuleContext = skylarkRuleContext;
       this.ruleClassName = ruleClassName;
       attrObject =
-          NativeClassObjectConstructor.STRUCT.create(
+          NativeProvider.STRUCT.create(
               attrs,
               "No attribute '%s' in attr. Make sure you declared a rule attribute with this name.");
       executableObject =
-          NativeClassObjectConstructor.STRUCT.create(
+          NativeProvider.STRUCT.create(
               executables,
               "No attribute '%s' in executable. Make sure there is a label type attribute marked "
                   + "as 'executable' with this name");
       fileObject =
-          NativeClassObjectConstructor.STRUCT.create(
+          NativeProvider.STRUCT.create(
               singleFiles,
               "No attribute '%s' in file. Make sure there is a label type attribute marked "
                   + "as 'single_file' with this name");
       filesObject =
-          NativeClassObjectConstructor.STRUCT.create(
+          NativeProvider.STRUCT.create(
               files,
               "No attribute '%s' in files. Make sure there is a label or label_list type attribute "
                   + "with this name");
@@ -538,25 +538,25 @@
     }
 
     @SkylarkCallable(name = "attr", structField = true, doc = ATTR_DOC)
-    public SkylarkClassObject getAttr() throws EvalException {
+    public Info getAttr() throws EvalException {
       checkMutable("attr");
       return attrObject;
     }
 
     @SkylarkCallable(name = "executable", structField = true, doc = EXECUTABLE_DOC)
-    public SkylarkClassObject getExecutable() throws EvalException {
+    public Info getExecutable() throws EvalException {
       checkMutable("executable");
       return executableObject;
     }
 
     @SkylarkCallable(name = "file", structField = true, doc = FILE_DOC)
-    public SkylarkClassObject getFile() throws EvalException {
+    public Info getFile() throws EvalException {
       checkMutable("file");
       return fileObject;
     }
 
     @SkylarkCallable(name = "files", structField = true, doc = FILES_DOC)
-    public SkylarkClassObject getFiles() throws EvalException {
+    public Info getFiles() throws EvalException {
       checkMutable("files");
       return filesObject;
     }
@@ -625,8 +625,9 @@
   @SkylarkCallable(
     name = "default_provider",
     structField = true,
-    doc = "Deprecated. Use <a href=\"globals.html#DefaultInfo\">DefaultInfo</a> instead.")
-  public static ClassObjectConstructor getDefaultProvider() {
+    doc = "Deprecated. Use <a href=\"globals.html#DefaultInfo\">DefaultInfo</a> instead."
+  )
+  public static Provider getDefaultProvider() {
     return DefaultProvider.SKYLARK_CONSTRUCTOR;
   }
 
@@ -660,13 +661,13 @@
   }
 
   @SkylarkCallable(name = "attr", structField = true, doc = ATTR_DOC)
-  public SkylarkClassObject getAttr() throws EvalException {
+  public Info getAttr() throws EvalException {
     checkMutable("attr");
     return attributesCollection.getAttr();
   }
 
   @SkylarkCallable(name = "split_attr", structField = true, doc = SPLIT_ATTR_DOC)
-  public SkylarkClassObject getSplitAttr() throws EvalException {
+  public Info getSplitAttr() throws EvalException {
     checkMutable("split_attr");
     if (splitAttributes == null) {
       throw new EvalException(
@@ -675,29 +676,23 @@
     return splitAttributes;
   }
 
-  /**
-   * <p>See {@link RuleContext#getExecutablePrerequisite(String, Mode)}.
-   */
+  /** See {@link RuleContext#getExecutablePrerequisite(String, Mode)}. */
   @SkylarkCallable(name = "executable", structField = true, doc = EXECUTABLE_DOC)
-  public SkylarkClassObject getExecutable() throws EvalException {
+  public Info getExecutable() throws EvalException {
     checkMutable("executable");
     return attributesCollection.getExecutable();
   }
 
-  /**
-   * See {@link RuleContext#getPrerequisiteArtifact(String, Mode)}.
-   */
+  /** See {@link RuleContext#getPrerequisiteArtifact(String, Mode)}. */
   @SkylarkCallable(name = "file", structField = true, doc = FILE_DOC)
-  public SkylarkClassObject getFile() throws EvalException {
+  public Info getFile() throws EvalException {
     checkMutable("file");
     return attributesCollection.getFile();
   }
 
-  /**
-   * See {@link RuleContext#getPrerequisiteArtifacts(String, Mode)}.
-   */
+  /** See {@link RuleContext#getPrerequisiteArtifacts(String, Mode)}. */
   @SkylarkCallable(name = "files", structField = true, doc = FILES_DOC)
-  public SkylarkClassObject getFiles() throws EvalException {
+  public Info getFiles() throws EvalException {
     checkMutable("files");
     return attributesCollection.getFiles();
   }
@@ -798,7 +793,7 @@
   }
 
   @SkylarkCallable(structField = true, doc = OUTPUTS_DOC)
-  public SkylarkClassObject outputs() throws EvalException {
+  public Info outputs() throws EvalException {
     checkMutable("outputs");
     if (outputsObject == null) {
       throw new EvalException(Location.BUILTIN, "'outputs' is not defined");
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java
index 2a52489..85788a8 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java
@@ -38,10 +38,10 @@
 import com.google.devtools.build.lib.packages.AggregatingAttributeMapper;
 import com.google.devtools.build.lib.packages.AttributeMap;
 import com.google.devtools.build.lib.packages.BuildType;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 import com.google.devtools.build.lib.packages.Rule;
 import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
 import com.google.devtools.build.lib.packages.TriState;
 import com.google.devtools.build.lib.rules.android.AndroidConfiguration.AndroidAaptVersion;
 import com.google.devtools.build.lib.rules.android.ResourceContainer.ResourceType;
@@ -101,8 +101,8 @@
     return builder.build();
   }
 
-  public static final <T extends SkylarkClassObject> Iterable<T> getTransitivePrerequisites(
-      RuleContext ruleContext, Mode mode, NativeClassObjectConstructor<T> key) {
+  public static final <T extends Info> Iterable<T> getTransitivePrerequisites(
+      RuleContext ruleContext, Mode mode, NativeProvider<T> key) {
     IterablesChain.Builder<T> builder = IterablesChain.builder();
     AttributeMap attributes = ruleContext.attributes();
     for (String attr : TRANSITIVE_ATTRIBUTES) {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDeviceScriptFixtureInfoProvider.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDeviceScriptFixtureInfoProvider.java
index 901b2e2..27689da 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDeviceScriptFixtureInfoProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDeviceScriptFixtureInfoProvider.java
@@ -17,21 +17,20 @@
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 
 /**
  * Information about an {@code android_device_script_fixture} to run as part of an {@code
  * android_instrumentation_test}.
  */
 @Immutable
-public class AndroidDeviceScriptFixtureInfoProvider extends SkylarkClassObject {
+public class AndroidDeviceScriptFixtureInfoProvider extends Info {
 
   private static final String SKYLARK_NAME = "DeviceScriptFixtureInfo";
-  public static final NativeClassObjectConstructor<AndroidDeviceScriptFixtureInfoProvider>
-      SKYLARK_CONSTRUCTOR =
-          new NativeClassObjectConstructor<AndroidDeviceScriptFixtureInfoProvider>(
-              AndroidDeviceScriptFixtureInfoProvider.class, SKYLARK_NAME) {};
+  public static final NativeProvider<AndroidDeviceScriptFixtureInfoProvider> SKYLARK_CONSTRUCTOR =
+      new NativeProvider<AndroidDeviceScriptFixtureInfoProvider>(
+          AndroidDeviceScriptFixtureInfoProvider.class, SKYLARK_NAME) {};
 
   private final Artifact fixtureScript;
   private final NestedSet<Artifact> supportApks;
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidHostServiceFixtureInfoProvider.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidHostServiceFixtureInfoProvider.java
index 73ac965..e37a693 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidHostServiceFixtureInfoProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidHostServiceFixtureInfoProvider.java
@@ -18,20 +18,20 @@
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 
 /**
  * Information about an {@code android_host_service_fixture} to run as part of an {@code
  * android_instrumentation_test}.
  */
 @Immutable
-public class AndroidHostServiceFixtureInfoProvider extends SkylarkClassObject {
+public class AndroidHostServiceFixtureInfoProvider extends Info {
 
   private static final String SKYLARK_NAME = "HostServiceFixtureInfo";
-  static final NativeClassObjectConstructor<AndroidHostServiceFixtureInfoProvider>
+  static final NativeProvider<AndroidHostServiceFixtureInfoProvider>
       ANDROID_HOST_SERVICE_FIXTURE_INFO =
-          new NativeClassObjectConstructor<AndroidHostServiceFixtureInfoProvider>(
+          new NativeProvider<AndroidHostServiceFixtureInfoProvider>(
               AndroidHostServiceFixtureInfoProvider.class, SKYLARK_NAME) {};
 
   private final Artifact executable;
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidInstrumentationInfoProvider.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidInstrumentationInfoProvider.java
index 292b2f0..530096e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidInstrumentationInfoProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidInstrumentationInfoProvider.java
@@ -16,21 +16,20 @@
 import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 
 /**
  * A provider for targets that create Android instrumentations. Consumed by {@link
  * AndroidInstrumentationTest}.
  */
 @Immutable
-public class AndroidInstrumentationInfoProvider extends SkylarkClassObject {
+public class AndroidInstrumentationInfoProvider extends Info {
 
   private static final String SKYLARK_NAME = "AndroidInstrumentationInfo";
-  static final NativeClassObjectConstructor<AndroidInstrumentationInfoProvider>
-      ANDROID_INSTRUMENTATION_INFO =
-          new NativeClassObjectConstructor<AndroidInstrumentationInfoProvider>(
-              AndroidInstrumentationInfoProvider.class, SKYLARK_NAME) {};
+  static final NativeProvider<AndroidInstrumentationInfoProvider> ANDROID_INSTRUMENTATION_INFO =
+      new NativeProvider<AndroidInstrumentationInfoProvider>(
+          AndroidInstrumentationInfoProvider.class, SKYLARK_NAME) {};
 
   private final Artifact targetApk;
   private final Artifact instrumentationApk;
diff --git a/src/main/java/com/google/devtools/build/lib/rules/apple/ApplePlatform.java b/src/main/java/com/google/devtools/build/lib/rules/apple/ApplePlatform.java
index cd22873..6be2024 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/apple/ApplePlatform.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/apple/ApplePlatform.java
@@ -16,9 +16,9 @@
 
 import com.google.common.collect.ImmutableSet;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-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.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
+import com.google.devtools.build.lib.packages.Provider;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
@@ -212,15 +212,13 @@
   }
 
   /** Returns a Skylark struct that contains the instances of this enum. */
-  public static SkylarkClassObject getSkylarkStruct() {
-    ClassObjectConstructor constructor =
-        new NativeClassObjectConstructor<SkylarkClassObject>(
-            SkylarkClassObject.class, "platforms") {};
+  public static Info getSkylarkStruct() {
+    Provider constructor = new NativeProvider<Info>(Info.class, "platforms") {};
     HashMap<String, Object> fields = new HashMap<>();
     for (ApplePlatform type : values()) {
       fields.put(type.skylarkKey, type);
     }
-    return new SkylarkClassObject(constructor, fields);
+    return new Info(constructor, fields);
   }
 
   @Override
@@ -288,15 +286,13 @@
     }
 
     /** Returns a Skylark struct that contains the instances of this enum. */
-    public static SkylarkClassObject getSkylarkStruct() {
-      ClassObjectConstructor constructor =
-          new NativeClassObjectConstructor<SkylarkClassObject>(
-              SkylarkClassObject.class, "platform_types") {};
+    public static Info getSkylarkStruct() {
+      Provider constructor = new NativeProvider<Info>(Info.class, "platform_types") {};
       HashMap<String, Object> fields = new HashMap<>();
       for (PlatformType type : values()) {
         fields.put(type.skylarkKey, type);
       }
-      return new SkylarkClassObject(constructor, fields);
+      return new Info(constructor, fields);
     }
 
     @Override
diff --git a/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeVersionProperties.java b/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeVersionProperties.java
index da22fa5..a75fae2 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeVersionProperties.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeVersionProperties.java
@@ -19,22 +19,21 @@
 import com.google.common.base.Strings;
 import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 import java.util.Map;
 import javax.annotation.Nullable;
 
 /** A tuple containing information about a version of xcode and its properties. */
 @Immutable
-public class XcodeVersionProperties extends SkylarkClassObject {
+public class XcodeVersionProperties extends Info {
 
   /** Skylark name for the XcodeVersionProperties provider. */
   public static final String SKYLARK_NAME = "XcodeProperties";
 
   /** Skylark constructor and identifier for XcodeVersionProperties provider. */
-  public static final NativeClassObjectConstructor<XcodeVersionProperties> SKYLARK_CONSTRUCTOR =
-      new NativeClassObjectConstructor<XcodeVersionProperties>(
-          XcodeVersionProperties.class, SKYLARK_NAME) {};
+  public static final NativeProvider<XcodeVersionProperties> SKYLARK_CONSTRUCTOR =
+      new NativeProvider<XcodeVersionProperties>(XcodeVersionProperties.class, SKYLARK_NAME) {};
 
   @VisibleForTesting public static final String DEFAULT_IOS_SDK_VERSION = "8.4";
   @VisibleForTesting public static final String DEFAULT_WATCHOS_SDK_VERSION = "2.0";
diff --git a/src/main/java/com/google/devtools/build/lib/rules/config/ConfigFeatureFlagProvider.java b/src/main/java/com/google/devtools/build/lib/rules/config/ConfigFeatureFlagProvider.java
index 0481714..8e5f0d5 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/config/ConfigFeatureFlagProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/config/ConfigFeatureFlagProvider.java
@@ -18,8 +18,8 @@
 import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 import com.google.devtools.build.lib.packages.SkylarkProviderIdentifier;
 import com.google.devtools.build.lib.skylarkinterface.Param;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
@@ -31,14 +31,14 @@
   doc = "A provider used to access information about config_feature_flag rules."
 )
 @Immutable
-public class ConfigFeatureFlagProvider extends SkylarkClassObject {
+public class ConfigFeatureFlagProvider extends Info {
 
   /** Name used in Skylark for accessing ConfigFeatureFlagProvider. */
   static final String SKYLARK_NAME = "FeatureFlagInfo";
 
   /** Skylark constructor and identifier for ConfigFeatureFlagProvider. */
-  static final NativeClassObjectConstructor<ConfigFeatureFlagProvider> SKYLARK_CONSTRUCTOR =
-      new NativeClassObjectConstructor<ConfigFeatureFlagProvider>(
+  static final NativeProvider<ConfigFeatureFlagProvider> SKYLARK_CONSTRUCTOR =
+      new NativeProvider<ConfigFeatureFlagProvider>(
           ConfigFeatureFlagProvider.class, SKYLARK_NAME) {};
 
   private final String value;
@@ -87,7 +87,7 @@
   }
 
   // ConfigFeatureFlagProvider instances should all be unique, so we override the default
-  // equals and hashCode from SkylarkClassObject to ensure that. SCO's toString is fine, however.
+  // equals and hashCode from Info to ensure that. SCO's toString is fine, however.
   @Override
   public boolean equals(Object other) {
     return other == this;
diff --git a/src/main/java/com/google/devtools/build/lib/rules/config/ConfigSkylarkCommon.java b/src/main/java/com/google/devtools/build/lib/rules/config/ConfigSkylarkCommon.java
index f464a45..83df9ae 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/config/ConfigSkylarkCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/config/ConfigSkylarkCommon.java
@@ -14,7 +14,7 @@
 
 package com.google.devtools.build.lib.rules.config;
 
-import com.google.devtools.build.lib.packages.ClassObjectConstructor;
+import com.google.devtools.build.lib.packages.Provider;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
 
@@ -31,7 +31,7 @@
     doc = "The key used to retrieve the provider containing config_feature_flag's value.",
     structField = true
   )
-  public ClassObjectConstructor getConfigFeatureFlagProviderConstructor() {
+  public Provider getConfigFeatureFlagProviderConstructor() {
     return ConfigFeatureFlagProvider.SKYLARK_CONSTRUCTOR;
   }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkParamsProvider.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkParamsProvider.java
index cc6d68a..1331f7e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkParamsProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkParamsProvider.java
@@ -18,16 +18,15 @@
 import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 import com.google.devtools.build.lib.rules.cpp.CcLinkParamsStore.CcLinkParamsStoreImpl;
 
 /** A target that provides C linker parameters. */
 @Immutable
-public final class CcLinkParamsProvider extends SkylarkClassObject {
-  public static final NativeClassObjectConstructor<CcLinkParamsProvider> CC_LINK_PARAMS =
-      new NativeClassObjectConstructor<CcLinkParamsProvider>(
-          CcLinkParamsProvider.class, "link_params") {};
+public final class CcLinkParamsProvider extends Info {
+  public static final NativeProvider<CcLinkParamsProvider> CC_LINK_PARAMS =
+      new NativeProvider<CcLinkParamsProvider>(CcLinkParamsProvider.class, "link_params") {};
   public static final Function<TransitiveInfoCollection, CcLinkParamsStore> TO_LINK_PARAMS =
       input -> {
         // ... then try Skylark.
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProvider.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProvider.java
index 79bbd99..8eb12d6 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProvider.java
@@ -21,8 +21,8 @@
 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.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
 import com.google.devtools.build.lib.util.Pair;
@@ -31,20 +31,14 @@
 import java.util.Map;
 import javax.annotation.Nullable;
 
-/**
- * Information about a C++ compiler used by the <code>cc_*</code> rules.
- */
-@SkylarkModule(
-    name = "CcToolchainInfo",
-    doc = "Information about the C++ compiler being used."
-)
+/** Information about a C++ compiler used by the <code>cc_*</code> rules. */
+@SkylarkModule(name = "CcToolchainInfo", doc = "Information about the C++ compiler being used.")
 @Immutable
-public final class CcToolchainProvider extends SkylarkClassObject {
+public final class CcToolchainProvider extends Info {
   public static final String SKYLARK_NAME = "CcToolchainInfo";
 
-  public static final NativeClassObjectConstructor<CcToolchainProvider> SKYLARK_CONSTRUCTOR =
-      new NativeClassObjectConstructor<CcToolchainProvider>(
-          CcToolchainProvider.class, SKYLARK_NAME) {};
+  public static final NativeProvider<CcToolchainProvider> SKYLARK_CONSTRUCTOR =
+      new NativeProvider<CcToolchainProvider>(CcToolchainProvider.class, SKYLARK_NAME) {};
 
   /** An empty toolchain to be returned in the error case (instead of null). */
   public static final CcToolchainProvider EMPTY_TOOLCHAIN_IS_ERROR =
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java
index 51f9fd5..8448232 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java
@@ -40,8 +40,8 @@
 import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
 import com.google.devtools.build.lib.collect.nestedset.Order;
 import com.google.devtools.build.lib.packages.BuildType;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 import com.google.devtools.build.lib.packages.Target;
 import com.google.devtools.build.lib.packages.TargetUtils;
 import com.google.devtools.build.lib.rules.cpp.CppCompilationContext;
@@ -878,8 +878,7 @@
   }
 
   /** Gets all the deps that implement a particular provider. */
-  public final <P extends SkylarkClassObject> Iterable<P> getDependencies(
-      NativeClassObjectConstructor<P> provider) {
+  public final <P extends Info> Iterable<P> getDependencies(NativeProvider<P> provider) {
     return AnalysisUtils.getProviders(getDependencies(), provider);
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaProvider.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaProvider.java
index e691a4f..d701b37 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaProvider.java
@@ -24,8 +24,8 @@
 import com.google.devtools.build.lib.analysis.TransitiveInfoProviderMap;
 import com.google.devtools.build.lib.analysis.TransitiveInfoProviderMapBuilder;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
 import java.util.ArrayList;
 import java.util.LinkedList;
@@ -34,10 +34,10 @@
 
 /** A Skylark declared provider that encapsulates all providers that are needed by Java rules. */
 @Immutable
-public final class JavaProvider extends SkylarkClassObject {
+public final class JavaProvider extends Info {
 
-  public static final NativeClassObjectConstructor<JavaProvider> JAVA_PROVIDER =
-      new NativeClassObjectConstructor<JavaProvider>(JavaProvider.class, "java_common.provider") {};
+  public static final NativeProvider<JavaProvider> JAVA_PROVIDER =
+      new NativeProvider<JavaProvider>(JavaProvider.class, "java_common.provider") {};
 
   private static final ImmutableSet<Class<? extends TransitiveInfoProvider>> ALLOWED_PROVIDERS =
       ImmutableSet.of(
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeProvider.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeProvider.java
index 558ff04..e7f5708 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeProvider.java
@@ -18,24 +18,20 @@
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
 import com.google.devtools.build.lib.vfs.PathFragment;
 
 /** Information about the Java runtime used by the <code>java_*</code> rules. */
-@SkylarkModule(
-    name = "JavaRuntimeInfo",
-    doc = "Information about the Java runtime being used."
-)
+@SkylarkModule(name = "JavaRuntimeInfo", doc = "Information about the Java runtime being used.")
 @Immutable
-public class JavaRuntimeProvider extends SkylarkClassObject {
+public class JavaRuntimeProvider extends Info {
   public static final String SKYLARK_NAME = "JavaRuntimeInfo";
 
-  public static final NativeClassObjectConstructor<JavaRuntimeProvider> SKYLARK_CONSTRUCTOR =
-      new NativeClassObjectConstructor<JavaRuntimeProvider>(
-          JavaRuntimeProvider.class, SKYLARK_NAME) {};
+  public static final NativeProvider<JavaRuntimeProvider> SKYLARK_CONSTRUCTOR =
+      new NativeProvider<JavaRuntimeProvider>(JavaRuntimeProvider.class, SKYLARK_NAME) {};
 
   private final NestedSet<Artifact> javaBaseInputs;
   private final PathFragment javaHome;
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java
index 175d864..a532e61 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java
@@ -24,7 +24,7 @@
 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.packages.ClassObjectConstructor;
+import com.google.devtools.build.lib.packages.Provider;
 import com.google.devtools.build.lib.rules.SkylarkRuleContext;
 import com.google.devtools.build.lib.rules.java.proto.StrictDepsUtils;
 import com.google.devtools.build.lib.skylarkinterface.Param;
@@ -50,7 +50,7 @@
     structField = true,
     doc = "Returns the Java declared provider."
   )
-  public ClassObjectConstructor getJavaProvider() {
+  public Provider getJavaProvider() {
     return JavaProvider.JAVA_PROVIDER;
   }
 
@@ -454,12 +454,13 @@
   }
 
   @SkylarkCallable(
-      name = JavaRuntimeProvider.SKYLARK_NAME,
-      doc = "The key used to retrieve the provider that contains information about the Java "
-          + "runtime being used.",
-      structField = true
+    name = JavaRuntimeProvider.SKYLARK_NAME,
+    doc =
+        "The key used to retrieve the provider that contains information about the Java "
+            + "runtime being used.",
+    structField = true
   )
-  public static ClassObjectConstructor getJavaRuntimeProvider() {
+  public static Provider getJavaRuntimeProvider() {
     return JavaRuntimeProvider.SKYLARK_CONSTRUCTOR;
   }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleDebugOutputsProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleDebugOutputsProvider.java
index 650e1ee..0e55524 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleDebugOutputsProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleDebugOutputsProvider.java
@@ -17,8 +17,8 @@
 import com.google.common.collect.Maps;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 import java.util.HashMap;
 import java.util.Map.Entry;
 
@@ -37,7 +37,7 @@
  * <p>Example: { "arm64": { "bitcode_symbols": Artifact, "dsym_binary": Artifact } }
  */
 @Immutable
-public final class AppleDebugOutputsProvider extends SkylarkClassObject {
+public final class AppleDebugOutputsProvider extends Info {
 
   /** Expected types of debug outputs. */
   enum OutputType {
@@ -61,8 +61,8 @@
   public static final String SKYLARK_NAME = "AppleDebugOutputs";
 
   /** Skylark constructor and identifier for AppleDebugOutputsProvider. */
-  public static final NativeClassObjectConstructor<AppleDebugOutputsProvider> SKYLARK_CONSTRUCTOR =
-      new NativeClassObjectConstructor<AppleDebugOutputsProvider>(
+  public static final NativeProvider<AppleDebugOutputsProvider> SKYLARK_CONSTRUCTOR =
+      new NativeProvider<AppleDebugOutputsProvider>(
           AppleDebugOutputsProvider.class, SKYLARK_NAME) {};
 
   /**
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleDylibBinaryProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleDylibBinaryProvider.java
index 97adf82..248a13c 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleDylibBinaryProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleDylibBinaryProvider.java
@@ -16,28 +16,28 @@
 
 import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 
 /**
  * Provider containing the executable binary output that was built using an apple_binary target with
  * the 'dylib' type. This provider contains:
+ *
  * <ul>
- *   <li>'binary': The dylib artifact output by apple_binary</li>
+ *   <li>'binary': The dylib artifact output by apple_binary
  *   <li>'objc': An {@link ObjcProvider} which contains information about the transitive
- *     dependencies linked into the dylib, (intended so that binaries depending on this dylib may
- *     avoid relinking symbols included in the dylib</li>
- * </ul> 
+ *       dependencies linked into the dylib, (intended so that binaries depending on this dylib may
+ *       avoid relinking symbols included in the dylib
+ * </ul>
  */
-public final class AppleDylibBinaryProvider extends SkylarkClassObject {
+public final class AppleDylibBinaryProvider extends Info {
 
   /** Skylark name for the AppleDylibBinaryProvider. */
   public static final String SKYLARK_NAME = "AppleDylibBinary";
 
   /** Skylark constructor and identifier for AppleDylibBinaryProvider. */
-  public static final NativeClassObjectConstructor<AppleDylibBinaryProvider> SKYLARK_CONSTRUCTOR =
-      new NativeClassObjectConstructor<AppleDylibBinaryProvider>(
-          AppleDylibBinaryProvider.class, SKYLARK_NAME) {};
+  public static final NativeProvider<AppleDylibBinaryProvider> SKYLARK_CONSTRUCTOR =
+      new NativeProvider<AppleDylibBinaryProvider>(AppleDylibBinaryProvider.class, SKYLARK_NAME) {};
 
   private final Artifact dylibBinary;
   private final ObjcProvider depsObjcProvider;
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleDynamicFrameworkProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleDynamicFrameworkProvider.java
index e17e7f2..994afec 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleDynamicFrameworkProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleDynamicFrameworkProvider.java
@@ -17,34 +17,34 @@
 import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 import com.google.devtools.build.lib.vfs.PathFragment;
 import javax.annotation.Nullable;
 
 /**
  * Provider containing information about an Apple dynamic framework. This provider contains:
+ *
  * <ul>
- *   <li>'framework_dirs': The framework path names used as link inputs in order to link
- *       against the dynamic framework</li>
- *   <li>'framework_files': The full set of artifacts that should be included as inputs
- *       to link against the dynamic framework</li>
- *   <li>'binary': The dylib binary artifact of the dynamic framework</li>
+ *   <li>'framework_dirs': The framework path names used as link inputs in order to link against the
+ *       dynamic framework
+ *   <li>'framework_files': The full set of artifacts that should be included as inputs to link
+ *       against the dynamic framework
+ *   <li>'binary': The dylib binary artifact of the dynamic framework
  *   <li>'objc': An {@link ObjcProvider} which contains information about the transitive
- *     dependencies linked into the binary, (intended so that bundle loaders depending on this
- *     executable may avoid relinking symbols included in the loadable binary</li>
- * </ul> 
+ *       dependencies linked into the binary, (intended so that bundle loaders depending on this
+ *       executable may avoid relinking symbols included in the loadable binary
+ * </ul>
  */
-public final class AppleDynamicFrameworkProvider extends SkylarkClassObject {
+public final class AppleDynamicFrameworkProvider extends Info {
 
   /** Skylark name for the AppleDynamicFrameworkProvider. */
   public static final String SKYLARK_NAME = "AppleDynamicFramework";
 
   /** Skylark constructor and identifier for AppleDynamicFrameworkProvider. */
-  public static final NativeClassObjectConstructor<AppleDynamicFrameworkProvider>
-      SKYLARK_CONSTRUCTOR =
-          new NativeClassObjectConstructor<AppleDynamicFrameworkProvider>(
-              AppleDynamicFrameworkProvider.class, SKYLARK_NAME) {};
+  public static final NativeProvider<AppleDynamicFrameworkProvider> SKYLARK_CONSTRUCTOR =
+      new NativeProvider<AppleDynamicFrameworkProvider>(
+          AppleDynamicFrameworkProvider.class, SKYLARK_NAME) {};
 
   /** Field name for the dylib binary artifact of the dynamic framework. */
   public static final String DYLIB_BINARY_FIELD_NAME = "binary";
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleExecutableBinaryProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleExecutableBinaryProvider.java
index 7b072bd..910a940 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleExecutableBinaryProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleExecutableBinaryProvider.java
@@ -16,29 +16,29 @@
 
 import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 
 /**
  * Provider containing the executable binary output that was built using an apple_binary target with
- * the 'executable' type.  This provider contains:
+ * the 'executable' type. This provider contains:
+ *
  * <ul>
- *   <li>'binary': The dylib artifact output by apple_binary</li>
+ *   <li>'binary': The dylib artifact output by apple_binary
  *   <li>'objc': An {@link ObjcProvider} which contains information about the transitive
- *     dependencies linked into the binary, (intended so that bundle loaders depending on this
- *     executable may avoid relinking symbols included in the loadable binary</li>
- * </ul> 
+ *       dependencies linked into the binary, (intended so that bundle loaders depending on this
+ *       executable may avoid relinking symbols included in the loadable binary
+ * </ul>
  */
-public final class AppleExecutableBinaryProvider extends SkylarkClassObject {
+public final class AppleExecutableBinaryProvider extends Info {
 
   /** Skylark name for the AppleExecutableBinaryProvider. */
   public static final String SKYLARK_NAME = "AppleExecutableBinary";
 
   /** Skylark constructor and identifier for AppleExecutableBinaryProvider. */
-  public static final NativeClassObjectConstructor<AppleExecutableBinaryProvider>
-      SKYLARK_CONSTRUCTOR =
-          new NativeClassObjectConstructor<AppleExecutableBinaryProvider>(
-              AppleExecutableBinaryProvider.class, SKYLARK_NAME) {};
+  public static final NativeProvider<AppleExecutableBinaryProvider> SKYLARK_CONSTRUCTOR =
+      new NativeProvider<AppleExecutableBinaryProvider>(
+          AppleExecutableBinaryProvider.class, SKYLARK_NAME) {};
 
   private final Artifact appleExecutableBinary;
   private final ObjcProvider depsObjcProvider;
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleLoadableBundleBinaryProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleLoadableBundleBinaryProvider.java
index c276dc7..a8df0a8 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleLoadableBundleBinaryProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleLoadableBundleBinaryProvider.java
@@ -16,26 +16,26 @@
 
 import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 
 /**
  * Provider containing the executable binary output that was built using an apple_binary target with
  * the 'loadable_bundle' type. This provider contains:
+ *
  * <ul>
- *   <li>'binary': The binary artifact output by apple_binary</li>
- * </ul> 
+ *   <li>'binary': The binary artifact output by apple_binary
+ * </ul>
  */
-public final class AppleLoadableBundleBinaryProvider extends SkylarkClassObject {
+public final class AppleLoadableBundleBinaryProvider extends Info {
 
   /** Skylark name for the AppleLoadableBundleBinary. */
   public static final String SKYLARK_NAME = "AppleLoadableBundleBinary";
 
   /** Skylark constructor and identifier for AppleLoadableBundleBinary. */
-  public static final NativeClassObjectConstructor<AppleLoadableBundleBinaryProvider>
-      SKYLARK_CONSTRUCTOR =
-          new NativeClassObjectConstructor<AppleLoadableBundleBinaryProvider>(
-              AppleLoadableBundleBinaryProvider.class, SKYLARK_NAME) {};
+  public static final NativeProvider<AppleLoadableBundleBinaryProvider> SKYLARK_CONSTRUCTOR =
+      new NativeProvider<AppleLoadableBundleBinaryProvider>(
+          AppleLoadableBundleBinaryProvider.class, SKYLARK_NAME) {};
 
   private final Artifact appleLoadableBundleBinary;
 
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleSkylarkCommon.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleSkylarkCommon.java
index 7f5820b..4291fbe 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleSkylarkCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleSkylarkCommon.java
@@ -20,8 +20,8 @@
 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.packages.ClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.Provider;
 import com.google.devtools.build.lib.rules.apple.ApplePlatform;
 import com.google.devtools.build.lib.rules.apple.ApplePlatform.PlatformType;
 import com.google.devtools.build.lib.rules.apple.AppleToolchain;
@@ -73,10 +73,8 @@
   @VisibleForTesting
   public static final String MISSING_KEY_ERROR = "No value for required key %s was present.";
 
-  @Nullable
-  private SkylarkClassObject platformType;
-  @Nullable
-  private SkylarkClassObject platform;
+  @Nullable private Info platformType;
+  @Nullable private Info platform;
 
   @SkylarkCallable(
       name = "apple_toolchain",
@@ -88,23 +86,24 @@
 
   @SkylarkCallable(
     name = "platform_type",
-    doc = "An enum-like struct that contains the following fields corresponding to Apple platform "
-        + "types:<br><ul>"
-        + "<li><code>ios</code></li>"
-        + "<li><code>macos</code></li>"
-        + "<li><code>tvos</code></li>"
-        + "<li><code>watchos</code></li>"
-        + "</ul><p>"
-        + "These values can be passed to methods that expect a platform type, like the 'apple' "
-        + "configuration fragment's "
-        + "<a href='apple.html#multi_arch_platform'>multi_arch_platform</a> method.<p>"
-        + "Example:<p>"
-        + "<pre class='language-python'>\n"
-        + "ctx.fragments.apple.multi_arch_platform(apple_common.platform_type.ios)\n"
-        + "</pre>",
+    doc =
+        "An enum-like struct that contains the following fields corresponding to Apple platform "
+            + "types:<br><ul>"
+            + "<li><code>ios</code></li>"
+            + "<li><code>macos</code></li>"
+            + "<li><code>tvos</code></li>"
+            + "<li><code>watchos</code></li>"
+            + "</ul><p>"
+            + "These values can be passed to methods that expect a platform type, like the 'apple' "
+            + "configuration fragment's "
+            + "<a href='apple.html#multi_arch_platform'>multi_arch_platform</a> method.<p>"
+            + "Example:<p>"
+            + "<pre class='language-python'>\n"
+            + "ctx.fragments.apple.multi_arch_platform(apple_common.platform_type.ios)\n"
+            + "</pre>",
     structField = true
   )
-  public SkylarkClassObject getPlatformTypeStruct() {
+  public Info getPlatformTypeStruct() {
     if (platformType == null) {
       platformType = PlatformType.getSkylarkStruct();
     }
@@ -112,22 +111,23 @@
   }
 
   @SkylarkCallable(
-      name = "platform",
-      doc = "An enum-like struct that contains the following fields corresponding to Apple "
-          + "platforms:<br><ul>"
-          + "<li><code>ios_device</code></li>"
-          + "<li><code>ios_simulator</code></li>"
-          + "<li><code>macos</code></li>"
-          + "<li><code>tvos_device</code></li>"
-          + "<li><code>tvos_simulator</code></li>"
-          + "<li><code>watchos_device</code></li>"
-          + "<li><code>watchos_device</code></li>"
-          + "</ul><p>"
-          + "These values can be passed to methods that expect a platform, like "
-          + "<a href='apple.html#sdk_version_for_platform'>apple.sdk_version_for_platform</a>.",
-      structField = true
+    name = "platform",
+    doc =
+        "An enum-like struct that contains the following fields corresponding to Apple "
+            + "platforms:<br><ul>"
+            + "<li><code>ios_device</code></li>"
+            + "<li><code>ios_simulator</code></li>"
+            + "<li><code>macos</code></li>"
+            + "<li><code>tvos_device</code></li>"
+            + "<li><code>tvos_simulator</code></li>"
+            + "<li><code>watchos_device</code></li>"
+            + "<li><code>watchos_device</code></li>"
+            + "</ul><p>"
+            + "These values can be passed to methods that expect a platform, like "
+            + "<a href='apple.html#sdk_version_for_platform'>apple.sdk_version_for_platform</a>.",
+    structField = true
   )
-  public SkylarkClassObject getPlatformStruct() {
+  public Info getPlatformStruct() {
     if (platform == null) {
       platform = ApplePlatform.getSkylarkStruct();
     }
@@ -136,16 +136,17 @@
 
   @SkylarkCallable(
     name = XcodeVersionProperties.SKYLARK_NAME,
-    doc = "The constructor/key for the <code>XcodeVersionProperties</code> provider.<p>"
-        + "If a target propagates the <code>XcodeVersionProperties</code> provider, use this as "
-        + "the key with which to retrieve it. Example:<br>"
-        + "<pre class='language-python'>\n"
-        + "dep = ctx.attr.deps[0]\n"
-        + "p = dep[apple_common.XcodeVersionProperties]\n"
-        + "</pre>",
+    doc =
+        "The constructor/key for the <code>XcodeVersionProperties</code> provider.<p>"
+            + "If a target propagates the <code>XcodeVersionProperties</code> provider,"
+            + " use this as the key with which to retrieve it. Example:<br>"
+            + "<pre class='language-python'>\n"
+            + "dep = ctx.attr.deps[0]\n"
+            + "p = dep[apple_common.XcodeVersionProperties]\n"
+            + "</pre>",
     structField = true
   )
-  public ClassObjectConstructor getXcodeVersionPropertiesConstructor() {
+  public Provider getXcodeVersionPropertiesConstructor() {
     return XcodeVersionProperties.SKYLARK_CONSTRUCTOR;
   }
 
@@ -153,117 +154,125 @@
     // TODO(b/63899207): This currently does not match ObjcProvider.SKYLARK_NAME as it requires
     // a migration of existing skylark rules.
     name = "Objc",
-    doc = "The constructor/key for the <code>Objc</code> provider.<p>"
-        + "If a target propagates the <code>Objc</code> provider, use this as the "
-        + "key with which to retrieve it. Example:<br>"
-        + "<pre class='language-python'>\n"
-        + "dep = ctx.attr.deps[0]\n"
-        + "p = dep[apple_common.Objc]\n"
-        + "</pre>",
+    doc =
+        "The constructor/key for the <code>Objc</code> provider.<p>"
+            + "If a target propagates the <code>Objc</code> provider, use this as the "
+            + "key with which to retrieve it. Example:<br>"
+            + "<pre class='language-python'>\n"
+            + "dep = ctx.attr.deps[0]\n"
+            + "p = dep[apple_common.Objc]\n"
+            + "</pre>",
     structField = true
   )
-  public ClassObjectConstructor getObjcProviderConstructor() {
+  public Provider getObjcProviderConstructor() {
     return ObjcProvider.SKYLARK_CONSTRUCTOR;
   }
 
   @SkylarkCallable(
     name = AppleDynamicFrameworkProvider.SKYLARK_NAME,
-    doc = "The constructor/key for the <code>AppleDynamicFramework</code> provider.<p>"
-        + "If a target propagates the <code>AppleDynamicFramework</code> provider, use this as the "
-        + "key with which to retrieve it. Example:<br>"
-        + "<pre class='language-python'>\n"
-        + "dep = ctx.attr.deps[0]\n"
-        + "p = dep[apple_common.AppleDynamicFramework]\n"
-        + "</pre>",
+    doc =
+        "The constructor/key for the <code>AppleDynamicFramework</code> provider.<p>"
+            + "If a target propagates the <code>AppleDynamicFramework</code> provider, use this "
+            + "as the key with which to retrieve it. Example:<br>"
+            + "<pre class='language-python'>\n"
+            + "dep = ctx.attr.deps[0]\n"
+            + "p = dep[apple_common.AppleDynamicFramework]\n"
+            + "</pre>",
     structField = true
   )
-  public ClassObjectConstructor getAppleDynamicFrameworkConstructor() {
+  public Provider getAppleDynamicFrameworkConstructor() {
     return AppleDynamicFrameworkProvider.SKYLARK_CONSTRUCTOR;
   }
 
   @SkylarkCallable(
     name = AppleDylibBinaryProvider.SKYLARK_NAME,
-    doc = "The constructor/key for the <code>AppleDylibBinary</code> provider.<p>"
-        + "If a target propagates the <code>AppleDylibBinary</code> provider, use this as the "
-        + "key with which to retrieve it. Example:<br>"
-        + "<pre class='language-python'>\n"
-        + "dep = ctx.attr.deps[0]\n"
-        + "p = dep[apple_common.AppleDylibBinary]\n"
-        + "</pre>",
+    doc =
+        "The constructor/key for the <code>AppleDylibBinary</code> provider.<p>"
+            + "If a target propagates the <code>AppleDylibBinary</code> provider, use this as the "
+            + "key with which to retrieve it. Example:<br>"
+            + "<pre class='language-python'>\n"
+            + "dep = ctx.attr.deps[0]\n"
+            + "p = dep[apple_common.AppleDylibBinary]\n"
+            + "</pre>",
     structField = true
   )
-  public ClassObjectConstructor getAppleDylibBinaryConstructor() {
+  public Provider getAppleDylibBinaryConstructor() {
     return AppleDylibBinaryProvider.SKYLARK_CONSTRUCTOR;
   }
 
   @SkylarkCallable(
     name = AppleExecutableBinaryProvider.SKYLARK_NAME,
-    doc = "The constructor/key for the <code>AppleExecutableBinary</code> provider.<p>"
-        + "If a target propagates the <code>AppleExecutableBinary</code> provider, use this as the "
-        + "key with which to retrieve it. Example:<br>"
-        + "<pre class='language-python'>\n"
-        + "dep = ctx.attr.deps[0]\n"
-        + "p = dep[apple_common.AppleExecutableBinary]\n"
-        + "</pre>",
+    doc =
+        "The constructor/key for the <code>AppleExecutableBinary</code> provider.<p>"
+            + "If a target propagates the <code>AppleExecutableBinary</code> provider,"
+            + " use this as the key with which to retrieve it. Example:<br>"
+            + "<pre class='language-python'>\n"
+            + "dep = ctx.attr.deps[0]\n"
+            + "p = dep[apple_common.AppleExecutableBinary]\n"
+            + "</pre>",
     structField = true
   )
-  public ClassObjectConstructor getAppleExecutableBinaryConstructor() {
+  public Provider getAppleExecutableBinaryConstructor() {
     return AppleExecutableBinaryProvider.SKYLARK_CONSTRUCTOR;
   }
 
   @SkylarkCallable(
     name = AppleStaticLibraryProvider.SKYLARK_NAME,
-    doc = "The constructor/key for the <code>AppleStaticLibrary</code> provider.<p>"
-        + "If a target propagates the <code>AppleStaticLibrary</code> provider, use this as the "
-        + "key with which to retrieve it. Example:<br>"
-        + "<pre class='language-python'>\n"
-        + "dep = ctx.attr.deps[0]\n"
-        + "p = dep[apple_common.AppleStaticLibrary]\n"
-        + "</pre>",
+    doc =
+        "The constructor/key for the <code>AppleStaticLibrary</code> provider.<p>"
+            + "If a target propagates the <code>AppleStaticLibrary</code> provider, use "
+            + "this as the key with which to retrieve it. Example:<br>"
+            + "<pre class='language-python'>\n"
+            + "dep = ctx.attr.deps[0]\n"
+            + "p = dep[apple_common.AppleStaticLibrary]\n"
+            + "</pre>",
     structField = true
   )
-  public ClassObjectConstructor getAppleStaticLibraryProvider() {
+  public Provider getAppleStaticLibraryProvider() {
     return AppleStaticLibraryProvider.SKYLARK_CONSTRUCTOR;
   }
 
   @SkylarkCallable(
     name = AppleDebugOutputsProvider.SKYLARK_NAME,
-    doc = "The constructor/key for the <code>AppleDebugOutputs</code> provider.<p>"
-        + "If a target propagates the <code>AppleDebugOutputs</code> provider, use this as the "
-        + "key with which to retrieve it. Example:<br>"
-        + "<pre class='language-python'>\n"
-        + "dep = ctx.attr.deps[0]\n"
-        + "p = dep[apple_common.AppleDebugOutputs]\n"
-        + "</pre>",
+    doc =
+        "The constructor/key for the <code>AppleDebugOutputs</code> provider.<p>"
+            + "If a target propagates the <code>AppleDebugOutputs</code> provider, use this as the "
+            + "key with which to retrieve it. Example:<br>"
+            + "<pre class='language-python'>\n"
+            + "dep = ctx.attr.deps[0]\n"
+            + "p = dep[apple_common.AppleDebugOutputs]\n"
+            + "</pre>",
     structField = true
   )
-  public ClassObjectConstructor getAppleDebugOutputsConstructor() {
+  public Provider getAppleDebugOutputsConstructor() {
     return AppleDebugOutputsProvider.SKYLARK_CONSTRUCTOR;
   }
 
   @SkylarkCallable(
     name = AppleLoadableBundleBinaryProvider.SKYLARK_NAME,
-    doc = "The constructor/key for the <code>AppleLoadableBundleBinary</code> provider.<p>"
-        + "If a target propagates the <code>AppleLoadableBundleBinary</code> provider, use this as "
-        + "the key with which to retrieve it. Example:<br>"
-        + "<pre class='language-python'>\n"
-        + "dep = ctx.attr.deps[0]\n"
-        + "p = dep[apple_common.AppleLoadableBundleBinary]\n"
-        + "</pre>",
+    doc =
+        "The constructor/key for the <code>AppleLoadableBundleBinary</code> provider.<p>"
+            + "If a target propagates the <code>AppleLoadableBundleBinary</code> provider, "
+            + "use this as the key with which to retrieve it. Example:<br>"
+            + "<pre class='language-python'>\n"
+            + "dep = ctx.attr.deps[0]\n"
+            + "p = dep[apple_common.AppleLoadableBundleBinary]\n"
+            + "</pre>",
     structField = true
   )
-  public ClassObjectConstructor getAppleLoadableBundleBinaryConstructor() {
+  public Provider getAppleLoadableBundleBinaryConstructor() {
     return AppleLoadableBundleBinaryProvider.SKYLARK_CONSTRUCTOR;
   }
 
   @SkylarkCallable(
     name = IosDeviceProvider.SKYLARK_NAME,
-    doc = "<b>Deprecated. Use the new Skylark testing rules instead.</b> Returns the provider "
-        + "constructor for IosDeviceProvider. Use this as a key to access the attributes exposed "
-        + "by ios_device.",
+    doc =
+        "<b>Deprecated. Use the new Skylark testing rules instead.</b> Returns the provider "
+            + "constructor for IosDeviceProvider. Use this as a key to access the attributes "
+            + "exposed by ios_device.",
     structField = true
   )
-  public ClassObjectConstructor getIosDeviceProviderConstructor() {
+  public Provider getIosDeviceProviderConstructor() {
     return IosDeviceProvider.SKYLARK_CONSTRUCTOR;
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibraryProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibraryProvider.java
index f18a9b4..cc0f064 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibraryProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleStaticLibraryProvider.java
@@ -16,28 +16,30 @@
 
 import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 
 /**
  * Provider containing information regarding multi-architecture Apple static libraries, as is
  * propagated that by the {@code apple_static_library} rule.
+ *
  * <p>This provider contains:
+ *
  * <ul>
- *   <li>'archive': The multi-arch archive (.a) output by apple_static_library</li>
+ *   <li>'archive': The multi-arch archive (.a) output by apple_static_library
  *   <li>'objc': An {@link ObjcProvider} which contains information about the transitive
- *     dependencies linked into the library, (intended so that targets may avoid linking
- *     symbols included in this archive multiple times).</li>
- * </ul> 
+ *       dependencies linked into the library, (intended so that targets may avoid linking symbols
+ *       included in this archive multiple times).
+ * </ul>
  */
-public final class AppleStaticLibraryProvider extends SkylarkClassObject {
+public final class AppleStaticLibraryProvider extends Info {
 
   /** Skylark name for the AppleStaticLibraryProvider. */
   public static final String SKYLARK_NAME = "AppleStaticLibrary";
 
   /** Skylark constructor and identifier for AppleStaticLibraryProvider. */
-  public static final NativeClassObjectConstructor<AppleStaticLibraryProvider> SKYLARK_CONSTRUCTOR =
-      new NativeClassObjectConstructor<AppleStaticLibraryProvider>(
+  public static final NativeProvider<AppleStaticLibraryProvider> SKYLARK_CONSTRUCTOR =
+      new NativeProvider<AppleStaticLibraryProvider>(
           AppleStaticLibraryProvider.class, SKYLARK_NAME) {};
 
   private final Artifact multiArchArchive;
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IosDeviceProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IosDeviceProvider.java
index 1128ae8..8ad4575 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/IosDeviceProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IosDeviceProvider.java
@@ -18,8 +18,8 @@
 import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction.Substitution;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 import com.google.devtools.build.lib.rules.apple.DottedVersion;
 import com.google.devtools.build.lib.util.Preconditions;
 import java.util.Map;
@@ -27,7 +27,7 @@
 
 /** Provider that describes a simulator device. */
 @Immutable
-public final class IosDeviceProvider extends SkylarkClassObject {
+public final class IosDeviceProvider extends Info {
   /** A builder of {@link IosDeviceProvider}s. */
   public static final class Builder {
     private String type;
@@ -76,8 +76,8 @@
   public static final String SKYLARK_NAME = "IosDevice";
 
   /** Skylark constructor and identifier for the IosDeviceProvider. */
-  public static final NativeClassObjectConstructor<IosDeviceProvider> SKYLARK_CONSTRUCTOR =
-      new NativeClassObjectConstructor<IosDeviceProvider>(IosDeviceProvider.class, SKYLARK_NAME) {};
+  public static final NativeProvider<IosDeviceProvider> SKYLARK_CONSTRUCTOR =
+      new NativeProvider<IosDeviceProvider>(IosDeviceProvider.class, SKYLARK_NAME) {};
 
   private final String type;
   private final DottedVersion iosVersion;
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..cd4553c 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,8 @@
 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.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 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;
@@ -299,10 +299,10 @@
       return listBuilder;
     }
 
-    private <T extends SkylarkClassObject> ImmutableList.Builder<T> addAnyProviders(
+    private <T extends Info> ImmutableList.Builder<T> addAnyProviders(
         ImmutableList.Builder<T> listBuilder,
         TransitiveInfoCollection collection,
-        NativeClassObjectConstructor<T> providerClass) {
+        NativeProvider<T> providerClass) {
       T provider = collection.get(providerClass);
       if (provider != null) {
         listBuilder.add(provider);
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 d7e8ff4..2e0f05d 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
@@ -29,9 +29,9 @@
 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.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
+import com.google.devtools.build.lib.packages.NativeProvider.WithLegacySkylarkName;
 import com.google.devtools.build.lib.rules.cpp.CcLinkParamsProvider;
 import com.google.devtools.build.lib.rules.cpp.CppModuleMap;
 import com.google.devtools.build.lib.rules.cpp.LinkerInputs;
@@ -55,7 +55,7 @@
   category = SkylarkModuleCategory.PROVIDER,
   doc = "A provider for compilation and linking of objc."
 )
-public final class ObjcProvider extends SkylarkClassObject {
+public final class ObjcProvider extends Info {
 
   /** Skylark name for the ObjcProvider. */
   public static final String SKYLARK_NAME = "objc";
@@ -499,8 +499,7 @@
   private final ImmutableMap<Key<?>, NestedSet<?>> strictDependencyItems;
 
   /** Skylark constructor and identifier for ObjcProvider. */
-  public static final NativeClassObjectConstructor<ObjcProvider> SKYLARK_CONSTRUCTOR =
-      new Constructor();
+  public static final NativeProvider<ObjcProvider> SKYLARK_CONSTRUCTOR = new Constructor();
 
   private ObjcProvider(
       ImmutableMap<Key<?>, NestedSet<?>> items,
@@ -1007,8 +1006,7 @@
     }
   }
 
-  private static class Constructor
-      extends NativeClassObjectConstructor<ObjcProvider>
+  private static class Constructor extends NativeProvider<ObjcProvider>
       implements WithLegacySkylarkName {
     public Constructor() {
       super(ObjcProvider.class, ObjcProvider.SKYLARK_NAME);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProviderSkylarkConverters.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProviderSkylarkConverters.java
index 03c2ae2..f3937f6 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProviderSkylarkConverters.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProviderSkylarkConverters.java
@@ -24,8 +24,8 @@
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
 import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 import com.google.devtools.build.lib.rules.objc.ObjcProvider.Key;
 import com.google.devtools.build.lib.syntax.EvalException;
 import com.google.devtools.build.lib.syntax.EvalUtils;
@@ -160,26 +160,24 @@
     @SuppressWarnings("unchecked")
     @Override
     public Object valueForSkylark(Key<?> javaKey, NestedSet<?> javaValue) {
-      NestedSetBuilder<SkylarkClassObject> result = NestedSetBuilder.stableOrder();
+      NestedSetBuilder<Info> result = NestedSetBuilder.stableOrder();
       for (BundleableFile bundleableFile : (Iterable<BundleableFile>) javaValue) {
-        result.add(NativeClassObjectConstructor.STRUCT.create(
-            ImmutableMap.<String, Object>of(
-                BUNDLED_FIELD, bundleableFile.getBundled(),
-                BUNDLE_PATH_FIELD, bundleableFile.getBundlePath()
-            ),
-            "No such attribute '%s'"
-        ));
+        result.add(
+            NativeProvider.STRUCT.create(
+                ImmutableMap.<String, Object>of(
+                    BUNDLED_FIELD, bundleableFile.getBundled(),
+                    BUNDLE_PATH_FIELD, bundleableFile.getBundlePath()),
+                "No such attribute '%s'"));
       }
-      return SkylarkNestedSet.of(SkylarkClassObject.class, result.build());
+      return SkylarkNestedSet.of(Info.class, result.build());
     }
 
     @SuppressWarnings("unchecked")
     @Override
     public Iterable<?> valueForJava(Key<?> javaKey, Object skylarkValue) {
-      validateTypes(skylarkValue, SkylarkClassObject.class, javaKey.getSkylarkKeyName());
+      validateTypes(skylarkValue, Info.class, javaKey.getSkylarkKeyName());
       NestedSetBuilder<BundleableFile> result = NestedSetBuilder.stableOrder();
-      for (SkylarkClassObject struct :
-          ((SkylarkNestedSet) skylarkValue).toCollection(SkylarkClassObject.class)) {
+      for (Info struct : ((SkylarkNestedSet) skylarkValue).toCollection(Info.class)) {
         Artifact artifact;
         String path;
         try {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/TestSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/TestSupport.java
index 47f5a30..d6d57f9 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/TestSupport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/TestSupport.java
@@ -30,7 +30,7 @@
 import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction.Substitution;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
 import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
 import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
 import com.google.devtools.build.lib.rules.apple.DottedVersion;
 import com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.SimulatorRule;
@@ -255,7 +255,7 @@
    * Returns any additional providers that need to be exported to the rule context to the passed
    * builder.
    */
-  public Iterable<SkylarkClassObject> getExtraProviders() {
+  public Iterable<Info> getExtraProviders() {
     IosDeviceProvider deviceProvider =
         ruleContext.getPrerequisite(
             IosTest.TARGET_DEVICE, Mode.TARGET, IosDeviceProvider.SKYLARK_CONSTRUCTOR);
@@ -274,7 +274,7 @@
       envBuilder.put("APPLE_COVERAGE", "1");
     }
 
-    return ImmutableList.<SkylarkClassObject>of(new TestEnvironmentProvider(envBuilder.build()));
+    return ImmutableList.<Info>of(new TestEnvironmentProvider(envBuilder.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..a120925 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
@@ -17,9 +17,9 @@
 import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.actions.Artifact;
 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.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
+import com.google.devtools.build.lib.packages.NativeProvider.WithLegacySkylarkName;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
 import com.google.devtools.build.lib.util.Preconditions;
@@ -33,14 +33,13 @@
       "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 Info {
   /**
    * 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();
+  public static final NativeProvider<XcTestAppProvider> SKYLARK_CONSTRUCTOR = new Constructor();
 
   private final Artifact bundleLoader;
   private final Artifact ipa;
@@ -85,8 +84,7 @@
         .build();
   }
 
-  private static class Constructor
-      extends NativeClassObjectConstructor<XcTestAppProvider>
+  private static class Constructor extends NativeProvider<XcTestAppProvider>
       implements WithLegacySkylarkName {
 
     private Constructor() {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/platform/PlatformCommon.java b/src/main/java/com/google/devtools/build/lib/rules/platform/PlatformCommon.java
index 48e9057..c793dea 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/platform/PlatformCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/platform/PlatformCommon.java
@@ -18,7 +18,7 @@
 import com.google.devtools.build.lib.analysis.platform.ConstraintValueInfo;
 import com.google.devtools.build.lib.analysis.platform.PlatformInfo;
 import com.google.devtools.build.lib.analysis.platform.ToolchainInfo;
-import com.google.devtools.build.lib.packages.ClassObjectConstructor;
+import com.google.devtools.build.lib.packages.Provider;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
 import com.google.devtools.build.lib.syntax.SkylarkSignatureProcessor;
@@ -37,7 +37,7 @@
             + "ConstraintValueInfo providers that defines the platform.",
     structField = true
   )
-  public ClassObjectConstructor getPlatformInfoConstructor() {
+  public Provider getPlatformInfoConstructor() {
     return PlatformInfo.SKYLARK_CONSTRUCTOR;
   }
 
@@ -48,7 +48,7 @@
             + "uniquely identifies the constraint (and which should always be ctx.label).",
     structField = true
   )
-  public ClassObjectConstructor getConstraintSettingInfoConstructor() {
+  public Provider getConstraintSettingInfoConstructor() {
     return ConstraintSettingInfo.SKYLARK_CONSTRUCTOR;
   }
 
@@ -60,7 +60,7 @@
             + "and the ConstraintSettingInfo which the value belongs to.",
     structField = true
   )
-  public ClassObjectConstructor getConstraintValueInfoConstructor() {
+  public Provider getConstraintValueInfoConstructor() {
     return ConstraintValueInfo.SKYLARK_CONSTRUCTOR;
   }
 
@@ -71,7 +71,7 @@
             + "toolchain, and a map of the toolchain's data.",
     structField = true
   )
-  public ClassObjectConstructor getToolchainInfoConstructor() {
+  public Provider getToolchainInfoConstructor() {
     return ToolchainInfo.SKYLARK_CONSTRUCTOR;
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/rules/python/PyCommon.java b/src/main/java/com/google/devtools/build/lib/rules/python/PyCommon.java
index de9d22e..b0cafa8 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/python/PyCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/python/PyCommon.java
@@ -38,9 +38,9 @@
 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.BuildType;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 import com.google.devtools.build.lib.packages.Rule;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
 import com.google.devtools.build.lib.rules.cpp.CppFileTypes;
 import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector;
 import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector.LocalMetadataCollector;
@@ -162,11 +162,11 @@
   /**
    * Returns a Skylark struct for exposing transitive Python sources:
    *
-   *     addSkylarkTransitiveInfo(PYTHON_SKYLARK_PROVIDER_NAME, createSourceProvider(...))
+   * <p>addSkylarkTransitiveInfo(PYTHON_SKYLARK_PROVIDER_NAME, createSourceProvider(...))
    */
-  public static SkylarkClassObject createSourceProvider(
+  public static Info createSourceProvider(
       NestedSet<Artifact> transitivePythonSources, boolean isUsingSharedLibrary) {
-    return NativeClassObjectConstructor.STRUCT.create(
+    return NativeProvider.STRUCT.create(
         ImmutableMap.<String, Object>of(
             TRANSITIVE_PYTHON_SRCS,
             SkylarkNestedSet.of(Artifact.class, transitivePythonSources),
@@ -301,14 +301,15 @@
 
   private NestedSet<Artifact> getTransitivePythonSourcesFromSkylarkProvider(
       TransitiveInfoCollection dep) {
-    SkylarkClassObject pythonSkylarkProvider = null;
+    Info pythonSkylarkProvider = null;
     try {
-      pythonSkylarkProvider = SkylarkType.cast(
+      pythonSkylarkProvider =
+          SkylarkType.cast(
               dep.get(PYTHON_SKYLARK_PROVIDER_NAME),
-              SkylarkClassObject.class,
+              Info.class,
               null,
-              "%s should be a struct", PYTHON_SKYLARK_PROVIDER_NAME
-      );
+              "%s should be a struct",
+              PYTHON_SKYLARK_PROVIDER_NAME);
 
       if (pythonSkylarkProvider != null) {
         Object sourceFiles = pythonSkylarkProvider.getValue(TRANSITIVE_PYTHON_SRCS);
@@ -487,8 +488,8 @@
     for (TransitiveInfoCollection dep : deps) {
       Object providerObject = dep.get(PYTHON_SKYLARK_PROVIDER_NAME);
       if (providerObject != null) {
-        SkylarkType.checkType(providerObject, SkylarkClassObject.class, null);
-        SkylarkClassObject provider = (SkylarkClassObject) providerObject;
+        SkylarkType.checkType(providerObject, Info.class, null);
+        Info provider = (Info) providerObject;
         Boolean isUsingSharedLibrary = provider.getValue(IS_USING_SHARED_LIBRARY, Boolean.class);
         if (Boolean.TRUE.equals(isUsingSharedLibrary)) {
           return true;
diff --git a/src/main/java/com/google/devtools/build/lib/rules/test/ExecutionInfoProvider.java b/src/main/java/com/google/devtools/build/lib/rules/test/ExecutionInfoProvider.java
index 32cabb0..4f1e40a 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/test/ExecutionInfoProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/test/ExecutionInfoProvider.java
@@ -15,8 +15,8 @@
 
 import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 import java.util.Map;
 
 /**
@@ -24,12 +24,11 @@
  * tests).
  */
 @Immutable
-public final class ExecutionInfoProvider extends SkylarkClassObject {
+public final class ExecutionInfoProvider extends Info {
 
   /** Skylark constructor and identifier for ExecutionInfoProvider. */
-  public static final NativeClassObjectConstructor<ExecutionInfoProvider> SKYLARK_CONSTRUCTOR =
-      new NativeClassObjectConstructor<ExecutionInfoProvider>(
-          ExecutionInfoProvider.class, "ExecutionInfo") {};
+  public static final NativeProvider<ExecutionInfoProvider> SKYLARK_CONSTRUCTOR =
+      new NativeProvider<ExecutionInfoProvider>(ExecutionInfoProvider.class, "ExecutionInfo") {};
 
   private final ImmutableMap<String, String> executionInfo;
 
diff --git a/src/main/java/com/google/devtools/build/lib/rules/test/TestEnvironmentProvider.java b/src/main/java/com/google/devtools/build/lib/rules/test/TestEnvironmentProvider.java
index fe52a23..c4fb3f6 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/test/TestEnvironmentProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/test/TestEnvironmentProvider.java
@@ -17,17 +17,17 @@
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 import java.util.Map;
 
 /** Provider containing any additional environment variables for use in the test action. */
 @Immutable
-public final class TestEnvironmentProvider extends SkylarkClassObject {
+public final class TestEnvironmentProvider extends Info {
 
   /** Skylark constructor and identifier for TestEnvironmentProvider. */
-  public static final NativeClassObjectConstructor<TestEnvironmentProvider> SKYLARK_CONSTRUCTOR =
-      new NativeClassObjectConstructor<TestEnvironmentProvider>(
+  public static final NativeProvider<TestEnvironmentProvider> SKYLARK_CONSTRUCTOR =
+      new NativeProvider<TestEnvironmentProvider>(
           TestEnvironmentProvider.class, "TestEnvironment") {};
 
   private final Map<String, String> environment;
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkAspectFactory.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkAspectFactory.java
index 190e40a..3ca1942 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkAspectFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkAspectFactory.java
@@ -24,8 +24,8 @@
 import com.google.devtools.build.lib.events.Location;
 import com.google.devtools.build.lib.packages.AspectDescriptor;
 import com.google.devtools.build.lib.packages.AspectParameters;
+import com.google.devtools.build.lib.packages.Info;
 import com.google.devtools.build.lib.packages.SkylarkAspect;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
 import com.google.devtools.build.lib.rules.SkylarkRuleConfiguredTargetUtil;
 import com.google.devtools.build.lib.rules.SkylarkRuleContext;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
@@ -84,7 +84,7 @@
 
         if (ruleContext.hasErrors()) {
           return null;
-        } else if (!(aspectSkylarkObject instanceof SkylarkClassObject)
+        } else if (!(aspectSkylarkObject instanceof Info)
             && !(aspectSkylarkObject instanceof Iterable)) {
           ruleContext.ruleError(
               String.format(
@@ -114,7 +114,7 @@
     if (aspectSkylarkObject instanceof Iterable) {
       addDeclaredProviders(builder, (Iterable) aspectSkylarkObject);
     } else {
-      SkylarkClassObject struct = (SkylarkClassObject) aspectSkylarkObject;
+      Info struct = (Info) aspectSkylarkObject;
       Location loc = struct.getCreationLoc();
       for (String key : struct.getKeys()) {
         if (key.equals("output_groups")) {
@@ -145,10 +145,10 @@
       throws EvalException {
     for (Object o : aspectSkylarkObject) {
       Location loc = skylarkAspect.getImplementation().getLocation();
-      SkylarkClassObject declaredProvider =
+      Info declaredProvider =
           SkylarkType.cast(
               o,
-              SkylarkClassObject.class,
+              Info.class,
               loc,
               "A return value of an aspect implementation function should be "
                   + "a sequence of declared providers");
diff --git a/src/test/java/com/google/devtools/build/lib/packages/RequiredProvidersTest.java b/src/test/java/com/google/devtools/build/lib/packages/RequiredProvidersTest.java
index 05ba757..ca8a996 100644
--- a/src/test/java/com/google/devtools/build/lib/packages/RequiredProvidersTest.java
+++ b/src/test/java/com/google/devtools/build/lib/packages/RequiredProvidersTest.java
@@ -37,11 +37,11 @@
   private static final class P2 {}
   private static final class P3 {}
 
-  private static final ClassObjectConstructor P_NATIVE =
-      new NativeClassObjectConstructor<SkylarkClassObject>(SkylarkClassObject.class, "p_native") {};
+  private static final Provider P_NATIVE = new NativeProvider<Info>(Info.class, "p_native") {};
 
-  private static final SkylarkClassObjectConstructor P_SKYLARK =
-      new SkylarkClassObjectConstructor("p_skylark", Location.BUILTIN);
+  private static final SkylarkProvider P_SKYLARK =
+      new SkylarkProvider("p_skylark", Location.BUILTIN);
+
   static {
     try {
       P_SKYLARK.export(Label.create("foo/bar", "x.bzl"), "p_skylark");
@@ -61,10 +61,11 @@
       RequiredProviders requiredProviders) {
     boolean result = requiredProviders.isSatisfiedBy(providers);
 
-    assertThat(requiredProviders.isSatisfiedBy(
-        providers.getNativeProviders()::contains,
-        providers.getSkylarkProviders()::contains
-    )).isEqualTo(result);
+    assertThat(
+            requiredProviders.isSatisfiedBy(
+                providers.getNativeProviders()::contains,
+                providers.getSkylarkProviders()::contains))
+        .isEqualTo(result);
     return result;
   }
 
@@ -121,27 +122,23 @@
   @Test
   public void nativeProvidersBranchMatch() {
     assertThat(
-        validateNative(
-          AdvertisedProviderSet.builder()
-              .addNative(P1.class)
-              .build(),
-          NO_PROVIDERS_REQUIRED,
-          ImmutableSet.<Class<?>>of(P1.class),
-          ImmutableSet.<Class<?>>of(P2.class)
-        )).isTrue();
+            validateNative(
+                AdvertisedProviderSet.builder().addNative(P1.class).build(),
+                NO_PROVIDERS_REQUIRED,
+                ImmutableSet.<Class<?>>of(P1.class),
+                ImmutableSet.<Class<?>>of(P2.class)))
+        .isTrue();
   }
 
   @Test
   public void nativeProvidersNoMatch() {
     assertThat(
-        validateNative(
-            AdvertisedProviderSet.builder()
-                .addNative(P3.class)
-                .build(),
-            "P1 or P2",
-            ImmutableSet.<Class<?>>of(P1.class),
-            ImmutableSet.<Class<?>>of(P2.class)
-        )).isFalse();
+            validateNative(
+                AdvertisedProviderSet.builder().addNative(P3.class).build(),
+                "P1 or P2",
+                ImmutableSet.<Class<?>>of(P1.class),
+                ImmutableSet.<Class<?>>of(P2.class)))
+        .isFalse();
   }
 
   @Test
@@ -161,27 +158,23 @@
   @Test
   public void skylarkProvidersBranchMatch() {
     assertThat(
-        validateSkylark(
-            AdvertisedProviderSet.builder()
-                .addSkylark(ID_LEGACY)
-                .build(),
-            NO_PROVIDERS_REQUIRED,
-            ImmutableSet.of(ID_LEGACY),
-            ImmutableSet.of(ID_NATIVE)
-        )).isTrue();
+            validateSkylark(
+                AdvertisedProviderSet.builder().addSkylark(ID_LEGACY).build(),
+                NO_PROVIDERS_REQUIRED,
+                ImmutableSet.of(ID_LEGACY),
+                ImmutableSet.of(ID_NATIVE)))
+        .isTrue();
   }
 
   @Test
   public void skylarkProvidersNoMatch() {
     assertThat(
-        validateSkylark(
-            AdvertisedProviderSet.builder()
-                .addSkylark(ID_SKYLARK)
-                .build(),
-            "'p_legacy' or 'p_native'",
-            ImmutableSet.of(ID_LEGACY),
-            ImmutableSet.of(ID_NATIVE)
-        )).isFalse();
+            validateSkylark(
+                AdvertisedProviderSet.builder().addSkylark(ID_SKYLARK).build(),
+                "'p_legacy' or 'p_native'",
+                ImmutableSet.of(ID_LEGACY),
+                ImmutableSet.of(ID_NATIVE)))
+        .isFalse();
   }
 
   @Test
@@ -190,18 +183,19 @@
         .isEqualTo("no providers required");
     assertThat(RequiredProviders.acceptNoneBuilder().build().getDescription())
         .isEqualTo("no providers accepted");
-    assertThat(RequiredProviders.acceptAnyBuilder()
-        .addSkylarkSet(ImmutableSet.of(ID_LEGACY, ID_SKYLARK))
-        .addSkylarkSet(ImmutableSet.of(ID_SKYLARK))
-        .addNativeSet(ImmutableSet.of(P1.class, P2.class))
-        .build().getDescription())
+    assertThat(
+            RequiredProviders.acceptAnyBuilder()
+                .addSkylarkSet(ImmutableSet.of(ID_LEGACY, ID_SKYLARK))
+                .addSkylarkSet(ImmutableSet.of(ID_SKYLARK))
+                .addNativeSet(ImmutableSet.of(P1.class, P2.class))
+                .build()
+                .getDescription())
         .isEqualTo("[P1, P2] or ['p_legacy', 'p_skylark'] or 'p_skylark'");
   }
 
   @SafeVarargs
-  private static boolean validateNative(AdvertisedProviderSet providerSet,
-      String missing,
-      ImmutableSet<Class<?>>... sets) {
+  private static boolean validateNative(
+      AdvertisedProviderSet providerSet, String missing, ImmutableSet<Class<?>>... sets) {
     Builder anyBuilder = RequiredProviders.acceptAnyBuilder();
     Builder noneBuilder = RequiredProviders.acceptNoneBuilder();
     for (ImmutableSet<Class<?>> set : sets) {
diff --git a/src/test/java/com/google/devtools/build/lib/rules/java/JavaSkylarkApiTest.java b/src/test/java/com/google/devtools/build/lib/rules/java/JavaSkylarkApiTest.java
index c81d7ed..d8387a1 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/java/JavaSkylarkApiTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/java/JavaSkylarkApiTest.java
@@ -23,8 +23,8 @@
 import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
 import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
-import com.google.devtools.build.lib.packages.SkylarkClassObjectConstructor.SkylarkKey;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.SkylarkProvider.SkylarkKey;
 import com.google.devtools.build.lib.rules.java.JavaRuleOutputJarsProvider.OutputJar;
 import com.google.devtools.build.lib.syntax.SkylarkList;
 import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
@@ -96,19 +96,17 @@
         "my_rule = rule(impl, attrs = { 'dep' : attr.label() })");
 
     ConfiguredTarget configuredTarget = getConfiguredTarget("//java/test:my");
-    SkylarkClassObject skylarkClassObject =
+    Info info =
         configuredTarget.get(
             new SkylarkKey(Label.parseAbsolute("//java/test:extension.bzl"), "result"));
 
-    SkylarkNestedSet sourceJars = ((SkylarkNestedSet) skylarkClassObject.getValue("source_jars"));
-    SkylarkNestedSet transitiveDeps =
-        ((SkylarkNestedSet) skylarkClassObject.getValue("transitive_deps"));
+    SkylarkNestedSet sourceJars = ((SkylarkNestedSet) info.getValue("source_jars"));
+    SkylarkNestedSet transitiveDeps = ((SkylarkNestedSet) info.getValue("transitive_deps"));
     SkylarkNestedSet transitiveRuntimeDeps =
-        ((SkylarkNestedSet) skylarkClassObject.getValue("transitive_runtime_deps"));
+        ((SkylarkNestedSet) info.getValue("transitive_runtime_deps"));
     SkylarkNestedSet transitiveSourceJars =
-        ((SkylarkNestedSet) skylarkClassObject.getValue("transitive_source_jars"));
-    SkylarkList<OutputJar> outputJars =
-        ((SkylarkList<OutputJar>) skylarkClassObject.getValue("outputs"));
+        ((SkylarkNestedSet) info.getValue("transitive_source_jars"));
+    SkylarkList<OutputJar> outputJars = ((SkylarkList<OutputJar>) info.getValue("outputs"));
 
     assertThat(artifactFilesNames(sourceJars.toCollection(Artifact.class)))
         .containsExactly("libdep-src.jar");
@@ -157,15 +155,15 @@
       "    srcs = ['ToBeProcessed.java'])",
       "my_rule(name = 'my', dep = ':to_be_processed')");
     ConfiguredTarget configuredTarget = getConfiguredTarget("//java/test:my");
-    SkylarkClassObject skylarkClassObject = configuredTarget.get(
-          new SkylarkKey(Label.parseAbsolute("//java/test:extension.bzl"), "result"));
+    Info info =
+        configuredTarget.get(
+            new SkylarkKey(Label.parseAbsolute("//java/test:extension.bzl"), "result"));
 
-    assertThat((List<?>) skylarkClassObject.getValue("processor_classnames"))
+    assertThat((List<?>) info.getValue("processor_classnames"))
         .containsExactly("com.google.process.stuff");
     assertThat(
             Iterables.transform(
-                ((SkylarkNestedSet) skylarkClassObject.getValue("processor_classpath"))
-                    .toCollection(),
+                ((SkylarkNestedSet) info.getValue("processor_classpath")).toCollection(),
                 new Function<Object, String>() {
                   @Override
                   public String apply(Object o) {
@@ -173,7 +171,6 @@
                   }
                 }))
         .containsExactly("libplugin.jar", "libplugin_dep.jar");
-
   }
 
   @Test
@@ -211,16 +208,15 @@
     ConfiguredTarget javaLibraryTarget = getConfiguredTarget("//java/test:jl");
 
     // Extract out the information from skylark rule
-    SkylarkClassObject skylarkClassObject =
+    Info info =
         myConfiguredTarget.get(
             new SkylarkKey(Label.parseAbsolute("//java/test:extension.bzl"), "result"));
 
-    SkylarkNestedSet rawMyCompileJars =
-        (SkylarkNestedSet) (skylarkClassObject.getValue("compile_jars"));
+    SkylarkNestedSet rawMyCompileJars = (SkylarkNestedSet) (info.getValue("compile_jars"));
     SkylarkNestedSet rawMyTransitiveRuntimeJars =
-        (SkylarkNestedSet) (skylarkClassObject.getValue("transitive_runtime_jars"));
+        (SkylarkNestedSet) (info.getValue("transitive_runtime_jars"));
     SkylarkNestedSet rawMyTransitiveCompileTimeJars =
-        (SkylarkNestedSet) (skylarkClassObject.getValue("transitive_compile_time_jars"));
+        (SkylarkNestedSet) (info.getValue("transitive_compile_time_jars"));
 
     NestedSet<Artifact> myCompileJars = rawMyCompileJars.getSet(Artifact.class);
     NestedSet<Artifact> myTransitiveRuntimeJars = rawMyTransitiveRuntimeJars.getSet(Artifact.class);
@@ -299,18 +295,18 @@
         "    transitive_runtime_jars = ['libd.jar'],",
         ")");
     ConfiguredTarget target = getConfiguredTarget("//foo:myrule");
-    SkylarkClassObject skylarkClassObject = target.get(JavaProvider.JAVA_PROVIDER);
+    Info info = target.get(JavaProvider.JAVA_PROVIDER);
 
-    SkylarkNestedSet compileJars = (SkylarkNestedSet) skylarkClassObject.getValue("compile_jars");
+    SkylarkNestedSet compileJars = (SkylarkNestedSet) info.getValue("compile_jars");
     assertThat(prettyJarNames(compileJars.getSet(Artifact.class))).containsExactly("foo/liba.jar");
 
     SkylarkNestedSet transitiveCompileTimeJars =
-        (SkylarkNestedSet) skylarkClassObject.getValue("transitive_compile_time_jars");
+        (SkylarkNestedSet) info.getValue("transitive_compile_time_jars");
     assertThat(prettyJarNames(
         transitiveCompileTimeJars.getSet(Artifact.class))).containsExactly("foo/libc.jar");
 
     SkylarkNestedSet transitiveRuntimeJars =
-        (SkylarkNestedSet) skylarkClassObject.getValue("transitive_runtime_jars");
+        (SkylarkNestedSet) info.getValue("transitive_runtime_jars");
     assertThat(prettyJarNames(
         transitiveRuntimeJars.getSet(Artifact.class))).containsExactly("foo/libd.jar");
   }
@@ -339,17 +335,17 @@
         "    transitive_runtime_jars = ['libd.jar'],",
         ")");
     ConfiguredTarget target = getConfiguredTarget("//foo:myrule");
-    SkylarkClassObject skylarkClassObject = target.get(JavaProvider.JAVA_PROVIDER);
+    Info info = target.get(JavaProvider.JAVA_PROVIDER);
 
-    SkylarkNestedSet compileJars = (SkylarkNestedSet) skylarkClassObject.getValue("compile_jars");
+    SkylarkNestedSet compileJars = (SkylarkNestedSet) info.getValue("compile_jars");
     assertThat(prettyJarNames(compileJars.getSet(Artifact.class))).containsExactly("foo/liba.jar");
 
     SkylarkNestedSet transitiveCompileTimeJars =
-        (SkylarkNestedSet) skylarkClassObject.getValue("transitive_compile_time_jars");
+        (SkylarkNestedSet) info.getValue("transitive_compile_time_jars");
     assertThat(prettyJarNames(transitiveCompileTimeJars.getSet(Artifact.class))).isEmpty();
 
     SkylarkNestedSet transitiveRuntimeJars =
-        (SkylarkNestedSet) skylarkClassObject.getValue("transitive_runtime_jars");
+        (SkylarkNestedSet) info.getValue("transitive_runtime_jars");
     assertThat(prettyJarNames(
         transitiveRuntimeJars.getSet(Artifact.class))).containsExactly("foo/libd.jar");
   }
@@ -508,8 +504,7 @@
     ConfiguredTarget javaLibraryTarget = getConfiguredTarget("//foo:jl");
     SkylarkKey myProviderKey =
         new SkylarkKey(Label.parseAbsolute("//foo:extension.bzl"), "my_provider");
-    SkylarkClassObject declaredProvider =
-        myRuleTarget.get(myProviderKey);
+    Info declaredProvider = myRuleTarget.get(myProviderKey);
     Object javaProvider = declaredProvider.getValue("p");
     assertThat(javaProvider).isInstanceOf(JavaProvider.class);
     assertThat(javaLibraryTarget.get(JavaProvider.JAVA_PROVIDER)).isEqualTo(javaProvider);
@@ -728,9 +723,9 @@
         "myrule(name='myrule')"
     );
     ConfiguredTarget configuredTarget = getConfiguredTarget("//foo:myrule");
-    SkylarkClassObject skylarkClassObject =
+    Info info =
         configuredTarget.get(new SkylarkKey(Label.parseAbsolute("//foo:rule.bzl"), "result"));
-    assertThat(((String) skylarkClassObject.getValue("strict_java_deps"))).isEqualTo("default");
+    assertThat(((String) info.getValue("strict_java_deps"))).isEqualTo("default");
   }
 
   @Test
@@ -752,9 +747,9 @@
     );
     useConfiguration("--strict_java_deps=ERROR");
     ConfiguredTarget configuredTarget = getConfiguredTarget("//foo:myrule");
-    SkylarkClassObject skylarkClassObject =
+    Info info =
         configuredTarget.get(new SkylarkKey(Label.parseAbsolute("//foo:rule.bzl"), "result"));
-    assertThat(((String) skylarkClassObject.getValue("strict_java_deps"))).isEqualTo("error");
+    assertThat(((String) info.getValue("strict_java_deps"))).isEqualTo("error");
   }
 
   @Test
@@ -778,9 +773,9 @@
         "myrule(name='myrule')"
     );
     ConfiguredTarget configuredTarget = getConfiguredTarget("//foo:myrule");
-    SkylarkClassObject skylarkClassObject =
+    Info info =
         configuredTarget.get(new SkylarkKey(Label.parseAbsolute("//foo:rule.bzl"), "result"));
-    Label javaToolchainLabel = ((Label) skylarkClassObject.getValue("java_toolchain_label"));
+    Label javaToolchainLabel = ((Label) info.getValue("java_toolchain_label"));
     assertThat(javaToolchainLabel.toString()).endsWith("jdk:toolchain");
   }
 
@@ -806,9 +801,9 @@
     );
     useConfiguration("--java_toolchain=//java/com/google/test:toolchain");
     ConfiguredTarget configuredTarget = getConfiguredTarget("//foo:myrule");
-    SkylarkClassObject skylarkClassObject =
+    Info info =
         configuredTarget.get(new SkylarkKey(Label.parseAbsolute("//foo:rule.bzl"), "result"));
-    Label javaToolchainLabel = ((Label) skylarkClassObject.getValue("java_toolchain_label"));
+    Label javaToolchainLabel = ((Label) info.getValue("java_toolchain_label"));
     assertThat(javaToolchainLabel.toString()).isEqualTo("//java/com/google/test:toolchain");
   }
 
diff --git a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkAspectsTest.java b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkAspectsTest.java
index 8b2dc21..df2ba60 100644
--- a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkAspectsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkAspectsTest.java
@@ -33,8 +33,8 @@
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
 import com.google.devtools.build.lib.packages.AspectDefinition;
 import com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
-import com.google.devtools.build.lib.packages.SkylarkClassObjectConstructor.SkylarkKey;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.SkylarkProvider.SkylarkKey;
 import com.google.devtools.build.lib.rules.cpp.CppConfiguration;
 import com.google.devtools.build.lib.rules.java.Jvm;
 import com.google.devtools.build.lib.skyframe.AspectValue;
@@ -96,10 +96,8 @@
     SkylarkKey fooKey = new SkylarkKey(Label.parseAbsolute("//test:aspect.bzl"), "foo");
     SkylarkKey barKey = new SkylarkKey(Label.parseAbsolute("//test:aspect.bzl"), "bar");
 
-    assertThat(configuredAspect.get(fooKey).getConstructor().getKey())
-        .isEqualTo(fooKey);
-    assertThat(configuredAspect.get(barKey).getConstructor().getKey())
-        .isEqualTo(barKey);
+    assertThat(configuredAspect.get(fooKey).getProvider().getKey()).isEqualTo(fooKey);
+    assertThat(configuredAspect.get(barKey).getProvider().getKey()).isEqualTo(barKey);
   }
 
   @Test
@@ -125,10 +123,8 @@
     SkylarkKey fooKey = new SkylarkKey(Label.parseAbsolute("//test:aspect.bzl"), "foo");
     SkylarkKey barKey = new SkylarkKey(Label.parseAbsolute("//test:aspect.bzl"), "bar");
 
-    assertThat(configuredAspect.get(fooKey).getConstructor().getKey())
-        .isEqualTo(fooKey);
-    assertThat(configuredAspect.get(barKey).getConstructor().getKey())
-        .isEqualTo(barKey);
+    assertThat(configuredAspect.get(fooKey).getProvider().getKey()).isEqualTo(fooKey);
+    assertThat(configuredAspect.get(barKey).getProvider().getKey()).isEqualTo(barKey);
   }
 
   private Iterable<String> getAspectDescriptions(AnalysisResult analysisResult) {
@@ -348,7 +344,7 @@
     AnalysisResult analysisResult = update("//test:yyy");
     ConfiguredTarget target = Iterables.getOnlyElement(analysisResult.getTargetsToBuild());
 
-    SkylarkClassObject names = target.get(providerKey);
+    Info names = target.get(providerKey);
     assertThat((Iterable<?>) names.getValue("dir"))
         .containsExactly(
             "aspect_provider",
diff --git a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkIntegrationTest.java b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkIntegrationTest.java
index 6db9009..3879286 100644
--- a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkIntegrationTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkIntegrationTest.java
@@ -33,9 +33,9 @@
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
 import com.google.devtools.build.lib.packages.AttributeContainer;
 import com.google.devtools.build.lib.packages.BuildFileContainsErrorsException;
-import com.google.devtools.build.lib.packages.ClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
-import com.google.devtools.build.lib.packages.SkylarkClassObjectConstructor;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.Provider;
+import com.google.devtools.build.lib.packages.SkylarkProvider;
 import com.google.devtools.build.lib.rules.test.InstrumentedFilesProvider;
 import com.google.devtools.build.lib.skyframe.PackageFunction;
 import com.google.devtools.build.lib.skyframe.SkyFunctions;
@@ -1009,12 +1009,13 @@
     );
 
     ConfiguredTarget configuredTarget = getConfiguredTarget("//test:r");
-    ClassObjectConstructor.Key key = new SkylarkClassObjectConstructor.SkylarkKey(
-        Label.create(configuredTarget.getLabel().getPackageIdentifier(), "extension.bzl"),
-        "my_provider");
-    SkylarkClassObject declaredProvider = configuredTarget.get(key);
+    Provider.Key key =
+        new SkylarkProvider.SkylarkKey(
+            Label.create(configuredTarget.getLabel().getPackageIdentifier(), "extension.bzl"),
+            "my_provider");
+    Info declaredProvider = configuredTarget.get(key);
     assertThat(declaredProvider).isNotNull();
-    assertThat(declaredProvider.getConstructor().getKey()).isEqualTo(key);
+    assertThat(declaredProvider.getProvider().getKey()).isEqualTo(key);
     assertThat(declaredProvider.getValue("x")).isEqualTo(1);
   }
 
@@ -1034,12 +1035,13 @@
     );
 
     ConfiguredTarget configuredTarget  = getConfiguredTarget("//test:r");
-    ClassObjectConstructor.Key key = new SkylarkClassObjectConstructor.SkylarkKey(
-        Label.create(configuredTarget.getLabel().getPackageIdentifier(), "extension.bzl"),
-        "my_provider");
-    SkylarkClassObject declaredProvider = configuredTarget.get(key);
+    Provider.Key key =
+        new SkylarkProvider.SkylarkKey(
+            Label.create(configuredTarget.getLabel().getPackageIdentifier(), "extension.bzl"),
+            "my_provider");
+    Info declaredProvider = configuredTarget.get(key);
     assertThat(declaredProvider).isNotNull();
-    assertThat(declaredProvider.getConstructor().getKey()).isEqualTo(key);
+    assertThat(declaredProvider.getProvider().getKey()).isEqualTo(key);
     assertThat(declaredProvider.getValue("x")).isEqualTo(1);
   }
 
diff --git a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java
index 9c20c6b..c212605 100644
--- a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java
@@ -29,15 +29,15 @@
 import com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition;
 import com.google.devtools.build.lib.packages.BuildType;
 import com.google.devtools.build.lib.packages.ImplicitOutputsFunction;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 import com.google.devtools.build.lib.packages.PredicateWithMessage;
 import com.google.devtools.build.lib.packages.RequiredProviders;
 import com.google.devtools.build.lib.packages.RuleClass;
 import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType;
 import com.google.devtools.build.lib.packages.SkylarkAspect;
 import com.google.devtools.build.lib.packages.SkylarkAspectClass;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
-import com.google.devtools.build.lib.packages.SkylarkClassObjectConstructor;
+import com.google.devtools.build.lib.packages.SkylarkProvider;
 import com.google.devtools.build.lib.packages.SkylarkProviderIdentifier;
 import com.google.devtools.build.lib.rules.SkylarkAttr;
 import com.google.devtools.build.lib.rules.SkylarkAttr.Descriptor;
@@ -240,7 +240,7 @@
 
   private static SkylarkProviderIdentifier declared(String exportedName) {
     return SkylarkProviderIdentifier.forKey(
-        new SkylarkClassObjectConstructor.SkylarkKey(FAKE_LABEL, exportedName));
+        new SkylarkProvider.SkylarkKey(FAKE_LABEL, exportedName));
   }
 
   @Test
@@ -249,39 +249,32 @@
         buildAttribute("a1",
             "b = provider()",
             "attr.label_list(allow_files = True, providers = ['a', b])");
-    assertThat(attr.getRequiredProviders().isSatisfiedBy(set(legacy("a"), declared("b"))))
-        .isTrue();
-    assertThat(attr.getRequiredProviders().isSatisfiedBy(set(legacy("a"))))
-        .isFalse();
-
+    assertThat(attr.getRequiredProviders().isSatisfiedBy(set(legacy("a"), declared("b")))).isTrue();
+    assertThat(attr.getRequiredProviders().isSatisfiedBy(set(legacy("a")))).isFalse();
   }
 
   @Test
   public void testAttrWithProvidersOneEmpty() throws Exception {
     Attribute attr =
-        buildAttribute("a1",
+        buildAttribute(
+            "a1",
             "b = provider()",
             "attr.label_list(allow_files = True, providers = [['a', b],[]])");
     assertThat(attr.getRequiredProviders().acceptsAny()).isTrue();
   }
 
-
   @Test
   public void testAttrWithProvidersList() throws Exception {
     Attribute attr =
         buildAttribute("a1",
             "b = provider()",
             "attr.label_list(allow_files = True, providers = [['a', b], ['c']])");
-    assertThat(attr.getRequiredProviders().isSatisfiedBy(set(legacy("a"), declared("b"))))
-        .isTrue();
-    assertThat(attr.getRequiredProviders().isSatisfiedBy(set(legacy("c"))))
-        .isTrue();
-    assertThat(attr.getRequiredProviders().isSatisfiedBy(set(legacy("a"))))
-        .isFalse();
-
+    assertThat(attr.getRequiredProviders().isSatisfiedBy(set(legacy("a"), declared("b")))).isTrue();
+    assertThat(attr.getRequiredProviders().isSatisfiedBy(set(legacy("c")))).isTrue();
+    assertThat(attr.getRequiredProviders().isSatisfiedBy(set(legacy("a")))).isFalse();
   }
 
-  private static AdvertisedProviderSet set(SkylarkProviderIdentifier ...ids) {
+  private static AdvertisedProviderSet set(SkylarkProviderIdentifier... ids) {
     AdvertisedProviderSet.Builder builder = AdvertisedProviderSet.builder();
     for (SkylarkProviderIdentifier id : ids) {
       builder.addSkylark(id);
@@ -450,9 +443,9 @@
 
   private static final RuleClass.ConfiguredTargetFactory<Object, Object>
       DUMMY_CONFIGURED_TARGET_FACTORY =
-      ruleContext -> {
-        throw new IllegalStateException();
-      };
+          ruleContext -> {
+            throw new IllegalStateException();
+          };
 
   private RuleClass ruleClass(String name) {
     return new RuleClass.Builder(name, RuleClassType.NORMAL, false)
@@ -1056,7 +1049,7 @@
     eval("x = struct(a = 1, b = 2)",
         "y = struct(c = 1, d = 2)",
         "z = x + y\n");
-    SkylarkClassObject z = (SkylarkClassObject) lookup("z");
+    Info z = (Info) lookup("z");
     assertThat(z.getKeys()).isEqualTo(ImmutableSet.of("a", "b", "c", "d"));
   }
 
@@ -1066,7 +1059,7 @@
     eval("x = struct(a = 1, b = 2)",
         "y = struct(c = 1, d = 2)",
         "z = x + y\n");
-    SkylarkClassObject z = (SkylarkClassObject) lookup("z");
+    Info z = (Info) lookup("z");
     assertThat(z.getValue("a")).isEqualTo(1);
     assertThat(z.getValue("b")).isEqualTo(2);
     assertThat(z.getValue("c")).isEqualTo(1);
@@ -1088,7 +1081,7 @@
         "    x += struct(c = 1, d = 2)",
         "  return x",
         "x = func()");
-    SkylarkClassObject x = (SkylarkClassObject) lookup("x");
+    Info x = (Info) lookup("x");
     assertThat(x.getValue("a")).isEqualTo(1);
     assertThat(x.getValue("b")).isEqualTo(2);
     assertThat(x.getValue("c")).isEqualTo(1);
@@ -1160,8 +1153,7 @@
     eval(
         "s = struct(x = {'a' : 1})",
         "s.x['b'] = 2\n");
-    assertThat(((SkylarkClassObject) lookup("s")).getValue("x"))
-        .isEqualTo(ImmutableMap.of("a", 1, "b", 2));
+    assertThat(((Info) lookup("s")).getValue("x")).isEqualTo(ImmutableMap.of("a", 1, "b", 2));
   }
 
   @Test
@@ -1169,7 +1161,7 @@
     eval("def func():", "  return depset([struct(a='a')])", "s = func()");
     Collection<Object> result = ((SkylarkNestedSet) lookup("s")).toCollection();
     assertThat(result).hasSize(1);
-    assertThat(result.iterator().next()).isInstanceOf(SkylarkClassObject.class);
+    assertThat(result.iterator().next()).isInstanceOf(Info.class);
   }
 
   @Test
@@ -1178,21 +1170,22 @@
     checkEvalError("depsets cannot contain mutable items", "depset([struct(a=[])])");
   }
 
-  private static SkylarkClassObject makeStruct(String field, Object value) {
-    return NativeClassObjectConstructor.STRUCT.create(
-        ImmutableMap.of(field, value),
-        "no field '%'");
+  private static Info makeStruct(String field, Object value) {
+    return NativeProvider.STRUCT.create(ImmutableMap.of(field, value), "no field '%'");
   }
 
-  private static SkylarkClassObject makeBigStruct(Environment env) {
+  private static Info makeBigStruct(Environment env) {
     // struct(a=[struct(x={1:1}), ()], b=(), c={2:2})
-    return NativeClassObjectConstructor.STRUCT.create(
+    return NativeProvider.STRUCT.create(
         ImmutableMap.<String, Object>of(
-            "a", MutableList.<Object>of(env,
-                NativeClassObjectConstructor.STRUCT.create(ImmutableMap.<String, Object>of(
-                    "x", SkylarkDict.<Object, Object>of(env, 1, 1)),
-                    "no field '%s'"),
-                Tuple.of()),
+            "a",
+                MutableList.<Object>of(
+                    env,
+                    NativeProvider.STRUCT.create(
+                        ImmutableMap.<String, Object>of(
+                            "x", SkylarkDict.<Object, Object>of(env, 1, 1)),
+                        "no field '%s'"),
+                    Tuple.of()),
             "b", Tuple.of(),
             "c", SkylarkDict.<Object, Object>of(env, 2, 2)),
         "no field '%s'");
@@ -1228,14 +1221,13 @@
     );
     assertThat(lookup("d_x")).isEqualTo(1);
     assertThat(lookup("d_y")).isEqualTo("abc");
-    SkylarkClassObjectConstructor dataConstructor = (SkylarkClassObjectConstructor) lookup("data");
-    SkylarkClassObject data = (SkylarkClassObject) lookup("d");
-    assertThat(data.getConstructor()).isEqualTo(dataConstructor);
+    SkylarkProvider dataConstructor = (SkylarkProvider) lookup("data");
+    Info data = (Info) lookup("d");
+    assertThat(data.getProvider()).isEqualTo(dataConstructor);
     assertThat(dataConstructor.isExported()).isTrue();
     assertThat(dataConstructor.getPrintableName()).isEqualTo("data");
-    assertThat(dataConstructor.getKey()).isEqualTo(
-        new SkylarkClassObjectConstructor.SkylarkKey(FAKE_LABEL, "data")
-    );
+    assertThat(dataConstructor.getKey())
+        .isEqualTo(new SkylarkProvider.SkylarkKey(FAKE_LABEL, "data"));
   }
 
   @Test
@@ -1250,11 +1242,11 @@
     );
     assertThat(lookup("x")).isEqualTo(1);
     assertThat(lookup("y")).isEqualTo("abc");
-    SkylarkClassObjectConstructor dataConstructor = (SkylarkClassObjectConstructor) lookup("data");
-    SkylarkClassObject dx = (SkylarkClassObject) lookup("dx");
-    assertThat(dx.getConstructor()).isEqualTo(dataConstructor);
-    SkylarkClassObject dy = (SkylarkClassObject) lookup("dy");
-    assertThat(dy.getConstructor()).isEqualTo(dataConstructor);
+    SkylarkProvider dataConstructor = (SkylarkProvider) lookup("data");
+    Info dx = (Info) lookup("dx");
+    assertThat(dx.getProvider()).isEqualTo(dataConstructor);
+    Info dy = (Info) lookup("dy");
+    assertThat(dy.getProvider()).isEqualTo(dataConstructor);
   }
 
   @Test
@@ -1276,11 +1268,10 @@
     evalAndExport(
         "data = struct(x = 1)"
     );
-    SkylarkClassObject data = (SkylarkClassObject) lookup("data");
-    assertThat(NativeClassObjectConstructor.STRUCT.isExported()).isTrue();
-    assertThat(data.getConstructor()).isEqualTo(NativeClassObjectConstructor.STRUCT);
-    assertThat(data.getConstructor().getKey())
-        .isEqualTo(NativeClassObjectConstructor.STRUCT.getKey());
+    Info data = (Info) lookup("data");
+    assertThat(NativeProvider.STRUCT.isExported()).isTrue();
+    assertThat(data.getProvider()).isEqualTo(NativeProvider.STRUCT);
+    assertThat(data.getProvider().getKey()).isEqualTo(NativeProvider.STRUCT.getKey());
   }
 
   @Test
@@ -1450,15 +1441,13 @@
         "     provider() ]",
         "]"
     );
-    SkylarkClassObjectConstructor p = (SkylarkClassObjectConstructor) lookup("p");
+    SkylarkProvider p = (SkylarkProvider) lookup("p");
     SkylarkAspect a = (SkylarkAspect) lookup("a");
-    SkylarkClassObjectConstructor p1 = (SkylarkClassObjectConstructor) lookup("p1");
+    SkylarkProvider p1 = (SkylarkProvider) lookup("p1");
     assertThat(p.getPrintableName()).isEqualTo("p");
-    assertThat(p.getKey())
-        .isEqualTo(new SkylarkClassObjectConstructor.SkylarkKey(FAKE_LABEL, "p"));
+    assertThat(p.getKey()).isEqualTo(new SkylarkProvider.SkylarkKey(FAKE_LABEL, "p"));
     assertThat(p1.getPrintableName()).isEqualTo("p1");
-    assertThat(p1.getKey())
-        .isEqualTo(new SkylarkClassObjectConstructor.SkylarkKey(FAKE_LABEL, "p1"));
+    assertThat(p1.getKey()).isEqualTo(new SkylarkProvider.SkylarkKey(FAKE_LABEL, "p1"));
     assertThat(a.getAspectClass()).isEqualTo(
         new SkylarkAspectClass(FAKE_LABEL, "a")
     );
@@ -1470,13 +1459,11 @@
         "p = provider()",
         "p1 = p"
     );
-    SkylarkClassObjectConstructor p = (SkylarkClassObjectConstructor) lookup("p");
-    SkylarkClassObjectConstructor p1 = (SkylarkClassObjectConstructor) lookup("p1");
+    SkylarkProvider p = (SkylarkProvider) lookup("p");
+    SkylarkProvider p1 = (SkylarkProvider) lookup("p1");
     assertThat(p).isEqualTo(p1);
-    assertThat(p.getKey())
-        .isEqualTo(new SkylarkClassObjectConstructor.SkylarkKey(FAKE_LABEL, "p"));
-    assertThat(p1.getKey())
-        .isEqualTo(new SkylarkClassObjectConstructor.SkylarkKey(FAKE_LABEL, "p"));
+    assertThat(p.getKey()).isEqualTo(new SkylarkProvider.SkylarkKey(FAKE_LABEL, "p"));
+    assertThat(p1.getKey()).isEqualTo(new SkylarkProvider.SkylarkKey(FAKE_LABEL, "p"));
   }
 
 
diff --git a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleContextTest.java b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleContextTest.java
index 5610d42..ae4afc46 100644
--- a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleContextTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleContextTest.java
@@ -27,7 +27,7 @@
 import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
 import com.google.devtools.build.lib.analysis.actions.SpawnAction;
 import com.google.devtools.build.lib.cmdline.Label;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
 import com.google.devtools.build.lib.rules.SkylarkRuleContext;
 import com.google.devtools.build.lib.rules.java.JavaProvider;
 import com.google.devtools.build.lib.rules.java.JavaSourceJarsProvider;
@@ -1524,9 +1524,8 @@
     SkylarkRuleContext ruleContext = createRuleContext("//test:testing");
 
     Object provider = evalRuleContextCode(ruleContext, "ruleContext.attr.dep[Actions]");
-    assertThat(provider).isInstanceOf(SkylarkClassObject.class);
-    assertThat(((SkylarkClassObject) provider).getConstructor())
-        .isEqualTo(ActionsProvider.SKYLARK_CONSTRUCTOR);
+    assertThat(provider).isInstanceOf(Info.class);
+    assertThat(((Info) provider).getProvider()).isEqualTo(ActionsProvider.SKYLARK_CONSTRUCTOR);
     update("actions", provider);
 
     Object mapping = eval("actions.by_file");
diff --git a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleImplementationFunctionsTest.java b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleImplementationFunctionsTest.java
index 7ad6346..e23df8b 100644
--- a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleImplementationFunctionsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleImplementationFunctionsTest.java
@@ -35,8 +35,8 @@
 import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction.Substitution;
 import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.events.Event;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
-import com.google.devtools.build.lib.packages.SkylarkClassObjectConstructor.SkylarkKey;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.SkylarkProvider.SkylarkKey;
 import com.google.devtools.build.lib.rules.SkylarkRuleContext;
 import com.google.devtools.build.lib.skylark.util.SkylarkTestCase;
 import com.google.devtools.build.lib.skylarkinterface.Param;
@@ -906,8 +906,8 @@
 
     Object provider = configuredTarget.get("provider");
     assertThat(provider).isInstanceOf(DefaultProvider.class);
-    assertThat(((SkylarkClassObject) provider).getConstructor().getKey()).isEqualTo(
-        DefaultProvider.SKYLARK_CONSTRUCTOR.getKey());
+    assertThat(((Info) provider).getProvider().getKey())
+        .isEqualTo(DefaultProvider.SKYLARK_CONSTRUCTOR.getKey());
 
     assertThat(configuredTarget.get("dir"))
         .isEqualTo(
@@ -983,8 +983,8 @@
 
     Object provider = configuredTarget.get("provider");
     assertThat(provider).isInstanceOf(DefaultProvider.class);
-    assertThat(((SkylarkClassObject) provider).getConstructor().getKey()).isEqualTo(
-        DefaultProvider.SKYLARK_CONSTRUCTOR.getKey());
+    assertThat(((Info) provider).getProvider().getKey())
+        .isEqualTo(DefaultProvider.SKYLARK_CONSTRUCTOR.getKey());
 
     assertThat(configuredTarget.get("dir"))
         .isEqualTo(
@@ -1076,8 +1076,8 @@
 
     Object provider = configuredTarget.get("provider");
     assertThat(provider).isInstanceOf(DefaultProvider.class);
-    assertThat(((SkylarkClassObject) provider).getConstructor().getKey()).isEqualTo(
-        DefaultProvider.SKYLARK_CONSTRUCTOR.getKey());
+    assertThat(((Info) provider).getProvider().getKey())
+        .isEqualTo(DefaultProvider.SKYLARK_CONSTRUCTOR.getKey());
 
     assertThat(configuredTarget.get("dir"))
         .isEqualTo(
@@ -1139,8 +1139,8 @@
     ConfiguredTarget configuredTarget = getConfiguredTarget("//test:my_rule");
     Object provider = configuredTarget.get("default");
     assertThat(provider).isInstanceOf(DefaultProvider.class);
-    assertThat(((SkylarkClassObject) provider).getConstructor().getKey()).isEqualTo(
-        DefaultProvider.SKYLARK_CONSTRUCTOR.getKey());
+    assertThat(((Info) provider).getProvider().getKey())
+        .isEqualTo(DefaultProvider.SKYLARK_CONSTRUCTOR.getKey());
   }
 
   @Test
@@ -1210,9 +1210,9 @@
         "bar_rule(name = 'my_rule', deps = [':dep_rule'])");
     ConfiguredTarget configuredTarget = getConfiguredTarget("//test:my_rule");
     Object provider = configuredTarget.get("proxy");
-    assertThat(provider).isInstanceOf(SkylarkClassObject.class);
-    assertThat(((SkylarkClassObject) provider).getConstructor().getKey()).isEqualTo(
-        new SkylarkKey(Label.parseAbsolute("//test:foo.bzl"), "foo_provider"));
+    assertThat(provider).isInstanceOf(Info.class);
+    assertThat(((Info) provider).getProvider().getKey())
+        .isEqualTo(new SkylarkKey(Label.parseAbsolute("//test:foo.bzl"), "foo_provider"));
   }
 
   @Test
@@ -1250,10 +1250,10 @@
         "bar_rule(name = 'my_rule', deps = [':dep_rule'])");
     ConfiguredTarget configuredTarget = getConfiguredTarget("//test:my_rule");
     Object provider = configuredTarget.get("proxy");
-    assertThat(provider).isInstanceOf(SkylarkClassObject.class);
-    assertThat(((SkylarkClassObject) provider).getConstructor().getKey()).isEqualTo(
-        new SkylarkKey(Label.parseAbsolute("//test:foo.bzl"), "foo_provider"));
-    assertThat(((SkylarkClassObject) provider).getValue("a")).isEqualTo(123);
+    assertThat(provider).isInstanceOf(Info.class);
+    assertThat(((Info) provider).getProvider().getKey())
+        .isEqualTo(new SkylarkKey(Label.parseAbsolute("//test:foo.bzl"), "foo_provider"));
+    assertThat(((Info) provider).getValue("a")).isEqualTo(123);
   }
 
   @Test
@@ -1297,9 +1297,9 @@
         "bar_rule(name = 'my_rule', deps = [':dep_rule'])");
     ConfiguredTarget configuredTarget = getConfiguredTarget("//test:my_rule");
     Object provider = configuredTarget.get("proxy");
-    assertThat(provider).isInstanceOf(SkylarkClassObject.class);
-    assertThat(((SkylarkClassObject) provider).getConstructor().getKey()).isEqualTo(
-        new SkylarkKey(Label.parseAbsolute("//test:foo.bzl"), "foo_provider"));
+    assertThat(provider).isInstanceOf(Info.class);
+    assertThat(((Info) provider).getProvider().getKey())
+        .isEqualTo(new SkylarkKey(Label.parseAbsolute("//test:foo.bzl"), "foo_provider"));
   }
 
   @Test
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/EvalUtilsTest.java b/src/test/java/com/google/devtools/build/lib/syntax/EvalUtilsTest.java
index b7e6f04..3782c32 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/EvalUtilsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/EvalUtilsTest.java
@@ -20,7 +20,7 @@
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
+import com.google.devtools.build.lib.packages.NativeProvider;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
 import com.google.devtools.build.lib.syntax.EvalUtils.ComparisonException;
 import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
@@ -115,19 +115,18 @@
   @Test
   public void testComparatorWithDifferentTypes() throws Exception {
     Object[] objects = {
-        "1",
-        2,
-        true,
-        Runtime.NONE,
-        SkylarkList.Tuple.of(1, 2, 3),
-        SkylarkList.Tuple.of("1", "2", "3"),
-        SkylarkList.MutableList.of(env, 1, 2, 3),
-        SkylarkList.MutableList.of(env, "1", "2", "3"),
-        SkylarkDict.of(env, "key", 123),
-        SkylarkDict.of(env, 123, "value"),
-        NestedSetBuilder.stableOrder().add(1).add(2).add(3).build(),
-        NativeClassObjectConstructor.STRUCT.create(
-            ImmutableMap.of("key", (Object) "value"), "no field %s"),
+      "1",
+      2,
+      true,
+      Runtime.NONE,
+      SkylarkList.Tuple.of(1, 2, 3),
+      SkylarkList.Tuple.of("1", "2", "3"),
+      SkylarkList.MutableList.of(env, 1, 2, 3),
+      SkylarkList.MutableList.of(env, "1", "2", "3"),
+      SkylarkDict.of(env, "key", 123),
+      SkylarkDict.of(env, 123, "value"),
+      NestedSetBuilder.stableOrder().add(1).add(2).add(3).build(),
+      NativeProvider.STRUCT.create(ImmutableMap.of("key", (Object) "value"), "no field %s"),
     };
 
     for (int i = 0; i < objects.length; ++i) {
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java
index d760a9e..983c7a2 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java
@@ -25,8 +25,8 @@
 import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
 import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
+import com.google.devtools.build.lib.packages.NativeProvider;
 import com.google.devtools.build.lib.skylarkinterface.Param;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
@@ -1424,11 +1424,10 @@
   }
 
   @SkylarkModule(name = "SkylarkClassObjectWithSkylarkCallables", doc = "")
-  static final class SkylarkClassObjectWithSkylarkCallables extends SkylarkClassObject {
-    private static final NativeClassObjectConstructor<SkylarkClassObjectWithSkylarkCallables>
-        CONSTRUCTOR =
-            new NativeClassObjectConstructor<SkylarkClassObjectWithSkylarkCallables>(
-                SkylarkClassObjectWithSkylarkCallables.class, "struct_with_skylark_callables") {};
+  static final class SkylarkClassObjectWithSkylarkCallables extends Info {
+    private static final NativeProvider<SkylarkClassObjectWithSkylarkCallables> CONSTRUCTOR =
+        new NativeProvider<SkylarkClassObjectWithSkylarkCallables>(
+            SkylarkClassObjectWithSkylarkCallables.class, "struct_with_skylark_callables") {};
 
     SkylarkClassObjectWithSkylarkCallables() {
       super(
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/ValidationTest.java b/src/test/java/com/google/devtools/build/lib/syntax/ValidationTest.java
index 10c80c7..27b8442 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/ValidationTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/ValidationTest.java
@@ -18,7 +18,7 @@
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.analysis.RuleConfiguredTarget;
 import com.google.devtools.build.lib.events.Event;
-import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.Info;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
 import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
 import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
@@ -298,8 +298,7 @@
     assertThat(EvalUtils.getSkylarkType(emptyTupleClass)).isEqualTo(Tuple.class);
     assertThat(EvalUtils.getSkylarkType(tupleClass)).isEqualTo(Tuple.class);
 
-    assertThat(EvalUtils.getSkylarkType(SkylarkClassObject.class))
-        .isEqualTo(SkylarkClassObject.class);
+    assertThat(EvalUtils.getSkylarkType(Info.class)).isEqualTo(Info.class);
     try {
       EvalUtils.getSkylarkType(ClassObject.class);
       throw new Exception("Should have raised IllegalArgumentException exception");
@@ -338,8 +337,7 @@
     // TODO(bazel-team): move to some other place to remove dependency of syntax tests on Artifact?
     assertThat(SkylarkType.of(Artifact.SpecialArtifact.class))
         .isEqualTo(SkylarkType.of(Artifact.class));
-    assertThat(SkylarkType.of(RuleConfiguredTarget.class))
-        .isNotEqualTo(SkylarkType.of(SkylarkClassObject.class));
+    assertThat(SkylarkType.of(RuleConfiguredTarget.class)).isNotEqualTo(SkylarkType.of(Info.class));
   }
 
   @Test