aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec
diff options
context:
space:
mode:
authorGravatar mjhalupka <mjhalupka@google.com>2018-02-27 09:00:55 -0800
committerGravatar Copybara-Service <copybara-piper@google.com>2018-02-27 09:02:27 -0800
commit48794a6edac0944ad2ecffc495b765ed10a2a3c9 (patch)
treefad47be8b7423248b590d12dcc55ca429ebcdb39 /src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec
parent98ed9af727ec6342206d181fcd465e3e83980c52 (diff)
Tag ParameterFileWriteAction with @AutoCodec.
This requires codecs for CustomCommandLine and a Marshaller for Charset. Added AutoCodec functionality to generic classes like Iterable<T>. PiperOrigin-RevId: 187182889
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec')
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/AutoCodecProcessor.java22
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/Marshallers.java83
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/SerializationCodeGenerator.java8
3 files changed, 99 insertions, 14 deletions
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 1df5f51451..d7c2e8a7fd 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
@@ -49,8 +49,10 @@ import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.TypeVariable;
import javax.lang.model.util.ElementFilter;
import javax.tools.Diagnostic;
@@ -251,9 +253,9 @@ public class AutoCodecProcessor extends AbstractProcessor {
TypeKind typeKind = parameter.asType().getKind();
serializeBuilder.addStatement(
"$T unsafe_$L = ($T) $T.getInstance().get$L(input, $L_offset)",
- parameter.asType(),
+ sanitizeTypeParameterOfGenerics(parameter.asType()),
parameter.getSimpleName(),
- parameter.asType(),
+ sanitizeTypeParameterOfGenerics(parameter.asType()),
UnsafeProvider.class,
typeKind.isPrimitive() ? firstLetterUpper(typeKind.toString().toLowerCase()) : "Object",
parameter.getSimpleName());
@@ -276,6 +278,22 @@ public class AutoCodecProcessor extends AbstractProcessor {
return env.getTypeUtils().isAssignable(t1, t2) || env.getTypeUtils().isAssignable(t2, t1);
}
+ private TypeMirror sanitizeTypeParameterOfGenerics(TypeMirror type) {
+ if (type instanceof TypeVariable) {
+ return env.getTypeUtils().erasure(type);
+ }
+ if (!(type instanceof DeclaredType)) {
+ return type;
+ }
+ DeclaredType declaredType = (DeclaredType) type;
+ for (TypeMirror typeMirror : declaredType.getTypeArguments()) {
+ if (typeMirror instanceof TypeVariable) {
+ return env.getTypeUtils().erasure(type);
+ }
+ }
+ return type;
+ }
+
private String findGetterForClass(VariableElement parameter, TypeElement type) {
List<ExecutableElement> methods =
ElementFilter.methodsIn(env.getElementUtils().getAllMembers(type));
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/Marshallers.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/Marshallers.java
index fea22ae876..5c78bed826 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/Marshallers.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/Marshallers.java
@@ -35,6 +35,8 @@ import com.google.devtools.build.lib.skyframe.serialization.strings.StringCodecs
import com.google.protobuf.AbstractMessage;
import com.google.protobuf.ExtensionRegistryLite;
import com.google.protobuf.ProtocolMessageEnum;
+import com.squareup.javapoet.TypeName;
+import java.nio.charset.Charset;
import java.util.Collection;
import java.util.Comparator;
import java.util.LinkedHashMap;
@@ -51,6 +53,7 @@ import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.PrimitiveType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.TypeVariable;
/** Class containing all {@link Marshaller} instances. */
class Marshallers {
@@ -78,11 +81,22 @@ class Marshallers {
void writeDeserializationCode(Context context) {
SerializationCodeGenerator generator = getMatchingCodeGenerator(context.type);
boolean needsNullHandling = context.canBeNull() && generator != contextMarshaller;
+ // Check to see if this declared type is generic or if it contains a generic.
+ TypeName contextTypeName = context.getTypeName();
+ if (context.isDeclaredType() && !context.getDeclaredType().getTypeArguments().isEmpty()) {
+ for (TypeMirror paramTypeMirror : context.getDeclaredType().getTypeArguments()) {
+ if (paramTypeMirror instanceof TypeVariable) {
+ contextTypeName = TypeName.get(env.getTypeUtils().erasure(context.getDeclaredType()));
+ }
+ }
+ } else if (context.getTypeMirror() instanceof TypeVariable) {
+ contextTypeName = TypeName.get(env.getTypeUtils().erasure(context.getTypeMirror()));
+ }
if (needsNullHandling) {
- context.builder.addStatement("$T $L = null", context.getTypeName(), context.name);
+ context.builder.addStatement("$T $L = null", contextTypeName, context.name);
context.builder.beginControlFlow("if (codedIn.readBool())");
} else {
- context.builder.addStatement("$T $L", context.getTypeName(), context.name);
+ context.builder.addStatement("$T $L", contextTypeName, context.name);
}
generator.addDeserializationCode(context);
if (needsNullHandling) {
@@ -123,6 +137,11 @@ class Marshallers {
.orElseThrow(() -> new IllegalArgumentException("No generator for: " + primitiveType));
}
+ // We're dealing with a generic.
+ if (type instanceof TypeVariable) {
+ return contextMarshaller;
+ }
+
// TODO(cpeyser): Refactor primitive handling from AutoCodecProcessor.java
if (!(type instanceof DeclaredType)) {
throw new IllegalArgumentException(
@@ -476,11 +495,15 @@ class Marshallers {
// Writes the target count to the stream so deserialization knows when to stop.
context.builder.addStatement(
"codedOut.writeInt32NoTag($T.size($L))", Iterables.class, context.name);
+ TypeMirror typeParameter = context.getDeclaredType().getTypeArguments().get(0);
+ if (typeParameter instanceof TypeVariable) {
+ typeParameter = ((TypeVariable) typeParameter).getUpperBound();
+ }
Context repeated =
context.with(
context.getDeclaredType().getTypeArguments().get(0), context.makeName("repeated"));
- context.builder.beginControlFlow(
- "for ($T $L : $L)", repeated.getTypeName(), repeated.name, context.name);
+ context.builder.beginControlFlow(
+ "for ($T $L : $L)", typeParameter, repeated.name, context.name);
writeSerializationCode(repeated);
context.builder.endControlFlow();
}
@@ -489,14 +512,18 @@ class Marshallers {
Context repeated =
context.with(
context.getDeclaredType().getTypeArguments().get(0), context.makeName("repeated"));
- String builderName = context.makeName("builder");
- context.builder.addStatement(
- "$T<$T> $L = new $T<>()",
- ImmutableList.Builder.class,
- repeated.getTypeName(),
- builderName,
- ImmutableList.Builder.class);
- writeListDeserializationLoopAndBuild(context, repeated, builderName);
+ TypeMirror typeParameter = context.getDeclaredType().getTypeArguments().get(0);
+ if (typeParameter instanceof TypeVariable) {
+ typeParameter = ((TypeVariable) typeParameter).getUpperBound();
+ }
+ String builderName = context.makeName("builder");
+ context.builder.addStatement(
+ "$T<$T> $L = new $T<>()",
+ ImmutableList.Builder.class,
+ typeParameter,
+ builderName,
+ ImmutableList.Builder.class);
+ writeListDeserializationLoopAndBuild(context, repeated, builderName);
}
private final Marshaller iterableMarshaller =
@@ -883,6 +910,9 @@ class Marshallers {
private void addSerializationCodeForNestedSet(Context context) {
TypeMirror typeParameter = context.getDeclaredType().getTypeArguments().get(0);
+ if (typeParameter instanceof TypeVariable) {
+ typeParameter = ((TypeVariable) typeParameter).getUpperBound();
+ }
String nestedSetCodec = context.makeName("nestedSetCodec");
context.builder.addStatement(
"$T<$T> $L = new $T<>()",
@@ -901,6 +931,9 @@ class Marshallers {
private void addDeserializationCodeForNestedSet(Context context) {
TypeMirror typeParameter = context.getDeclaredType().getTypeArguments().get(0);
String nestedSetCodec = context.makeName("nestedSetCodec");
+ if (typeParameter instanceof TypeVariable) {
+ typeParameter = ((TypeVariable) typeParameter).getUpperBound();
+ }
context.builder.addStatement(
"$T<$T> $L = new $T<>()",
NestedSetCodec.class,
@@ -953,6 +986,31 @@ class Marshallers {
}
};
+ private final Marshaller charsetMarshaller =
+ new Marshaller() {
+ @Override
+ public boolean matches(DeclaredType type) {
+ return matchesType(type, Charset.class);
+ }
+
+ @Override
+ public void addSerializationCode(Context context) {
+ context.builder.addStatement(
+ "$T.asciiOptimized().serialize(context, $L.name(), codedOut)",
+ StringCodecs.class,
+ context.name);
+ }
+
+ @Override
+ public void addDeserializationCode(Context context) {
+ context.builder.addStatement(
+ "$L = $T.forName($T.asciiOptimized().deserialize(context, codedIn))",
+ context.name,
+ Charset.class,
+ StringCodecs.class);
+ }
+ };
+
private final ImmutableList<PrimitiveValueSerializationCodeGenerator> primitiveGenerators =
ImmutableList.of(
INT_CODE_GENERATOR,
@@ -982,6 +1040,7 @@ class Marshallers {
hashCodeMarshaller,
protoMarshaller,
iterableMarshaller,
+ charsetMarshaller,
contextMarshaller);
/** True when {@code type} has the same type as {@code clazz}. */
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/SerializationCodeGenerator.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/SerializationCodeGenerator.java
index 94690393ab..0cf644bd6e 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/SerializationCodeGenerator.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec/SerializationCodeGenerator.java
@@ -67,6 +67,14 @@ interface SerializationCodeGenerator {
return (DeclaredType) type;
}
+ boolean isDeclaredType() {
+ return type instanceof DeclaredType;
+ }
+
+ TypeMirror getTypeMirror() {
+ return type;
+ }
+
/** Returns true if this Context represents a type that can be null */
boolean canBeNull() {
return !(type instanceof PrimitiveType);