From 875068a65663c63f9d3110ae197a43d89561ae19 Mon Sep 17 00:00:00 2001 From: cpeyser Date: Thu, 1 Feb 2018 08:40:58 -0800 Subject: Add a CODEC for Artifact. PiperOrigin-RevId: 184144301 --- .../build/lib/actions/ActionLookupValue.java | 7 +++ .../devtools/build/lib/actions/Artifact.java | 60 ++++++++++++++-------- .../devtools/build/lib/actions/ArtifactRoot.java | 14 ++++- 3 files changed, 59 insertions(+), 22 deletions(-) (limited to 'src/main/java/com/google/devtools/build/lib') diff --git a/src/main/java/com/google/devtools/build/lib/actions/ActionLookupValue.java b/src/main/java/com/google/devtools/build/lib/actions/ActionLookupValue.java index f1d91ba376..000f359315 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/ActionLookupValue.java +++ b/src/main/java/com/google/devtools/build/lib/actions/ActionLookupValue.java @@ -23,6 +23,9 @@ import com.google.common.collect.Maps; import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe; +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.skyframe.SkyKey; import com.google.devtools.build.skyframe.SkyValue; import java.util.ArrayList; @@ -187,7 +190,11 @@ public class ActionLookupValue implements SkyValue { * subclasses of ActionLookupKey. This allows callers to easily find the value key, while * remaining agnostic to what ActionLookupValues actually exist. */ + @AutoCodec(strategy = Strategy.POLYMORPHIC) public abstract static class ActionLookupKey implements ArtifactOwner, SkyKey { + public static final ObjectCodec CODEC = + new ActionLookupValue_ActionLookupKey_AutoCodec(); + @Override public Label getLabel() { return null; 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 d45d16d587..6993478742 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,6 +31,9 @@ import com.google.devtools.build.lib.analysis.actions.CommandLineItem; 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.autocodec.AutoCodec; +import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization; import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable; import com.google.devtools.build.lib.skylarkinterface.SkylarkModule; import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory; @@ -40,6 +43,7 @@ import com.google.devtools.build.lib.syntax.EvalUtils; 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; @@ -115,6 +119,7 @@ import javax.annotation.Nullable; + " Then you can access the File through the rule's " + "ctx.outputs." ) +@AutoCodec(dependency = FileSystemProvider.class) public class Artifact implements FileType.HasFileType, ActionInput, @@ -122,6 +127,9 @@ public class Artifact Comparable, CommandLineItem { + public static final InjectingObjectCodec CODEC = + new Artifact_AutoCodec(); + /** Compares artifact according to their exec paths. Sorts null values first. */ @SuppressWarnings("ReferenceEquality") // "a == b" is an optimization public static final Comparator EXEC_PATH_COMPARATOR = @@ -194,6 +202,7 @@ public class Artifact * */ @VisibleForTesting + @AutoCodec.Instantiator public Artifact(Path path, ArtifactRoot root, PathFragment execPath, ArtifactOwner owner) { if (root == null || !root.getRoot().contains(path)) { throw new IllegalArgumentException(root + ": illegal root for " + path @@ -454,16 +463,21 @@ public class Artifact /** * A special kind of artifact that either is a fileset or needs special metadata caching behavior. * - *

We subclass {@link Artifact} instead of storing the special attributes inside in order - * to save memory. The proportion of artifacts that are special is very small, and by not having - * to keep around the attribute for the rest we save some memory. + *

We subclass {@link Artifact} instead of storing the special attributes inside in order to + * save memory. The proportion of artifacts that are special is very small, and by not having to + * keep around the attribute for the rest we save some memory. */ @Immutable @VisibleForTesting + @AutoCodec(dependency = FileSystemProvider.class) public static final class SpecialArtifact extends Artifact { + + public static final InjectingObjectCodec CODEC = + new Artifact_SpecialArtifact_AutoCodec(); + private final SpecialArtifactType type; - @VisibleForTesting + @VisibleForSerialization public SpecialArtifact( Path path, ArtifactRoot root, @@ -508,19 +522,24 @@ public class Artifact } /** - * A special kind of artifact that represents a concrete file created at execution time under - * its associated TreeArtifact. + * A special kind of artifact that represents a concrete file created at execution time under its + * associated TreeArtifact. * - *

TreeFileArtifacts should be only created during execution time inside some special actions - * to support action inputs and outputs that are unpredictable at analysis time. - * TreeFileArtifacts should not be created directly by any rules at analysis time. + *

TreeFileArtifacts should be only created during execution time inside some special actions + * to support action inputs and outputs that are unpredictable at analysis time. TreeFileArtifacts + * should not be created directly by any rules at analysis time. * - *

We subclass {@link Artifact} instead of storing the extra fields directly inside in order - * to save memory. The proportion of TreeFileArtifacts is very small, and by not having to keep + *

We subclass {@link Artifact} instead of storing the extra fields directly inside in order to + * save memory. The proportion of TreeFileArtifacts is very small, and by not having to keep * around the extra fields for the rest we save some memory. */ @Immutable + @AutoCodec(dependency = FileSystemProvider.class) public static final class TreeFileArtifact extends Artifact { + + public static final InjectingObjectCodec CODEC = + new Artifact_TreeFileArtifact_AutoCodec(); + private final Artifact parentTreeArtifact; private final PathFragment parentRelativePath; @@ -537,23 +556,24 @@ public class Artifact * Constructs a TreeFileArtifact with the given parent-relative path under the given parent * TreeArtifact, owned by the given {@code artifactOwner}. */ - TreeFileArtifact(Artifact parent, PathFragment parentRelativePath, - ArtifactOwner artifactOwner) { + @AutoCodec.Instantiator + TreeFileArtifact( + Artifact parentTreeArtifact, PathFragment parentRelativePath, ArtifactOwner owner) { super( - parent.getPath().getRelative(parentRelativePath), - parent.getRoot(), - parent.getExecPath().getRelative(parentRelativePath), - artifactOwner); + parentTreeArtifact.getPath().getRelative(parentRelativePath), + parentTreeArtifact.getRoot(), + parentTreeArtifact.getExecPath().getRelative(parentRelativePath), + owner); Preconditions.checkState( - parent.isTreeArtifact(), + parentTreeArtifact.isTreeArtifact(), "The parent of TreeFileArtifact (parent-relative path: %s) is not a TreeArtifact: %s", parentRelativePath, - parent); + parentTreeArtifact); Preconditions.checkState( parentRelativePath.isNormalized() && !parentRelativePath.isAbsolute(), "%s is not a proper normalized relative path", parentRelativePath); - this.parentTreeArtifact = parent; + this.parentTreeArtifact = parentTreeArtifact; this.parentRelativePath = parentRelativePath; } 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 3363dc33da..1a84425e61 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,11 +17,15 @@ package com.google.devtools.build.lib.actions; 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.autocodec.AutoCodec; +import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization; 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.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; @@ -52,8 +56,12 @@ import java.util.Objects; + "together into a single directory tree to form the execution environment." ) @Immutable +@AutoCodec(dependency = FileSystemProvider.class) public final class ArtifactRoot implements Comparable, Serializable, SkylarkValue { + public static final InjectingObjectCodec 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. public static ArtifactRoot computeSourceRoot(Root packageRoot, RepositoryName repository) { @@ -96,7 +104,8 @@ public final class ArtifactRoot implements Comparable, Serializabl return new ArtifactRoot(Root.fromPath(root), execPath, RootType.Middleman); } - private enum RootType { + @VisibleForSerialization + enum RootType { Source, Output, Middleman @@ -106,7 +115,8 @@ public final class ArtifactRoot implements Comparable, Serializabl private final PathFragment execPath; private final RootType rootType; - private ArtifactRoot(Root root, PathFragment execPath, RootType rootType) { + @AutoCodec.Instantiator + ArtifactRoot(Root root, PathFragment execPath, RootType rootType) { this.root = Preconditions.checkNotNull(root); this.execPath = execPath; this.rootType = rootType; -- cgit v1.2.3