diff options
Diffstat (limited to 'src/main')
8 files changed, 103 insertions, 199 deletions
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 f9f3c40bc6..ce0a75a63b 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 @@ -52,12 +52,7 @@ import com.google.devtools.build.lib.events.Event; import com.google.devtools.build.lib.events.EventHandler; 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.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.skylarkinterface.SkylarkCallable; import com.google.devtools.build.lib.skylarkinterface.SkylarkModule; import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory; @@ -75,9 +70,6 @@ import com.google.devtools.common.options.OptionEffectTag; import com.google.devtools.common.options.OptionMetadataTag; import com.google.devtools.common.options.OptionsParsingException; import com.google.devtools.common.options.TriState; -import com.google.protobuf.CodedInputStream; -import com.google.protobuf.CodedOutputStream; -import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -118,6 +110,9 @@ import javax.annotation.Nullable; "Data required for the analysis of a target that comes from targets that " + "depend on it and not targets that it depends on." ) +// TODO(janakr): If overhead of fragments class names is too high, add constructor that just takes +// fragments and gets names from them. +@AutoCodec public class BuildConfiguration implements BuildConfigurationInterface { /** * Sorts fragments by class name. This produces a stable order which, e.g., facilitates consistent @@ -1244,10 +1239,8 @@ public class BuildConfiguration implements BuildConfigurationInterface { return hashCode; } - /** - * Returns map of all the fragments for this configuration. - */ - public ImmutableMap<Class<? extends Fragment>, Fragment> getAllFragments() { + /** Returns map of all the fragments for this configuration. */ + public ImmutableMap<Class<? extends Fragment>, Fragment> getFragmentsMap() { return fragments; } @@ -2095,42 +2088,4 @@ public class BuildConfiguration implements BuildConfigurationInterface { .setCpu(getCpu()); return GenericBuildEvent.protoChaining(this).setConfiguration(builder.build()).build(); } - - private static class BuildConfigurationCodec implements ObjectCodec<BuildConfiguration> { - @Override - public Class<BuildConfiguration> getEncodedClass() { - return BuildConfiguration.class; - } - - @Override - public void serialize( - SerializationContext context, - BuildConfiguration obj, - CodedOutputStream codedOut) - throws SerializationException, IOException { - context.serialize(obj.directories, codedOut); - codedOut.writeInt32NoTag(obj.fragments.size()); - for (Fragment fragment : obj.fragments.values()) { - context.serialize(fragment, codedOut); - } - context.serialize(obj.buildOptions, codedOut); - StringCodecs.asciiOptimized().serialize(context, obj.repositoryName, codedOut); - } - - @Override - public BuildConfiguration deserialize(DeserializationContext context, CodedInputStream codedIn) - throws SerializationException, IOException { - BlazeDirectories blazeDirectories = context.deserialize(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 = context.deserialize(codedIn); - builder.put(fragment.getClass(), fragment); - } - BuildOptions options = context.deserialize(codedIn); - String repositoryName = StringCodecs.asciiOptimized().deserialize(context, codedIn); - return new BuildConfiguration(blazeDirectories, builder.build(), options, repositoryName); - } - } } diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildOptions.java b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildOptions.java index 7383fdfe08..76dcaad029 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildOptions.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildOptions.java @@ -23,10 +23,7 @@ import com.google.common.collect.ImmutableSortedMap; import com.google.common.collect.Sets; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.runtime.proto.InvocationPolicyOuterClass.InvocationPolicy; -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.autocodec.AutoCodec; import com.google.devtools.build.lib.util.Fingerprint; import com.google.devtools.common.options.InvocationPolicyEnforcer; import com.google.devtools.common.options.OptionDefinition; @@ -34,9 +31,6 @@ import com.google.devtools.common.options.OptionsBase; import com.google.devtools.common.options.OptionsClassProvider; import com.google.devtools.common.options.OptionsParser; import com.google.devtools.common.options.OptionsParsingException; -import com.google.protobuf.CodedInputStream; -import com.google.protobuf.CodedOutputStream; -import java.io.IOException; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; @@ -51,9 +45,10 @@ import java.util.TreeMap; import java.util.TreeSet; import javax.annotation.Nullable; -/** - * Stores the command-line options from a set of configuration fragments. - */ +/** Stores the command-line options from a set of configuration fragments. */ +// TODO(janakr): If overhead of FragmentOptions class names is too high, add constructor that just +// takes fragments and gets names from them. +@AutoCodec public final class BuildOptions implements Cloneable, Serializable { private static final Comparator<Class<? extends FragmentOptions>> lexicalFragmentOptionsComparator = Comparator.comparing(Class::getName); @@ -297,8 +292,8 @@ public final class BuildOptions implements Cloneable, Serializable { */ private final ImmutableMap<Class<? extends FragmentOptions>, FragmentOptions> fragmentOptionsMap; - private BuildOptions( - ImmutableMap<Class<? extends FragmentOptions>, FragmentOptions> fragmentOptionsMap) { + @AutoCodec.VisibleForSerialization + BuildOptions(ImmutableMap<Class<? extends FragmentOptions>, FragmentOptions> fragmentOptionsMap) { this.fragmentOptionsMap = fragmentOptionsMap; } @@ -440,33 +435,4 @@ public final class BuildOptions implements Cloneable, Serializable { return toReturn.toString(); } } - - private static class BuildOptionsCodec implements ObjectCodec<BuildOptions> { - @Override - public Class<BuildOptions> getEncodedClass() { - return BuildOptions.class; - } - - @Override - public void serialize( - SerializationContext context, BuildOptions buildOptions, CodedOutputStream codedOut) - throws IOException, SerializationException { - Collection<FragmentOptions> fragmentOptions = buildOptions.getOptions(); - codedOut.writeInt32NoTag(fragmentOptions.size()); - for (FragmentOptions options : buildOptions.getOptions()) { - context.serialize(options, codedOut); - } - } - - @Override - public BuildOptions deserialize(DeserializationContext context, CodedInputStream codedIn) - throws IOException, SerializationException { - BuildOptions.Builder builder = BuildOptions.builder(); - int length = codedIn.readInt32(); - for (int i = 0; i < length; ++i) { - builder.add(context.deserialize(codedIn)); - } - return builder.build(); - } - } } diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/ConfigurationResolver.java b/src/main/java/com/google/devtools/build/lib/analysis/config/ConfigurationResolver.java index fd0a933c91..e67ea1e6c9 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/config/ConfigurationResolver.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/config/ConfigurationResolver.java @@ -393,7 +393,7 @@ public final class ConfigurationResolver { SkyFunction.Environment env, Label dep, BuildConfiguration parentConfig) throws InterruptedException { if (!parentConfig.trimConfigurations()) { - return parentConfig.getAllFragments().keySet(); + return parentConfig.getFragmentsMap().keySet(); } SkyKey fragmentsKey = TransitiveTargetKey.of(dep); TransitiveTargetValue transitiveDepInfo = (TransitiveTargetValue) env.getValue(fragmentsKey); @@ -458,7 +458,7 @@ public final class ConfigurationResolver { throws ConfiguredTargetFunction.DependencyEvaluationException { Set<String> ctgFragmentNames = new HashSet<>(); for (BuildConfiguration.Fragment fragment : - ctgValue.getConfiguration().getAllFragments().values()) { + ctgValue.getConfiguration().getFragmentsMap().values()) { ctgFragmentNames.add(fragment.getClass().getSimpleName()); } Set<String> depFragmentNames = new HashSet<>(); diff --git a/src/main/java/com/google/devtools/build/lib/rules/apple/DottedVersion.java b/src/main/java/com/google/devtools/build/lib/rules/apple/DottedVersion.java index a3085525a0..4082f1cf41 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/apple/DottedVersion.java +++ b/src/main/java/com/google/devtools/build/lib/rules/apple/DottedVersion.java @@ -21,17 +21,12 @@ import com.google.common.collect.ComparisonChain; import com.google.common.collect.ImmutableList; import com.google.common.collect.Ordering; 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.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.skylarkinterface.SkylarkPrinter; import com.google.devtools.build.lib.skylarkinterface.SkylarkValue; -import com.google.protobuf.CodedInputStream; -import com.google.protobuf.CodedOutputStream; -import java.io.IOException; import java.util.ArrayList; import java.util.Objects; import java.util.regex.Matcher; @@ -85,6 +80,7 @@ import javax.annotation.Nullable; + "1.2.3.4." ) @Immutable +@AutoCodec public final class DottedVersion implements Comparable<DottedVersion>, SkylarkValue { private static final Splitter DOT_SPLITTER = Splitter.on('.'); private static final Pattern COMPONENT_PATTERN = Pattern.compile("(\\d+)(?:([a-z]+)(\\d*))?"); @@ -155,10 +151,11 @@ public final class DottedVersion implements Comparable<DottedVersion>, SkylarkVa private final String stringRepresentation; private final int numOriginalComponents; - private DottedVersion(ImmutableList<Component> components, String version, - int numOriginalComponents) { + @AutoCodec.VisibleForSerialization + DottedVersion( + ImmutableList<Component> components, String stringRepresentation, int numOriginalComponents) { this.components = components; - this.stringRepresentation = version; + this.stringRepresentation = stringRepresentation; this.numOriginalComponents = numOriginalComponents; } @@ -262,44 +259,16 @@ public final class DottedVersion implements Comparable<DottedVersion>, SkylarkVa printer.append(stringRepresentation); } - private static class DottedVersionCodec implements ObjectCodec<DottedVersion> { - @Override - public Class<DottedVersion> getEncodedClass() { - return DottedVersion.class; - } - - @Override - public void serialize( - SerializationContext context, DottedVersion obj, CodedOutputStream codedOut) - throws IOException { - codedOut.writeInt32NoTag(obj.components.size()); - for (Component component : obj.components) { - component.serialize(codedOut); - } - codedOut.writeStringNoTag(obj.stringRepresentation); - codedOut.writeInt32NoTag(obj.numOriginalComponents); - } - - @Override - public DottedVersion deserialize(DeserializationContext context, CodedInputStream codedIn) - throws IOException { - int numComponents = codedIn.readInt32(); - // TODO(janakr: Presize this if/when https://github.com/google/guava/issues/196 is resolved. - ImmutableList.Builder<Component> components = ImmutableList.builder(); - for (int i = 0; i < numComponents; i++) { - components.add(Component.deserialize(codedIn)); - } - return new DottedVersion(components.build(), codedIn.readString(), codedIn.readInt32()); - } - } - - private static final class Component implements Comparable<Component> { + @AutoCodec.VisibleForSerialization + @AutoCodec + static final class Component implements Comparable<Component> { private final int firstNumber; @Nullable private final String alphaSequence; private final int secondNumber; private final String stringRepresentation; - public Component( + @AutoCodec.VisibleForSerialization + Component( int firstNumber, @Nullable String alphaSequence, int secondNumber, @@ -340,25 +309,5 @@ public final class DottedVersion implements Comparable<DottedVersion>, SkylarkVa public String toString() { return stringRepresentation; } - - void serialize(CodedOutputStream out) throws IOException { - if (alphaSequence == null) { - out.writeBoolNoTag(false); - } else { - out.writeBoolNoTag(true); - out.writeStringNoTag(alphaSequence); - } - out.writeInt32NoTag(firstNumber); - out.writeInt32NoTag(secondNumber); - out.writeStringNoTag(stringRepresentation); - } - - static Component deserialize(CodedInputStream in) throws IOException { - String alphaSequence = null; - if (in.readBool()) { - alphaSequence = in.readString(); - } - return new Component(in.readInt32(), alphaSequence, in.readInt32(), in.readString()); - } } } diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/CollectPackagesUnderDirectoryValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/CollectPackagesUnderDirectoryValue.java index 9ca228c3a0..a742bb656b 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/CollectPackagesUnderDirectoryValue.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/CollectPackagesUnderDirectoryValue.java @@ -52,8 +52,9 @@ import javax.annotation.Nullable; * directories above that one, but they don't need to be re-run. */ public abstract class CollectPackagesUnderDirectoryValue implements SkyValue { - - private final ImmutableMap<RootedPath, Boolean> subdirectoryTransitivelyContainsPackagesOrErrors; + @AutoCodec.VisibleForSerialization + protected final ImmutableMap<RootedPath, Boolean> + subdirectoryTransitivelyContainsPackagesOrErrors; CollectPackagesUnderDirectoryValue( ImmutableMap<RootedPath, Boolean> subdirectoryTransitivelyContainsPackagesOrErrors) { @@ -62,15 +63,19 @@ public abstract class CollectPackagesUnderDirectoryValue implements SkyValue { } /** Represents a successfully loaded package or a directory without a BUILD file. */ + @AutoCodec public static class NoErrorCollectPackagesUnderDirectoryValue extends CollectPackagesUnderDirectoryValue { + @AutoCodec public static final NoErrorCollectPackagesUnderDirectoryValue EMPTY = new NoErrorCollectPackagesUnderDirectoryValue( false, ImmutableMap.<RootedPath, Boolean>of()); private final boolean isDirectoryPackage; - private NoErrorCollectPackagesUnderDirectoryValue( + @AutoCodec.VisibleForSerialization + @AutoCodec.Instantiator + NoErrorCollectPackagesUnderDirectoryValue( boolean isDirectoryPackage, ImmutableMap<RootedPath, Boolean> subdirectoryTransitivelyContainsPackagesOrErrors) { super(subdirectoryTransitivelyContainsPackagesOrErrors); @@ -123,11 +128,14 @@ public abstract class CollectPackagesUnderDirectoryValue implements SkyValue { } /** Represents a directory with a BUILD file that failed to load. */ + @AutoCodec public static class ErrorCollectPackagesUnderDirectoryValue extends CollectPackagesUnderDirectoryValue { private final String errorMessage; - private ErrorCollectPackagesUnderDirectoryValue( + @AutoCodec.VisibleForSerialization + @AutoCodec.Instantiator + ErrorCollectPackagesUnderDirectoryValue( String errorMessage, ImmutableMap<RootedPath, Boolean> subdirectoryTransitivelyContainsPackagesOrErrors) { super(subdirectoryTransitivelyContainsPackagesOrErrors); 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 94c73f9f67..648cd67d0c 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 @@ -23,19 +23,11 @@ import com.google.devtools.build.lib.concurrent.BlazeInterners; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; 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.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.skyframe.SkyFunctionName; import com.google.devtools.build.skyframe.SkyKey; import com.google.devtools.build.skyframe.SkyValue; -import com.google.protobuf.CodedInputStream; -import com.google.protobuf.CodedOutputStream; -import java.io.IOException; import java.util.Objects; import javax.annotation.Nullable; @@ -69,6 +61,7 @@ public class ConfigurationFragmentValue implements SkyValue { } /** {@link SkyKey} for {@link ConfigurationFragmentValue}. */ + @AutoCodec public static final class ConfigurationFragmentKey implements SkyKey { private static Interner<ConfigurationFragmentKey> interner = BlazeInterners.newWeakInterner(); @@ -83,7 +76,9 @@ public class ConfigurationFragmentValue implements SkyValue { this.fragmentType = Preconditions.checkNotNull(fragmentType); } - private static ConfigurationFragmentKey of( + @AutoCodec.VisibleForSerialization + @AutoCodec.Instantiator + static ConfigurationFragmentKey of( BuildOptions buildOptions, Class<? extends Fragment> fragmentType) { return interner.intern(new ConfigurationFragmentKey(buildOptions, fragmentType)); } @@ -124,36 +119,5 @@ public class ConfigurationFragmentValue implements SkyValue { public SkyFunctionName functionName() { return SkyFunctions.CONFIGURATION_FRAGMENT; } - - private static class Codec implements ObjectCodec<ConfigurationFragmentKey> { - @Override - public Class<ConfigurationFragmentKey> getEncodedClass() { - return ConfigurationFragmentKey.class; - } - - @Override - public void serialize( - SerializationContext context, ConfigurationFragmentKey obj, CodedOutputStream codedOut) - throws SerializationException, IOException { - context.serialize(obj.buildOptions, codedOut); - StringCodecs.asciiOptimized().serialize(context, obj.fragmentType.getName(), codedOut); - } - - @SuppressWarnings("unchecked") // Cast to Class<? extends Fragment>. - @Override - public ConfigurationFragmentKey deserialize( - DeserializationContext context, CodedInputStream codedIn) - throws SerializationException, IOException { - - try { - return of( - context.deserialize(codedIn), - (Class<? extends Fragment>) - Class.forName(StringCodecs.asciiOptimized().deserialize(context, codedIn))); - } catch (ClassNotFoundException e) { - throw new SerializationException("Couldn't deserialize ConfigurationFragmentKey", e); - } - } - } } } diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/ClassCodec.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/ClassCodec.java new file mode 100644 index 0000000000..e3675ee9e8 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/ClassCodec.java @@ -0,0 +1,45 @@ +// 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.skyframe.serialization; + +import com.google.protobuf.CodedInputStream; +import com.google.protobuf.CodedOutputStream; +import java.io.IOException; + +/** Codec for {@link Class}. */ +class ClassCodec implements ObjectCodec<Class<?>> { + @SuppressWarnings("unchecked") + @Override + public Class<Class<?>> getEncodedClass() { + return (Class<Class<?>>) (Object) Class.class; + } + + @Override + public void serialize(SerializationContext context, Class<?> obj, CodedOutputStream codedOut) + throws SerializationException, IOException { + context.serialize(obj.getName(), codedOut); + } + + @Override + public Class<?> deserialize(DeserializationContext context, CodedInputStream codedIn) + throws SerializationException, IOException { + String className = context.deserialize(codedIn); + try { + return Class.forName(className); + } catch (ClassNotFoundException e) { + throw new SerializationException("Couldn't find class for " + className, e); + } + } +} 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 e732e87e99..9051467c0f 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 @@ -16,6 +16,7 @@ package com.google.devtools.build.lib.skyframe.serialization.testutils; import static com.google.common.truth.Truth.assertThat; +import com.google.common.collect.ImmutableMap; import com.google.devtools.build.lib.skyframe.serialization.CodecRegisterer; import com.google.devtools.build.lib.skyframe.serialization.DeserializationContext; import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec; @@ -23,6 +24,7 @@ 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.syntax.Environment.GlobalFrame; +import com.google.protobuf.ByteString; import com.google.protobuf.CodedInputStream; import com.google.protobuf.CodedOutputStream; import java.io.ByteArrayOutputStream; @@ -43,12 +45,27 @@ public class TestUtils { return bytes.toByteArray(); } + public static <T> ByteString toBytes(T value, ImmutableMap<Class<?>, Object> dependencies) + throws IOException, SerializationException { + ByteString.Output output = ByteString.newOutput(); + CodedOutputStream codedOut = CodedOutputStream.newInstance(output); + new SerializationContext(dependencies).serialize(value, codedOut); + codedOut.flush(); + return output.toByteString(); + } + /** Deserialize a value from a byte array. */ public static <T> T fromBytes(DeserializationContext context, ObjectCodec<T> codec, byte[] bytes) throws SerializationException, IOException { return codec.deserialize(context, CodedInputStream.newInstance(bytes)); } + public static <T> T roundTrip(T value, ImmutableMap<Class<?>, Object> dependencies) + throws IOException, SerializationException { + return new DeserializationContext(dependencies) + .deserialize(toBytes(value, dependencies).newCodedInput()); + } + /** * Asserts that two {@link GlobalFrame}s have the same structure. Needed because * {@link GlobalFrame} doesn't override {@link Object#equals}. |