Spam lib/rules/android with @AutoValue. Mostly created by

--
MOS_MIGRATED_REVID=131832497
diff --git a/src/main/java/com/google/devtools/build/lib/BUILD b/src/main/java/com/google/devtools/build/lib/BUILD
index 0acce5a..4a34d25 100644
--- a/src/main/java/com/google/devtools/build/lib/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/BUILD
@@ -882,6 +882,7 @@
         "//src/main/protobuf:android_deploy_info_java_proto",
         "//src/main/protobuf:apk_manifest_java_proto",
         "//third_party:android_sdklib",
+        "//third_party:auto_value",
         "//third_party:guava",
         "//third_party:jsr305",
         "//third_party/protobuf",
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java
index 5f3f3c6..21ed2dd 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java
@@ -71,14 +71,12 @@
 import com.google.devtools.build.lib.syntax.Type;
 import com.google.devtools.build.lib.util.Preconditions;
 import com.google.devtools.build.lib.vfs.PathFragment;
-
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-
 import javax.annotation.Nullable;
 
 /**
@@ -689,8 +687,8 @@
 
     if (proguardOutput.getMapping() != null) {
       builder.add(ProguardMappingProvider.class,
-          new ProguardMappingProvider(proguardOutput.getMapping(),
-                                      proguardOutput.getProtoMapping()));
+          ProguardMappingProvider.create(
+              proguardOutput.getMapping(), proguardOutput.getProtoMapping()));
     }
 
     return builder
@@ -709,11 +707,11 @@
             JavaSourceInfoProvider.fromJavaTargetAttributes(resourceClasses, javaSemantics))
         .add(
             ApkProvider.class,
-            new ApkProvider(
+            ApkProvider.create(
                 NestedSetBuilder.create(Order.STABLE_ORDER, zipAlignedApk),
                 coverageMetadata,
                 NestedSetBuilder.create(Order.STABLE_ORDER, applicationManifest.getManifest())))
-        .add(AndroidPreDexJarProvider.class, new AndroidPreDexJarProvider(jarToDex))
+        .add(AndroidPreDexJarProvider.class, AndroidPreDexJarProvider.create(jarToDex))
         .addOutputGroup("mobile_install_full" + INTERNAL_SUFFIX, fullInstallOutputGroup)
         .addOutputGroup(
             "mobile_install_incremental" + INTERNAL_SUFFIX, incrementalInstallOutputGroup)
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCcLinkParamsProvider.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCcLinkParamsProvider.java
index 096a60b..c19034b 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCcLinkParamsProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCcLinkParamsProvider.java
@@ -13,6 +13,7 @@
 // limitations under the License.
 package com.google.devtools.build.lib.rules.android;
 
+import com.google.auto.value.AutoValue;
 import com.google.common.base.Function;
 import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
 import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
@@ -20,20 +21,15 @@
 import com.google.devtools.build.lib.rules.cpp.CcLinkParamsStore;
 import com.google.devtools.build.lib.rules.cpp.CcLinkParamsStore.CcLinkParamsStoreImpl;
 
-/**
- * A target that provides C++ libraries to be linked into Android targets.
- */
+/** A target that provides C++ libraries to be linked into Android targets. */
+@AutoValue
 @Immutable
-public final class AndroidCcLinkParamsProvider implements TransitiveInfoProvider {
-  private final CcLinkParamsStoreImpl store;
-
-  public AndroidCcLinkParamsProvider(CcLinkParamsStore store) {
-    this.store = new CcLinkParamsStoreImpl(store);
+public abstract class AndroidCcLinkParamsProvider implements TransitiveInfoProvider {
+  public static AndroidCcLinkParamsProvider create(CcLinkParamsStore store) {
+    return new AutoValue_AndroidCcLinkParamsProvider(new CcLinkParamsStoreImpl(store));
   }
 
-  public CcLinkParamsStore getLinkParams() {
-    return store;
-  }
+  public abstract CcLinkParamsStore getLinkParams();
 
   public static final Function<TransitiveInfoCollection, CcLinkParamsStore> TO_LINK_PARAMS =
       new Function<TransitiveInfoCollection, CcLinkParamsStore>() {
@@ -44,4 +40,6 @@
           return provider == null ? null : provider.getLinkParams();
         }
       };
+
+  AndroidCcLinkParamsProvider() {}
 }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidIdlHelper.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidIdlHelper.java
index 40d3495..8a8f963 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidIdlHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidIdlHelper.java
@@ -385,8 +385,8 @@
     }
     importsBuilder.addAll(idlImports);
 
-    return new AndroidIdlProvider(rootsBuilder.build(),
-        importsBuilder.build(), jarsBuilder.build());
+    return AndroidIdlProvider.create(
+        rootsBuilder.build(), importsBuilder.build(), jarsBuilder.build());
   }
 
   /**
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidIdlProvider.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidIdlProvider.java
index c7365db..9170544 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidIdlProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidIdlProvider.java
@@ -13,6 +13,7 @@
 // limitations under the License.
 package com.google.devtools.build.lib.rules.android;
 
+import com.google.auto.value.AutoValue;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
@@ -24,45 +25,32 @@
  * Configured targets implementing this provider can contribute Android IDL information to the
  * compilation.
  */
+@AutoValue
 @Immutable
