Replaces InjectingObjectCodec with dependencies threaded through (Des|S)erializationContext.

PiperOrigin-RevId: 185547740
diff --git a/src/main/java/com/google/devtools/build/lib/actions/Artifact.java b/src/main/java/com/google/devtools/build/lib/actions/Artifact.java
index 4f6ac30..a3da211 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/Artifact.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/Artifact.java
@@ -31,7 +31,7 @@
 import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
 import com.google.devtools.build.lib.shell.ShellUtils;
-import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodec;
+import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
@@ -43,7 +43,6 @@
 import com.google.devtools.build.lib.syntax.EvalUtils.ComparisonException;
 import com.google.devtools.build.lib.util.FileType;
 import com.google.devtools.build.lib.util.FileTypeSet;
-import com.google.devtools.build.lib.vfs.FileSystemProvider;
 import com.google.devtools.build.lib.vfs.Path;
 import com.google.devtools.build.lib.vfs.PathFragment;
 import java.util.ArrayList;
@@ -114,7 +113,7 @@
           + "<a href='actions.html#declare_file'>ctx.actions.declare_file</a>, "
           + "or <a href='actions.html#declare_directory'>ctx.actions.declare_directory</a>."
 )
-@AutoCodec(dependency = FileSystemProvider.class)
+@AutoCodec
 public class Artifact
     implements FileType.HasFileType,
         ActionInput,
