Add AspectCodec. Can't be @AutoCodec because we don't want to serialize the full content of native aspects.

PiperOrigin-RevId: 190489694
diff --git a/src/main/java/com/google/devtools/build/lib/packages/Aspect.java b/src/main/java/com/google/devtools/build/lib/packages/Aspect.java
index 14e9d5d..b0ccfe6 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/Aspect.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/Aspect.java
@@ -15,6 +15,13 @@
 
 import com.google.common.base.Preconditions;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
+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 com.google.protobuf.CodedOutputStream;
+import java.io.IOException;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
@@ -105,4 +112,40 @@
     // All aspect attributes are implicit.
     return false;
   }
+
+  /** {@link ObjectCodec} for {@link Aspect}. */
+  static class AspectCodec implements ObjectCodec<Aspect> {
+    @Override
+    public Class<Aspect> getEncodedClass() {
+      return Aspect.class;
+    }
+
+    @Override
+    public void serialize(SerializationContext context, Aspect obj, CodedOutputStream codedOut)
+        throws SerializationException, IOException {
+      context.serialize(obj.getDescriptor(), codedOut);
+      boolean nativeAspect = obj.getDescriptor().getAspectClass() instanceof NativeAspectClass;
+      codedOut.writeBoolNoTag(nativeAspect);
+      if (!nativeAspect) {
+        context.serialize(obj.getDefinition(), codedOut);
+      }
+    }
+
+    @Override
+    public Aspect deserialize(DeserializationContext context, CodedInputStream codedIn)
+        throws SerializationException, IOException {
+      AspectDescriptor aspectDescriptor = context.deserialize(codedIn);
+      if (codedIn.readBool()) {
+        return forNative(
+            (NativeAspectClass) aspectDescriptor.getAspectClass(),
+            aspectDescriptor.getParameters());
+      } else {
+        AspectDefinition aspectDefinition = context.deserialize(codedIn);
+        return forSkylark(
+            (SkylarkAspectClass) aspectDescriptor.getAspectClass(),
+            aspectDefinition,
+            aspectDescriptor.getParameters());
+      }
+    }
+  }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/packages/AspectDefinition.java b/src/main/java/com/google/devtools/build/lib/packages/AspectDefinition.java
index 3036a68..1b537e4 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/AspectDefinition.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/AspectDefinition.java
@@ -26,6 +26,7 @@
 import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
 import com.google.devtools.build.lib.packages.ConfigurationFragmentPolicy.MissingFragmentPolicy;
+import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
 import com.google.devtools.build.lib.syntax.Type;
 import com.google.devtools.build.lib.syntax.Type.LabelClass;
 import com.google.devtools.build.lib.syntax.Type.LabelVisitor;
@@ -38,11 +39,12 @@
 import javax.annotation.Nullable;
 
 /**
- * The definition of an aspect (see {@link Aspect} for moreinformation.)
+ * The definition of an aspect (see {@link Aspect} for more information).
  *
  * <p>Contains enough information to build up the configured target graph except for the actual way
- * to build the Skyframe node (that is the territory of
- * {@link com.google.devtools.build.lib.view AspectFactory}). In particular:
+ * to build the Skyframe node (that is the territory of {@link com.google.devtools.build.lib.view
+ * AspectFactory}). In particular:
+ *
  * <ul>
  *   <li>The condition that must be fulfilled for an aspect to be able to operate on a configured
  *       target
@@ -54,6 +56,7 @@
  * <p>The way to build the Skyframe node is not here because this data needs to be accessible from
  * the {@code .packages} package and that one requires references to the {@code .view} package.
  */
+@AutoCodec
 @Immutable
 public final class AspectDefinition {
   private final AspectClass aspectClass;
@@ -78,11 +81,12 @@
     return advertisedProviders;
   }
 
-  private AspectDefinition(
+  @AutoCodec.VisibleForSerialization
+  AspectDefinition(
       AspectClass aspectClass,
       AdvertisedProviderSet advertisedProviders,
       RequiredProviders requiredProviders,
-      RequiredProviders requiredAspectProviders,
+      RequiredProviders requiredProvidersForAspects,
       ImmutableMap<String, Attribute> attributes,
       ImmutableSet<Label> requiredToolchains,
       @Nullable ImmutableSet<String> restrictToAttributes,
@@ -91,7 +95,7 @@
     this.aspectClass = aspectClass;
     this.advertisedProviders = advertisedProviders;
     this.requiredProviders = requiredProviders;
-    this.requiredProvidersForAspects = requiredAspectProviders;
+    this.requiredProvidersForAspects = requiredProvidersForAspects;
 
     this.attributes = attributes;
     this.requiredToolchains = requiredToolchains;