diff options
author | 2018-03-16 14:03:22 -0700 | |
---|---|---|
committer | 2018-03-16 14:04:55 -0700 | |
commit | 706bdb36c3c43895fae7966e9a89f5b03fbea469 (patch) | |
tree | e0567bc3462657a477f5391f648cf562335e04b2 /src/main/java/com/google/devtools | |
parent | 7d46249768662cbc76545ae2ce09c26c3b976831 (diff) |
Deletes list marshaller and makes map entry marshaller into a runtime codec.
PiperOrigin-RevId: 189390024
Diffstat (limited to 'src/main/java/com/google/devtools')
4 files changed, 163 insertions, 122 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/ArrayListCodec.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/ArrayListCodec.java new file mode 100644 index 0000000000..e768e8426c --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/ArrayListCodec.java @@ -0,0 +1,53 @@ +// 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; +import java.util.ArrayList; + +@SuppressWarnings("rawtypes") +class ArrayListCodec implements ObjectCodec<ArrayList> { + + @Override + public Class<ArrayList> getEncodedClass() { + return ArrayList.class; + } + + @Override + public void serialize(SerializationContext context, ArrayList list, CodedOutputStream codedOut) + throws IOException, SerializationException { + codedOut.writeInt32NoTag(list.size()); + for (Object obj : list) { + context.serialize(obj, codedOut); + } + } + + @Override + public ArrayList deserialize(DeserializationContext context, CodedInputStream codedIn) + throws SerializationException, IOException { + int length = codedIn.readInt32(); + if (length < 0) { + throw new SerializationException("Expected non-negative length: " + length); + } + + ArrayList<Object> list = new ArrayList<>(length); + for (int i = 0; i < length; ++i) { + list.add(context.deserialize(codedIn)); + } + return list; + } +} diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/EmptyListCodec.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/EmptyListCodec.java new file mode 100644 index 0000000000..18cbc7d1fe --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/EmptyListCodec.java @@ -0,0 +1,44 @@ +// 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.util.Collections; +import java.util.List; + +/** + * Codec for {@link Collections.EMPTY_LIST} + * + * <p>TODO(shahan): this might be better as an AutoCodec field tag, but this package, the logical + * home for the codec, is a dependency of AutoCodec, so doing so would create a circular dependency. + */ +@SuppressWarnings("rawtypes") +class EmptyListCodec implements ObjectCodec<List> { + + @Override + public Class<? extends List> getEncodedClass() { + return Collections.emptyList().getClass(); + } + + @Override + public void serialize( + SerializationContext unusedContext, List unusedValue, CodedOutputStream unusedCodedOut) {} + + @Override + public List deserialize(DeserializationContext unusedContext, CodedInputStream unusedCodedIn) { + return Collections.emptyList(); + } +} diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/MapEntryCodec.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/MapEntryCodec.java new file mode 100644 index 0000000000..59f1ca95e4 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/MapEntryCodec.java @@ -0,0 +1,64 @@ +// 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.common.collect.ImmutableList; +import com.google.common.collect.Maps; +import com.google.protobuf.CodedInputStream; +import com.google.protobuf.CodedOutputStream; +import java.io.IOException; +import java.util.AbstractMap; +import java.util.Map; +import java.util.function.BiFunction; + +@SuppressWarnings("rawtypes") +class MapEntryCodec implements ObjectCodec<Map.Entry> { + + private final BiFunction<Object, Object, Map.Entry> factory; + private final Class<? extends Map.Entry> type; + + private MapEntryCodec(BiFunction<Object, Object, Map.Entry> factory) { + this.factory = factory; + this.type = factory.apply(0, 0).getClass(); + } + + @Override + public Class<? extends Map.Entry> getEncodedClass() { + return type; + } + + @Override + public void serialize(SerializationContext context, Map.Entry entry, CodedOutputStream codedOut) + throws IOException, SerializationException { + context.serialize(entry.getKey(), codedOut); + context.serialize(entry.getValue(), codedOut); + } + + @Override + public Map.Entry deserialize(DeserializationContext context, CodedInputStream codedIn) + throws SerializationException, IOException { + return factory.apply(context.deserialize(codedIn), context.deserialize(codedIn)); + } + + private static class MapEntryCodecRegisterer implements CodecRegisterer<MapEntryCodec> { + @Override + public Iterable<MapEntryCodec> getCodecsToRegister() { + return ImmutableList.of( + new MapEntryCodec(Maps::immutableEntry), + new MapEntryCodec(AbstractMap.SimpleEntry::new), + new MapEntryCodec(AbstractMap.SimpleImmutableEntry::new)); + } + } +} 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 330c2e4429..461c8feda8 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 @@ -21,18 +21,13 @@ import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSortedSet; import com.google.common.collect.Iterables; -import com.google.common.collect.Maps; import com.google.devtools.build.lib.skyframe.serialization.autocodec.SerializationCodeGenerator.Context; import com.google.devtools.build.lib.skyframe.serialization.autocodec.SerializationCodeGenerator.Marshaller; import com.google.devtools.build.lib.skyframe.serialization.autocodec.SerializationCodeGenerator.PrimitiveValueSerializationCodeGenerator; import com.google.devtools.build.lib.skyframe.serialization.strings.StringCodecs; import com.squareup.javapoet.TypeName; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; import java.util.Comparator; import java.util.LinkedHashMap; -import java.util.List; import java.util.Map; import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.TypeElement; @@ -94,21 +89,6 @@ class Marshallers { } } - /** - * Writes out the deserialization loop and build code for any entity serialized as a list. - * - * @param context context object for list with possibly another type. - * @param repeated context for generic type deserialization. - * @param builderName String for referencing the entity builder. - */ - private void writeListDeserializationLoopAndBuild( - Context context, Context repeated, String builderName) { - if (matchesErased(context.getDeclaredType(), ImmutableList.class)) { - writeIterableDeserializationLoopWithoutNullsAndBuild(context, repeated, builderName); - } else { - writeListDeserializationLoopWithNullsAndBuild(context, repeated, builderName); - } - } private void writeIterableDeserializationLoopWithoutNullsAndBuild( Context context, Context repeated, String builderName) { @@ -123,35 +103,6 @@ class Marshallers { context.builder.addStatement("$L = $L.build()", context.name, builderName); } - private void writeListDeserializationLoopWithNullsAndBuild( - Context context, Context repeated, String builderName) { - String lengthName = context.makeName("length"); - context.builder.addStatement("int $L = codedIn.readInt32()", lengthName); - String arrayListInCaseNull = context.makeName("arrayListInCaseNull"); - context.builder.addStatement("$T $L = null", ArrayList.class, arrayListInCaseNull); - String indexName = context.makeName("i"); - context.builder.beginControlFlow( - "for (int $L = 0; $L < $L; ++$L)", indexName, indexName, lengthName, indexName); - writeDeserializationCode(repeated); - context - .builder - .beginControlFlow("if ($L == null && $L == null)", repeated.name, arrayListInCaseNull) - .addStatement("$L = new ArrayList($L.build())", arrayListInCaseNull, builderName) - .endControlFlow() - .beginControlFlow("if ($L == null)", arrayListInCaseNull) - .addStatement("$L.add($L)", builderName, repeated.name) - .nextControlFlow("else") - .addStatement("$L.add($L)", arrayListInCaseNull, repeated.name) - .endControlFlow() - .endControlFlow() - .addStatement( - "$L = $L == null ? $L.build() : $T.unmodifiableList($L)", - context.name, - arrayListInCaseNull, - builderName, - Collections.class, - arrayListInCaseNull); - } private SerializationCodeGenerator getMatchingCodeGenerator(TypeMirror type) { if (type.getKind() == TypeKind.ARRAY) { @@ -375,36 +326,6 @@ class Marshallers { } }; - private final Marshaller mapEntryMarshaller = - new Marshaller() { - @Override - public boolean matches(DeclaredType type) { - return matchesErased(type, Map.Entry.class); - } - - @Override - public void addSerializationCode(Context context) { - DeclaredType keyType = (DeclaredType) context.getDeclaredType().getTypeArguments().get(0); - writeSerializationCode(context.with(keyType, context.name + ".getKey()")); - DeclaredType valueType = - (DeclaredType) context.getDeclaredType().getTypeArguments().get(1); - writeSerializationCode(context.with(valueType, context.name + ".getValue()")); - } - - @Override - public void addDeserializationCode(Context context) { - DeclaredType keyType = (DeclaredType) context.getDeclaredType().getTypeArguments().get(0); - String keyName = context.makeName("key"); - writeDeserializationCode(context.with(keyType, keyName)); - DeclaredType valueType = - (DeclaredType) context.getDeclaredType().getTypeArguments().get(1); - String valueName = context.makeName("value"); - writeDeserializationCode(context.with(valueType, valueName)); - context.builder.addStatement( - "$L = $T.immutableEntry($L, $L)", context.name, Maps.class, keyName, valueName); - } - }; - private void addSerializationCodeForIterable(Context context) { // Writes the target count to the stream so deserialization knows when to stop. context.builder.addStatement( @@ -423,45 +344,6 @@ class Marshallers { context.builder.endControlFlow(); } - private void addDeserializationCodeForIterable(Context context) { - Context repeated = - context.with( - context.getDeclaredType().getTypeArguments().get(0), context.makeName("repeated")); - TypeMirror typeParameter = context.getDeclaredType().getTypeArguments().get(0); - // If this is generic we have to get the erasure since we don't know what <T> or <?> are. - if (isVariableOrWildcardType(typeParameter)) { - typeParameter = env.getTypeUtils().erasure(typeParameter); - } - 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 listMarshaller = - new Marshaller() { - @Override - public boolean matches(DeclaredType type) { - // TODO(shahan): refine this as needed by splitting this into separate marshallers. - return matchesErased(type, Collection.class) - || matchesErased(type, List.class) - || matchesErased(type, ImmutableList.class); - } - - @Override - public void addSerializationCode(Context context) { - addSerializationCodeForIterable(context); - } - - @Override - public void addDeserializationCode(Context context) { - addDeserializationCodeForIterable(context); - } - }; private final Marshaller immutableSetMarshaller = new Marshaller() { @@ -472,7 +354,7 @@ class Marshallers { @Override public void addSerializationCode(Context context) { - listMarshaller.addSerializationCode(context); + addSerializationCodeForIterable(context); } @Override @@ -501,7 +383,7 @@ class Marshallers { @Override public void addSerializationCode(Context context) { - listMarshaller.addSerializationCode(context); + addSerializationCodeForIterable(context); } @Override @@ -670,8 +552,6 @@ class Marshallers { ImmutableList.of( charSequenceMarshaller, supplierMarshaller, - mapEntryMarshaller, - listMarshaller, immutableSetMarshaller, immutableSortedSetMarshaller, mapMarshaller, |