-public final class AndroidIdlProvider implements TransitiveInfoProvider {
+public abstract class AndroidIdlProvider implements TransitiveInfoProvider {
 
-  public static final AndroidIdlProvider EMPTY = new AndroidIdlProvider(
-      NestedSetBuilder.<String>emptySet(Order.STABLE_ORDER),
-      NestedSetBuilder.<Artifact>emptySet(Order.STABLE_ORDER),
-      NestedSetBuilder.<Artifact>emptySet(Order.STABLE_ORDER));
+  public static final AndroidIdlProvider EMPTY =
+      AndroidIdlProvider.create(
+          NestedSetBuilder.<String>emptySet(Order.STABLE_ORDER),
+          NestedSetBuilder.<Artifact>emptySet(Order.STABLE_ORDER),
+          NestedSetBuilder.<Artifact>emptySet(Order.STABLE_ORDER));
 
-  private final NestedSet<String> transitiveIdlImportRoots;
-  private final NestedSet<Artifact> transitiveIdlImports;
-  private final NestedSet<Artifact> transitiveIdlJars;
-
-  public AndroidIdlProvider(
+  public static AndroidIdlProvider create(
       NestedSet<String> transitiveIdlImportRoots,
       NestedSet<Artifact> transitiveIdlImports,
       NestedSet<Artifact> transitiveIdlJars) {
-    this.transitiveIdlImportRoots = transitiveIdlImportRoots;
-    this.transitiveIdlImports = transitiveIdlImports;
-    this.transitiveIdlJars = transitiveIdlJars;
+    return new AutoValue_AndroidIdlProvider(
+        transitiveIdlImportRoots, transitiveIdlImports, transitiveIdlJars);
   }
 
-  /**
-   * The set of IDL import roots need for compiling the IDL sources in the transitive closure.
-   */
-  public NestedSet<String> getTransitiveIdlImportRoots() {
-    return transitiveIdlImportRoots;
-  }
+  /** The set of IDL import roots need for compiling the IDL sources in the transitive closure. */
+  public abstract NestedSet<String> getTransitiveIdlImportRoots();
 
-  /**
-   * The IDL files in the transitive closure.
-   */
-  public NestedSet<Artifact> getTransitiveIdlImports() {
-    return transitiveIdlImports;
-  }
+  /** The IDL files in the transitive closure. */
+  public abstract NestedSet<Artifact> getTransitiveIdlImports();
 
-  /**
-   * The IDL jars in the transitive closure, both class and source jars.
-   */
-  public NestedSet<Artifact> getTransitiveIdlJars() {
-    return transitiveIdlJars;
-  }
+  /** The IDL jars in the transitive closure, both class and source jars. */
+  public abstract NestedSet<Artifact> getTransitiveIdlJars();
+
+  AndroidIdlProvider() {}
 }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibrary.java
index f310e41..676f9cd 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibrary.java
@@ -134,12 +134,12 @@
       primaryResources = resourceApk.getPrimaryResource();
       // applicationManifest has already been checked for nullness above in this method
       ApplicationManifest applicationManifest = androidSemantics.getManifestForRule(ruleContext);
-      aar = new Aar(aarOut, applicationManifest.getManifest());
+      aar = Aar.create(aarOut, applicationManifest.getManifest());
       transitiveAars.add(aar);
     } else if (AndroidCommon.getAndroidResources(ruleContext) != null) {
       primaryResources = Iterables.getOnlyElement(
           AndroidCommon.getAndroidResources(ruleContext).getDirectAndroidResources());
-      aar = new Aar(aarOut, primaryResources.getManifest());
+      aar = Aar.create(aarOut, primaryResources.getManifest());
       transitiveAars.add(aar);
     } else {
       // there are no local resources and resources attribute was not specified either
@@ -149,7 +149,7 @@
 
       String javaPackage = AndroidCommon.getJavaPackage(ruleContext);
 
-      ResourceContainer resourceContainer = new ResourceContainer(ruleContext.getLabel(),
+      ResourceContainer resourceContainer = ResourceContainer.create(ruleContext.getLabel(),
           javaPackage,
           null /* renameManifestPackage */,
           false /* inlinedConstants */,
@@ -193,28 +193,34 @@
 
     NestedSetBuilder<Artifact> transitiveResourcesJars = collectTransitiveResourceJars(ruleContext);
     if (androidCommon.getResourceClassJar() != null) {
-      transitiveResourcesJars.add(androidCommon.getResourceClassJar());      
+      transitiveResourcesJars.add(androidCommon.getResourceClassJar());
     }
 
     builder
-        .add(AndroidNativeLibraryProvider.class,
-            new AndroidNativeLibraryProvider(transitiveNativeLibraries))
-        .add(JavaNeverlinkInfoProvider.class,
+        .add(
+            AndroidNativeLibraryProvider.class,
+            AndroidNativeLibraryProvider.create(transitiveNativeLibraries))
+        .add(
+            JavaNeverlinkInfoProvider.class,
             new JavaNeverlinkInfoProvider(androidCommon.isNeverLink()))
-        .add(JavaSourceInfoProvider.class,
+        .add(
+            JavaSourceInfoProvider.class,
             JavaSourceInfoProvider.fromJavaTargetAttributes(javaTargetAttributes, javaSemantics))
         .add(JavaSourceJarsProvider.class, androidCommon.getJavaSourceJarsProvider())
-        .add(AndroidCcLinkParamsProvider.class,
-            new AndroidCcLinkParamsProvider(androidCommon.getCcLinkParamsStore()))
+        .add(
+            AndroidCcLinkParamsProvider.class,
+            AndroidCcLinkParamsProvider.create(androidCommon.getCcLinkParamsStore()))
         .add(JavaPluginInfoProvider.class, JavaCommon.getTransitivePlugins(ruleContext))
         .add(ProguardSpecProvider.class, new ProguardSpecProvider(transitiveProguardConfigs))
         .addOutputGroup(OutputGroupProvider.HIDDEN_TOP_LEVEL, transitiveProguardConfigs)
-        .add(AndroidLibraryResourceClassJarProvider.class,
-            new AndroidLibraryResourceClassJarProvider(transitiveResourcesJars.build()));
+        .add(
+            AndroidLibraryResourceClassJarProvider.class,
+            AndroidLibraryResourceClassJarProvider.create(transitiveResourcesJars.build()));
 
     if (!JavaCommon.isNeverLink(ruleContext)) {
-      builder.add(AndroidLibraryAarProvider.class,
-          new AndroidLibraryAarProvider(aar, transitiveAars.build()));
+      builder.add(
+          AndroidLibraryAarProvider.class,
+          AndroidLibraryAarProvider.create(aar, transitiveAars.build()));
     }
 
     return builder.build();
@@ -244,7 +250,7 @@
     }
     return builder;
   }
-  
+
   private NestedSetBuilder<Artifact> collectTransitiveResourceJars(RuleContext ruleContext) {
     NestedSetBuilder<Artifact> builder = NestedSetBuilder.naiveLinkOrder();
     Iterable<AndroidLibraryResourceClassJarProvider> providers =
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibraryAarProvider.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibraryAarProvider.java
index 2f4cef5..ff9236e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibraryAarProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibraryAarProvider.java
@@ -13,73 +13,43 @@
 // limitations under the License.
 package com.google.devtools.build.lib.rules.android;
 
+import com.google.auto.value.AutoValue;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-import com.google.devtools.build.lib.util.Preconditions;
-
-import java.util.Objects;
+import javax.annotation.Nullable;
 
 /**
  * A target that can provide the aar artifact of Android libraries and all the manifests that are
  * merged into the main aar manifest.
  */
+@AutoValue
 @Immutable
-public final class AndroidLibraryAarProvider implements TransitiveInfoProvider {
+public abstract class AndroidLibraryAarProvider implements TransitiveInfoProvider {
 
-  private final Aar aar;
-  private final NestedSet<Aar> transitiveAars;
-
-  public AndroidLibraryAarProvider(Aar aar, NestedSet<Aar> transitiveAars) {
-    this.aar = aar;
-    this.transitiveAars = transitiveAars;
+  public static AndroidLibraryAarProvider create(@Nullable Aar aar, NestedSet<Aar> transitiveAars) {
+    return new AutoValue_AndroidLibraryAarProvider(aar, transitiveAars);
   }
 
-  public Aar getAar() {
-    return aar;
-  }
+  @Nullable public abstract Aar getAar();
 
-  public NestedSet<Aar> getTransitiveAars() {
-    return transitiveAars;
-  }
+  public abstract NestedSet<Aar> getTransitiveAars();
 
-  /**
-   * The .aar file and associated AndroidManifest.xml contributed by a single target.
-   */
+  /** The .aar file and associated AndroidManifest.xml contributed by a single target. */
+  @AutoValue
   @Immutable
-  public static final class Aar {
-    private final Artifact aar;
-    private final Artifact manifest;
-
-    public Aar(Artifact aar, Artifact manifest) {
-      this.aar = Preconditions.checkNotNull(aar);
-      this.manifest = Preconditions.checkNotNull(manifest);
+  public abstract static class Aar {
+    public static Aar create(Artifact aar, Artifact manifest) {
+      return new AutoValue_AndroidLibraryAarProvider_Aar(aar, manifest);
     }
 
-    public Artifact getAar() {
-      return aar;
-    }
+    public abstract Artifact getAar();
 
-    public Artifact getManifest() {
-      return manifest;
-    }
+    public abstract Artifact getManifest();
 
-    @Override
-    public int hashCode() {
-      return Objects.hash(aar, manifest);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-      if (this == obj) {
-        return true;
-      }
-      if (!(obj instanceof Aar)) {
-        return false;
-      }
-      Aar other = (Aar) obj;
-      return aar.equals(other.aar) && manifest.equals(other.manifest);
-    }
+    Aar() {}
   }
+
+  AndroidLibraryAarProvider() {}
 }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibraryResourceClassJarProvider.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibraryResourceClassJarProvider.java
index 69d2a7e..8135b06 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibraryResourceClassJarProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibraryResourceClassJarProvider.java
@@ -14,31 +14,26 @@
 
 package com.google.devtools.build.lib.rules.android;
 
-import static com.google.common.base.Preconditions.checkNotNull;
-
+import com.google.auto.value.AutoValue;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
-
 import javax.annotation.Nonnull;
 
 /**
- * A provider which contains the resource class jars from android_library rules. See
- * {@link AndroidRuleClasses#ANDROID_RESOURCES_CLASS_JAR}.
+ * A provider which contains the resource class jars from android_library rules. See {@link
+ * AndroidRuleClasses#ANDROID_RESOURCES_CLASS_JAR}.
  */
-public class AndroidLibraryResourceClassJarProvider implements TransitiveInfoProvider {
+@AutoValue
+public abstract class AndroidLibraryResourceClassJarProvider implements TransitiveInfoProvider {
 
-  @Nonnull
-  private final NestedSet<Artifact> resourceClassJars;
-
-  public AndroidLibraryResourceClassJarProvider(NestedSet<Artifact> resourceClassJars) {
-    checkNotNull(resourceClassJars);
-    this.resourceClassJars = resourceClassJars;
+  public static AndroidLibraryResourceClassJarProvider create(
+      NestedSet<Artifact> resourceClassJars) {
+    return new AutoValue_AndroidLibraryResourceClassJarProvider(resourceClassJars);
   }
 
   @Nonnull
-  public NestedSet<Artifact> getResourceClassJars() {
-    return resourceClassJars;
-  }
+  public abstract NestedSet<Artifact> getResourceClassJars();
+
+  AndroidLibraryResourceClassJarProvider() {}
 }
-
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidNativeLibraryProvider.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidNativeLibraryProvider.java
index 7998547..1ff4797 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidNativeLibraryProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidNativeLibraryProvider.java
@@ -13,25 +13,25 @@
 // limitations under the License.
 package com.google.devtools.build.lib.rules.android;
 
+import com.google.auto.value.AutoValue;
 import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
 import com.google.devtools.build.lib.rules.cpp.LinkerInput;
 
 /**
- * A target that can provide native libraries (they are always dynamic ones) to
- * Android binaries.
+ * A target that can provide native libraries (they are always dynamic ones) to Android binaries.
  */
+@AutoValue
 @Immutable
-public final class AndroidNativeLibraryProvider implements TransitiveInfoProvider {
+public abstract class AndroidNativeLibraryProvider implements TransitiveInfoProvider {
 
-  private final NestedSet<LinkerInput> transitiveAndroidNativeLibraries;
-
-  public AndroidNativeLibraryProvider(NestedSet<LinkerInput> transitiveAndroidNativeLibraries) {
-    this.transitiveAndroidNativeLibraries = transitiveAndroidNativeLibraries;
+  public static AndroidNativeLibraryProvider create(
+      NestedSet<LinkerInput> transitiveAndroidNativeLibraries) {
+    return new AutoValue_AndroidNativeLibraryProvider(transitiveAndroidNativeLibraries);
   }
 
-  public NestedSet<LinkerInput> getTransitiveAndroidNativeLibraries() {
-    return transitiveAndroidNativeLibraries;
-  }
+  public abstract NestedSet<LinkerInput> getTransitiveAndroidNativeLibraries();
+
+  AndroidNativeLibraryProvider() {}
 }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidNeverLinkLibrariesProvider.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidNeverLinkLibrariesProvider.java
index 21dfc73..917558d 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidNeverLinkLibrariesProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidNeverLinkLibrariesProvider.java
@@ -13,32 +13,29 @@
 // limitations under the License.
 package com.google.devtools.build.lib.rules.android;
 
+import com.google.auto.value.AutoValue;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-import com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider;
 
 /**
  * A target that can provide neverlink libraries for Android targets.
  *
- * <p>All targets implementing this interface must also implement
- * {@link JavaCompilationArgsProvider}.
+ * <p>All targets implementing this interface must also implement {@link
+ * com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider}.
  */
+@AutoValue
 @Immutable
-public final class AndroidNeverLinkLibrariesProvider implements TransitiveInfoProvider {
+public abstract class AndroidNeverLinkLibrariesProvider implements TransitiveInfoProvider {
 
-  private final NestedSet<Artifact> transitiveNeverLinkLibraries;
-
-  public AndroidNeverLinkLibrariesProvider(
+  public static AndroidNeverLinkLibrariesProvider create(
       NestedSet<Artifact> transitiveNeverLinkLibraries) {
-    this.transitiveNeverLinkLibraries = transitiveNeverLinkLibraries;
+    return new AutoValue_AndroidNeverLinkLibrariesProvider(transitiveNeverLinkLibraries);
   }
 
-  /**
-   * Returns the set of neverlink libraries in the transitive closure.
-   */
-  public NestedSet<Artifact> getTransitiveNeverLinkLibraries() {
-    return transitiveNeverLinkLibraries;
-  }
+  /** Returns the set of neverlink libraries in the transitive closure. */
+  public abstract NestedSet<Artifact> getTransitiveNeverLinkLibraries();
+
+  AndroidNeverLinkLibrariesProvider() {}
 }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidNeverlinkAspect.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidNeverlinkAspect.java
index 8e4cea1..dbfe68f 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidNeverlinkAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidNeverlinkAspect.java
@@ -27,7 +27,6 @@
 import com.google.devtools.build.lib.rules.java.JavaCommon;
 import com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider;
 import com.google.devtools.build.lib.rules.java.JavaRuntimeJarProvider;
-
 import java.util.ArrayList;
 import java.util.List;
 
@@ -69,7 +68,7 @@
     return new ConfiguredAspect.Builder(NAME, ruleContext)
         .addProvider(
             AndroidNeverLinkLibrariesProvider.class,
-            new AndroidNeverLinkLibrariesProvider(
+            AndroidNeverLinkLibrariesProvider.create(
                 AndroidCommon.collectTransitiveNeverlinkLibraries(
                     ruleContext,
                     deps,
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidPreDexJarProvider.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidPreDexJarProvider.java
index fc60bbe..56b0937 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidPreDexJarProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidPreDexJarProvider.java
@@ -13,27 +13,22 @@
 // limitations under the License.
 package com.google.devtools.build.lib.rules.android;
 
+import com.google.auto.value.AutoValue;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
 
-/**
- * A provider of the final Jar to be dexed for targets that build APKs.
- */
+/** A provider of the final Jar to be dexed for targets that build APKs. */
+@AutoValue
 @Immutable
-public final class AndroidPreDexJarProvider implements TransitiveInfoProvider {
+public abstract class AndroidPreDexJarProvider implements TransitiveInfoProvider {
 
-  private final Artifact preDexJar;
-
-
-  public AndroidPreDexJarProvider(Artifact preDexJar) {
-    this.preDexJar = preDexJar;
+  public static AndroidPreDexJarProvider create(Artifact preDexJar) {
+    return new AutoValue_AndroidPreDexJarProvider(preDexJar);
   }
 
-  /**
-   * Returns the jar to be dexed.
-   */
-  public Artifact getPreDexJar() {
-    return preDexJar;
-  }
+  /** Returns the jar to be dexed. */
+  public abstract Artifact getPreDexJar();
+
+  AndroidPreDexJarProvider() {}
 }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceContainerBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceContainerBuilder.java
index d027cfa..aa7e323 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceContainerBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceContainerBuilder.java
@@ -53,7 +53,7 @@
     return this;
   }
 
-  /** Creates a {@link ResourceContainer} from a {@link RuleContext}. 
+  /** Creates a {@link ResourceContainer} from a {@link RuleContext}.
    * @throws InterruptedException */
   public ResourceContainer buildFromRule(RuleContext ruleContext, @Nullable Artifact apk)
       throws InterruptedException {
@@ -61,7 +61,7 @@
     Preconditions.checkNotNull(this.data);
     Artifact rJavaSrcJar = ruleContext.getImplicitOutputArtifact(
         AndroidRuleClasses.ANDROID_JAVA_SOURCE_JAR);
-    return new AndroidResourcesProvider.ResourceContainer(
+    return AndroidResourcesProvider.ResourceContainer.create(
             ruleContext.getLabel(),
             getJavaPackage(ruleContext, rJavaSrcJar),
             getRenameManifestPackage(ruleContext),
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceMergingActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceMergingActionBuilder.java
index 21e49cd..c79fd21 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceMergingActionBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceMergingActionBuilder.java
@@ -168,7 +168,7 @@
             .build(context));
 
     // Return the full set of processed transitive dependencies.
-    return new ResourceContainer(
+    return ResourceContainer.create(
         primary.getLabel(),
         primary.getJavaPackage(),
         primary.getRenameManifestPackage(),
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceValidatorActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceValidatorActionBuilder.java
index 9cceee1..5a822b4 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceValidatorActionBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceValidatorActionBuilder.java
@@ -152,7 +152,7 @@
             .build(context));
 
     // Return the full set of validated transitive dependencies.
-    return new ResourceContainer(
+    return ResourceContainer.create(
         primary.getLabel(),
         primary.getJavaPackage(),
         primary.getRenameManifestPackage(),
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourcesProcessorBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourcesProcessorBuilder.java
index 181cc91..45ee468 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourcesProcessorBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourcesProcessorBuilder.java
@@ -307,7 +307,7 @@
             .build(context));
 
     // Return the full set of processed transitive dependencies.
-    return new ResourceContainer(primary.getLabel(),
+    return ResourceContainer.create(primary.getLabel(),
         primary.getJavaPackage(),
         primary.getRenameManifestPackage(),
         primary.getConstantsInlined(),
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourcesProvider.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourcesProvider.java
index 9f3d7a9..9995840 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourcesProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourcesProvider.java
@@ -13,6 +13,7 @@
 // limitations under the License.
 package com.google.devtools.build.lib.rules.android;
 
+import com.google.auto.value.AutoValue;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 import com.google.devtools.build.lib.actions.Artifact;
@@ -20,50 +21,33 @@
 import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-import com.google.devtools.build.lib.util.Preconditions;
 import com.google.devtools.build.lib.vfs.PathFragment;
-
 import java.util.Objects;
-
 import javax.annotation.Nullable;
 
-/**
- * A provider that supplies ResourceContainers from its transitive closure.
- */
+/** A provider that supplies ResourceContainers from its transitive closure. */
+@AutoValue
 @Immutable
-public final class AndroidResourcesProvider implements TransitiveInfoProvider {
-  private final Label label;
-  private final NestedSet<ResourceContainer> transitiveAndroidResources;
-  private final NestedSet<ResourceContainer> directAndroidResources;
+public abstract class AndroidResourcesProvider implements TransitiveInfoProvider {
 
-  public AndroidResourcesProvider(
-      Label label, NestedSet<ResourceContainer> transitiveAndroidResources,
+  public static AndroidResourcesProvider create(
+      Label label,
+      NestedSet<ResourceContainer> transitiveAndroidResources,
       NestedSet<ResourceContainer> directAndroidResources) {
-    this.label = label;
-    this.directAndroidResources = directAndroidResources;
-    this.transitiveAndroidResources = transitiveAndroidResources;
+    return new AutoValue_AndroidResourcesProvider(
+        label, transitiveAndroidResources, directAndroidResources);
   }
 
   /**
    * Returns the label that is associated with this piece of information.
    */
-  public Label getLabel() {
-    return label;
-  }
+  public abstract Label getLabel();
 
-  /**
-   * Returns the transitive ResourceContainers for the label.
-   */
-  public NestedSet<ResourceContainer> getTransitiveAndroidResources() {
-    return transitiveAndroidResources;
-  }
+  /** Returns the transitive ResourceContainers for the label. */
+  public abstract NestedSet<ResourceContainer> getTransitiveAndroidResources();
 
-  /**
-   * Returns the immediate ResourceContainers for the label.
-   */
-  public NestedSet<ResourceContainer> getDirectAndroidResources() {
-    return directAndroidResources;
-  }
+  /** Returns the immediate ResourceContainers for the label. */
+  public abstract NestedSet<ResourceContainer> getDirectAndroidResources();
 
 
   /**
@@ -84,120 +68,81 @@
     }
   }
 
-
   /**
    * The resources contributed by a single target.
    */
+  @AutoValue
   @Immutable
-  public static final class ResourceContainer {
-    private final Label label;
-    private final String javaPackage;
-    private final String renameManifestPackage;
-    private final boolean constantsInlined;
-    private final Artifact apk;
-    private final Artifact manifest;
-    private final ImmutableList<Artifact> assets;
-    private final ImmutableList<Artifact> resources;
-    private final ImmutableList<PathFragment> assetsRoots;
-    private final ImmutableList<PathFragment> resourcesRoots;
-    private final boolean manifestExported;
-    private final Artifact javaSourceJar;
-    private final Artifact javaClassJar;
-    private final Artifact rTxt;
-    private final Artifact symbolsTxt;
+  public abstract static class ResourceContainer {
 
-    public ResourceContainer(Label label,
+    public static ResourceContainer create(
+        Label label,
         String javaPackage,
         @Nullable String renameManifestPackage,
         boolean constantsInlined,
         @Nullable Artifact apk,
         Artifact manifest,
-        Artifact javaSourceJar,
+        @Nullable Artifact javaSourceJar,
         @Nullable Artifact javaClassJar,
         ImmutableList<Artifact> assets,
         ImmutableList<Artifact> resources,
         ImmutableList<PathFragment> assetsRoots,
         ImmutableList<PathFragment> resourcesRoots,
         boolean manifestExported,
-        Artifact rTxt,
-        Artifact symbolsTxt) {
-      this.javaSourceJar = javaSourceJar;
-      this.javaClassJar = javaClassJar;
-      this.manifestExported = manifestExported;
-      this.label = Preconditions.checkNotNull(label);
-      this.javaPackage = Preconditions.checkNotNull(javaPackage);
-      this.renameManifestPackage = renameManifestPackage;
-      this.constantsInlined = constantsInlined;
-      this.apk = apk;
-      this.manifest = Preconditions.checkNotNull(manifest);
-      this.assets = Preconditions.checkNotNull(assets);
-      this.resources = Preconditions.checkNotNull(resources);
-      this.assetsRoots = Preconditions.checkNotNull(assetsRoots);
-      this.resourcesRoots = Preconditions.checkNotNull(resourcesRoots);
-      this.rTxt = rTxt;
-      this.symbolsTxt = symbolsTxt;
+        @Nullable Artifact rTxt,
+        @Nullable Artifact symbolsTxt) {
+      return new AutoValue_AndroidResourcesProvider_ResourceContainer(
+          label,
+          javaPackage,
+          renameManifestPackage,
+          constantsInlined,
+          apk,
+          manifest,
+          javaSourceJar,
+          javaClassJar,
+          assets,
+          resources,
+          assetsRoots,
+          resourcesRoots,
+          manifestExported,
+          rTxt,
+          symbolsTxt);
     }
 
-    public Label getLabel() {
-      return label;
-    }
+    public abstract Label getLabel();
+    public abstract String getJavaPackage();
+    @Nullable public abstract String getRenameManifestPackage();
+    public abstract boolean getConstantsInlined();
+    @Nullable public abstract Artifact getApk();
+    public abstract Artifact getManifest();
+    @Nullable public abstract Artifact getJavaSourceJar();
+    @Nullable public abstract Artifact getJavaClassJar();
 
-    public String getJavaPackage() {
-      return javaPackage;
-    }
-
-    public String getRenameManifestPackage() {
-      return renameManifestPackage;
-    }
-
-    public boolean getConstantsInlined() {
-      return constantsInlined;
-    }
-
-    public Artifact getApk() {
-      return apk;
-    }
-
-    public Artifact getJavaSourceJar() {
-      return javaSourceJar;
-    }
-
-    public Artifact getJavaClassJar() {
-      return javaClassJar;
-    }
-
-    public Artifact getManifest() {
-      return manifest;
-    }
-
-    public boolean isManifestExported() {
-      return manifestExported;
-    }
+    abstract ImmutableList<Artifact> getAssets();
+    abstract ImmutableList<Artifact> getResources();
 
     public ImmutableList<Artifact> getArtifacts(ResourceType resourceType) {
-      return resourceType == ResourceType.ASSETS ? assets : resources;
+      return resourceType == ResourceType.ASSETS ? getAssets() : getResources();
     }
 
     public Iterable<Artifact> getArtifacts() {
-      return Iterables.concat(assets, resources);
+      return Iterables.concat(getAssets(), getResources());
     }
 
-    public Artifact getRTxt() {
-      return rTxt;
-    }
-
-
-    public Artifact getSymbolsTxt() {
-      return symbolsTxt;
-    }
-
+    abstract ImmutableList<PathFragment> getAssetsRoots();
+    abstract ImmutableList<PathFragment> getResourcesRoots();
     public ImmutableList<PathFragment> getRoots(ResourceType resourceType) {
-      return resourceType == ResourceType.ASSETS ? assetsRoots : resourcesRoots;
+      return resourceType == ResourceType.ASSETS ? getAssetsRoots() : getResourcesRoots();
     }
 
+    public abstract boolean isManifestExported();
+    @Nullable public abstract Artifact getRTxt();
+    @Nullable public abstract Artifact getSymbolsTxt();
+
+    // TODO(somebody) evaluate if we can just use hashCode and equals from AutoValue
     @Override
     public int hashCode() {
-      return Objects.hash(label, rTxt, symbolsTxt);
+      return Objects.hash(getLabel(), getRTxt(), getSymbolsTxt());
     }
 
     @Override
@@ -209,21 +154,11 @@
         return false;
       }
       ResourceContainer other = (ResourceContainer) obj;
-      return Objects.equals(label, other.label)
-          && Objects.equals(rTxt, other.rTxt)
-          && Objects.equals(symbolsTxt, other.symbolsTxt);
-    }
-
-    @Override
-    public String toString() {
-      return String.format(
-          "ResourceContainer [label=%s, javaPackage=%s, renameManifestPackage=%s,"
-          + " constantsInlined=%s, apk=%s, manifest=%s, assets=%s, resources=%s, assetsRoots=%s,"
-          + " resourcesRoots=%s, manifestExported=%s, javaSourceJar=%s, javaClassJar=%s,"
-          + " rTxt=%s, symbolsTxt=%s]",
-          label, javaPackage, renameManifestPackage, constantsInlined, apk, manifest, assets,
-          resources, assetsRoots, resourcesRoots, manifestExported, javaSourceJar,
-          javaClassJar, rTxt, symbolsTxt);
+      return Objects.equals(getLabel(), other.getLabel())
+          && Objects.equals(getRTxt(), other.getRTxt())
+          && Objects.equals(getSymbolsTxt(), other.getSymbolsTxt());
     }
   }
+
+  AndroidResourcesProvider() {}
 }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSdk.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSdk.java
index 214797c..da7b3b4 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSdk.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSdk.java
@@ -13,6 +13,7 @@
 // limitations under the License.
 package com.google.devtools.build.lib.rules.android;
 
+import com.android.sdklib.repository.FullRevision;
 import com.google.common.base.Strings;
 import com.google.common.collect.ImmutableList;
 import com.google.devtools.build.lib.actions.Artifact;
@@ -32,9 +33,6 @@
 import com.google.devtools.build.lib.rules.java.JavaConfiguration;
 import com.google.devtools.build.lib.rules.java.JavaToolchainProvider;
 import com.google.devtools.build.lib.syntax.Type;
-
-import com.android.sdklib.repository.FullRevision;
-
 import java.util.Collection;
 
 /**
@@ -106,7 +104,7 @@
     return new RuleConfiguredTargetBuilder(ruleContext)
         .add(
             AndroidSdkProvider.class,
-            new AndroidSdkProvider(
+            AndroidSdkProvider.create(
                 buildToolsVersion,
                 aaptSupportsMainDexGeneration,
                 frameworkAidl,
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSdkProvider.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSdkProvider.java
index 59efb55..c790e30 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSdkProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSdkProvider.java
@@ -13,6 +13,7 @@
 // limitations under the License.
 package com.google.devtools.build.lib.rules.android;
 
+import com.google.auto.value.AutoValue;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.analysis.FilesToRunProvider;
 import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
@@ -22,34 +23,12 @@
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
 
-/**
- * Description of the tools Blaze needs from an Android SDK.
- */
+/** Description of the tools Blaze needs from an Android SDK. */
+@AutoValue
 @Immutable
-public final class AndroidSdkProvider implements TransitiveInfoProvider {
+public abstract class AndroidSdkProvider implements TransitiveInfoProvider {
 
-  private final String buildToolsVersion;
-  private final boolean aaptSupportsMainDexGeneration;
-  private final Artifact frameworkAidl;
-  private final Artifact androidJar;
-  private final Artifact shrinkedAndroidJar;
-  private final NestedSet<Artifact> androidBaseClasspathForJack;
-  private final NestedSet<Artifact> javaBaseClasspathForJack;
-  private final Artifact annotationsJar;
-  private final Artifact mainDexClasses;
-  private final FilesToRunProvider adb;
-  private final FilesToRunProvider dx;
-  private final FilesToRunProvider mainDexListCreator;
-  private final FilesToRunProvider aidl;
-  private final FilesToRunProvider aapt;
-  private final FilesToRunProvider apkBuilder;
-  private final FilesToRunProvider proguard;
-  private final FilesToRunProvider zipalign;
-  private final FilesToRunProvider jack;
-  private final FilesToRunProvider jill;
-  private final FilesToRunProvider resourceExtractor;
-
-  public AndroidSdkProvider(
+  public static AndroidSdkProvider create(
       String buildToolsVersion,
       boolean aaptSupportsMainDexGeneration,
       Artifact frameworkAidl,
@@ -71,26 +50,27 @@
       FilesToRunProvider jill,
       FilesToRunProvider resourceExtractor) {
 
-    this.buildToolsVersion = buildToolsVersion;
-    this.aaptSupportsMainDexGeneration = aaptSupportsMainDexGeneration;
-    this.frameworkAidl = frameworkAidl;
-    this.androidJar = androidJar;
-    this.shrinkedAndroidJar = shrinkedAndroidJar;
-    this.androidBaseClasspathForJack = androidBaseClasspathForJack;
-    this.javaBaseClasspathForJack = javaBaseClasspathForJack;
-    this.annotationsJar = annotationsJar;
-    this.mainDexClasses = mainDexClasses;
-    this.adb = adb;
-    this.dx = dx;
-    this.mainDexListCreator = mainDexListCreator;
-    this.aidl = aidl;
-    this.aapt = aapt;
-    this.apkBuilder = apkBuilder;
-    this.proguard = proguard;
-    this.zipalign = zipalign;
-    this.jack = jack;
-    this.jill = jill;
-    this.resourceExtractor = resourceExtractor;
+    return new AutoValue_AndroidSdkProvider(
+        buildToolsVersion,
+        aaptSupportsMainDexGeneration,
+        frameworkAidl,
+        androidJar,
+        shrinkedAndroidJar,
+        androidBaseClasspathForJack,
+        javaBaseClasspathForJack,
+        annotationsJar,
+        mainDexClasses,
+        adb,
+        dx,
+        mainDexListCreator,
+        aidl,
+        aapt,
+        apkBuilder,
+        proguard,
+        zipalign,
+        jack,
+        jill,
+        resourceExtractor);
   }
 
   /**
@@ -119,94 +99,54 @@
     return true;
   }
 
-  /**
-   * The value of build_tools_version. May be null or empty.
-   */
-  public String getBuildToolsVersion() {
-    return buildToolsVersion;
-  }
+  /** The value of build_tools_version. May be null or empty. */
+  public abstract String getBuildToolsVersion();
 
-  public boolean getAaptSupportsMainDexGeneration() {
-    return aaptSupportsMainDexGeneration;
-  }
+  public abstract boolean getAaptSupportsMainDexGeneration();
 
-  public Artifact getFrameworkAidl() {
-    return frameworkAidl;
-  }
+  public abstract Artifact getFrameworkAidl();
 
-  public Artifact getAndroidJar() {
-    return androidJar;
-  }
+  public abstract Artifact getAndroidJar();
 
-  public Artifact getShrinkedAndroidJar() {
-    return shrinkedAndroidJar;
-  }
+  public abstract Artifact getShrinkedAndroidJar();
 
   /**
    * Returns the set of jack files to be used as a base classpath for jack compilation of Android
    * rules, typically a Jack translation of the jar returned by {@link getAndroidJar}.
    */
-  public NestedSet<Artifact> getAndroidBaseClasspathForJack() {
-    return androidBaseClasspathForJack;
-  }
+  public abstract NestedSet<Artifact> getAndroidBaseClasspathForJack();
 
   /**
    * Returns the set of jack files to be used as a base classpath for jack compilation of Java
    * rules, typically a Jack translation of the jars in the Java bootclasspath.
    */
-  public NestedSet<Artifact> getJavaBaseClasspathForJack() {
-    return javaBaseClasspathForJack;
-  }
+  public abstract NestedSet<Artifact> getJavaBaseClasspathForJack();
 
-  public Artifact getAnnotationsJar() {
-    return annotationsJar;
-  }
+  public abstract Artifact getAnnotationsJar();
 
-  public Artifact getMainDexClasses() {
-    return mainDexClasses;
-  }
+  public abstract Artifact getMainDexClasses();
 
-  public FilesToRunProvider getAdb() {
-    return adb;
-  }
+  public abstract FilesToRunProvider getAdb();
 
-  public FilesToRunProvider getDx() {
-    return dx;
-  }
+  public abstract FilesToRunProvider getDx();
 
-  public FilesToRunProvider getMainDexListCreator() {
-    return mainDexListCreator;
-  }
+  public abstract FilesToRunProvider getMainDexListCreator();
 
-  public FilesToRunProvider getAidl() {
-    return aidl;
-  }
+  public abstract FilesToRunProvider getAidl();
 
-  public FilesToRunProvider getAapt() {
-    return aapt;
-  }
+  public abstract FilesToRunProvider getAapt();
 
-  public FilesToRunProvider getApkBuilder() {
-    return apkBuilder;
-  }
+  public abstract FilesToRunProvider getApkBuilder();
 
-  public FilesToRunProvider getProguard() {
-    return proguard;
-  }
+  public abstract FilesToRunProvider getProguard();
 
-  public FilesToRunProvider getZipalign() {
-    return zipalign;
-  }
+  public abstract FilesToRunProvider getZipalign();
 
-  public FilesToRunProvider getJack() {
-    return jack;
-  }
+  public abstract FilesToRunProvider getJack();
 
-  public FilesToRunProvider getJill() {
-    return jill;
-  }
+  public abstract FilesToRunProvider getJill();
 
-  public FilesToRunProvider getResourceExtractor() {
-    return resourceExtractor;
-  }
+  public abstract FilesToRunProvider getResourceExtractor();
+
+  AndroidSdkProvider() {}
 }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ApkProvider.java b/src/main/java/com/google/devtools/build/lib/rules/android/ApkProvider.java
index 2ac6c0d..c14c61c 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/ApkProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/ApkProvider.java
@@ -13,48 +13,32 @@
 // limitations under the License.
 package com.google.devtools.build.lib.rules.android;
 
+import com.google.auto.value.AutoValue;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
 
-/**
- * A provider for targets that can build .apk files. Currently used for coverage collection.
- */
+/** A provider for targets that can build .apk files. Currently used for coverage collection. */
+@AutoValue
 @Immutable
-public final class ApkProvider implements TransitiveInfoProvider {
+public abstract class ApkProvider implements TransitiveInfoProvider {
 
-  private final NestedSet<Artifact> transitiveApks;
-
-  private final NestedSet<Artifact> coverageMetadata;
-
-  private final NestedSet<Artifact> mergedManifests;
-
-  public ApkProvider(NestedSet<Artifact> transitiveApks, NestedSet<Artifact> coverageMetdata,
+  public static ApkProvider create(
+      NestedSet<Artifact> transitiveApks,
+      NestedSet<Artifact> coverageMetdata,
       NestedSet<Artifact> mergedManifests) {
-    this.transitiveApks = transitiveApks;
-    this.coverageMetadata = coverageMetdata;
-    this.mergedManifests = mergedManifests;
+    return new AutoValue_ApkProvider(transitiveApks, coverageMetdata, mergedManifests);
   }
 
-  /**
-   * Returns the APK files generated in the transitive closure.
-   */
-  public NestedSet<Artifact> getTransitiveApks() {
-    return transitiveApks;
-  }
+  /** Returns the APK files generated in the transitive closure. */
+  public abstract NestedSet<Artifact> getTransitiveApks();
 
-  /**
-   * Returns the coverage metadata artifacts generated in the transitive closure.
-   */
-  public NestedSet<Artifact> getCoverageMetadata() {
-    return coverageMetadata;
-  }
+  /** Returns the coverage metadata artifacts generated in the transitive closure. */
+  public abstract NestedSet<Artifact> getCoverageMetadata();
 
-  /**
-   * Returns the merged manifests
-   */
-  public NestedSet<Artifact> getMergedManifests() {
-    return mergedManifests;
-  }
+  /** Returns the merged manifests */
+  public abstract NestedSet<Artifact> getMergedManifests();
+
+  ApkProvider() {}
 }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ApplicationManifest.java b/src/main/java/com/google/devtools/build/lib/rules/android/ApplicationManifest.java
index 1799213..2a0eb04 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/ApplicationManifest.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/ApplicationManifest.java
@@ -574,7 +574,7 @@
     aaptActionHelper.createGenerateApkAction(resourceApk,
         resourceContainer.getRenameManifestPackage(), additionalAaptOpts.build(), densities);
 
-    ResourceContainer updatedResources = new ResourceContainer(
+    ResourceContainer updatedResources = ResourceContainer.create(
         ruleContext.getLabel(),
         resourceContainer.getJavaPackage(),
         resourceContainer.getRenameManifestPackage(),
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/JackCompilationHelper.java b/src/main/java/com/google/devtools/build/lib/rules/android/JackCompilationHelper.java
index dea28d9..87e3443 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/JackCompilationHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/JackCompilationHelper.java
@@ -37,13 +37,11 @@
 import com.google.devtools.build.lib.util.Preconditions;
 import com.google.devtools.build.lib.vfs.FileSystemUtils;
 import com.google.devtools.build.lib.vfs.PathFragment;
-
 import java.util.Collection;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
 import java.util.Map;
 import java.util.Map.Entry;
-
 import javax.annotation.Nullable;
 
 /**
@@ -298,7 +296,7 @@
    */
   public JackLibraryProvider compileAsNeverlinkLibrary() {
     JackLibraryProvider nonNeverlink = compileAsLibrary();
-    return new JackLibraryProvider(
+    return JackLibraryProvider.create(
         /* transitiveJackLibrariesToLink */
         NestedSetBuilder.<Artifact>emptySet(Order.NAIVE_LINK_ORDER),
         nonNeverlink.getTransitiveJackClasspathLibraries());
@@ -370,7 +368,7 @@
         .addAll(Iterables.transform(dexJars, nonLibraryFileConverter))
         .addTransitive(dexJacks);
 
-    alreadyCompiledLibrary = new JackLibraryProvider(dexContents.build(), exports.build());
+    alreadyCompiledLibrary = JackLibraryProvider.create(dexContents.build(), exports.build());
     return alreadyCompiledLibrary;
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/JackLibraryProvider.java b/src/main/java/com/google/devtools/build/lib/rules/android/JackLibraryProvider.java
index 830a99c..cb209f5 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/JackLibraryProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/JackLibraryProvider.java
@@ -13,13 +13,13 @@
 // limitations under the License.
 package com.google.devtools.build.lib.rules.android;
 
+import com.google.auto.value.AutoValue;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
 import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
 import com.google.devtools.build.lib.collect.nestedset.Order;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-import com.google.devtools.build.lib.util.Preconditions;
 
 /**
  * Configured targets implementing this provider can contribute Jack libraries to the compilation of
@@ -28,38 +28,31 @@
  * @see <a href="http://tools.android.com/tech-docs/jackandjill">Jack documentation</a>
  * @see JackCompilationHelper
  */
+@AutoValue
 @Immutable
-public final class JackLibraryProvider implements TransitiveInfoProvider {
+public abstract class JackLibraryProvider implements TransitiveInfoProvider {
   public static final JackLibraryProvider EMPTY =
-      new JackLibraryProvider(
+      JackLibraryProvider.create(
           NestedSetBuilder.<Artifact>emptySet(Order.STABLE_ORDER),
           NestedSetBuilder.<Artifact>emptySet(Order.STABLE_ORDER));
 
-  private final NestedSet<Artifact> transitiveJackLibrariesToLink;
-  private final NestedSet<Artifact> transitiveJackClasspathLibraries;
-
-  public JackLibraryProvider(
+  public static JackLibraryProvider create(
       NestedSet<Artifact> transitiveJackLibrariesToLink,
       NestedSet<Artifact> transitiveJackClasspathLibraries) {
-    this.transitiveJackLibrariesToLink = Preconditions.checkNotNull(transitiveJackLibrariesToLink);
-    this.transitiveJackClasspathLibraries =
-        Preconditions.checkNotNull(transitiveJackClasspathLibraries);
+    return new AutoValue_JackLibraryProvider(
+        transitiveJackLibrariesToLink, transitiveJackClasspathLibraries);
   }
 
   /**
    * Gets the Jack libraries in the transitive closure which should be added to the final dex file.
    */
-  public NestedSet<Artifact> getTransitiveJackLibrariesToLink() {
-    return transitiveJackLibrariesToLink;
-  }
+  public abstract NestedSet<Artifact> getTransitiveJackLibrariesToLink();
 
   /**
    * Gets the Jack libraries which should be added to the classpath of any Jack action depending on
    * this provider.
    */
-  public NestedSet<Artifact> getTransitiveJackClasspathLibraries() {
-    return transitiveJackClasspathLibraries;
-  }
+  public abstract NestedSet<Artifact> getTransitiveJackClasspathLibraries();
 
   /**
    * Builder class to combine multiple JackLibraryProviders into a single one.
@@ -77,8 +70,10 @@
     }
 
     public JackLibraryProvider build() {
-      return new JackLibraryProvider(
+      return JackLibraryProvider.create(
           transitiveJackLibrariesToLink.build(), transitiveJackClasspathLibraries.build());
     }
   }
+
+  JackLibraryProvider() {}
 }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ProguardMappingProvider.java b/src/main/java/com/google/devtools/build/lib/rules/android/ProguardMappingProvider.java
index 68287cd..63a9f24 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/ProguardMappingProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/ProguardMappingProvider.java
@@ -13,29 +13,24 @@
 // limitations under the License.
 package com.google.devtools.build.lib.rules.android;
 
+import com.google.auto.value.AutoValue;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
 
-/**
- * A target that can provide a proguard obfuscation mapping to Android binaries or tests.
- */
+/** A target that can provide a proguard obfuscation mapping to Android binaries or tests. */
+@AutoValue
 @Immutable
-public final class ProguardMappingProvider implements TransitiveInfoProvider {
+public abstract class ProguardMappingProvider implements TransitiveInfoProvider {
 
-  private final Artifact proguardMapping;
-  private final Artifact proguardProtoMapping;
-
-  public ProguardMappingProvider(Artifact proguardMapping, Artifact proguardProtoMapping) {
-    this.proguardMapping = proguardMapping;
-    this.proguardProtoMapping = proguardProtoMapping;
+  public static ProguardMappingProvider create(
+      Artifact proguardMapping, Artifact proguardProtoMapping) {
+    return new AutoValue_ProguardMappingProvider(proguardMapping, proguardProtoMapping);
   }
 
-  public Artifact getProguardMapping() {
-    return proguardMapping;
-  }
+  public abstract Artifact getProguardMapping();
 
-  public Artifact getProguardProtoMapping() {
-    return proguardProtoMapping;
-  }
+  public abstract Artifact getProguardProtoMapping();
+
+  ProguardMappingProvider() {}
 }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ResourceDependencies.java b/src/main/java/com/google/devtools/build/lib/rules/android/ResourceDependencies.java
index f8309de..0c4b56f 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/ResourceDependencies.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/ResourceDependencies.java
@@ -167,7 +167,7 @@
     if (neverlink) {
       return ResourceDependencies.empty().toProvider(label);
     }
-    return new AndroidResourcesProvider(
+    return AndroidResourcesProvider.create(
         label,
         NestedSetBuilder.<ResourceContainer>naiveLinkOrder()
             .addTransitive(transitiveResources)
@@ -190,7 +190,7 @@
     if (neverlink) {
       return ResourceDependencies.empty().toProvider(label);
     }
-    return new AndroidResourcesProvider(label, transitiveResources, directResources);
+    return AndroidResourcesProvider.create(label, transitiveResources, directResources);
   }
 
   /**