aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar janakr <janakr@google.com>2018-02-09 15:19:25 -0800
committerGravatar Copybara-Service <copybara-piper@google.com>2018-02-09 15:22:12 -0800
commitacdffead4761160fd016404811ca744507d16c96 (patch)
treeda99fc9d523d968bfc6548b0e71e5420f10ff7f9
parent5a405eb93c092aa9bfd1c69a3fcbdb0997e3c55b (diff)
Add support to Polymorphic strategy for grandchild classes that have no codec, but whose parent classes have codecs. This is ok because the polymorphic strategy doesn't need an instance of the grandchild class: the parent class is fine, so long as it has a codec.
PiperOrigin-RevId: 185200943
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/serialization/PolymorphicHelper.java51
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/AutoCodecProcessor.java11
-rw-r--r--third_party/ijar/test/BUILD1
3 files changed, 52 insertions, 11 deletions
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
index a325e7ea96..11689bade6 100644
--- 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
@@ -36,12 +36,16 @@ public class PolymorphicHelper {
*/
@SuppressWarnings("unchecked")
public static void serialize(
- Object input, CodedOutputStream codedOut, @Nullable Optional<?> dependency)
+ Object input,
+ Class<?> baseClass,
+ CodedOutputStream codedOut,
+ @Nullable Optional<?> dependency)
throws IOException, SerializationException {
if (input != null) {
- Class<?> clazz = input.getClass();
try {
- Object codec = getCodec(clazz);
+ ClassAndCodec classAndCodec = getClassAndCodecInClassHierarchy(input, baseClass);
+ Class<?> clazz = classAndCodec.clazz;
+ Object codec = classAndCodec.codec;
codedOut.writeBoolNoTag(true);
StringCodecs.asciiOptimized().serialize(clazz.getName(), codedOut);
if (codec instanceof ObjectCodec) {
@@ -100,11 +104,46 @@ public class PolymorphicHelper {
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 {
- Field codecField = clazz.getDeclaredField("CODEC");
- codecField.setAccessible(true);
- return codecField.get(null);
+ 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/AutoCodecProcessor.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/AutoCodecProcessor.java
index c576f0c52c..ff99931c8e 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
@@ -596,7 +596,7 @@ public class AutoCodecProcessor extends AbstractProcessor {
return Optional.empty();
}
- private static TypeSpec.Builder buildClassWithPolymorphicStrategy(
+ private TypeSpec.Builder buildClassWithPolymorphicStrategy(
TypeElement encodedType, @Nullable TypeElement dependency) {
if (!encodedType.getModifiers().contains(Modifier.ABSTRACT)) {
throw new IllegalArgumentException(
@@ -609,16 +609,19 @@ public class AutoCodecProcessor extends AbstractProcessor {
return codecClassBuilder;
}
- private static MethodSpec buildPolymorphicSerializeMethod(
+ private MethodSpec buildPolymorphicSerializeMethod(
TypeElement encodedType, @Nullable TypeElement dependency) {
MethodSpec.Builder builder =
AutoCodecUtil.initializeSerializeMethodBuilder(encodedType, dependency);
+ TypeName polyClass = TypeName.get(env.getTypeUtils().erasure(encodedType.asType()));
if (dependency == null) {
- builder.addStatement("$T.serialize(input, codedOut, null)", PolymorphicHelper.class);
+ builder.addStatement(
+ "$T.serialize(input, $T.class, codedOut, null)", PolymorphicHelper.class, polyClass);
} else {
builder.addStatement(
- "$T.serialize(input, codedOut, $T.ofNullable(dependency))",
+ "$T.serialize(input, $T.class, codedOut, $T.ofNullable(dependency))",
PolymorphicHelper.class,
+ polyClass,
Optional.class);
}
return builder.build();
diff --git a/third_party/ijar/test/BUILD b/third_party/ijar/test/BUILD
index 2a3d982294..6b4eeb908e 100644
--- a/third_party/ijar/test/BUILD
+++ b/third_party/ijar/test/BUILD
@@ -192,7 +192,6 @@ java_test(
":local_and_anonymous-interface.jar",
":module_info-interface.jar",
"//third_party/java/jdk/langtools:javac_jar",
- ":interface_ijar_testlib_with_target_label",
],
jvm_flags = [
# Simulates how Bazel invokes javac