blob: 2d543b22cf2383d6db08fd247393d0eb303627ec [file]
// Copyright 2024 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.actions;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.actions.Artifact.ArchivedTreeArtifact;
import com.google.devtools.build.lib.actions.Artifact.ArtifactSerializationContext;
import com.google.devtools.build.lib.actions.Artifact.ConstantMetadataArtifact;
import com.google.devtools.build.lib.actions.Artifact.DerivedArtifact;
import com.google.devtools.build.lib.actions.Artifact.FilesetArtifact;
import com.google.devtools.build.lib.actions.Artifact.RunfilesArtifact;
import com.google.devtools.build.lib.actions.Artifact.SourceArtifact;
import com.google.devtools.build.lib.actions.Artifact.TreeArtifact;
import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact;
import com.google.devtools.build.lib.actions.Artifact.UnresolvedSymlinkArtifact;
import com.google.devtools.build.lib.skyframe.serialization.AsyncDeserializationContext;
import com.google.devtools.build.lib.skyframe.serialization.AsyncDeserializationContext.FieldSetter;
import com.google.devtools.build.lib.skyframe.serialization.DeferredObjectCodec;
import com.google.devtools.build.lib.skyframe.serialization.DeferredObjectCodec.DeferredValue;
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.ValueSharingAdapter;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.errorprone.annotations.Keep;
import com.google.protobuf.CodedInputStream;
import com.google.protobuf.CodedOutputStream;
import java.io.IOException;
import javax.annotation.Nullable;
/**
* Codec implementations for {@link Artifact} subclasses.
*
* <p>Each Artifact's codec implementation is split into two codecs: the main codec that handles the
* individual fields, and a value-sharing codec.
*/
public final class ArtifactCodecs {
public static final ImmutableList<ObjectCodec<? extends Artifact>> VALUE_SHARING_CODECS =
ImmutableList.of(
new ValueSharingAdapter<>(DerivedArtifactCodec.INSTANCE),
new ValueSharingAdapter<>(SourceArtifactCodec.INSTANCE),
new ValueSharingAdapter<>(TreeArtifactCodec.INSTANCE),
new ValueSharingAdapter<>(FilesetArtifactCodec.INSTANCE),
new ValueSharingAdapter<>(RunfilesArtifactCodec.INSTANCE),
new ValueSharingAdapter<>(UnresolvedSymlinkArtifactCodec.INSTANCE),
new ValueSharingAdapter<>(ConstantMetadataArtifactCodec.INSTANCE));
/**
* {@link ObjectCodec} for {@link DerivedArtifact}.
*
* <p>To be kept in sync with {@link TreeArtifactCodec}, {@link FilesetArtifactCodec}, {@link
* RunfilesArtifactCodec}, {@link UnresolvedSymlinkArtifactCodec}, and {@link
* ConstantMetadataArtifactCodec}.
*/
@Keep // Used by reflection.
private static final class DerivedArtifactCodec extends DeferredObjectCodec<DerivedArtifact> {
private static final DerivedArtifactCodec INSTANCE = new DerivedArtifactCodec();
@Override
public Class<DerivedArtifact> getEncodedClass() {
return DerivedArtifact.class;
}
@Override
public void serialize(
SerializationContext context, DerivedArtifact obj, CodedOutputStream codedOut)
throws SerializationException, IOException {
context.serialize(obj.getRoot(), codedOut);
context.serialize(obj.getRootRelativePath(), codedOut);
serializeOrOmitGeneratingActionKey(context, obj, codedOut);
}
@Override
public DeferredValue<DerivedArtifact> deserializeDeferred(
AsyncDeserializationContext context, CodedInputStream codedIn)
throws SerializationException, IOException {
DeserializedDerivedArtifactBuilder builder = new DeserializedDerivedArtifactBuilder(context);
context.deserialize(codedIn, builder, DeserializedDerivedArtifactBuilder::setRoot);
context.deserialize(
codedIn, builder, DeserializedDerivedArtifactBuilder::setRootRelativePath);
deserializeOrGetGeneratingActionKey(
context, codedIn, builder, DeserializedDerivedArtifactBuilder::setGeneratingActionKey);
return builder;
}
}
private static class DeserializedDerivedArtifactBuilder
implements DeferredValue<DerivedArtifact> {
private final AsyncDeserializationContext context;
private ArtifactRoot root;
private PathFragment rootRelativePath;
private ActionLookupData generatingActionKey;
private DeserializedDerivedArtifactBuilder(AsyncDeserializationContext context) {
this.context = context;
}
@Override
public DerivedArtifact call() {
return context
.getDependency(ArtifactSerializationContext.class)
.intern(
new DerivedArtifact(
root,
getExecPathForDeserialization(root, rootRelativePath, generatingActionKey),
generatingActionKey),
context);
}
private static void setRoot(DeserializedDerivedArtifactBuilder builder, Object value) {
builder.root = (ArtifactRoot) value;
}
private static void setRootRelativePath(
DeserializedDerivedArtifactBuilder builder, Object value) {
builder.rootRelativePath = (PathFragment) value;
}
private static void setGeneratingActionKey(
DeserializedDerivedArtifactBuilder builder, Object value) {
builder.generatingActionKey = (ActionLookupData) value;
}
}
private static void serializeOrOmitGeneratingActionKey(
SerializationContext context, DerivedArtifact obj, CodedOutputStream codedOut)
throws IOException, SerializationException {
boolean include =
context
.getDependency(ArtifactSerializationContext.class)
.includeGeneratingActionKey(obj, context);
codedOut.writeBoolNoTag(include);
if (include) {
context.serialize(obj.getGeneratingActionKey(), codedOut);
}
}
private static <T> void deserializeOrGetGeneratingActionKey(
AsyncDeserializationContext context,
CodedInputStream codedIn,
T builder,
FieldSetter<T> setter)
throws IOException, SerializationException {
boolean included = codedIn.readBool();
if (included) {
context.deserialize(codedIn, builder, setter);
} else {
ActionLookupData generatingActionKey =
context
.getDependency(ArtifactSerializationContext.class)
.getOmittedGeneratingActionKey(context);
setter.set(builder, generatingActionKey);
}
}
private static PathFragment getExecPathForDeserialization(
ArtifactRoot root, PathFragment rootRelativePath, Object generatingActionKey) {
Preconditions.checkArgument(
!root.isSourceRoot(),
"Root not derived: %s (rootRelativePath=%s, generatingActionKey=%s)",
root,
rootRelativePath,
generatingActionKey);
Preconditions.checkArgument(
root.getRoot().isAbsolute() == rootRelativePath.isAbsolute(),
"Illegal root relative path: %s (root=%s, generatingActionKey=%s)",
rootRelativePath,
root,
generatingActionKey);
return root.getExecPath().getRelative(rootRelativePath);
}
/** {@link ObjectCodec} for {@link SourceArtifact} */
@Keep // Used by reflection.
private static final class SourceArtifactCodec extends DeferredObjectCodec<SourceArtifact> {
private static final SourceArtifactCodec INSTANCE = new SourceArtifactCodec();
@Override
public Class<SourceArtifact> getEncodedClass() {
return SourceArtifact.class;
}
@Override
public void serialize(
SerializationContext context, SourceArtifact obj, CodedOutputStream codedOut)
throws SerializationException, IOException {
context.serialize(obj.getExecPath(), codedOut);
context.serialize(obj.getRoot(), codedOut);
context.serialize(obj.getArtifactOwner(), codedOut);
}
@Override
public DeferredValue<SourceArtifact> deserializeDeferred(
AsyncDeserializationContext context, CodedInputStream codedIn)
throws SerializationException, IOException {
DeserializedSourceArtifactBuilder builder =
new DeserializedSourceArtifactBuilder(
context.getDependency(ArtifactSerializationContext.class));
context.deserialize(codedIn, builder, DeserializedSourceArtifactBuilder::setExecPath);
context.deserialize(codedIn, builder, DeserializedSourceArtifactBuilder::setRoot);
context.deserialize(codedIn, builder, DeserializedSourceArtifactBuilder::setOwner);
return builder;
}
}
private static class DeserializedSourceArtifactBuilder implements DeferredValue<SourceArtifact> {
private final ArtifactSerializationContext context;
private PathFragment execPath;
private ArtifactRoot root;
private ArtifactOwner owner;
private DeserializedSourceArtifactBuilder(ArtifactSerializationContext context) {
this.context = context;
}
@Override
public SourceArtifact call() {
return context.getSourceArtifact(execPath, root, owner);
}
private static void setExecPath(DeserializedSourceArtifactBuilder builder, Object value) {
builder.execPath = (PathFragment) value;
}
private static void setRoot(DeserializedSourceArtifactBuilder builder, Object value) {
builder.root = (ArtifactRoot) value;
}
private static void setOwner(DeserializedSourceArtifactBuilder builder, Object value) {
builder.owner = (ArtifactOwner) value;
}
}
/**
* {@link ObjectCodec} for {@link TreeArtifact}.
*
* <p>To be kept in sync with {@link DerivedArtifactCodec}.
*/
@Keep // Used by reflection.
private static final class TreeArtifactCodec extends DeferredObjectCodec<TreeArtifact> {
private static final TreeArtifactCodec INSTANCE = new TreeArtifactCodec();
@Override
public Class<TreeArtifact> getEncodedClass() {
return TreeArtifact.class;
}
@Override
public void serialize(
SerializationContext context, TreeArtifact obj, CodedOutputStream codedOut)
throws SerializationException, IOException {
context.serialize(obj.getRoot(), codedOut);
context.serialize(obj.getRootRelativePath(), codedOut);
serializeOrOmitGeneratingActionKey(context, obj, codedOut);
context.serialize(obj.getParent(), codedOut);
context.serialize(obj.getParentRelativePath(), codedOut);
}
@Override
public DeferredValue<TreeArtifact> deserializeDeferred(
AsyncDeserializationContext context, CodedInputStream codedIn)
throws SerializationException, IOException {
DeserializedTreeArtifactBuilder builder = new DeserializedTreeArtifactBuilder(context);
context.deserialize(codedIn, builder, DeserializedTreeArtifactBuilder::setRoot);
context.deserialize(codedIn, builder, DeserializedTreeArtifactBuilder::setRootRelativePath);
deserializeOrGetGeneratingActionKey(
context, codedIn, builder, DeserializedTreeArtifactBuilder::setGeneratingActionKey);
context.deserialize(codedIn, builder, DeserializedTreeArtifactBuilder::setParent);
context.deserialize(codedIn, builder, DeserializedTreeArtifactBuilder::setParentRelativePath);
return builder;
}
}
private static final class DeserializedTreeArtifactBuilder
implements DeferredValue<TreeArtifact> {
private final AsyncDeserializationContext context;
private ArtifactRoot root;
private PathFragment rootRelativePath;
private ActionLookupData generatingActionKey;
@Nullable private TreeArtifact parent;
@Nullable private PathFragment parentRelativePath;
private DeserializedTreeArtifactBuilder(AsyncDeserializationContext context) {
this.context = context;
}
@Override
public TreeArtifact call() {
return (TreeArtifact)
context
.getDependency(ArtifactSerializationContext.class)
.intern(
new TreeArtifact(
root,
getExecPathForDeserialization(root, rootRelativePath, generatingActionKey),
generatingActionKey,
parent,
parentRelativePath),
context);
}
private static void setRoot(DeserializedTreeArtifactBuilder builder, Object value) {
builder.root = (ArtifactRoot) value;
}
private static void setRootRelativePath(DeserializedTreeArtifactBuilder builder, Object value) {
builder.rootRelativePath = (PathFragment) value;
}
private static void setGeneratingActionKey(
DeserializedTreeArtifactBuilder builder, Object value) {
builder.generatingActionKey = (ActionLookupData) value;
}
private static void setParent(DeserializedTreeArtifactBuilder builder, Object value) {
builder.parent = (TreeArtifact) value;
}
private static void setParentRelativePath(
DeserializedTreeArtifactBuilder builder, Object value) {
builder.parentRelativePath = (PathFragment) value;
}
}
/**
* {@link ObjectCodec} for {@link FilesetArtifact}.
*
* <p>To be kept in sync with {@link DerivedArtifactCodec}.
*/
@Keep // Used by reflection.
private static final class FilesetArtifactCodec extends DeferredObjectCodec<FilesetArtifact> {
private static final FilesetArtifactCodec INSTANCE = new FilesetArtifactCodec();
@Override
public Class<FilesetArtifact> getEncodedClass() {
return FilesetArtifact.class;
}
@Override
public void serialize(
SerializationContext context, FilesetArtifact obj, CodedOutputStream codedOut)
throws SerializationException, IOException {
context.serialize(obj.getRoot(), codedOut);
context.serialize(obj.getRootRelativePath(), codedOut);
serializeOrOmitGeneratingActionKey(context, obj, codedOut);
}
@Override
public DeferredValue<FilesetArtifact> deserializeDeferred(
AsyncDeserializationContext context, CodedInputStream codedIn)
throws SerializationException, IOException {
DeserializedFilesetArtifactBuilder builder = new DeserializedFilesetArtifactBuilder(context);
context.deserialize(codedIn, builder, DeserializedFilesetArtifactBuilder::setRoot);
context.deserialize(
codedIn, builder, DeserializedFilesetArtifactBuilder::setRootRelativePath);
deserializeOrGetGeneratingActionKey(
context, codedIn, builder, DeserializedFilesetArtifactBuilder::setGeneratingActionKey);
return builder;
}
}
private static final class DeserializedFilesetArtifactBuilder
implements DeferredValue<FilesetArtifact> {
private final AsyncDeserializationContext context;
private ArtifactRoot root;
private PathFragment rootRelativePath;
private ActionLookupData generatingActionKey;
private DeserializedFilesetArtifactBuilder(AsyncDeserializationContext context) {
this.context = context;
}
@Override
public FilesetArtifact call() {
return (FilesetArtifact)
context
.getDependency(ArtifactSerializationContext.class)
.intern(
new FilesetArtifact(
root,
getExecPathForDeserialization(root, rootRelativePath, generatingActionKey),
generatingActionKey),
context);
}
private static void setRoot(DeserializedFilesetArtifactBuilder builder, Object value) {
builder.root = (ArtifactRoot) value;
}
private static void setRootRelativePath(
DeserializedFilesetArtifactBuilder builder, Object value) {
builder.rootRelativePath = (PathFragment) value;
}
private static void setGeneratingActionKey(
DeserializedFilesetArtifactBuilder builder, Object value) {
builder.generatingActionKey = (ActionLookupData) value;
}
}
/**
* {@link ObjectCodec} for {@link RunfilesArtifact}.
*
* <p>To be kept in sync with {@link DerivedArtifactCodec}.
*/
@Keep // Used by reflection.
private static final class RunfilesArtifactCodec extends DeferredObjectCodec<RunfilesArtifact> {
private static final RunfilesArtifactCodec INSTANCE = new RunfilesArtifactCodec();
@Override
public Class<RunfilesArtifact> getEncodedClass() {
return RunfilesArtifact.class;
}
@Override
public void serialize(
SerializationContext context, RunfilesArtifact obj, CodedOutputStream codedOut)
throws SerializationException, IOException {
context.serialize(obj.getRoot(), codedOut);
context.serialize(obj.getRootRelativePath(), codedOut);
serializeOrOmitGeneratingActionKey(context, obj, codedOut);
}
@Override
public DeferredValue<RunfilesArtifact> deserializeDeferred(
AsyncDeserializationContext context, CodedInputStream codedIn)
throws SerializationException, IOException {
DeserializedRunfilesArtifactBuilder builder =
new DeserializedRunfilesArtifactBuilder(context);
context.deserialize(codedIn, builder, DeserializedRunfilesArtifactBuilder::setRoot);
context.deserialize(
codedIn, builder, DeserializedRunfilesArtifactBuilder::setRootRelativePath);
deserializeOrGetGeneratingActionKey(
context, codedIn, builder, DeserializedRunfilesArtifactBuilder::setGeneratingActionKey);
return builder;
}
}
private static final class DeserializedRunfilesArtifactBuilder
implements DeferredValue<RunfilesArtifact> {
private final AsyncDeserializationContext context;
private ArtifactRoot root;
private PathFragment rootRelativePath;
private ActionLookupData generatingActionKey;
private DeserializedRunfilesArtifactBuilder(AsyncDeserializationContext context) {
this.context = context;
}
@Override
public RunfilesArtifact call() {
return (RunfilesArtifact)
context
.getDependency(ArtifactSerializationContext.class)
.intern(
new RunfilesArtifact(
root,
getExecPathForDeserialization(root, rootRelativePath, generatingActionKey),
generatingActionKey),
context);
}
private static void setRoot(DeserializedRunfilesArtifactBuilder builder, Object value) {
builder.root = (ArtifactRoot) value;
}
private static void setRootRelativePath(
DeserializedRunfilesArtifactBuilder builder, Object value) {
builder.rootRelativePath = (PathFragment) value;
}
private static void setGeneratingActionKey(
DeserializedRunfilesArtifactBuilder builder, Object value) {
builder.generatingActionKey = (ActionLookupData) value;
}
}
/**
* {@link ObjectCodec} for {@link UnresolvedSymlinkArtifact}.
*
* <p>To be kept in sync with {@link DerivedArtifactCodec}.
*/
@Keep // Used by reflection.
private static final class UnresolvedSymlinkArtifactCodec
extends DeferredObjectCodec<UnresolvedSymlinkArtifact> {
private static final UnresolvedSymlinkArtifactCodec INSTANCE =
new UnresolvedSymlinkArtifactCodec();
@Override
public Class<UnresolvedSymlinkArtifact> getEncodedClass() {
return UnresolvedSymlinkArtifact.class;
}
@Override
public void serialize(
SerializationContext context, UnresolvedSymlinkArtifact obj, CodedOutputStream codedOut)
throws SerializationException, IOException {
context.serialize(obj.getRoot(), codedOut);
context.serialize(obj.getRootRelativePath(), codedOut);
serializeOrOmitGeneratingActionKey(context, obj, codedOut);
}
@Override
public DeferredValue<UnresolvedSymlinkArtifact> deserializeDeferred(
AsyncDeserializationContext context, CodedInputStream codedIn)
throws SerializationException, IOException {
DeserializedUnresolvedSymlinkArtifactBuilder builder =
new DeserializedUnresolvedSymlinkArtifactBuilder(context);
context.deserialize(codedIn, builder, DeserializedUnresolvedSymlinkArtifactBuilder::setRoot);
context.deserialize(
codedIn, builder, DeserializedUnresolvedSymlinkArtifactBuilder::setRootRelativePath);
deserializeOrGetGeneratingActionKey(
context,
codedIn,
builder,
DeserializedUnresolvedSymlinkArtifactBuilder::setGeneratingActionKey);
return builder;
}
}
private static final class DeserializedUnresolvedSymlinkArtifactBuilder
implements DeferredValue<UnresolvedSymlinkArtifact> {
private final AsyncDeserializationContext context;
private ArtifactRoot root;
private PathFragment rootRelativePath;
private ActionLookupData generatingActionKey;
private DeserializedUnresolvedSymlinkArtifactBuilder(AsyncDeserializationContext context) {
this.context = context;
}
@Override
public UnresolvedSymlinkArtifact call() {
return (UnresolvedSymlinkArtifact)
context
.getDependency(ArtifactSerializationContext.class)
.intern(
new UnresolvedSymlinkArtifact(
root,
getExecPathForDeserialization(root, rootRelativePath, generatingActionKey),
generatingActionKey),
context);
}
private static void setRoot(
DeserializedUnresolvedSymlinkArtifactBuilder builder, Object value) {
builder.root = (ArtifactRoot) value;
}
private static void setRootRelativePath(
DeserializedUnresolvedSymlinkArtifactBuilder builder, Object value) {
builder.rootRelativePath = (PathFragment) value;
}
private static void setGeneratingActionKey(
DeserializedUnresolvedSymlinkArtifactBuilder builder, Object value) {
builder.generatingActionKey = (ActionLookupData) value;
}
}
/**
* {@link ObjectCodec} for {@link ConstantMetadataArtifact}.
*
* <p>To be kept in sync with {@link DerivedArtifactCodec}.
*/
@Keep // Used by reflection.
private static final class ConstantMetadataArtifactCodec
extends DeferredObjectCodec<ConstantMetadataArtifact> {
private static final ConstantMetadataArtifactCodec INSTANCE =
new ConstantMetadataArtifactCodec();
@Override
public Class<ConstantMetadataArtifact> getEncodedClass() {
return ConstantMetadataArtifact.class;
}
@Override
public void serialize(
SerializationContext context, ConstantMetadataArtifact obj, CodedOutputStream codedOut)
throws SerializationException, IOException {
context.serialize(obj.getRoot(), codedOut);
context.serialize(obj.getRootRelativePath(), codedOut);
serializeOrOmitGeneratingActionKey(context, obj, codedOut);
}
@Override
public DeferredValue<ConstantMetadataArtifact> deserializeDeferred(
AsyncDeserializationContext context, CodedInputStream codedIn)
throws SerializationException, IOException {
DeserializedConstantMetadataArtifactBuilder builder =
new DeserializedConstantMetadataArtifactBuilder(context);
context.deserialize(codedIn, builder, DeserializedConstantMetadataArtifactBuilder::setRoot);
context.deserialize(
codedIn, builder, DeserializedConstantMetadataArtifactBuilder::setRootRelativePath);
deserializeOrGetGeneratingActionKey(
context,
codedIn,
builder,
DeserializedConstantMetadataArtifactBuilder::setGeneratingActionKey);
return builder;
}
}
private static final class DeserializedConstantMetadataArtifactBuilder
implements DeferredValue<ConstantMetadataArtifact> {
private final AsyncDeserializationContext context;
private ArtifactRoot root;
private PathFragment rootRelativePath;
private ActionLookupData generatingActionKey;
private DeserializedConstantMetadataArtifactBuilder(AsyncDeserializationContext context) {
this.context = context;
}
@Override
public ConstantMetadataArtifact call() {
return (ConstantMetadataArtifact)
context
.getDependency(ArtifactSerializationContext.class)
.intern(
new ConstantMetadataArtifact(
root,
getExecPathForDeserialization(root, rootRelativePath, generatingActionKey),
generatingActionKey),
context);
}
private static void setRoot(DeserializedConstantMetadataArtifactBuilder builder, Object value) {
builder.root = (ArtifactRoot) value;
}
private static void setRootRelativePath(
DeserializedConstantMetadataArtifactBuilder builder, Object value) {
builder.rootRelativePath = (PathFragment) value;
}
private static void setGeneratingActionKey(
DeserializedConstantMetadataArtifactBuilder builder, Object value) {
builder.generatingActionKey = (ActionLookupData) value;
}
}
@SuppressWarnings("unused") // Codec used by reflection.
private static final class ArchivedTreeArtifactCodec
extends DeferredObjectCodec<ArchivedTreeArtifact> {
@Override
public Class<ArchivedTreeArtifact> getEncodedClass() {
return ArchivedTreeArtifact.class;
}
@Override
public void serialize(
SerializationContext context, ArchivedTreeArtifact obj, CodedOutputStream codedOut)
throws SerializationException, IOException {
PathFragment derivedTreeRoot = obj.getRoot().getExecPath().subFragment(1, 2);
context.serialize(obj.getParent(), codedOut);
context.serialize(derivedTreeRoot, codedOut);
context.serialize(obj.getRootRelativePath(), codedOut);
}
@Override
public DeferredValue<ArchivedTreeArtifact> deserializeDeferred(
AsyncDeserializationContext context, CodedInputStream codedIn)
throws SerializationException, IOException {
DeserializedArchivedTreeArtifactBuilder builder =
new DeserializedArchivedTreeArtifactBuilder();
context.deserialize(
codedIn, builder, DeserializedArchivedTreeArtifactBuilder::setTreeArtifact);
context.deserialize(
codedIn, builder, DeserializedArchivedTreeArtifactBuilder::setDerivedTreeRoot);
context.deserialize(
codedIn, builder, DeserializedArchivedTreeArtifactBuilder::setRootRelativePath);
return builder;
}
}
private static class DeserializedArchivedTreeArtifactBuilder
implements DeferredValue<ArchivedTreeArtifact> {
private TreeArtifact treeArtifact;
private PathFragment derivedTreeRoot;
private PathFragment rootRelativePath;
@Override
public ArchivedTreeArtifact call() {
return ArchivedTreeArtifact.createWithCustomDerivedTreeRoot(
treeArtifact, derivedTreeRoot, rootRelativePath);
}
private static void setTreeArtifact(
DeserializedArchivedTreeArtifactBuilder builder, Object value) {
builder.treeArtifact = (TreeArtifact) value;
}
private static void setDerivedTreeRoot(
DeserializedArchivedTreeArtifactBuilder builder, Object value) {
builder.derivedTreeRoot = (PathFragment) value;
}
private static void setRootRelativePath(
DeserializedArchivedTreeArtifactBuilder builder, Object value) {
builder.rootRelativePath = (PathFragment) value;
}
}
@SuppressWarnings("unused") // Used by reflection.
private static final class TreeFileArtifactCodec extends DeferredObjectCodec<TreeFileArtifact> {
@Override
public Class<TreeFileArtifact> getEncodedClass() {
return TreeFileArtifact.class;
}
@Override
public void serialize(
SerializationContext context, TreeFileArtifact obj, CodedOutputStream codedOut)
throws SerializationException, IOException {
context.serialize(obj.getParent(), codedOut);
context.serialize(obj.getParentRelativePath(), codedOut);
serializeOrOmitGeneratingActionKey(context, obj, codedOut);
}
@Override
public DeferredValue<TreeFileArtifact> deserializeDeferred(
AsyncDeserializationContext context, CodedInputStream codedIn)
throws SerializationException, IOException {
DeserializedTreeFileArtifactBuilder builder = new DeserializedTreeFileArtifactBuilder();
context.deserialize(codedIn, builder, DeserializedTreeFileArtifactBuilder::setParent);
context.deserialize(
codedIn, builder, DeserializedTreeFileArtifactBuilder::setParentRelativePath);
deserializeOrGetGeneratingActionKey(
context, codedIn, builder, DeserializedTreeFileArtifactBuilder::setGeneratingActionKey);
return builder;
}
}
private static class DeserializedTreeFileArtifactBuilder
implements DeferredValue<TreeFileArtifact> {
private TreeArtifact parent;
private PathFragment parentRelativePath;
private ActionLookupData generatingActionKey;
@Override
public TreeFileArtifact call() {
return new TreeFileArtifact(parent, parentRelativePath, generatingActionKey);
}
private static void setParent(DeserializedTreeFileArtifactBuilder builder, Object value) {
builder.parent = (TreeArtifact) value;
}
private static void setParentRelativePath(
DeserializedTreeFileArtifactBuilder builder, Object value) {
builder.parentRelativePath = (PathFragment) value;
}
private static void setGeneratingActionKey(
DeserializedTreeFileArtifactBuilder builder, Object value) {
builder.generatingActionKey = (ActionLookupData) value;
}
}
private ArtifactCodecs() {}
}