diff options
author | 2018-02-20 16:06:00 -0800 | |
---|---|---|
committer | 2018-02-20 16:08:28 -0800 | |
commit | 569e169a5d015ed7d9840ed904f39c4ac7a43503 (patch) | |
tree | 92cb77e75472aed646b0fb50a79664931ac1c395 /src/main/java/com/google/devtools/build/lib/skyframe | |
parent | 7b1b4a41dbfbf34a8e077590612cf5fe3aaaa987 (diff) |
Deletes POLYMORPHIC strategy. ObjectCodec now uses runtime type information to select a codec.
PiperOrigin-RevId: 186378153
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/skyframe')
4 files changed, 3 insertions, 189 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceStatusValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceStatusValue.java index be647065d4..777dcbab4a 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceStatusValue.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceStatusValue.java @@ -17,8 +17,7 @@ import com.google.devtools.build.lib.actions.ActionKeyContext; import com.google.devtools.build.lib.actions.ActionLookupValue; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.analysis.WorkspaceStatusAction; -import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec; -import com.google.devtools.build.lib.skyframe.serialization.SingletonCodec; +import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; import com.google.devtools.build.skyframe.SkyFunctionName; import com.google.devtools.build.skyframe.SkyKey; @@ -55,10 +54,9 @@ public class WorkspaceStatusValue extends ActionLookupValue { } /** {@link SkyKey} for {@link WorkspaceStatusValue}. */ + @AutoCodec(strategy = AutoCodec.Strategy.SINGLETON) public static class BuildInfoKey extends ActionLookupKey { - private static final BuildInfoKey INSTANCE = new BuildInfoKey(); - public static final ObjectCodec<BuildInfoKey> CODEC = - SingletonCodec.of(INSTANCE, "build_info_key"); + @AutoCodec.VisibleForSerialization static final BuildInfoKey INSTANCE = new BuildInfoKey(); private BuildInfoKey() {} @@ -66,6 +64,5 @@ public class WorkspaceStatusValue extends ActionLookupValue { public SkyFunctionName functionName() { return SkyFunctions.BUILD_INFO; } - } } 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 deleted file mode 100644 index b199ca6ce1..0000000000 --- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/PolymorphicHelper.java +++ /dev/null @@ -1,139 +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.skyframe.serialization; - -import com.google.devtools.build.lib.skyframe.serialization.strings.StringCodecs; -import com.google.protobuf.CodedInputStream; -import com.google.protobuf.CodedOutputStream; -import java.io.IOException; -import java.lang.reflect.Field; -import java.util.Optional; -import javax.annotation.Nullable; - -/** Helper methods for polymorphic codecs using reflection. */ -public class PolymorphicHelper { - - private PolymorphicHelper() {} - - /** - * Serializes a polymorphic type. - * - * @param dependency if null, it means that the parent, polymorphic type, provides no dependency. - * It is valid for dependency to be non-null, with an enclosed null value. This means that - * dependency itself is null (as opposed to non-existent). - */ - @SuppressWarnings("unchecked") - public static void serialize( - SerializationContext context, - Object input, - Class<?> baseClass, - CodedOutputStream codedOut, - @Nullable Optional<?> dependency) - throws IOException, SerializationException { - if (input != null) { - try { - ClassAndCodec classAndCodec = getClassAndCodecInClassHierarchy(input, baseClass); - Class<?> clazz = classAndCodec.clazz; - Object codec = classAndCodec.codec; - codedOut.writeBoolNoTag(true); - StringCodecs.asciiOptimized().serialize(context, clazz.getName(), codedOut); - if (codec instanceof ObjectCodec) { - ((ObjectCodec) codec).serialize(context, input, codedOut); - } else { - throw new SerializationException( - clazz.getCanonicalName() - + ".CODEC has unexpected type " - + codec.getClass().getCanonicalName()); - } - } catch (ReflectiveOperationException e) { - throw new SerializationException(input.getClass().getName(), e); - } - } else { - codedOut.writeBoolNoTag(false); - } - } - - /** - * Deserializes a polymorphic type. - * - * @param dependency if null, it means that the parent, polymorphic type, provides no dependency. - * It is valid for dependency to be non-null, with an enclosed null value. This means the - * dependency itself is null (as opposed to non-existent). - */ - @SuppressWarnings("unchecked") - public static Object deserialize( - DeserializationContext context, CodedInputStream codedIn, @Nullable Optional<?> dependency) - throws IOException, SerializationException { - Object deserialized = null; - if (codedIn.readBool()) { - String className = StringCodecs.asciiOptimized().deserialize(context, codedIn); - try { - Object codec = getCodec(Class.forName(className)); - if (codec instanceof ObjectCodec) { - return ((ObjectCodec) codec).deserialize(context, codedIn); - } else { - throw new SerializationException( - className + ".CODEC has unexpected type " + codec.getClass().getCanonicalName()); - } - } catch (ReflectiveOperationException e) { - throw new SerializationException(className, e); - } - } - return deserialized; - } - - private static ClassAndCodec getClassAndCodecInClassHierarchy(Object input, Class<?> baseClass) - throws SerializationException, IllegalAccessException { - Class<?> clazz = input.getClass(); - Field codecField = null; - while (!clazz.equals(baseClass)) { - try { - codecField = getCodecField(clazz); - break; - } catch (NoSuchFieldException e) { - clazz = clazz.getSuperclass(); - } - } - if (clazz.equals(baseClass)) { - throw new SerializationException("Could not find codec for " + input.getClass()); - } - return new ClassAndCodec(clazz, getValueOfField(codecField)); - } - - private static Field getCodecField(Class<?> clazz) throws NoSuchFieldException { - return clazz.getDeclaredField("CODEC"); - } - - private static Object getValueOfField(Field field) throws IllegalAccessException { - field.setAccessible(true); - return field.get(null); - } - - /** Returns the static CODEC instance for {@code clazz}. */ - private static Object getCodec(Class<?> clazz) - throws NoSuchFieldException, IllegalAccessException { - return getValueOfField(getCodecField(clazz)); - } - - private static class ClassAndCodec { - final Class<?> clazz; - final Object codec; - - ClassAndCodec(Class<?> clazz, Object codec) { - this.clazz = clazz; - this.codec = codec; - } - } -} 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 0f597dbee1..cb88b0ae8e 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 @@ -62,16 +62,6 @@ public @interface AutoCodec { */ PUBLIC_FIELDS, /** - * For use with abstract classes (enforced at compile time). - * - * <p>Uses reflection to determine the concrete subclass, stores the name of the subclass and - * uses its codec to serialize the data. - * - * <p>This is no longer needed and only adds useless overhead. - */ - // TODO(shahan): delete this and all references to it - POLYMORPHIC, - /** * For use with classes that are singleton. * * <p>The serialized class must have a codec accessible, static INSTANCE field. 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 c3d14df9f2..935e97383c 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 @@ -21,7 +21,6 @@ import com.google.auto.value.AutoValue; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec; -import com.google.devtools.build.lib.skyframe.serialization.PolymorphicHelper; import com.google.devtools.build.lib.skyframe.serialization.SerializationException; import com.google.devtools.build.lib.skyframe.serialization.autocodec.SerializationCodeGenerator.Marshaller; import com.squareup.javapoet.ClassName; @@ -102,9 +101,6 @@ public class AutoCodecProcessor extends AbstractProcessor { case PUBLIC_FIELDS: codecClassBuilder = buildClassWithPublicFieldsStrategy(encodedType); break; - case POLYMORPHIC: - codecClassBuilder = buildClassWithPolymorphicStrategy(encodedType); - break; case SINGLETON: codecClassBuilder = buildClassWithSingletonStrategy(encodedType); break; @@ -536,36 +532,6 @@ public class AutoCodecProcessor extends AbstractProcessor { return Optional.empty(); } - 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); - codecClassBuilder.addMethod(buildPolymorphicSerializeMethod(encodedType)); - codecClassBuilder.addMethod(buildPolymorphicDeserializeMethod(encodedType)); - return codecClassBuilder; - } - - private MethodSpec buildPolymorphicSerializeMethod(TypeElement encodedType) { - MethodSpec.Builder builder = AutoCodecUtil.initializeSerializeMethodBuilder(encodedType); - TypeName polyClass = TypeName.get(env.getTypeUtils().erasure(encodedType.asType())); - builder.addStatement( - "$T.serialize(context, input, $T.class, codedOut, null)", - PolymorphicHelper.class, - polyClass); - return builder.build(); - } - - 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); - return builder.build(); - } - private static TypeSpec.Builder buildClassWithSingletonStrategy(TypeElement encodedType) { TypeSpec.Builder codecClassBuilder = AutoCodecUtil.initializeCodecClassBuilder(encodedType); // Serialization is a no-op. |