@@ -122,8 +121,7 @@
         Comparable<Object>,
         CommandLineItem {
 
-  public static final InjectingObjectCodec<Artifact, FileSystemProvider> CODEC =
-      new Artifact_AutoCodec();
+  public static final ObjectCodec<Artifact> CODEC = new Artifact_AutoCodec();
 
   /** Compares artifact according to their exec paths. Sorts null values first. */
   @SuppressWarnings("ReferenceEquality")  // "a == b" is an optimization
@@ -451,10 +449,10 @@
    */
   @Immutable
   @VisibleForTesting
-  @AutoCodec(dependency = FileSystemProvider.class)
+  @AutoCodec
   public static final class SpecialArtifact extends Artifact {
 
-    public static final InjectingObjectCodec<SpecialArtifact, FileSystemProvider> CODEC =
+    public static final ObjectCodec<SpecialArtifact> CODEC =
         new Artifact_SpecialArtifact_AutoCodec();
 
     private final SpecialArtifactType type;
@@ -512,9 +510,9 @@
    * around the extra fields for the rest we save some memory.
    */
   @Immutable
-  @AutoCodec(dependency = FileSystemProvider.class)
+  @AutoCodec
   public static final class TreeFileArtifact extends Artifact {
-    public static final InjectingObjectCodec<TreeFileArtifact, FileSystemProvider> CODEC =
+    public static final ObjectCodec<TreeFileArtifact> CODEC =
         new Artifact_TreeFileArtifact_AutoCodec();
 
     private final SpecialArtifact parentTreeArtifact;
diff --git a/src/main/java/com/google/devtools/build/lib/actions/ArtifactRoot.java b/src/main/java/com/google/devtools/build/lib/actions/ArtifactRoot.java
index 1a84425..0e32c86 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/ArtifactRoot.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/ArtifactRoot.java
@@ -17,7 +17,7 @@
 import com.google.common.base.Preconditions;
 import com.google.devtools.build.lib.cmdline.RepositoryName;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodec;
+import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
@@ -25,7 +25,6 @@
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
-import com.google.devtools.build.lib.vfs.FileSystemProvider;
 import com.google.devtools.build.lib.vfs.Path;
 import com.google.devtools.build.lib.vfs.PathFragment;
 import com.google.devtools.build.lib.vfs.Root;
@@ -56,11 +55,10 @@
           + "together into a single directory tree to form the execution environment."
 )
 @Immutable
-@AutoCodec(dependency = FileSystemProvider.class)
+@AutoCodec
 public final class ArtifactRoot implements Comparable<ArtifactRoot>, Serializable, SkylarkValue {
 
-  public static final InjectingObjectCodec<ArtifactRoot, FileSystemProvider> CODEC =
-      new ArtifactRoot_AutoCodec();
+  public static final ObjectCodec<ArtifactRoot> CODEC = new ArtifactRoot_AutoCodec();
 
   // This must always be consistent with Package.getSourceRoot; otherwise computing source roots
   // from exec paths does not work, which can break the action cache for input-discovering actions.
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/BlazeDirectories.java b/src/main/java/com/google/devtools/build/lib/analysis/BlazeDirectories.java
index d121a3d..7445761 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/BlazeDirectories.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/BlazeDirectories.java
@@ -18,10 +18,9 @@
 import com.google.common.hash.HashCode;
 import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodec;
+import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
 import com.google.devtools.build.lib.util.StringCanonicalizer;
-import com.google.devtools.build.lib.vfs.FileSystemProvider;
 import com.google.devtools.build.lib.vfs.Path;
 import java.util.Objects;
 
@@ -44,11 +43,10 @@
  *
  * <p>Do not put shortcuts to specific files here!
  */
-@AutoCodec(dependency = FileSystemProvider.class)
+@AutoCodec
 @Immutable
 public final class BlazeDirectories {
-  public static final InjectingObjectCodec<BlazeDirectories, FileSystemProvider> CODEC =
-      new BlazeDirectories_AutoCodec();
+  public static final ObjectCodec<BlazeDirectories> CODEC = new BlazeDirectories_AutoCodec();
 
   // Include directory name, relative to execRoot/blaze-out/configuration.
   public static final String RELATIVE_INCLUDE_DIR = StringCanonicalizer.intern("include");
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ServerDirectories.java b/src/main/java/com/google/devtools/build/lib/analysis/ServerDirectories.java
index 6797cb2..0e34cf3 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/ServerDirectories.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/ServerDirectories.java
@@ -19,9 +19,8 @@
 import com.google.common.hash.HashCode;
 import com.google.common.hash.Hashing;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodec;
+import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
-import com.google.devtools.build.lib.vfs.FileSystemProvider;
 import com.google.devtools.build.lib.vfs.Path;
 import java.util.Objects;
 import javax.annotation.Nullable;
@@ -33,11 +32,10 @@
  * <p>The <code>installBase</code> is the directory where the Blaze binary has been installed. The
  * <code>outputBase</code> is the directory below which Blaze puts all its state.
  */
-@AutoCodec(dependency = FileSystemProvider.class)
+@AutoCodec
 @Immutable
 public final class ServerDirectories {
-  public static final InjectingObjectCodec<ServerDirectories, FileSystemProvider> CODEC =
-      new ServerDirectories_AutoCodec();
+  public static final ObjectCodec<ServerDirectories> CODEC = new ServerDirectories_AutoCodec();
 
   /** Where Blaze gets unpacked. */
   private final Path installBase;
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java
index abeec41..59c5bad 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java
@@ -54,7 +54,6 @@
 import com.google.devtools.build.lib.packages.RuleClassProvider;
 import com.google.devtools.build.lib.packages.Target;
 import com.google.devtools.build.lib.skyframe.serialization.DeserializationContext;
-import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.SerializationContext;
 import com.google.devtools.build.lib.skyframe.serialization.SerializationException;
@@ -66,7 +65,6 @@
 import com.google.devtools.build.lib.util.Fingerprint;
 import com.google.devtools.build.lib.util.OS;
 import com.google.devtools.build.lib.util.RegexFilter;
-import com.google.devtools.build.lib.vfs.FileSystemProvider;
 import com.google.devtools.build.lib.vfs.Path;
 import com.google.devtools.build.lib.vfs.PathFragment;
 import com.google.devtools.common.options.Converter;
@@ -122,8 +120,7 @@
           + "depend on it and not targets that it depends on."
 )
 public class BuildConfiguration implements BuildConfigurationInterface {
-  public static final InjectingObjectCodec<BuildConfiguration, FileSystemProvider> CODEC =
-      new BuildConfigurationCodec();
+  public static final ObjectCodec<BuildConfiguration> CODEC = new BuildConfigurationCodec();
 
   /**
    * Sorts fragments by class name. This produces a stable order which, e.g., facilitates consistent
@@ -142,10 +139,9 @@
    * declare {@link ImmutableList} signatures on their interfaces vs. {@link List}). This is because
    * fragment instances may be shared across configurations.
    */
-  @AutoCodec(strategy = AutoCodec.Strategy.POLYMORPHIC, dependency = FileSystemProvider.class)
+  @AutoCodec(strategy = AutoCodec.Strategy.POLYMORPHIC)
   public abstract static class Fragment {
-    public static final InjectingObjectCodec<Fragment, FileSystemProvider> CODEC =
-        new BuildConfiguration_Fragment_AutoCodec();
+    public static final ObjectCodec<Fragment> CODEC = new BuildConfiguration_Fragment_AutoCodec();
 
     /**
      * Validates the options for this Fragment. Issues warnings for the
@@ -2182,8 +2178,7 @@
     return GenericBuildEvent.protoChaining(this).setConfiguration(builder.build()).build();
   }
 
-  private static class BuildConfigurationCodec
-      implements InjectingObjectCodec<BuildConfiguration, FileSystemProvider> {
+  private static class BuildConfigurationCodec implements ObjectCodec<BuildConfiguration> {
     @Override
     public Class<BuildConfiguration> getEncodedClass() {
       return BuildConfiguration.class;
@@ -2191,31 +2186,28 @@
 
     @Override
     public void serialize(
-        FileSystemProvider fsProvider,
         SerializationContext context,
         BuildConfiguration obj,
         CodedOutputStream codedOut)
         throws SerializationException, IOException {
-      BlazeDirectories.CODEC.serialize(fsProvider, context, obj.directories, codedOut);
+      BlazeDirectories.CODEC.serialize(context, obj.directories, codedOut);
       codedOut.writeInt32NoTag(obj.fragments.size());
       for (Fragment fragment : obj.fragments.values()) {
-        Fragment.CODEC.serialize(fsProvider, context, fragment, codedOut);
+        Fragment.CODEC.serialize(context, fragment, codedOut);
       }
       BuildOptions.CODEC.serialize(context, obj.buildOptions, codedOut);
       StringCodecs.asciiOptimized().serialize(context, obj.repositoryName, codedOut);
     }
 
     @Override
-    public BuildConfiguration deserialize(
-        FileSystemProvider fsProvider, DeserializationContext context, CodedInputStream codedIn)
+    public BuildConfiguration deserialize(DeserializationContext context, CodedInputStream codedIn)
         throws SerializationException, IOException {
-      BlazeDirectories blazeDirectories =
-          BlazeDirectories.CODEC.deserialize(fsProvider, context, codedIn);
+      BlazeDirectories blazeDirectories = BlazeDirectories.CODEC.deserialize(context, codedIn);
       int length = codedIn.readInt32();
       ImmutableSortedMap.Builder<Class<? extends Fragment>, Fragment> builder =
           new ImmutableSortedMap.Builder<>(lexicalFragmentSorter);
       for (int i = 0; i < length; ++i) {
-        Fragment fragment = Fragment.CODEC.deserialize(fsProvider, context, codedIn);
+        Fragment fragment = Fragment.CODEC.deserialize(context, codedIn);
         builder.put(fragment.getClass(), fragment);
       }
       BuildOptions options = BuildOptions.CODEC.deserialize(context, codedIn);
diff --git a/src/main/java/com/google/devtools/build/lib/cmdline/PackageIdentifier.java b/src/main/java/com/google/devtools/build/lib/cmdline/PackageIdentifier.java
index 2067b64..e763fc9 100644
--- a/src/main/java/com/google/devtools/build/lib/cmdline/PackageIdentifier.java
+++ b/src/main/java/com/google/devtools/build/lib/cmdline/PackageIdentifier.java
@@ -18,6 +18,7 @@
 import com.google.common.collect.ComparisonChain;
 import com.google.common.collect.Interner;
 import com.google.devtools.build.lib.concurrent.BlazeInterners;
+import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
 import com.google.devtools.build.lib.vfs.Canonicalizer;
@@ -37,6 +38,8 @@
 public final class PackageIdentifier
     implements Comparable<PackageIdentifier>, Serializable, SkylarkValue {
 
+  public static final ObjectCodec<PackageIdentifier> CODEC = new PackageIdentifierCodec();
+
   private static final Interner<PackageIdentifier> INTERNER = BlazeInterners.newWeakInterner();
 
   public static PackageIdentifier create(String repository, PathFragment pkgName)
diff --git a/src/main/java/com/google/devtools/build/lib/collect/nestedset/NestedSetCodec.java b/src/main/java/com/google/devtools/build/lib/collect/nestedset/NestedSetCodec.java
index 475e93b..ec61883 100644
--- a/src/main/java/com/google/devtools/build/lib/collect/nestedset/NestedSetCodec.java
+++ b/src/main/java/com/google/devtools/build/lib/collect/nestedset/NestedSetCodec.java
@@ -18,8 +18,6 @@
 import com.google.common.hash.HashingOutputStream;
 import com.google.devtools.build.lib.skyframe.serialization.DeserializationContext;
 import com.google.devtools.build.lib.skyframe.serialization.EnumCodec;
-import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodec;
-import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodecAdapter;
 import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.SerializationContext;
 import com.google.devtools.build.lib.skyframe.serialization.SerializationException;
@@ -50,10 +48,6 @@
     this.objectCodec = objectCodec;
   }
 
-  public <D> NestedSetCodec(InjectingObjectCodec<T, D> injectingObjectCodec, D dependency) {
-    this.objectCodec = new InjectingObjectCodecAdapter<>(injectingObjectCodec, dependency);
-  }
-
   @SuppressWarnings("unchecked")
   @Override
   public Class<NestedSet<T>> getEncodedClass() {
diff --git a/src/main/java/com/google/devtools/build/lib/packages/Package.java b/src/main/java/com/google/devtools/build/lib/packages/Package.java
index 1d7ee3a..648343c 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/Package.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/Package.java
@@ -35,7 +35,7 @@
 import com.google.devtools.build.lib.events.Location;
 import com.google.devtools.build.lib.packages.AttributeMap.AcceptsLabelAttribute;
 import com.google.devtools.build.lib.packages.License.DistributionType;
-import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodec;
+import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.SerializationException;
 import com.google.devtools.build.lib.syntax.SkylarkSemantics;
 import com.google.devtools.build.lib.util.SpellChecker;
@@ -68,8 +68,7 @@
  */
 @SuppressWarnings("JavaLangClash")
 public class Package {
-  public static final InjectingObjectCodec<Package, PackageCodecDependencies> CODEC =
-      new PackageCodec();
+  public static final ObjectCodec<Package> CODEC = new PackageCodec();
 
   /**
    * Common superclass for all name-conflict exceptions.
@@ -1575,8 +1574,7 @@
   }
 
   /** Package codec implementation. */
-  private static final class PackageCodec
-      implements InjectingObjectCodec<Package, PackageCodecDependencies> {
+  private static final class PackageCodec implements ObjectCodec<Package> {
     @Override
     public Class<Package> getEncodedClass() {
       return Package.class;
@@ -1584,20 +1582,20 @@
 
     @Override
     public void serialize(
-        PackageCodecDependencies codecDeps,
         com.google.devtools.build.lib.skyframe.serialization.SerializationContext context,
         Package input,
         CodedOutputStream codedOut)
         throws IOException, SerializationException {
+      PackageCodecDependencies codecDeps = context.getDependency(PackageCodecDependencies.class);
       codecDeps.getPackageSerializer().serialize(input, codedOut);
     }
 
     @Override
     public Package deserialize(
-        PackageCodecDependencies codecDeps,
         com.google.devtools.build.lib.skyframe.serialization.DeserializationContext context,
         CodedInputStream codedIn)
         throws SerializationException, IOException {
+      PackageCodecDependencies codecDeps = context.getDependency(PackageCodecDependencies.class);
       try {
         return codecDeps.getPackageDeserializer().deserialize(codedIn);
       } catch (PackageDeserializationException e) {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java
index 410fb41..c89164a 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java
@@ -38,13 +38,11 @@
 import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.Strategy;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
 import com.google.devtools.build.lib.util.Pair;
-import com.google.devtools.build.lib.vfs.FileSystemProvider;
 import com.google.devtools.build.lib.vfs.PathFragment;
 import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CToolchain;
 import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CToolchain.WithFeatureSet;
@@ -1129,9 +1127,9 @@
    * instance could serve as a top level View used to expand all flag_groups.
    */
   @Immutable
-  @AutoCodec(dependency = FileSystemProvider.class)
+  @AutoCodec
   public static class Variables {
-    public static final InjectingObjectCodec<Variables, FileSystemProvider> CODEC =
+    public static final ObjectCodec<Variables> CODEC =
         new CcToolchainFeatures_Variables_AutoCodec();
 
     /** An empty variables instance. */
@@ -1165,9 +1163,9 @@
      * <p>Implementations must be immutable and without any side-effects. They will be expanded and
      * queried multiple times.
      */
-    @AutoCodec(strategy = Strategy.POLYMORPHIC, dependency = FileSystemProvider.class)
+    @AutoCodec(strategy = Strategy.POLYMORPHIC)
     interface VariableValue {
-      public static final InjectingObjectCodec<VariableValue, FileSystemProvider> CODEC =
+      public static final ObjectCodec<VariableValue> CODEC =
           new CcToolchainFeatures_Variables_VariableValue_AutoCodec();
 
       /**
@@ -1381,9 +1379,9 @@
      * significantly reduces memory overhead.
      */
     @Immutable
-    @AutoCodec(dependency = FileSystemProvider.class)
+    @AutoCodec
     public static class LibraryToLinkValue extends VariableValueAdapter {
-      public static final InjectingObjectCodec<LibraryToLinkValue, FileSystemProvider> CODEC =
+      public static final ObjectCodec<LibraryToLinkValue> CODEC =
           new CcToolchainFeatures_Variables_LibraryToLinkValue_AutoCodec();
 
       public static final String OBJECT_FILES_FIELD_NAME = "object_files";
@@ -1514,10 +1512,10 @@
 
     /** Sequence of arbitrary VariableValue objects. */
     @Immutable
-    @AutoCodec(dependency = FileSystemProvider.class)
+    @AutoCodec
     @VisibleForSerialization
     static final class Sequence extends VariableValueAdapter {
-      public static final InjectingObjectCodec<Sequence, FileSystemProvider> CODEC =
+      public static final ObjectCodec<Sequence> CODEC =
           new CcToolchainFeatures_Variables_Sequence_AutoCodec();
 
       private static final String SEQUENCE_VARIABLE_TYPE_NAME = "sequence";
@@ -1550,10 +1548,10 @@
      * significantly reduces memory overhead.
      */
     @Immutable
-    @AutoCodec(dependency = FileSystemProvider.class)
+    @AutoCodec
     @VisibleForSerialization
     static final class StructureSequence extends VariableValueAdapter {
-      public static final InjectingObjectCodec<StructureSequence, FileSystemProvider> CODEC =
+      public static final ObjectCodec<StructureSequence> CODEC =
           new CcToolchainFeatures_Variables_StructureSequence_AutoCodec();
 
       private final ImmutableList<ImmutableMap<String, VariableValue>> values;
@@ -1627,10 +1625,10 @@
      * memory overhead is prohibitively big. Use optimized {@link StructureSequence} instead.
      */
     @Immutable
-    @AutoCodec(dependency = FileSystemProvider.class)
+    @AutoCodec
     @VisibleForSerialization
     static final class StructureValue extends VariableValueAdapter {
-      public static final InjectingObjectCodec<StructureValue, FileSystemProvider> CODEC =
+      public static final ObjectCodec<StructureValue> CODEC =
           new CcToolchainFeatures_Variables_StructureValue_AutoCodec();
 
       private static final String STRUCTURE_VARIABLE_TYPE_NAME = "structure";
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CompileCommandLine.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CompileCommandLine.java
index 7eef57f..a3d55e2 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CompileCommandLine.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CompileCommandLine.java
@@ -21,11 +21,10 @@
 import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration;
 import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.Variables;
 import com.google.devtools.build.lib.rules.cpp.CppCompileAction.DotdFile;
-import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodec;
+import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
 import com.google.devtools.build.lib.util.Pair;
-import com.google.devtools.build.lib.vfs.FileSystemProvider;
 import com.google.devtools.build.lib.vfs.PathFragment;
 import java.util.ArrayList;
 import java.util.List;
@@ -33,10 +32,9 @@
 import javax.annotation.Nullable;
 
 /** The compile command line for the C++ compile action. */
-@AutoCodec(dependency = FileSystemProvider.class)
+@AutoCodec
 public final class CompileCommandLine {
-  public static final InjectingObjectCodec<CompileCommandLine, FileSystemProvider> CODEC =
-      new CompileCommandLine_AutoCodec();
+  public static final ObjectCodec<CompileCommandLine> CODEC = new CompileCommandLine_AutoCodec();
 
   private final Artifact sourceFile;
   private final CoptsFilter coptsFilter;
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompilationContext.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompilationContext.java
index ea12fad..9ef128c 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompilationContext.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompilationContext.java
@@ -29,11 +29,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.rules.cpp.CppHelper.PregreppedHeader;
-import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
-import com.google.devtools.build.lib.vfs.FileSystemProvider;
 import com.google.devtools.build.lib.vfs.PathFragment;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -47,9 +45,9 @@
  * Immutable store of information needed for C++ compilation that is aggregated across dependencies.
  */
 @Immutable
-@AutoCodec(dependency = FileSystemProvider.class)
+@AutoCodec
 public final class CppCompilationContext implements TransitiveInfoProvider {
-  public static final InjectingObjectCodec<CppCompilationContext, FileSystemProvider> CODEC =
+  public static final ObjectCodec<CppCompilationContext> CODEC =
       new CppCompilationContext_AutoCodec();
 
   /** An empty compilation context. */
@@ -782,9 +780,9 @@
    * either gather data on PIC or on no-PIC .pcm files.
    */
   @Immutable
-  @AutoCodec(dependency = FileSystemProvider.class)
+  @AutoCodec
   public static final class ModuleInfo {
-    public static final InjectingObjectCodec<ModuleInfo, FileSystemProvider> CODEC =
+    public static final ObjectCodec<ModuleInfo> CODEC =
         new CppCompilationContext_ModuleInfo_AutoCodec();
 
     /**
@@ -918,9 +916,9 @@
 
   /** Collects data for a specific module in a special format that makes pruning easy. */
   @Immutable
-  @AutoCodec(dependency = FileSystemProvider.class)
+  @AutoCodec
   public static final class TransitiveModuleHeaders {
-    public static final InjectingObjectCodec<TransitiveModuleHeaders, FileSystemProvider> CODEC =
+    public static final ObjectCodec<TransitiveModuleHeaders> CODEC =
         new CppCompilationContext_TransitiveModuleHeaders_AutoCodec();
 
     /**
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java
index 8b26bad..79df9f4 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java
@@ -58,13 +58,12 @@
 import com.google.devtools.build.lib.rules.cpp.CppCompileActionContext.Reply;
 import com.google.devtools.build.lib.rules.cpp.CppConfiguration.Tool;
 import com.google.devtools.build.lib.rules.cpp.CppHelper.PregreppedHeader;
-import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodec;
+import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
 import com.google.devtools.build.lib.util.DependencySet;
 import com.google.devtools.build.lib.util.Fingerprint;
 import com.google.devtools.build.lib.util.ShellEscaper;
-import com.google.devtools.build.lib.vfs.FileSystemProvider;
 import com.google.devtools.build.lib.vfs.FileSystemUtils;
 import com.google.devtools.build.lib.vfs.Path;
 import com.google.devtools.build.lib.vfs.PathFragment;
@@ -1337,15 +1336,15 @@
 
   /**
    * A reference to a .d file. There are two modes:
+   *
    * <ol>
    *   <li>an Artifact that represents a real on-disk file
    *   <li>just an execPath that refers to a virtual .d file that is not written to disk
    * </ol>
    */
-  @AutoCodec(dependency = FileSystemProvider.class)
+  @AutoCodec
   public static class DotdFile {
-    public static final InjectingObjectCodec<DotdFile, FileSystemProvider> CODEC =
-        new CppCompileAction_DotdFile_AutoCodec();
+    public static final ObjectCodec<DotdFile> CODEC = new CppCompileAction_DotdFile_AutoCodec();
 
     private final Artifact artifact;
     private final PathFragment execPath;
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java
index 36624d8..2049d04 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java
@@ -43,12 +43,11 @@
 import com.google.devtools.build.lib.rules.cpp.CrosstoolConfigurationLoader.CrosstoolFile;
 import com.google.devtools.build.lib.rules.cpp.transitions.ContextCollectorOwnerTransition;
 import com.google.devtools.build.lib.rules.cpp.transitions.DisableLipoTransition;
-import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodec;
+import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
-import com.google.devtools.build.lib.vfs.FileSystemProvider;
 import com.google.devtools.build.lib.vfs.Path;
 import com.google.devtools.build.lib.vfs.PathFragment;
 import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig;
@@ -62,7 +61,7 @@
  * architecture, target architecture, compiler version, and a standard library version. It has
  * information about the tools locations and the flags required for compiling.
  */
-@AutoCodec(dependency = FileSystemProvider.class)
+@AutoCodec
 @SkylarkModule(
   name = "cpp",
   doc = "A configuration fragment for C++.",
@@ -70,8 +69,7 @@
 )
 @Immutable
 public final class CppConfiguration extends BuildConfiguration.Fragment {
-  public static final InjectingObjectCodec<CppConfiguration, FileSystemProvider> CODEC =
-      new CppConfiguration_AutoCodec();
+  public static final ObjectCodec<CppConfiguration> CODEC = new CppConfiguration_AutoCodec();
 
   /**
    * String indicating a Mac system, for example when used in a crosstool configuration's host or
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java
index 1888c81..126fda0 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java
@@ -65,12 +65,11 @@
 import com.google.devtools.build.lib.rules.cpp.CppConfiguration.DynamicMode;
 import com.google.devtools.build.lib.rules.cpp.Link.LinkTargetType;
 import com.google.devtools.build.lib.shell.ShellUtils;
-import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodec;
+import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
 import com.google.devtools.build.lib.syntax.Type;
 import com.google.devtools.build.lib.util.FileTypeSet;
 import com.google.devtools.build.lib.util.Pair;
-import com.google.devtools.build.lib.vfs.FileSystemProvider;
 import com.google.devtools.build.lib.vfs.PathFragment;
 import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.LipoMode;
 import java.util.ArrayList;
@@ -575,10 +574,10 @@
    * A header that has been grepped for #include statements. Includes the original header as well as
    * a stripped version of that header that contains only #include statements.
    */
-  @AutoCodec(dependency = FileSystemProvider.class)
+  @AutoCodec
   @AutoValue
   abstract static class PregreppedHeader {
-    public static final InjectingObjectCodec<PregreppedHeader, FileSystemProvider> CODEC =
+    public static final ObjectCodec<PregreppedHeader> CODEC =
         new CppHelper_PregreppedHeader_AutoCodec();
 
     @AutoCodec.Instantiator
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModuleMap.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModuleMap.java
index 8428d2c..1e158882 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModuleMap.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModuleMap.java
@@ -16,17 +16,15 @@
 import com.google.common.base.Optional;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodec;
+import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
-import com.google.devtools.build.lib.vfs.FileSystemProvider;
 
 /** Structure for C++ module maps. Stores the name of the module and a .cppmap artifact. */
 @Immutable
-@AutoCodec(dependency = FileSystemProvider.class)
+@AutoCodec
 public final class CppModuleMap {
-  public static final InjectingObjectCodec<CppModuleMap, FileSystemProvider> CODEC =
-      new CppModuleMap_AutoCodec();
+  public static final ObjectCodec<CppModuleMap> CODEC = new CppModuleMap_AutoCodec();
 
   // NOTE: If you add a field here, you'll likely need to update CppModuleMapAction.computeKey().
   private final Artifact artifact;
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/LinkerInputs.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/LinkerInputs.java
index 808db7b..8039c7b 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/LinkerInputs.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/LinkerInputs.java
@@ -20,11 +20,10 @@
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.collect.CollectionUtils;
 import com.google.devtools.build.lib.concurrent.ThreadSafety;
-import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodec;
+import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.Strategy;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
-import com.google.devtools.build.lib.vfs.FileSystemProvider;
 
 /**
  * Factory for creating new {@link LinkerInput} objects.
@@ -145,9 +144,9 @@
    * A library the user can link to. This is different from a simple linker input in that it also
    * has a library identifier.
    */
-  @AutoCodec(strategy = Strategy.POLYMORPHIC, dependency = FileSystemProvider.class)
+  @AutoCodec(strategy = Strategy.POLYMORPHIC)
   public interface LibraryToLink extends LinkerInput {
-    public static final InjectingObjectCodec<LibraryToLink, FileSystemProvider> CODEC =
+    public static final ObjectCodec<LibraryToLink> CODEC =
         new LinkerInputs_LibraryToLink_AutoCodec();
 
     ImmutableMap<Artifact, Artifact> getLtoBitcodeFiles();
@@ -174,9 +173,9 @@
    * library that it links to.
    */
   @ThreadSafety.Immutable
-  @AutoCodec(dependency = FileSystemProvider.class)
+  @AutoCodec
   public static class SolibLibraryToLink implements LibraryToLink {
-    public static final InjectingObjectCodec<SolibLibraryToLink, FileSystemProvider> CODEC =
+    public static final ObjectCodec<SolibLibraryToLink> CODEC =
         new LinkerInputs_SolibLibraryToLink_AutoCodec();
 
     private final Artifact solibSymlinkArtifact;
@@ -276,10 +275,10 @@
 
   /** This class represents a library that may contain object files. */
   @ThreadSafety.Immutable
-  @AutoCodec(dependency = FileSystemProvider.class)
+  @AutoCodec
   @VisibleForSerialization
   static class CompoundLibraryToLink implements LibraryToLink {
-    public static final InjectingObjectCodec<CompoundLibraryToLink, FileSystemProvider> CODEC =
+    public static final ObjectCodec<CompoundLibraryToLink> CODEC =
         new LinkerInputs_CompoundLibraryToLink_AutoCodec();
 
     private final Artifact libraryArtifact;
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/LtoBackendArtifacts.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/LtoBackendArtifacts.java
index 6ab5488..883ca4d 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/LtoBackendArtifacts.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/LtoBackendArtifacts.java
@@ -22,10 +22,9 @@
 import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration;
 import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.Variables;
 import com.google.devtools.build.lib.rules.cpp.CppConfiguration.Tool;
-import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodec;
+import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
-import com.google.devtools.build.lib.vfs.FileSystemProvider;
 import com.google.devtools.build.lib.vfs.FileSystemUtils;
 import com.google.devtools.build.lib.vfs.PathFragment;
 import java.util.ArrayList;
@@ -53,10 +52,9 @@
  *   <li>4. Backend link (once). This is the traditional link, and produces the final executable.
  * </ul>
  */
-@AutoCodec(dependency = FileSystemProvider.class)
+@AutoCodec
 public final class LtoBackendArtifacts {
-  public static final InjectingObjectCodec<LtoBackendArtifacts, FileSystemProvider> CODEC =
-      new LtoBackendArtifacts_AutoCodec();
+  public static final ObjectCodec<LtoBackendArtifacts> CODEC = new LtoBackendArtifacts_AutoCodec();
 
   // A file containing mapping of symbol => bitcode file containing the symbol.
   private final Artifact index;
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactSkyKey.java b/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactSkyKey.java
index 4370089..dd3aa91f 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactSkyKey.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactSkyKey.java
@@ -21,9 +21,8 @@
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.concurrent.BlazeInterners;
 import com.google.devtools.build.lib.concurrent.ThreadSafety;
-import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodec;
+import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
-import com.google.devtools.build.lib.vfs.FileSystemProvider;
 import com.google.devtools.build.skyframe.SkyFunctionName;
 import com.google.devtools.build.skyframe.SkyKey;
 import java.util.Collection;
@@ -54,11 +53,10 @@
  * check the owner, but only within these keys, since outside of Skyframe it is quite crucial that
  * Artifacts with different owners be able to compare equal.
  */
-@AutoCodec(dependency = FileSystemProvider.class)
+@AutoCodec
 public class ArtifactSkyKey implements SkyKey {
   private static final Interner<ArtifactSkyKey> INTERNER = BlazeInterners.newWeakInterner();
-  public static final InjectingObjectCodec<ArtifactSkyKey, FileSystemProvider> CODEC =
-      new ArtifactSkyKey_AutoCodec();
+  public static final ObjectCodec<ArtifactSkyKey> CODEC = new ArtifactSkyKey_AutoCodec();
   private static final Function<Artifact, SkyKey> TO_MANDATORY_KEY =
       artifact -> key(artifact, true);
   private static final Function<ArtifactSkyKey, Artifact> TO_ARTIFACT = ArtifactSkyKey::getArtifact;
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/BuildConfigurationValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/BuildConfigurationValue.java
index 76e8cbb..b2e7ee3 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/BuildConfigurationValue.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/BuildConfigurationValue.java
@@ -22,14 +22,12 @@
 import com.google.devtools.build.lib.concurrent.BlazeInterners;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe;
 import com.google.devtools.build.lib.skyframe.serialization.DeserializationContext;
-import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.SerializationContext;
 import com.google.devtools.build.lib.skyframe.serialization.SerializationException;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
 import com.google.devtools.build.lib.skyframe.serialization.strings.StringCodecs;
-import com.google.devtools.build.lib.vfs.FileSystemProvider;
 import com.google.devtools.build.skyframe.SkyFunctionName;
 import com.google.devtools.build.skyframe.SkyKey;
 import com.google.devtools.build.skyframe.SkyValue;
@@ -43,10 +41,10 @@
 /** A Skyframe value representing a {@link BuildConfiguration}. */
 // TODO(bazel-team): mark this immutable when BuildConfiguration is immutable.
 // @Immutable
-@AutoCodec(dependency = FileSystemProvider.class)
+@AutoCodec
 @ThreadSafe
 public class BuildConfigurationValue implements SkyValue {
-  public static final InjectingObjectCodec<BuildConfigurationValue, FileSystemProvider> CODEC =
+  public static final ObjectCodec<BuildConfigurationValue> CODEC =
       new BuildConfigurationValue_AutoCodec();
 
   private static final Interner<Key> keyInterner = BlazeInterners.newWeakInterner();
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ConfigurationFragmentValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/ConfigurationFragmentValue.java
index c81f29c..19d5ba3 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ConfigurationFragmentValue.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ConfigurationFragmentValue.java
@@ -24,14 +24,12 @@
 import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe;
 import com.google.devtools.build.lib.packages.RuleClassProvider;
 import com.google.devtools.build.lib.skyframe.serialization.DeserializationContext;
-import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.SerializationContext;
 import com.google.devtools.build.lib.skyframe.serialization.SerializationException;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
 import com.google.devtools.build.lib.skyframe.serialization.strings.StringCodecs;
 import com.google.devtools.build.lib.util.Fingerprint;
-import com.google.devtools.build.lib.vfs.FileSystemProvider;
 import com.google.devtools.build.skyframe.SkyFunctionName;
 import com.google.devtools.build.skyframe.SkyKey;
 import com.google.devtools.build.skyframe.SkyValue;
@@ -44,9 +42,9 @@
 /** A Skyframe node representing a build configuration fragment. */
 @Immutable
 @ThreadSafe
-@AutoCodec(dependency = FileSystemProvider.class)
+@AutoCodec
 public class ConfigurationFragmentValue implements SkyValue {
-  public static final InjectingObjectCodec<ConfigurationFragmentValue, FileSystemProvider> CODEC =
+  public static final ObjectCodec<ConfigurationFragmentValue> CODEC =
       new ConfigurationFragmentValue_AutoCodec();
 
   @Nullable
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/GlobDescriptor.java b/src/main/java/com/google/devtools/build/lib/skyframe/GlobDescriptor.java
index 01db160..4b20998 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/GlobDescriptor.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/GlobDescriptor.java
@@ -16,39 +16,30 @@
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Interner;
 import com.google.devtools.build.lib.cmdline.PackageIdentifier;
-import com.google.devtools.build.lib.cmdline.PackageIdentifierCodec;
 import com.google.devtools.build.lib.concurrent.BlazeInterners;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe;
-import com.google.devtools.build.lib.skyframe.serialization.DeserializationContext;
 import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
-import com.google.devtools.build.lib.skyframe.serialization.SerializationContext;
-import com.google.devtools.build.lib.skyframe.serialization.SerializationException;
-import com.google.devtools.build.lib.skyframe.serialization.strings.StringCodecs;
+import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
 import com.google.devtools.build.lib.util.StringCanonicalizer;
 import com.google.devtools.build.lib.vfs.PathFragment;
 import com.google.devtools.build.lib.vfs.Root;
 import com.google.devtools.build.skyframe.SkyFunctionName;
 import com.google.devtools.build.skyframe.SkyKey;
-import com.google.protobuf.CodedInputStream;
-import com.google.protobuf.CodedOutputStream;
-import java.io.IOException;
 
 /**
  * A descriptor for a glob request, used as the {@link SkyKey} for {@link GlobFunction}.
  *
- * <p>{@code subdir} must be empty or point to an existing directory.</p>
+ * <p>{@code subdir} must be empty or point to an existing directory.
  *
  * <p>{@code pattern} must be valid, as indicated by {@code UnixGlob#checkPatternForError}.
  */
+@AutoCodec
 @ThreadSafe
 public final class GlobDescriptor implements SkyKey {
 
   private static final Interner<GlobDescriptor> interner = BlazeInterners.newWeakInterner();
 
-  /** Creates and returns a new {@link ObjectCodec} for {@link GlobDescriptor}s. */
-  public static ObjectCodec<GlobDescriptor> getCodec(ObjectCodec<Root> rootCodec) {
-    return new GlobDescriptorCodec(rootCodec);
-  }
+  public static final ObjectCodec<GlobDescriptor> CODEC = new GlobDescriptor_AutoCodec();
 
   /**
    * Returns interned instance based on the parameters.
@@ -60,6 +51,7 @@
    * @param pattern a valid glob pattern
    * @param excludeDirs true if directories should be excluded from results
    */
+  @AutoCodec.Instantiator
   public static GlobDescriptor create(
       PackageIdentifier packageId,
       Root packageRoot,
@@ -166,43 +158,4 @@
   public SkyFunctionName functionName() {
     return SkyFunctions.GLOB;
   }
-
-  private static class GlobDescriptorCodec implements ObjectCodec<GlobDescriptor> {
-
-    private final PackageIdentifierCodec packageIdCodec = new PackageIdentifierCodec();
-    private final ObjectCodec<Root> rootCodec;
-    private final ObjectCodec<String> stringCodec = StringCodecs.asciiOptimized();
-
-    private GlobDescriptorCodec(ObjectCodec<Root> rootCodec) {
-      this.rootCodec = rootCodec;
-    }
-
-    @Override
-    public Class<GlobDescriptor> getEncodedClass() {
-      return GlobDescriptor.class;
-    }
-
-    @Override
-    public void serialize(
-        SerializationContext context, GlobDescriptor globDesc, CodedOutputStream codedOut)
-        throws IOException, SerializationException {
-      packageIdCodec.serialize(context, globDesc.getPackageId(), codedOut);
-      rootCodec.serialize(context, globDesc.getPackageRoot(), codedOut);
-      PathFragment.CODEC.serialize(context, globDesc.getSubdir(), codedOut);
-      stringCodec.serialize(context, globDesc.getPattern(), codedOut);
-      codedOut.writeBoolNoTag(globDesc.excludeDirs());
-    }
-
-    @Override
-    public GlobDescriptor deserialize(DeserializationContext context, CodedInputStream codedIn)
-        throws SerializationException, IOException {
-      PackageIdentifier packageId = packageIdCodec.deserialize(context, codedIn);
-      Root packageRoot = rootCodec.deserialize(context, codedIn);
-      PathFragment pathFragment = PathFragment.CODEC.deserialize(context, codedIn);
-      String pattern = stringCodec.deserialize(context, codedIn);
-      boolean excludeDirs = codedIn.readBool();
-      return GlobDescriptor.create(packageId, packageRoot, pathFragment, pattern, excludeDirs);
-    }
-  }
-
-}
\ No newline at end of file
+}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PackageValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/PackageValue.java
index f31bf09..96304a1 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/PackageValue.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/PackageValue.java
@@ -19,8 +19,7 @@
 import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe;
 import com.google.devtools.build.lib.packages.BuildFileContainsErrorsException;
 import com.google.devtools.build.lib.packages.Package;
-import com.google.devtools.build.lib.packages.PackageCodecDependencies;
-import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodec;
+import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
 import com.google.devtools.build.skyframe.LegacySkyKey;
 import com.google.devtools.build.skyframe.NotComparableSkyValue;
@@ -29,12 +28,11 @@
 import java.util.List;
 
 /** A Skyframe value representing a package. */
-@AutoCodec(dependency = PackageCodecDependencies.class)
+@AutoCodec
 @Immutable
 @ThreadSafe
 public class PackageValue implements NotComparableSkyValue {
-  public static final InjectingObjectCodec<PackageValue, PackageCodecDependencies> CODEC =
-      new PackageValue_AutoCodec();
+  public static final ObjectCodec<PackageValue> CODEC = new PackageValue_AutoCodec();
 
   private final Package pkg;
 
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/DeserializationContext.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/DeserializationContext.java
index 8b7d435..e1026b2 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/DeserializationContext.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/DeserializationContext.java
@@ -14,21 +14,33 @@
 
 package com.google.devtools.build.lib.skyframe.serialization;
 
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+
 /** Stateful class for providing additional context to a single deserialization "session". */
 // TODO(bazel-team): This class is just a shell, fill in.
 public class DeserializationContext {
-  // TODO(bazel-team): Replace with real stateless implementation when we start adding
-  // functionality.
-  private static final DeserializationContext EMPTY_STATELESS = new DeserializationContext();
 
-  public static DeserializationContext create() {
-    return new DeserializationContext();
+  /**
+   * This is a stub for context where it is less straightforward to thread from the top-level
+   * invocation.
+   *
+   * <p>This is a bug waiting to happen because it is very easy to accidentally modify a codec to
+   * use this context which won't contain any of the expected state.
+   */
+  // TODO(bazel-team): delete this and all references to it.
+  public static final DeserializationContext UNTHREADED_PLEASE_FIX =
+      new DeserializationContext(ImmutableMap.of());
+
+  private final ImmutableMap<Class<?>, Object> dependencies;
+
+  public DeserializationContext(ImmutableMap<Class<?>, Object> dependencies) {
+    this.dependencies = dependencies;
   }
 
-  /** Returns an empty instance which doesn't retain any state. */
-  public static DeserializationContext stateless() {
-    return EMPTY_STATELESS;
+  @SuppressWarnings("unchecked")
+  public <T> T getDependency(Class<T> type) {
+    Preconditions.checkNotNull(type);
+    return (T) dependencies.get(type);
   }
-
-  private DeserializationContext() {}
 }
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/InjectingObjectCodec.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/InjectingObjectCodec.java
deleted file mode 100644
index abd9d4d..0000000
--- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/InjectingObjectCodec.java
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2017 The Bazel Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.devtools.build.lib.skyframe.serialization;
-
-import com.google.protobuf.CodedInputStream;
-import com.google.protobuf.CodedOutputStream;
-import java.io.IOException;
-
-/** Like ObjectCodec, but allows user-specified injected dependencies. */
-public interface InjectingObjectCodec<T, D> extends BaseCodec<T> {
-
-  /**
-   * Serializes {@code obj}, inverse of {@link #deserialize(CodedInputStream)}.
-   *
-   * @param dependency the injected dependency
-   * @param obj the object to serialize
-   * @param codedOut the {@link CodedOutputStream} to write this object into. Implementations need
-   *     not call {@link CodedOutputStream#flush()}, this should be handled by the caller.
-   * @throws SerializationException on failure to serialize
-   * @throws IOException on {@link IOException} during serialization
-   */
-  void serialize(D dependency, SerializationContext context, T obj, CodedOutputStream codedOut)
-      throws SerializationException, IOException;
-
-  /**
-   * Deserializes from {@code codedIn}, inverse of {@link #serialize(Object, CodedOutputStream)}.
-   *
-   * @param dependency the injected dependency
-   * @param codedIn the {@link CodedInputStream} to read the serialized object from
-   * @return the object deserialized from {@code codedIn}
-   * @throws SerializationException on failure to deserialize
-   * @throws IOException on {@link IOException} during deserialization
-   */
-  T deserialize(D dependency, DeserializationContext context, CodedInputStream codedIn)
-      throws SerializationException, IOException;
-}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/InjectingObjectCodecAdapter.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/InjectingObjectCodecAdapter.java
deleted file mode 100644
index ae44f24..0000000
--- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/InjectingObjectCodecAdapter.java
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2017 The Bazel Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.devtools.build.lib.skyframe.serialization;
-
-import com.google.protobuf.CodedInputStream;
-import com.google.protobuf.CodedOutputStream;
-import java.io.IOException;
-
-/** Adapts an InjectingObjectCodec to an ObjectCodec. */
-public class InjectingObjectCodecAdapter<T, D> implements ObjectCodec<T> {
-
-  private final InjectingObjectCodec<T, D> codec;
-  private final D dependency;
-
-  /**
-   * Creates an ObjectCodec from an InjectingObjectCodec.
-   *
-   * @param codec underlying codec to delegate to
-   * @param dependency object forwarded to {@code codec.deserialize}
-   */
-  public InjectingObjectCodecAdapter(InjectingObjectCodec<T, D> codec, D dependency) {
-    this.codec = codec;
-    this.dependency = dependency;
-  }
-
-  @Override
-  public Class<T> getEncodedClass() {
-    return codec.getEncodedClass();
-  }
-
-  @Override
-  public void serialize(SerializationContext context, T obj, CodedOutputStream codedOut)
-      throws SerializationException, IOException {
-    codec.serialize(dependency, context, obj, codedOut);
-  }
-
-  @Override
-  public T deserialize(DeserializationContext context, CodedInputStream codedIn)
-      throws SerializationException, IOException {
-    return codec.deserialize(dependency, context, codedIn);
-  }
-}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/ObjectCodecs.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/ObjectCodecs.java
index 8eca0b5..99a02ae 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/ObjectCodecs.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/ObjectCodecs.java
@@ -14,6 +14,7 @@
 
 package com.google.devtools.build.lib.skyframe.serialization;
 
+import com.google.common.collect.ImmutableMap;
 import com.google.protobuf.ByteString;
 import com.google.protobuf.CodedInputStream;
 import com.google.protobuf.CodedOutputStream;
@@ -26,13 +27,19 @@
 public class ObjectCodecs {
 
   private final ObjectCodecRegistry codecRegistry;
+  // TODO(shahan): when per-invocation state is needed, for example, memoization, these may
+  // need to be constructed each time.
+  private final SerializationContext serializationContext;
+  private final DeserializationContext deserializationContext;
 
   /**
-   * Creates an instance using the supplied {@link ObjectCodecRegistry} for looking up
-   * {@link ObjectCodec}s.
+   * Creates an instance using the supplied {@link ObjectCodecRegistry} for looking up {@link
+   * ObjectCodec}s.
    */
-  ObjectCodecs(ObjectCodecRegistry codecRegistry) {
+  ObjectCodecs(ObjectCodecRegistry codecRegistry, ImmutableMap<Class<?>, Object> dependencies) {
     this.codecRegistry = codecRegistry;
+    serializationContext = new SerializationContext(dependencies);
+    deserializationContext = new DeserializationContext(dependencies);
   }
 
   /**
@@ -94,7 +101,7 @@
     // in some situations, bypassing a copy.
     codedIn.enableAliasing(true);
     try {
-      Object result = codec.deserialize(DeserializationContext.create(), codedIn);
+      Object result = codec.deserialize(deserializationContext, codedIn);
       if (result == null) {
         throw new NullPointerException(
             "ObjectCodec " + codec + " for " + classifier.toStringUtf8() + " returned null");
@@ -106,12 +113,11 @@
     }
   }
 
-  private static <T> void doSerialize(
+  private <T> void doSerialize(
       String classifier, ObjectCodec<T> codec, Object subject, CodedOutputStream codedOut)
       throws SerializationException, IOException {
     try {
-      codec.serialize(
-          SerializationContext.create(), codec.getEncodedClass().cast(subject), codedOut);
+      codec.serialize(serializationContext, codec.getEncodedClass().cast(subject), codedOut);
     } catch (ClassCastException e) {
       throw new SerializationException(
           "Codec "
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/PolymorphicHelper.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/PolymorphicHelper.java
index a92c1c5..b199ca6 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/PolymorphicHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/PolymorphicHelper.java
@@ -51,13 +51,6 @@
         StringCodecs.asciiOptimized().serialize(context, clazz.getName(), codedOut);
         if (codec instanceof ObjectCodec) {
           ((ObjectCodec) codec).serialize(context, input, codedOut);
-        } else if (codec instanceof InjectingObjectCodec) {
-          if (dependency == null) {
-            throw new SerializationException(
-                clazz.getCanonicalName() + " serialize parent class lacks required dependency.");
-          }
-          ((InjectingObjectCodec) codec)
-              .serialize(dependency.orElse(null), context, input, codedOut);
         } else {
           throw new SerializationException(
               clazz.getCanonicalName()
@@ -90,13 +83,6 @@
         Object codec = getCodec(Class.forName(className));
         if (codec instanceof ObjectCodec) {
           return ((ObjectCodec) codec).deserialize(context, codedIn);
-        } else if (codec instanceof InjectingObjectCodec) {
-          if (dependency == null) {
-            throw new SerializationException(
-                className + " deserialize parent class lacks required dependency.");
-          }
-          return ((InjectingObjectCodec) codec)
-              .deserialize(dependency.orElse(null), context, codedIn);
         } else {
           throw new SerializationException(
               className + ".CODEC has unexpected type " + codec.getClass().getCanonicalName());
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/SerializationContext.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/SerializationContext.java
index 234d049..c04e12d 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/SerializationContext.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/SerializationContext.java
@@ -14,21 +14,33 @@
 
 package com.google.devtools.build.lib.skyframe.serialization;
 
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+
 /** Stateful class for providing additional context to a single serialization "session". */
 // TODO(bazel-team): This class is just a shell, fill in.
 public class SerializationContext {
-  // TODO(bazel-team): Replace with real stateless implementation when we start adding
-  // functionality.
-  private static final SerializationContext EMPTY_STATELESS = new SerializationContext();
 
-  public static SerializationContext create() {
-    return stateless();
+  /**
+   * This is a stub for context where it is less straightforward to thread from the top-level
+   * invocation.
+   *
+   * <p>This is a bug waiting to happen because it is very easy to accidentally modify a codec to
+   * use this context which won't contain any of the expected state.
+   */
+  // TODO(bazel-team): delete this and all references to it.
+  public static final SerializationContext UNTHREADED_PLEASE_FIX =
+      new SerializationContext(ImmutableMap.of());
+
+  private final ImmutableMap<Class<?>, Object> dependencies;
+
+  public SerializationContext(ImmutableMap<Class<?>, Object> dependencies) {
+    this.dependencies = dependencies;
   }
 
-  /** Returns an empty instance which doesn't retain any state. */
-  public static SerializationContext stateless() {
-    return EMPTY_STATELESS;
+  @SuppressWarnings("unchecked")
+  public <T> T getDependency(Class<T> type) {
+    Preconditions.checkNotNull(type);
+    return (T) dependencies.get(type);
   }
-
-  private SerializationContext() {}
 }
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/SerializerAdapter.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/SerializerAdapter.java
index a6243cf..5eaed4e 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/SerializerAdapter.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/SerializerAdapter.java
@@ -38,7 +38,7 @@
       ByteArrayOutputStream byteOutput = new ByteArrayOutputStream();
       CodedOutputStream codedOut = CodedOutputStream.newInstance(byteOutput);
       // TODO(shahan): Determine if there's any context we can/should pass along from kryo.
-      codec.serialize(SerializationContext.create(), object, codedOut);
+      codec.serialize(SerializationContext.UNTHREADED_PLEASE_FIX, object, codedOut);
       codedOut.flush();
       byte[] byteData = byteOutput.toByteArray();
       output.writeInt(byteData.length, true);
@@ -54,7 +54,7 @@
       byte[] byteData = input.readBytes(input.readInt(true));
       // TODO(shahan): Determine if there's any context we can/should pass along from kryo.
       return codec.deserialize(
-          DeserializationContext.create(), CodedInputStream.newInstance(byteData));
+          DeserializationContext.UNTHREADED_PLEASE_FIX, CodedInputStream.newInstance(byteData));
     } catch (SerializationException | IOException e) {
       throw new KryoException(e);
     }
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/AutoCodec.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/AutoCodec.java
index be6a2bb..b627952 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/AutoCodec.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/AutoCodec.java
@@ -73,8 +73,6 @@
      * <p>Commonly used with the POLYMORPHIC strategy.
      *
      * <p>The serialized class must have a codec accessible, static INSTANCE field.
-     *
-     * <p>Illegal to use with a non-Void dependency.
      */
     SINGLETON
   }
@@ -88,37 +86,7 @@
   @Target({ElementType.CONSTRUCTOR, ElementType.METHOD})
   @interface Instantiator {}
 
-  /**
-   * Marks a specific constructor parameter as a dependency.
-   *
-   * <p>When a constructor selected for the {@code INSTANTIATOR} strategy has one of its parameters
-   * tagged {@code @Dependency}, {@code @AutoCodec} generates an {@link
-   * com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodec} instead of the usual
-   * {@link com.google.devtools.build.lib.skyframe.serialization.ObjectCodec} with the dependency
-   * type parameter matching the tagged parameter type.
-   *
-   * <p>At deserialization, the {@code @Dependency} tagged parameter will be forwarded from the
-   * {@code dependency} parameter of {@link
-   * com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodec#deserialize}.
-   *
-   * <p>A compiler error will result if more than one constructor parameter has the
-   * {@code @Dependency} annotation or if the annotation itself has a dependency element.
-   */
-  @Target(ElementType.PARAMETER)
-  @interface Dependency {}
-
   Strategy strategy() default Strategy.INSTANTIATOR;
-  /**
-   * Specifies a deserialization dependency.
-   *
-   * <p>When non-{@link Void}, generates an {@link
-   * com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodec} instead of the usual
-   * {@link com.google.devtools.build.lib.skyframe.serialization.ObjectCodec} with the dependency
-   * type parameter matching the returned type.
-   *
-   * <p>It is an error to use this in conjunction with {@code @AutoCodec.Dependency}.
-   */
-  Class<?> dependency() default Void.class;
 
   /**
    * Signals that the annotated element is only visible for use by serialization. It should not be
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/AutoCodecProcessor.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/AutoCodecProcessor.java
index 2fc4096..fc9547d 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/AutoCodecProcessor.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/AutoCodecProcessor.java
@@ -31,12 +31,10 @@
 import com.squareup.javapoet.TypeSpec;
 import java.io.IOException;
 import java.util.List;
-import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
-import javax.annotation.Nullable;
 import javax.annotation.processing.AbstractProcessor;
 import javax.annotation.processing.ProcessingEnvironment;
 import javax.annotation.processing.Processor;
@@ -48,8 +46,6 @@
 import javax.lang.model.element.Modifier;
 import javax.lang.model.element.TypeElement;
 import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.MirroredTypeException;
 import javax.lang.model.type.TypeKind;
 import javax.lang.model.type.TypeMirror;
 import javax.lang.model.util.ElementFilter;
@@ -98,20 +94,19 @@
     for (Element element : roundEnv.getElementsAnnotatedWith(AutoCodecUtil.ANNOTATION)) {
       AutoCodec annotation = element.getAnnotation(AutoCodecUtil.ANNOTATION);
       TypeElement encodedType = (TypeElement) element;
-      @Nullable TypeElement dependencyType = getDependencyType(annotation);
       TypeSpec.Builder codecClassBuilder = null;
       switch (annotation.strategy()) {
         case INSTANTIATOR:
-          codecClassBuilder = buildClassWithInstantiatorStrategy(encodedType, dependencyType);
+          codecClassBuilder = buildClassWithInstantiatorStrategy(encodedType);
           break;
         case PUBLIC_FIELDS:
-          codecClassBuilder = buildClassWithPublicFieldsStrategy(encodedType, dependencyType);
+          codecClassBuilder = buildClassWithPublicFieldsStrategy(encodedType);
           break;
         case POLYMORPHIC:
-          codecClassBuilder = buildClassWithPolymorphicStrategy(encodedType, dependencyType);
+          codecClassBuilder = buildClassWithPolymorphicStrategy(encodedType);
           break;
         case SINGLETON:
-          codecClassBuilder = buildClassWithSingletonStrategy(encodedType, dependencyType);
+          codecClassBuilder = buildClassWithSingletonStrategy(encodedType);
           break;
         default:
           throw new IllegalArgumentException("Unknown strategy: " + annotation.strategy());
@@ -137,86 +132,29 @@
     return true;
   }
 
-  /** Returns the type of the annotation dependency or null if the type is {@link Void}. */
-  @Nullable
-  private TypeElement getDependencyType(AutoCodec annotation) {
-    try {
-      annotation.dependency();
-      throw new AssertionError("Expected MirroredTypeException!");
-    } catch (MirroredTypeException e) {
-      DeclaredType dependencyMirror = (DeclaredType) e.getTypeMirror();
-      if (matchesType(dependencyMirror, Void.class)) {
-        return null;
-      }
-      return (TypeElement) dependencyMirror.asElement();
-    }
-  }
-
-  private TypeSpec.Builder buildClassWithInstantiatorStrategy(
-      TypeElement encodedType, @Nullable TypeElement dependency) {
+  private TypeSpec.Builder buildClassWithInstantiatorStrategy(TypeElement encodedType) {
     ExecutableElement constructor = selectInstantiator(encodedType);
-    PartitionedParameters parameters = isolateDependency(constructor);
-    if (dependency != null) {
-      if (parameters.dependency != null) {
-        throw new IllegalArgumentException(
-            encodedType.getQualifiedName()
-                + " has both a @Dependency annotated constructor parameter "
-                + "and a non-Void dependency element "
-                + dependency.getQualifiedName());
-      }
-      parameters.dependency = dependency;
-    }
+    List<? extends VariableElement> fields = constructor.getParameters();
 
-    TypeSpec.Builder codecClassBuilder =
-        AutoCodecUtil.initializeCodecClassBuilder(encodedType, parameters.dependency);
+    TypeSpec.Builder codecClassBuilder = AutoCodecUtil.initializeCodecClassBuilder(encodedType);
 
     if (encodedType.getAnnotation(AutoValue.class) == null) {
-      initializeUnsafeOffsets(codecClassBuilder, encodedType, parameters.fields);
-      codecClassBuilder.addMethod(buildSerializeMethodWithInstantiator(encodedType, parameters));
+      initializeUnsafeOffsets(codecClassBuilder, encodedType, fields);
+      codecClassBuilder.addMethod(buildSerializeMethodWithInstantiator(encodedType, fields));
     } else {
       codecClassBuilder.addMethod(
-          buildSerializeMethodWithInstantiatorForAutoValue(encodedType, parameters));
+          buildSerializeMethodWithInstantiatorForAutoValue(encodedType, fields));
     }
 
     MethodSpec.Builder deserializeBuilder =
-        AutoCodecUtil.initializeDeserializeMethodBuilder(encodedType, parameters.dependency);
-    buildDeserializeBody(deserializeBuilder, parameters.fields);
+        AutoCodecUtil.initializeDeserializeMethodBuilder(encodedType);
+    buildDeserializeBody(deserializeBuilder, fields);
     addReturnNew(deserializeBuilder, encodedType, constructor);
     codecClassBuilder.addMethod(deserializeBuilder.build());
 
     return codecClassBuilder;
   }
 
-  private static class PartitionedParameters {
-    /** Non-dependency parameters. */
-    List<VariableElement> fields;
-    /** Dependency for this codec or null if no such dependency exists. */
-    @Nullable TypeElement dependency;
-  }
-
-  /** Separates any dependency from the constructor parameters. */
-  private static PartitionedParameters isolateDependency(ExecutableElement constructor) {
-    Map<Boolean, List<VariableElement>> splitParameters =
-        constructor
-            .getParameters()
-            .stream()
-            .collect(
-                Collectors.partitioningBy(
-                    p -> p.getAnnotation(AutoCodec.Dependency.class) != null));
-    PartitionedParameters result = new PartitionedParameters();
-    result.fields = splitParameters.get(Boolean.FALSE);
-    List<VariableElement> dependencies = splitParameters.get(Boolean.TRUE);
-    if (dependencies.size() > 1) {
-      throw new IllegalArgumentException(
-          ((TypeElement) constructor.getEnclosingElement()).getQualifiedName()
-              + " constructor has multiple Dependency annotations.");
-    }
-    if (!dependencies.isEmpty()) {
-      result.dependency = (TypeElement) ((DeclaredType) dependencies.get(0).asType()).asElement();
-    }
-    return result;
-  }
-
   private ExecutableElement selectInstantiator(TypeElement encodedType) {
     List<ExecutableElement> constructors =
         ElementFilter.constructorsIn(encodedType.getEnclosedElements());
@@ -263,10 +201,10 @@
   }
 
   private MethodSpec buildSerializeMethodWithInstantiator(
-      TypeElement encodedType, PartitionedParameters parameters) {
+      TypeElement encodedType, List<? extends VariableElement> fields) {
     MethodSpec.Builder serializeBuilder =
-        AutoCodecUtil.initializeSerializeMethodBuilder(encodedType, parameters.dependency);
-    for (VariableElement parameter : parameters.fields) {
+        AutoCodecUtil.initializeSerializeMethodBuilder(encodedType);
+    for (VariableElement parameter : fields) {
       TypeKind typeKind = parameter.asType().getKind();
       switch (typeKind) {
         case BOOLEAN:
@@ -336,10 +274,10 @@
   }
 
   private MethodSpec buildSerializeMethodWithInstantiatorForAutoValue(
-      TypeElement encodedType, PartitionedParameters parameters) {
+      TypeElement encodedType, List<? extends VariableElement> fields) {
     MethodSpec.Builder serializeBuilder =
-        AutoCodecUtil.initializeSerializeMethodBuilder(encodedType, parameters.dependency);
-    for (VariableElement parameter : parameters.fields) {
+        AutoCodecUtil.initializeSerializeMethodBuilder(encodedType);
+    for (VariableElement parameter : fields) {
       TypeKind typeKind = parameter.asType().getKind();
       String getter = "input." + findGetterForAutoValue(parameter, encodedType) + "()";
       switch (typeKind) {
@@ -362,19 +300,16 @@
     return serializeBuilder.build();
   }
 
-  private TypeSpec.Builder buildClassWithPublicFieldsStrategy(
-      TypeElement encodedType, @Nullable TypeElement dependency) {
-    TypeSpec.Builder codecClassBuilder =
-        AutoCodecUtil.initializeCodecClassBuilder(encodedType, dependency);
+  private TypeSpec.Builder buildClassWithPublicFieldsStrategy(TypeElement encodedType) {
+    TypeSpec.Builder codecClassBuilder = AutoCodecUtil.initializeCodecClassBuilder(encodedType);
     ImmutableList<? extends VariableElement> publicFields =
         ElementFilter.fieldsIn(env.getElementUtils().getAllMembers(encodedType))
             .stream()
             .filter(this::isPublicField)
             .collect(toImmutableList());
-    codecClassBuilder.addMethod(
-        buildSerializeMethodWithPublicFields(encodedType, publicFields, dependency));
+    codecClassBuilder.addMethod(buildSerializeMethodWithPublicFields(encodedType, publicFields));
     MethodSpec.Builder deserializeBuilder =
-        AutoCodecUtil.initializeDeserializeMethodBuilder(encodedType, dependency);
+        AutoCodecUtil.initializeDeserializeMethodBuilder(encodedType);
     buildDeserializeBody(deserializeBuilder, publicFields);
     addInstantiatePopulateFieldsAndReturn(deserializeBuilder, encodedType, publicFields);
     codecClassBuilder.addMethod(deserializeBuilder.build());
@@ -390,12 +325,10 @@
   }
 
   private MethodSpec buildSerializeMethodWithPublicFields(
-      TypeElement encodedType,
-      List<? extends VariableElement> parameters,
-      @Nullable TypeElement dependency) {
+      TypeElement encodedType, List<? extends VariableElement> fields) {
     MethodSpec.Builder serializeBuilder =
-        AutoCodecUtil.initializeSerializeMethodBuilder(encodedType, dependency);
-    for (VariableElement parameter : parameters) {
+        AutoCodecUtil.initializeSerializeMethodBuilder(encodedType);
+    for (VariableElement parameter : fields) {
       String paramAccessor = "input." + parameter.getSimpleName();
       TypeKind typeKind = parameter.asType().getKind();
       switch (typeKind) {
@@ -428,8 +361,8 @@
    * is to avoid name collisions with variables used internally by AutoCodec.
    */
   private void buildDeserializeBody(
-      MethodSpec.Builder builder, List<? extends VariableElement> parameters) {
-    for (VariableElement parameter : parameters) {
+      MethodSpec.Builder builder, List<? extends VariableElement> fields) {
+    for (VariableElement parameter : fields) {
       String paramName = parameter.getSimpleName() + "_";
       TypeKind typeKind = parameter.asType().getKind();
       switch (typeKind) {
@@ -493,14 +426,9 @@
 
   /**
    * Coverts a constructor parameter to a String representing its handle within deserialize.
-   *
-   * <p>Uses the handle {@code dependency} for any parameter with the {@link AutoCodec.Dependency}
-   * annotation.
    */
   private static String handleFromParameter(VariableElement parameter) {
-    return parameter.getAnnotation(AutoCodec.Dependency.class) != null
-        ? "dependency"
-        : (parameter.getSimpleName() + "_");
+    return parameter.getSimpleName() + "_";
   }
 
   /**
@@ -595,71 +523,43 @@
     return Optional.empty();
   }
 
-  private TypeSpec.Builder buildClassWithPolymorphicStrategy(
-      TypeElement encodedType, @Nullable TypeElement dependency) {
+  private TypeSpec.Builder buildClassWithPolymorphicStrategy(TypeElement encodedType) {
     if (!encodedType.getModifiers().contains(Modifier.ABSTRACT)) {
       throw new IllegalArgumentException(
           encodedType + " is not abstract, but POLYMORPHIC was selected as the strategy.");
     }
-    TypeSpec.Builder codecClassBuilder =
-        AutoCodecUtil.initializeCodecClassBuilder(encodedType, dependency);
-    codecClassBuilder.addMethod(buildPolymorphicSerializeMethod(encodedType, dependency));
-    codecClassBuilder.addMethod(buildPolymorphicDeserializeMethod(encodedType, dependency));
+    TypeSpec.Builder codecClassBuilder = AutoCodecUtil.initializeCodecClassBuilder(encodedType);
+    codecClassBuilder.addMethod(buildPolymorphicSerializeMethod(encodedType));
+    codecClassBuilder.addMethod(buildPolymorphicDeserializeMethod(encodedType));
     return codecClassBuilder;
   }
 
-  private MethodSpec buildPolymorphicSerializeMethod(
-      TypeElement encodedType, @Nullable TypeElement dependency) {
-    MethodSpec.Builder builder =
-        AutoCodecUtil.initializeSerializeMethodBuilder(encodedType, dependency);
+  private MethodSpec buildPolymorphicSerializeMethod(TypeElement encodedType) {
+    MethodSpec.Builder builder = AutoCodecUtil.initializeSerializeMethodBuilder(encodedType);
     TypeName polyClass = TypeName.get(env.getTypeUtils().erasure(encodedType.asType()));
-    if (dependency == null) {
       builder.addStatement(
           "$T.serialize(context, input, $T.class, codedOut, null)",
           PolymorphicHelper.class,
           polyClass);
-    } else {
-      builder.addStatement(
-          "$T.serialize(context, input, $T.class, codedOut, $T.ofNullable(dependency))",
-          PolymorphicHelper.class,
-          polyClass,
-          Optional.class);
-    }
     return builder.build();
   }
 
-  private static MethodSpec buildPolymorphicDeserializeMethod(
-      TypeElement encodedType, @Nullable TypeElement dependency) {
-    MethodSpec.Builder builder =
-        AutoCodecUtil.initializeDeserializeMethodBuilder(encodedType, dependency);
-    if (dependency == null) {
+  private static MethodSpec buildPolymorphicDeserializeMethod(TypeElement encodedType) {
+    MethodSpec.Builder builder = AutoCodecUtil.initializeDeserializeMethodBuilder(encodedType);
       builder.addStatement(
           "return ($T) $T.deserialize(context, codedIn, null)",
           TypeName.get(encodedType.asType()),
           PolymorphicHelper.class);
-    } else {
-      builder.addStatement(
-          "return ($T) $T.deserialize(context, codedIn, $T.ofNullable(dependency))",
-          TypeName.get(encodedType.asType()),
-          PolymorphicHelper.class,
-          Optional.class);
-    }
     return builder.build();
   }
 
-  private static TypeSpec.Builder buildClassWithSingletonStrategy(
-      TypeElement encodedType, @Nullable TypeElement dependency) {
-    if (dependency != null) {
-      throw new IllegalArgumentException(
-          encodedType + " specifies a dependency, but SINGLETON is selected as the strategy.");
-    }
-    TypeSpec.Builder codecClassBuilder =
-        AutoCodecUtil.initializeCodecClassBuilder(encodedType, dependency);
+  private static TypeSpec.Builder buildClassWithSingletonStrategy(TypeElement encodedType) {
+    TypeSpec.Builder codecClassBuilder = AutoCodecUtil.initializeCodecClassBuilder(encodedType);
     // Serialization is a no-op.
     codecClassBuilder.addMethod(
-        AutoCodecUtil.initializeSerializeMethodBuilder(encodedType, dependency).build());
+        AutoCodecUtil.initializeSerializeMethodBuilder(encodedType).build());
     MethodSpec.Builder deserializeMethodBuilder =
-        AutoCodecUtil.initializeDeserializeMethodBuilder(encodedType, dependency);
+        AutoCodecUtil.initializeDeserializeMethodBuilder(encodedType);
     deserializeMethodBuilder.addStatement("return $T.INSTANCE", TypeName.get(encodedType.asType()));
     codecClassBuilder.addMethod(deserializeMethodBuilder.build());
     return codecClassBuilder;
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/AutoCodecUtil.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/AutoCodecUtil.java
index 4f54092..610badc 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/AutoCodecUtil.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/AutoCodecUtil.java
@@ -16,7 +16,6 @@
 
 import com.google.common.collect.ImmutableList;
 import com.google.devtools.build.lib.skyframe.serialization.DeserializationContext;
-import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.SerializationContext;
 import com.google.devtools.build.lib.skyframe.serialization.SerializationException;
@@ -29,7 +28,6 @@
 import com.squareup.javapoet.TypeSpec;
 import java.io.IOException;
 import java.util.stream.Collectors;
-import javax.annotation.Nullable;
 import javax.lang.model.element.Element;
 import javax.lang.model.element.Modifier;
 import javax.lang.model.element.TypeElement;
@@ -41,36 +39,15 @@
   static final Class<AutoCodec> ANNOTATION = AutoCodec.class;
 
   /**
-   * Initializes a builder for a class implementing {@link ObjectCodec}.
+   * Initializes a builder for a class of the appropriate type.
    *
    * @param encodedType type being serialized
    */
   static TypeSpec.Builder initializeCodecClassBuilder(TypeElement encodedType) {
-    return initializeCodecClassBuilder(encodedType, null);
-  }
-
-  /**
-   * Initializes a builder for a class of the appropriate type.
-   *
-   * <p>If the dependency is non-null, then the type is {@link InjectingObjectCodec} otherwise
-   * {@link ObjectCodec}.
-   *
-   * @param encodedType type being serialized
-   * @param dependency type being injected or null
-   */
-  static TypeSpec.Builder initializeCodecClassBuilder(
-      TypeElement encodedType, @Nullable TypeElement dependency) {
     TypeSpec.Builder builder = TypeSpec.classBuilder(getCodecName(encodedType));
-    if (dependency == null) {
-      return builder.addSuperinterface(
-          ParameterizedTypeName.get(
-              ClassName.get(ObjectCodec.class), TypeName.get(encodedType.asType())));
-    }
     return builder.addSuperinterface(
         ParameterizedTypeName.get(
-            ClassName.get(InjectingObjectCodec.class),
-            TypeName.get(encodedType.asType()),
-            TypeName.get(dependency.asType())));
+            ClassName.get(ObjectCodec.class), TypeName.get(encodedType.asType())));
   }
 
   static MethodSpec.Builder initializeGetEncodedClassMethod(TypeElement encodedType) {
@@ -82,21 +59,12 @@
                 ClassName.get(Class.class), TypeName.get(encodedType.asType())));
   }
 
-  static MethodSpec.Builder initializeSerializeMethodBuilder(TypeElement encodedType) {
-    return initializeSerializeMethodBuilder(encodedType, null);
-  }
-
   /**
-   * Initializes the appropriate deserialize method based on presence of dependency.
-   *
-   * <p>{@link InjectingObjectCodec#serialize} if dependency is non-null and {@link
-   * ObjectCodec#serialize} otherwise.
+   * Initializes the deserialize method.
    *
    * @param encodedType type being serialized
-   * @param dependency type being injected
    */
-  static MethodSpec.Builder initializeSerializeMethodBuilder(
-      TypeElement encodedType, @Nullable TypeElement dependency) {
+  static MethodSpec.Builder initializeSerializeMethodBuilder(TypeElement encodedType) {
     MethodSpec.Builder builder =
         MethodSpec.methodBuilder("serialize")
             .addModifiers(Modifier.PUBLIC)
@@ -104,31 +72,18 @@
             .addAnnotation(Override.class)
             .addException(SerializationException.class)
             .addException(IOException.class);
-    if (dependency != null) {
-      builder.addParameter(TypeName.get(dependency.asType()), "dependency");
-    }
     return builder
         .addParameter(SerializationContext.class, "context")
         .addParameter(TypeName.get(encodedType.asType()), "input")
         .addParameter(CodedOutputStream.class, "codedOut");
   }
 
-  /** Initializes {@link ObjectCodec#deserialize}. */
-  static MethodSpec.Builder initializeDeserializeMethodBuilder(TypeElement encodedType) {
-    return initializeDeserializeMethodBuilder(encodedType, null);
-  }
-
   /**
-   * Initializes the appropriate deserialize method based on presence of dependency.
-   *
-   * <p>{@link InjectingObjectCodec#deserialize} if dependency is non-null and {@link
-   * ObjectCodec#deserialize} otherwise.
+   * Initializes the deserialize method.
    *
    * @param encodedType type being serialized
-   * @param dependency type being injected
    */
-  static MethodSpec.Builder initializeDeserializeMethodBuilder(
-      TypeElement encodedType, @Nullable TypeElement dependency) {
+  static MethodSpec.Builder initializeDeserializeMethodBuilder(TypeElement encodedType) {
     MethodSpec.Builder builder =
         MethodSpec.methodBuilder("deserialize")
             .addModifiers(Modifier.PUBLIC)
@@ -136,9 +91,6 @@
             .addAnnotation(Override.class)
             .addException(SerializationException.class)
             .addException(IOException.class);
-    if (dependency != null) {
-      builder.addParameter(TypeName.get(dependency.asType()), "dependency");
-    }
     return builder
         .addParameter(DeserializationContext.class, "context")
         .addParameter(CodedInputStream.class, "codedIn");
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/Marshallers.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/Marshallers.java
index 541b1e3..bb8e6e9 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/Marshallers.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/Marshallers.java
@@ -28,7 +28,6 @@
 import com.google.common.hash.HashCode;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
 import com.google.devtools.build.lib.collect.nestedset.NestedSetCodec;
-import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.SerializationCodeGenerator.Context;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.SerializationCodeGenerator.Marshaller;
@@ -806,24 +805,13 @@
           typeParameter);
       return;
     }
-
-    if (matchesErased(typeParameterCodec.get().asType(), InjectingObjectCodec.class)) {
-            context.builder.addStatement(
-                "$T<$T> $L = new $T<>($T.CODEC, dependency)",
-                NestedSetCodec.class,
-                typeParameter,
-                nestedSetCodec,
-                NestedSetCodec.class,
-                typeParameter);
-          } else {
-            context.builder.addStatement(
-                "$T<$T> $L = new $T<>($T.CODEC)",
-                NestedSetCodec.class,
-                typeParameter,
-                nestedSetCodec,
-                NestedSetCodec.class,
-                typeParameter);
-          }
+    context.builder.addStatement(
+        "$T<$T> $L = new $T<>($T.CODEC)",
+        NestedSetCodec.class,
+        typeParameter,
+        nestedSetCodec,
+        NestedSetCodec.class,
+        typeParameter);
     context.builder.addStatement(
         "$L.serialize(context, ($T<$T>) $L, codedOut)",
         nestedSetCodec,
@@ -848,24 +836,13 @@
           typeParameter);
       return;
     }
-
-    if (matchesErased(typeParameterCodec.get().asType(), InjectingObjectCodec.class)) {
-            context.builder.addStatement(
-                "$T<$T> $L = new $T<>($T.CODEC, dependency)",
-                NestedSetCodec.class,
-                typeParameter,
-                nestedSetCodec,
-                NestedSetCodec.class,
-                typeParameter);
-          } else {
-            context.builder.addStatement(
-                "$T<$T> $L = new $T<>($T.CODEC)",
-                NestedSetCodec.class,
-                typeParameter,
-                nestedSetCodec,
-                NestedSetCodec.class,
-                typeParameter);
-          }
+    context.builder.addStatement(
+        "$T<$T> $L = new $T<>($T.CODEC)",
+        NestedSetCodec.class,
+        typeParameter,
+        nestedSetCodec,
+        NestedSetCodec.class,
+        typeParameter);
     context.builder.addStatement(
         "$L = $L.deserialize(context, codedIn)", context.name, nestedSetCodec);
   }
@@ -906,16 +883,11 @@
           if (isSubtypeErased(codecType, ObjectCodec.class)) {
             context.builder.addStatement(
                 "$T.CODEC.serialize(context, $L, codedOut)", context.getTypeName(), context.name);
-          } else if (isSubtypeErased(codecType, InjectingObjectCodec.class)) {
-            context.builder.addStatement(
-                "$T.CODEC.serialize(dependency, context, $L, codedOut)",
-                context.getTypeName(),
-                context.name);
           } else {
             throw new IllegalArgumentException(
                 "CODEC field of "
                     + ((TypeElement) context.getDeclaredType().asElement()).getQualifiedName()
-                    + " is neither ObjectCodec nor InjectingCodec");
+                    + " is not ObjectCodec");
           }
         }
 
@@ -925,16 +897,11 @@
           if (isSubtypeErased(codecType, ObjectCodec.class)) {
             context.builder.addStatement(
                 "$L = $T.CODEC.deserialize(context, codedIn)", context.name, context.getTypeName());
-          } else if (isSubtypeErased(codecType, InjectingObjectCodec.class)) {
-            context.builder.addStatement(
-                "$L = $T.CODEC.deserialize(dependency, context, codedIn)",
-                context.name,
-                context.getTypeName());
           } else {
             throw new IllegalArgumentException(
                 "CODEC field of "
                     + ((TypeElement) context.getDeclaredType().asElement()).getQualifiedName()
-                    + " is neither ObjectCodec nor InjectingCodec");
+                    + " is neither ObjectCodec");
           }
         }
       };
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/AbstractObjectCodecTest.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/AbstractObjectCodecTest.java
index 6be8562..3b60141 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/AbstractObjectCodecTest.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/AbstractObjectCodecTest.java
@@ -18,7 +18,9 @@
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.lib.skyframe.serialization.DeserializationContext;
 import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
+import com.google.devtools.build.lib.skyframe.serialization.SerializationContext;
 import com.google.devtools.build.lib.skyframe.serialization.SerializationException;
 import java.io.IOException;
 import javax.annotation.Nullable;
@@ -77,13 +79,15 @@
     objectCodecTester.testDeserializeJunkData();
   }
 
-  protected T fromBytes(byte[] bytes) throws SerializationException, IOException {
-    return TestUtils.fromBytes(underTest, bytes);
+  protected T fromBytes(DeserializationContext context, byte[] bytes)
+      throws SerializationException, IOException {
+    return TestUtils.fromBytes(context, underTest, bytes);
   }
 
   /** Serialize subject using the {@link ObjectCodec} under test. */
-  protected byte[] toBytes(T subject) throws IOException, SerializationException {
-    return TestUtils.toBytes(underTest, subject);
+  protected byte[] toBytes(SerializationContext context, T subject)
+      throws IOException, SerializationException {
+    return TestUtils.toBytes(context, underTest, subject);
   }
 
   protected void verifyDeserialization(T deserialized, T subject) {
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/FsUtils.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/FsUtils.java
index 29cb354..e244098 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/FsUtils.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/FsUtils.java
@@ -15,7 +15,6 @@
 package com.google.devtools.build.lib.skyframe.serialization.testutils;
 
 import com.google.devtools.build.lib.vfs.FileSystem;
-import com.google.devtools.build.lib.vfs.FileSystemProvider;
 import com.google.devtools.build.lib.vfs.PathFragment;
 import com.google.devtools.build.lib.vfs.Root;
 import com.google.devtools.build.lib.vfs.RootedPath;
@@ -26,8 +25,6 @@
 
   public static final FileSystem TEST_FILESYSTEM = new InMemoryFileSystem();
 
-  public static final FileSystemProvider TEST_FILESYSTEM_PROVIDER = () -> TEST_FILESYSTEM;
-
   public static final RootedPath TEST_ROOT =
       RootedPath.toRootedPath(
           Root.fromPath(TEST_FILESYSTEM.getPath(PathFragment.create("/anywhere/at/all"))),
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/ObjectCodecTester.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/ObjectCodecTester.java
index 82d4c36..a0f5873 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/ObjectCodecTester.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/ObjectCodecTester.java
@@ -20,8 +20,10 @@
 import com.google.common.base.Preconditions;
 import com.google.common.base.Stopwatch;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.skyframe.serialization.DeserializationContext;
 import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
+import com.google.devtools.build.lib.skyframe.serialization.SerializationContext;
 import com.google.devtools.build.lib.skyframe.serialization.SerializationException;
 import com.google.protobuf.CodedInputStream;
 import java.io.IOException;
@@ -55,17 +57,23 @@
 
   private final ObjectCodec<T> underTest;
   private final ImmutableList<T> subjects;
+  private final SerializationContext writeContext;
+  private final DeserializationContext readContext;
   private final boolean skipBadDataTest;
   private final VerificationFunction<T> verificationFunction;
 
   private ObjectCodecTester(
       ObjectCodec<T> underTest,
       ImmutableList<T> subjects,
+      SerializationContext writeContext,
+      DeserializationContext readContext,
       boolean skipBadDataTest,
       VerificationFunction<T> verificationFunction) {
     this.underTest = underTest;
     Preconditions.checkState(!subjects.isEmpty(), "No subjects provided");
     this.subjects = subjects;
+    this.writeContext = writeContext;
+    this.readContext = readContext;
     this.skipBadDataTest = skipBadDataTest;
     this.verificationFunction = verificationFunction;
   }
@@ -111,8 +119,7 @@
   void testDeserializeJunkData() {
     try {
       underTest.deserialize(
-          DeserializationContext.create(),
-          CodedInputStream.newInstance("junk".getBytes(StandardCharsets.UTF_8)));
+          readContext, CodedInputStream.newInstance("junk".getBytes(StandardCharsets.UTF_8)));
       fail("Expected exception");
     } catch (SerializationException | IOException e) {
       // Expected.
@@ -120,17 +127,19 @@
   }
 
   private T fromBytes(byte[] bytes) throws SerializationException, IOException {
-    return TestUtils.fromBytes(underTest, bytes);
+    return TestUtils.fromBytes(readContext, underTest, bytes);
   }
 
   private byte[] toBytes(T subject) throws IOException, SerializationException {
-    return TestUtils.toBytes(underTest, subject);
+    return TestUtils.toBytes(writeContext, underTest, subject);
   }
 
   /** Builder for {@link ObjectCodecTester}. */
   public static class Builder<T> {
     private final ObjectCodec<T> underTest;
     private final ImmutableList.Builder<T> subjectsBuilder = ImmutableList.builder();
+    private final ImmutableMap.Builder<Class<?>, Object> dependenciesBuilder =
+        ImmutableMap.builder();
     private boolean skipBadDataTest = false;
     private VerificationFunction<T> verificationFunction =
         (original, deserialized) -> assertThat(deserialized).isEqualTo(original);
@@ -151,6 +160,12 @@
       return this;
     }
 
+    /** Add subjects to be tested for serialization/deserialization. */
+    public final <D> Builder<T> addDependency(Class<? super D> type, D dependency) {
+      dependenciesBuilder.put(type, dependency);
+      return this;
+    }
+
     /**
      * Skip tests that check for the ability to detect bad data. This may be useful for simpler
      * codecs which don't do any error verification.
@@ -180,9 +195,12 @@
      * individually.
      */
     ObjectCodecTester<T> build() {
+      ImmutableMap<Class<?>, Object> dependencies = dependenciesBuilder.build();
       return new ObjectCodecTester<>(
           underTest,
           subjectsBuilder.build(),
+          new SerializationContext(dependencies),
+          new DeserializationContext(dependencies),
           skipBadDataTest,
           verificationFunction);
     }
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/TestUtils.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/TestUtils.java
index 8e87e46..8d914da 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/TestUtils.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/TestUtils.java
@@ -33,19 +33,19 @@
   private TestUtils() {}
 
   /** Serialize a value to a new byte array. */
-  public static <T> byte[] toBytes(ObjectCodec<T> codec, T value)
+  public static <T> byte[] toBytes(SerializationContext context, ObjectCodec<T> codec, T value)
       throws IOException, SerializationException {
     ByteArrayOutputStream bytes = new ByteArrayOutputStream();
     CodedOutputStream codedOut = CodedOutputStream.newInstance(bytes);
-    codec.serialize(SerializationContext.create(), value, codedOut);
+    codec.serialize(context, value, codedOut);
     codedOut.flush();
     return bytes.toByteArray();
   }
 
   /** Deserialize a value from a byte array. */
-  public static <T> T fromBytes(ObjectCodec<T> codec, byte[] bytes)
+  public static <T> T fromBytes(DeserializationContext context, ObjectCodec<T> codec, byte[] bytes)
       throws SerializationException, IOException {
-    return codec.deserialize(DeserializationContext.create(), CodedInputStream.newInstance(bytes));
+    return codec.deserialize(context, CodedInputStream.newInstance(bytes));
   }
 
   /**
diff --git a/src/main/java/com/google/devtools/build/lib/vfs/FileSystemProvider.java b/src/main/java/com/google/devtools/build/lib/vfs/FileSystemProvider.java
deleted file mode 100644
index 160bb2e..0000000
--- a/src/main/java/com/google/devtools/build/lib/vfs/FileSystemProvider.java
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2018 The Bazel Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.devtools.build.lib.vfs;
-
-/** Abstraction for injecting FileSystem dependencies. */
-public interface FileSystemProvider {
-
-  FileSystem getFileSystem();
-}
diff --git a/src/main/java/com/google/devtools/build/lib/vfs/Path.java b/src/main/java/com/google/devtools/build/lib/vfs/Path.java
index 649eea9..b4542ec 100644
--- a/src/main/java/com/google/devtools/build/lib/vfs/Path.java
+++ b/src/main/java/com/google/devtools/build/lib/vfs/Path.java
@@ -16,7 +16,6 @@
 import com.google.common.base.Preconditions;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe;
 import com.google.devtools.build.lib.skyframe.serialization.DeserializationContext;
-import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.SerializationContext;
 import com.google.devtools.build.lib.skyframe.serialization.SerializationException;
@@ -62,8 +61,7 @@
 @ThreadSafe
 public class Path
     implements Comparable<Path>, Serializable, SkylarkPrintable, FileType.HasFileType {
-  public static final InjectingObjectCodec<Path, FileSystemProvider> CODEC =
-      new PathCodecWithInjectedFileSystem();
+  public static final ObjectCodec<Path> CODEC = new Codec();
 
   private static FileSystem fileSystemForSerialization;
 
@@ -907,8 +905,7 @@
     driveStrLength = OS.getDriveStrLength(path);
   }
 
-  private static class PathCodecWithInjectedFileSystem
-      implements InjectingObjectCodec<Path, FileSystemProvider> {
+  private static class Codec implements ObjectCodec<Path> {
     private final ObjectCodec<String> stringCodec = StringCodecs.asciiOptimized();
 
     @Override
@@ -918,21 +915,23 @@
 
     @Override
     public void serialize(
-        FileSystemProvider fsProvider,
         SerializationContext context,
         Path path,
         CodedOutputStream codedOut)
         throws IOException, SerializationException {
-      Preconditions.checkArgument(path.getFileSystem() == fsProvider.getFileSystem());
+      Preconditions.checkArgument(
+          path.getFileSystem() == context.getDependency(FileSystem.class),
+          "%s != %s",
+          path.getFileSystem(),
+          context.getDependency(FileSystem.class));
       stringCodec.serialize(context, path.getPathString(), codedOut);
     }
 
     @Override
-    public Path deserialize(
-        FileSystemProvider fsProvider, DeserializationContext context, CodedInputStream codedIn)
+    public Path deserialize(DeserializationContext context, CodedInputStream codedIn)
         throws IOException, SerializationException {
       return Path.createAlreadyNormalized(
-          stringCodec.deserialize(context, codedIn), fsProvider.getFileSystem());
+          stringCodec.deserialize(context, codedIn), context.getDependency(FileSystem.class));
     }
   }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/vfs/Root.java b/src/main/java/com/google/devtools/build/lib/vfs/Root.java
index 73ff687..6f090e4 100644
--- a/src/main/java/com/google/devtools/build/lib/vfs/Root.java
+++ b/src/main/java/com/google/devtools/build/lib/vfs/Root.java
@@ -16,7 +16,7 @@
 import com.google.common.base.Objects;
 import com.google.common.base.Preconditions;
 import com.google.devtools.build.lib.skyframe.serialization.DeserializationContext;
-import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodec;
+import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.SerializationContext;
 import com.google.devtools.build.lib.skyframe.serialization.SerializationException;
 import com.google.protobuf.CodedInputStream;
@@ -35,7 +35,7 @@
  */
 public interface Root extends Comparable<Root>, Serializable {
 
-  InjectingObjectCodec<Root, FileSystemProvider> CODEC = new RootCodec();
+  ObjectCodec<Root> CODEC = new RootCodec();
 
   /** Constructs a root from a path. */
   static Root fromPath(Path path) {
@@ -258,7 +258,7 @@
   }
 
   /** Codec to serialize {@link Root}s. */
-  class RootCodec implements InjectingObjectCodec<Root, FileSystemProvider> {
+  class RootCodec implements ObjectCodec<Root> {
     @Override
     public Class<Root> getEncodedClass() {
       return Root.class;
@@ -266,16 +266,16 @@
 
     @Override
     public void serialize(
-        FileSystemProvider dependency,
         SerializationContext context,
         Root obj,
         CodedOutputStream codedOut)
         throws SerializationException, IOException {
       if (obj instanceof PathRoot) {
         codedOut.writeBoolNoTag(false);
-        Path.CODEC.serialize(dependency, context, ((PathRoot) obj).path, codedOut);
+        Path.CODEC.serialize(context, ((PathRoot) obj).path, codedOut);
       } else if (obj instanceof AbsoluteRoot) {
-        Preconditions.checkArgument(((AbsoluteRoot) obj).fileSystem == dependency.getFileSystem());
+        Preconditions.checkArgument(
+            ((AbsoluteRoot) obj).fileSystem == context.getDependency(FileSystem.class));
         codedOut.writeBoolNoTag(true);
       } else {
         throw new AssertionError("Unknown Root subclass: " + obj.getClass().getName());
@@ -283,14 +283,13 @@
     }
 
     @Override
-    public Root deserialize(
-        FileSystemProvider dependency, DeserializationContext context, CodedInputStream codedIn)
+    public Root deserialize(DeserializationContext context, CodedInputStream codedIn)
         throws SerializationException, IOException {
       boolean isAbsolute = codedIn.readBool();
       if (isAbsolute) {
-        return dependency.getFileSystem().getAbsoluteRoot();
+        return context.getDependency(FileSystem.class).getAbsoluteRoot();
       } else {
-        Path path = Path.CODEC.deserialize(dependency, context, codedIn);
+        Path path = Path.CODEC.deserialize(context, codedIn);
         return new PathRoot(path);
       }
     }
diff --git a/src/main/java/com/google/devtools/build/lib/vfs/RootedPath.java b/src/main/java/com/google/devtools/build/lib/vfs/RootedPath.java
index aa31534..bbc89a9 100644
--- a/src/main/java/com/google/devtools/build/lib/vfs/RootedPath.java
+++ b/src/main/java/com/google/devtools/build/lib/vfs/RootedPath.java
@@ -14,14 +14,8 @@
 package com.google.devtools.build.lib.vfs;
 
 import com.google.common.base.Preconditions;
-import com.google.devtools.build.lib.skyframe.serialization.DeserializationContext;
-import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodecAdapter;
 import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
-import com.google.devtools.build.lib.skyframe.serialization.SerializationContext;
-import com.google.devtools.build.lib.skyframe.serialization.SerializationException;
-import com.google.protobuf.CodedInputStream;
-import com.google.protobuf.CodedOutputStream;
-import java.io.IOException;
+import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
 import java.io.Serializable;
 import java.util.Objects;
 
@@ -35,13 +29,18 @@
  * <p>TODO(bazel-team): use an opaque root representation so as to not expose the absolute path to
  * clients via #asPath or #getRoot.
  */
+@AutoCodec
 public class RootedPath implements Serializable {
 
+  public static final ObjectCodec<RootedPath> CODEC = new RootedPath_AutoCodec();
+
   private final Root root;
   private final PathFragment rootRelativePath;
 
   /** Constructs a {@link RootedPath} from a {@link Root} and path fragment relative to the root. */
-  private RootedPath(Root root, PathFragment rootRelativePath) {
+  @AutoCodec.Instantiator
+  @AutoCodec.VisibleForSerialization
+  RootedPath(Root root, PathFragment rootRelativePath) {
     Preconditions.checkState(
         rootRelativePath.isAbsolute() == root.isAbsolute(),
         "rootRelativePath: %s root: %s",
@@ -123,36 +122,4 @@
   public String toString() {
     return "[" + root + "]/[" + rootRelativePath + "]";
   }
-
-  /** Custom serialization for {@link RootedPath}s. */
-  public static class RootedPathCodec implements ObjectCodec<RootedPath> {
-
-    private final ObjectCodec<Root> rootCodec;
-
-    /** Create an instance which will deserialize RootedPaths on {@code fileSystem}. */
-    public RootedPathCodec(FileSystem fileSystem) {
-      this.rootCodec = new InjectingObjectCodecAdapter<>(Root.CODEC, () -> fileSystem);
-    }
-
-    @Override
-    public Class<RootedPath> getEncodedClass() {
-      return RootedPath.class;
-    }
-
-    @Override
-    public void serialize(
-        SerializationContext context, RootedPath rootedPath, CodedOutputStream codedOut)
-        throws IOException, SerializationException {
-      rootCodec.serialize(context, rootedPath.getRoot(), codedOut);
-      PathFragment.CODEC.serialize(context, rootedPath.getRootRelativePath(), codedOut);
-    }
-
-    @Override
-    public RootedPath deserialize(DeserializationContext context, CodedInputStream codedIn)
-        throws IOException, SerializationException {
-      Root root = rootCodec.deserialize(context, codedIn);
-      PathFragment rootRelativePath = PathFragment.CODEC.deserialize(context, codedIn);
-      return toRootedPath(root, rootRelativePath);
-    }
-  }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/BUILD b/src/test/java/com/google/devtools/build/lib/BUILD
index cf66e2f..f1cc531 100644
--- a/src/test/java/com/google/devtools/build/lib/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/BUILD
@@ -856,6 +856,7 @@
         "//src/main/java/com/google/devtools/build/lib:packages",
         "//src/main/java/com/google/devtools/build/lib:skylarkinterface",
         "//src/main/java/com/google/devtools/build/lib:util",
+        "//src/main/java/com/google/devtools/build/lib/skyframe/serialization",
         "//src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils",
         "//src/main/java/com/google/devtools/build/lib/vfs",
         "//src/main/java/com/google/devtools/build/skyframe",
diff --git a/src/test/java/com/google/devtools/build/lib/actions/ArtifactTest.java b/src/test/java/com/google/devtools/build/lib/actions/ArtifactTest.java
index f26d00e..a0261e9 100644
--- a/src/test/java/com/google/devtools/build/lib/actions/ArtifactTest.java
+++ b/src/test/java/com/google/devtools/build/lib/actions/ArtifactTest.java
@@ -25,10 +25,10 @@
 import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.rules.cpp.CppFileTypes;
 import com.google.devtools.build.lib.rules.java.JavaSemantics;
-import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodecAdapter;
 import com.google.devtools.build.lib.skyframe.serialization.testutils.ObjectCodecTester;
 import com.google.devtools.build.lib.testutil.MoreAsserts;
 import com.google.devtools.build.lib.testutil.Scratch;
+import com.google.devtools.build.lib.vfs.FileSystem;
 import com.google.devtools.build.lib.vfs.Path;
 import com.google.devtools.build.lib.vfs.PathFragment;
 import com.google.devtools.build.lib.vfs.Root;
@@ -336,8 +336,7 @@
 
   @Test
   public void testCodec() throws Exception {
-    ObjectCodecTester.newBuilder(
-            new InjectingObjectCodecAdapter<>(Artifact.CODEC, () -> scratch.getFileSystem()))
+    ObjectCodecTester.newBuilder(Artifact.CODEC)
         .addSubjects(
             new Artifact(PathFragment.create("src/a"), rootDir),
             new Artifact(
@@ -347,6 +346,7 @@
                     scratch.getFileSystem().getPath("/"), scratch.dir("/src")),
                 PathFragment.create("src/c"),
                 new LabelArtifactOwner(Label.parseAbsoluteUnchecked("//foo:bar"))))
+        .addDependency(FileSystem.class, scratch.getFileSystem())
         .buildAndRunTests();
   }
 
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/BlazeDirectoriesTest.java b/src/test/java/com/google/devtools/build/lib/analysis/BlazeDirectoriesTest.java
index c686a1f..06ffcd0 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/BlazeDirectoriesTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/BlazeDirectoriesTest.java
@@ -15,7 +15,6 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodecAdapter;
 import com.google.devtools.build.lib.skyframe.serialization.testutils.FsUtils;
 import com.google.devtools.build.lib.skyframe.serialization.testutils.ObjectCodecTester;
 import com.google.devtools.build.lib.testutil.FoundationTestCase;
@@ -54,9 +53,7 @@
 
   @Test
   public void testCodec() throws Exception {
-    ObjectCodecTester.newBuilder(
-            new InjectingObjectCodecAdapter<>(
-                BlazeDirectories.CODEC, FsUtils.TEST_FILESYSTEM_PROVIDER))
+    ObjectCodecTester.newBuilder(BlazeDirectories.CODEC)
         .addSubjects(
             new BlazeDirectories(
                 new ServerDirectories(
@@ -77,6 +74,7 @@
                     FsUtils.TEST_FILESYSTEM.getPath("/output_base")),
                 FsUtils.TEST_FILESYSTEM.getPath("/workspace"),
                 "Bazel"))
+        .addDependency(FileSystem.class, FsUtils.TEST_FILESYSTEM)
         .buildAndRunTests();
   }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/config/BuildConfigurationTest.java b/src/test/java/com/google/devtools/build/lib/analysis/config/BuildConfigurationTest.java
index d3a1d4d..26b1d1e 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/config/BuildConfigurationTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/config/BuildConfigurationTest.java
@@ -29,8 +29,8 @@
 import com.google.devtools.build.lib.rules.cpp.CppConfiguration;
 import com.google.devtools.build.lib.rules.java.JavaConfiguration;
 import com.google.devtools.build.lib.rules.objc.J2ObjcConfiguration;
-import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodecAdapter;
 import com.google.devtools.build.lib.skyframe.serialization.testutils.ObjectCodecTester;
+import com.google.devtools.build.lib.vfs.FileSystem;
 import com.google.devtools.common.options.Options;
 import java.util.Map;
 import java.util.regex.Pattern;
@@ -430,9 +430,7 @@
 
   @Test
   public void testCodec() throws Exception {
-    ObjectCodecTester.newBuilder(
-            new InjectingObjectCodecAdapter<>(
-                BuildConfiguration.CODEC, () -> getScratch().getFileSystem()))
+    ObjectCodecTester.newBuilder(BuildConfiguration.CODEC)
         .addSubjects(
             create(),
             create("--cpu=piii"),
@@ -453,6 +451,7 @@
                 "qspace=a\\ quoted\\ space",
                 "--define",
                 "#a=pounda"))
+        .addDependency(FileSystem.class, getScratch().getFileSystem())
         .verificationFunction(BuildConfigurationTest::verifyDeserialized)
         .buildAndRunTests();
   }
diff --git a/src/test/java/com/google/devtools/build/lib/packages/SkylarkSemanticsConsistencyTest.java b/src/test/java/com/google/devtools/build/lib/packages/SkylarkSemanticsConsistencyTest.java
index 56d8039..339f060 100644
--- a/src/test/java/com/google/devtools/build/lib/packages/SkylarkSemanticsConsistencyTest.java
+++ b/src/test/java/com/google/devtools/build/lib/packages/SkylarkSemanticsConsistencyTest.java
@@ -16,6 +16,9 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import com.google.common.collect.ImmutableMap;
+import com.google.devtools.build.lib.skyframe.serialization.DeserializationContext;
+import com.google.devtools.build.lib.skyframe.serialization.SerializationContext;
 import com.google.devtools.build.lib.skyframe.serialization.testutils.TestUtils;
 import com.google.devtools.build.lib.syntax.SkylarkSemantics;
 import com.google.devtools.common.options.Options;
@@ -84,7 +87,10 @@
     for (int i = 0; i < NUM_RANDOM_TRIALS; i++) {
       SkylarkSemantics semantics = buildRandomSemantics(new Random(i));
       SkylarkSemantics deserialized =
-          TestUtils.fromBytes(codec, TestUtils.toBytes(codec, semantics));
+          TestUtils.fromBytes(
+              new DeserializationContext(ImmutableMap.of()),
+              codec,
+              TestUtils.toBytes(new SerializationContext(ImmutableMap.of()), codec, semantics));
       assertThat(deserialized).isEqualTo(semantics);
     }
   }
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/GlobDescriptorTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/GlobDescriptorTest.java
index ee37679..d5174c5 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/GlobDescriptorTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/GlobDescriptorTest.java
@@ -17,9 +17,9 @@
 
 import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
 import com.google.devtools.build.lib.cmdline.PackageIdentifier;
-import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodecAdapter;
 import com.google.devtools.build.lib.skyframe.serialization.testutils.FsUtils;
 import com.google.devtools.build.lib.skyframe.serialization.testutils.ObjectCodecTester;
+import com.google.devtools.build.lib.vfs.FileSystem;
 import com.google.devtools.build.lib.vfs.PathFragment;
 import com.google.devtools.build.lib.vfs.Root;
 import org.junit.Test;
@@ -32,9 +32,7 @@
 
   @Test
   public void testSerialization() throws Exception {
-    ObjectCodecTester.newBuilder(
-            GlobDescriptor.getCodec(
-                new InjectingObjectCodecAdapter<>(Root.CODEC, () -> FsUtils.TEST_FILESYSTEM)))
+    ObjectCodecTester.newBuilder(GlobDescriptor.CODEC)
         .addSubjects(
             GlobDescriptor.create(
                 PackageIdentifier.create("@foo", PathFragment.create("//bar")),
@@ -48,6 +46,7 @@
                 PathFragment.create("anotherSubdir"),
                 "pattern",
                 /*excludeDirs=*/ true))
+        .addDependency(FileSystem.class, FsUtils.TEST_FILESYSTEM)
         .verificationFunction((orig, deserialized) -> assertThat(deserialized).isSameAs(orig))
         .buildAndRunTests();
   }
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/PackageValueTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/PackageValueTest.java
index 3c3652d..c8d9d9e 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/PackageValueTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/PackageValueTest.java
@@ -21,12 +21,13 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.packages.Package;
+import com.google.devtools.build.lib.packages.PackageCodecDependencies;
 import com.google.devtools.build.lib.packages.PackageCodecDependencies.SimplePackageCodecDependencies;
 import com.google.devtools.build.lib.packages.PackageDeserializationException;
 import com.google.devtools.build.lib.packages.PackageDeserializerInterface;
 import com.google.devtools.build.lib.skyframe.serialization.DeserializationContext;
-import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodecAdapter;
 import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.SerializationException;
 import com.google.protobuf.CodedInputStream;
@@ -43,13 +44,13 @@
 
   private PackageDeserializerInterface mockDeserializer;
   private ObjectCodec<PackageValue> underTest;
+  SimplePackageCodecDependencies codecDeps;
 
   @Before
   public void setUp() {
     this.mockDeserializer = mock(PackageDeserializerInterface.class);
-    this.underTest =
-        new InjectingObjectCodecAdapter<>(
-            PackageValue.CODEC, new SimplePackageCodecDependencies(null, mockDeserializer));
+    this.underTest = PackageValue.CODEC;
+    this.codecDeps = new SimplePackageCodecDependencies(null, mockDeserializer);
   }
 
   @Test
@@ -63,7 +64,10 @@
         .thenReturn(mockPackage);
 
     CodedInputStream codedIn = CodedInputStream.newInstance(new byte[] {1, 2, 3, 4});
-    PackageValue result = underTest.deserialize(DeserializationContext.create(), codedIn);
+    PackageValue result =
+        underTest.deserialize(
+            new DeserializationContext(ImmutableMap.of(PackageCodecDependencies.class, codecDeps)),
+            codedIn);
 
     assertThat(result.getPackage()).isSameAs(mockPackage);
   }
@@ -75,7 +79,8 @@
 
     try {
       underTest.deserialize(
-          DeserializationContext.create(), CodedInputStream.newInstance(new byte[] {1, 2, 3, 4}));
+          new DeserializationContext(ImmutableMap.of(PackageCodecDependencies.class, codecDeps)),
+          CodedInputStream.newInstance(new byte[] {1, 2, 3, 4}));
       fail("Expected exception");
     } catch (IllegalStateException e) {
       assertThat(e)
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactBuildTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactBuildTest.java
index 5d24b9e..4928d73 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactBuildTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactBuildTest.java
@@ -52,7 +52,6 @@
 import com.google.devtools.build.lib.events.EventKind;
 import com.google.devtools.build.lib.events.StoredEventHandler;
 import com.google.devtools.build.lib.skyframe.ActionTemplateExpansionValue.ActionTemplateExpansionKey;
-import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodecAdapter;
 import com.google.devtools.build.lib.skyframe.serialization.testutils.ObjectCodecTester;
 import com.google.devtools.build.lib.testutil.TestUtils;
 import com.google.devtools.build.lib.vfs.FileStatus;
@@ -118,9 +117,9 @@
 
   @Test
   public void testCodec() throws Exception {
-    ObjectCodecTester.newBuilder(
-            new InjectingObjectCodecAdapter<>(Artifact.CODEC, () -> scratch.getFileSystem()))
+    ObjectCodecTester.newBuilder(Artifact.CODEC)
         .addSubjects(outOne, outOneFileOne)
+        .addDependency(FileSystem.class, scratch.getFileSystem())
         .buildAndRunTests();
   }
 
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/serialization/ObjectCodecsTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/serialization/ObjectCodecsTest.java
index 3b84c93..dc835c7 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/serialization/ObjectCodecsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/serialization/ObjectCodecsTest.java
@@ -26,6 +26,7 @@
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 
+import com.google.common.collect.ImmutableMap;
 import com.google.protobuf.ByteString;
 import com.google.protobuf.CodedInputStream;
 import com.google.protobuf.CodedOutputStream;
@@ -79,10 +80,10 @@
   @Before
   public final void setup() {
     spyObjectCodec = spy(new IntegerCodec());
-    this.underTest = new ObjectCodecs(
-        ObjectCodecRegistry.newBuilder()
-            .add(KNOWN_CLASSIFIER, spyObjectCodec)
-            .build());
+    this.underTest =
+        new ObjectCodecs(
+            ObjectCodecRegistry.newBuilder().add(KNOWN_CLASSIFIER, spyObjectCodec).build(),
+            ImmutableMap.of());
   }
 
   @Test
@@ -224,8 +225,10 @@
 
   @Test
   public void testSerializeFailsWhenNoCustomCodecAndFallbackDisabled() throws Exception {
-    ObjectCodecs underTest = new ObjectCodecs(
-        ObjectCodecRegistry.newBuilder().setAllowDefaultCodec(false).build());
+    ObjectCodecs underTest =
+        new ObjectCodecs(
+            ObjectCodecRegistry.newBuilder().setAllowDefaultCodec(false).build(),
+            ImmutableMap.of());
     SerializationException.NoCodecException expected =
         expectThrows(
             SerializationException.NoCodecException.class, () -> underTest.serialize("X", "Y"));
@@ -237,8 +240,10 @@
   @Test
   public void testDeserializeFailsWhenNoCustomCodecAndFallbackDisabled() throws Exception {
     ByteString serialized = ByteString.copyFromUtf8("doesn't matter");
-    ObjectCodecs underTest = new ObjectCodecs(
-        ObjectCodecRegistry.newBuilder().setAllowDefaultCodec(false).build());
+    ObjectCodecs underTest =
+        new ObjectCodecs(
+            ObjectCodecRegistry.newBuilder().setAllowDefaultCodec(false).build(),
+            ImmutableMap.of());
     SerializationException.NoCodecException expected =
         expectThrows(
             SerializationException.NoCodecException.class,
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/serialization/PrecomputedValueCodecTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/serialization/PrecomputedValueCodecTest.java
index f6532fc..f1bac51 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/serialization/PrecomputedValueCodecTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/serialization/PrecomputedValueCodecTest.java
@@ -14,6 +14,7 @@
 
 package com.google.devtools.build.lib.skyframe.serialization;
 
+import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.cmdline.LabelCodec;
 import com.google.devtools.build.lib.skyframe.PrecomputedValue;
@@ -30,13 +31,15 @@
   public PrecomputedValueCodecTest() {
     super(
         new PrecomputedValueCodec(
-            () -> new ObjectCodecs(
-                ObjectCodecRegistry.newBuilder()
-                    .asClassKeyedBuilder()
-                    // Note no PathFragmentCodec.
-                    .add(String.class, StringCodecs.asciiOptimized())
-                    .add(Label.class, LabelCodec.INSTANCE)
-                    .build())),
+            () ->
+                new ObjectCodecs(
+                    ObjectCodecRegistry.newBuilder()
+                        .asClassKeyedBuilder()
+                        // Note no PathFragmentCodec.
+                        .add(String.class, StringCodecs.asciiOptimized())
+                        .add(Label.class, LabelCodec.INSTANCE)
+                        .build(),
+                    ImmutableMap.of())),
         new PrecomputedValue(PathFragment.create("java serializable 1")),
         new PrecomputedValue(PathFragment.create("java serializable 2")),
         new PrecomputedValue("first string"),
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/serialization/RepositoryNameCodecTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/serialization/RepositoryNameCodecTest.java
index 30f4e08..f922e43 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/serialization/RepositoryNameCodecTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/serialization/RepositoryNameCodecTest.java
@@ -16,6 +16,7 @@
 
 import static org.junit.Assert.fail;
 
+import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
 import com.google.devtools.build.lib.cmdline.RepositoryName;
 import com.google.devtools.build.lib.cmdline.RepositoryNameCodec;
@@ -47,7 +48,7 @@
   @Test
   public void testDeserializeBadDataThrowsSerializationException() {
     try {
-      fromBytes(INVALID_ENCODED_REPOSITORY_NAME);
+      fromBytes(new DeserializationContext(ImmutableMap.of()), INVALID_ENCODED_REPOSITORY_NAME);
       fail("Expected exception");
     } catch (SerializationException | IOException e) {
       // Expected.
diff --git a/src/test/java/com/google/devtools/build/lib/vfs/RootTest.java b/src/test/java/com/google/devtools/build/lib/vfs/RootTest.java
index 9c67e72..e9605b3 100644
--- a/src/test/java/com/google/devtools/build/lib/vfs/RootTest.java
+++ b/src/test/java/com/google/devtools/build/lib/vfs/RootTest.java
@@ -18,8 +18,6 @@
 import com.google.common.collect.Lists;
 import com.google.common.testing.EqualsTester;
 import com.google.devtools.build.lib.clock.BlazeClock;
-import com.google.devtools.build.lib.skyframe.serialization.InjectingObjectCodecAdapter;
-import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
 import com.google.devtools.build.lib.skyframe.serialization.testutils.ObjectCodecTester;
 import com.google.devtools.build.lib.testutil.MoreAsserts;
 import com.google.devtools.build.lib.vfs.inmemoryfs.InMemoryFileSystem;
@@ -99,9 +97,9 @@
 
   @Test
   public void testSerialization() throws Exception {
-    ObjectCodec<Root> codec = new InjectingObjectCodecAdapter<>(Root.CODEC, () -> fs);
-    ObjectCodecTester.newBuilder(codec)
+    ObjectCodecTester.newBuilder(Root.CODEC)
         .addSubjects(Root.absoluteRoot(fs), Root.fromPath(fs.getPath("/foo")))
+        .addDependency(FileSystem.class, fs)
         .skipBadDataTest()
         .buildAndRunTests();
   }