aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main
diff options
context:
space:
mode:
authorGravatar shahan <shahan@google.com>2018-04-04 09:49:03 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-04-04 09:50:47 -0700
commit00b72a1590713e7650285d84ae2a1e5c2041defe (patch)
tree8a0c76d86b7dcb3e1f0eb9966c8e42ab44afc722 /src/main
parent77777d1a769e938839b82c65ff320e09b1e7a715 (diff)
Replaces JavaSerializableCodec with DynamicCodec as the default
* Skylark serialization was previously dropping location in error, which this fixes. * Deletes a lot of codecs with fidelity issues (DynamicCodec has full fidelity). * Deletes EnumRuntimeCodec which can now be replaced with the superior EnumCodec. * This should eventually allow us to delete Serializable from all Blaze. The remaining blocker is NoSuchPackageExceptionCodec. PiperOrigin-RevId: 191603929
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java12
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/SkylarkProvider.java5
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/serialization/AutoRegistry.java28
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/serialization/CodecScanner.java117
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/serialization/EnumRuntimeCodec.java42
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/serialization/ObjectCodecRegistry.java142
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/serialization/SerializationContext.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/NotSerializableCodec.java49
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/Argument.java5
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/AssignmentStatement.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/AugmentedAssignmentStatement.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/ConditionalExpression.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/DictComprehension.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/DictionaryLiteral.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/DotExpression.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/ExpressionStatement.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/FlowStatement.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/ForStatement.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/FuncallExpression.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/FunctionDefStatement.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/Identifier.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/IfStatement.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/IndexExpression.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/IntegerLiteral.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/LValue.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/ListComprehension.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/ListLiteral.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/LoadStatement.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/PassStatement.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/ReturnStatement.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/SkylarkType.java48
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/SliceExpression.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/StringLiteral.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/UnaryOperatorExpression.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/UserDefinedFunction.java2
37 files changed, 266 insertions, 240 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java
index e6e6e9c637..5ad5007e96 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java
@@ -71,7 +71,6 @@ import com.google.devtools.build.lib.packages.SkylarkProvider;
import com.google.devtools.build.lib.packages.TargetUtils;
import com.google.devtools.build.lib.packages.TestSize;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
-import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
import com.google.devtools.build.lib.skylarkinterface.Param;
import com.google.devtools.build.lib.skylarkinterface.ParamType;
import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
@@ -879,7 +878,6 @@ public class SkylarkRuleClassFunctions {
*
* <p>Exactly one of {@link #builder} or {@link #ruleClass} is null except inside {@link #export}.
*/
- @AutoCodec
public static final class SkylarkRuleFunction extends BaseFunction
implements SkylarkExportable, RuleFunction {
private RuleClass.Builder builder;
@@ -903,14 +901,8 @@ public class SkylarkRuleClassFunctions {
}
/** This is for post-export reconstruction for serialization. */
- @VisibleForSerialization
- @AutoCodec.Instantiator
- SkylarkRuleFunction(
- RuleClass ruleClass,
- RuleClassType type,
- Location definitionLocation,
- Label skylarkLabel
- ) {
+ private SkylarkRuleFunction(
+ RuleClass ruleClass, RuleClassType type, Location definitionLocation, Label skylarkLabel) {
super("rule", FunctionSignature.KWARGS);
Preconditions.checkNotNull(
ruleClass,
diff --git a/src/main/java/com/google/devtools/build/lib/packages/SkylarkProvider.java b/src/main/java/com/google/devtools/build/lib/packages/SkylarkProvider.java
index 0de9e682e7..95e64d9c7a 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/SkylarkProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/SkylarkProvider.java
@@ -44,7 +44,6 @@ import javax.annotation.Nullable;
* pre-exported provider directly. Exported providers use only their key for {@link #equals} and
* {@link #hashCode}.
*/
-@AutoCodec
public class SkylarkProvider extends Provider implements SkylarkExportable {
private static final FunctionSignature.WithValues<Object, SkylarkType> SCHEMALESS_SIGNATURE =
@@ -126,9 +125,7 @@ public class SkylarkProvider extends Provider implements SkylarkExportable {
* <p>If {@code key} is null, the provider is unexported. If {@code fields} is null, the provider
* is schemaless.
*/
- @AutoCodec.Instantiator
- @AutoCodec.VisibleForSerialization
- SkylarkProvider(
+ private SkylarkProvider(
@Nullable SkylarkKey key, @Nullable ImmutableList<String> fields, Location location) {
// We override getName() in order to use the name that is assigned when export() is called.
// Hence BaseFunction's constructor gets a null name.
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java
index 3533ce071d..18dd2de19d 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java
@@ -85,7 +85,6 @@ import java.util.UUID;
import javax.annotation.Nullable;
/** Action that represents some kind of C++ compilation step. */
-@AutoCodec
@ThreadCompatible
public class CppCompileAction extends AbstractAction
implements IncludeScannable, ExecutionInfoSpecifier, CommandAction {
@@ -346,7 +345,6 @@ public class CppCompileAction extends AbstractAction
Preconditions.checkArgument(!shouldPruneModules || shouldScanIncludes);
}
- @AutoCodec.Instantiator
@VisibleForSerialization
CppCompileAction(
ActionOwner owner,
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/AutoRegistry.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/AutoRegistry.java
index bf11b86e69..4af9f532f0 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/AutoRegistry.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/AutoRegistry.java
@@ -14,8 +14,10 @@
package com.google.devtools.build.lib.skyframe.serialization;
+import com.google.common.base.Predicates;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
+import com.google.common.collect.ImmutableList;
import java.io.IOException;
/**
@@ -29,15 +31,35 @@ public class AutoRegistry {
private static final Supplier<ObjectCodecRegistry> SUPPLIER =
Suppliers.memoize(AutoRegistry::create);
+ /* Common ancestor of common.google.devtools.build and com.google.devtools.common.options,
+ * where Tristate lives. */
+ private static final String PACKAGE_PREFIX = "com.google.devtools";
+
+ /** Classes outside {@link AutoRegistry#PACKAGE_PREFIX} that need to be serialized. */
+ private static final ImmutableList<String> EXTERNAL_CLASS_NAMES_TO_REGISTER =
+ ImmutableList.of("java.io.FileNotFoundException", "java.io.IOException");
+
+ private static final ImmutableList<Object> CONSTANTS_TO_REGISTER =
+ ImmutableList.of(
+ Predicates.alwaysTrue(),
+ Predicates.alwaysFalse(),
+ Predicates.isNull(),
+ Predicates.notNull());
+
public static ObjectCodecRegistry get() {
return SUPPLIER.get();
}
private static ObjectCodecRegistry create() {
try {
- return CodecScanner.initializeCodecRegistry("com.google.devtools.build")
- .setAllowDefaultCodec(false)
- .build();
+ ObjectCodecRegistry.Builder registry = CodecScanner.initializeCodecRegistry(PACKAGE_PREFIX);
+ for (String className : EXTERNAL_CLASS_NAMES_TO_REGISTER) {
+ registry.addClassName(className);
+ }
+ for (Object constant : CONSTANTS_TO_REGISTER) {
+ registry.addConstant(constant);
+ }
+ return registry.build();
} catch (IOException | ReflectiveOperationException e) {
throw new IllegalStateException(e);
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/CodecScanner.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/CodecScanner.java
index 635b5ad755..319e0c1152 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/CodecScanner.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/CodecScanner.java
@@ -27,11 +27,8 @@ import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashSet;
-import java.util.List;
-import java.util.function.Predicate;
import java.util.logging.Level;
import java.util.logging.Logger;
-import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
@@ -59,62 +56,73 @@ public class CodecScanner {
log.info("Building ObjectCodecRegistry");
ArrayList<Class<? extends ObjectCodec<?>>> codecs = new ArrayList<>();
ArrayList<Class<? extends CodecRegisterer<?>>> registerers = new ArrayList<>();
- List<ClassInfo> classInfos = getClassInfos(packagePrefix).collect(Collectors.toList());
- getCodecs(classInfos)
- .forEach(
- type -> {
- if (!ObjectCodec.class.equals(type)
- && ObjectCodec.class.isAssignableFrom(type)
- && !Modifier.isAbstract(type.getModifiers())) {
- codecs.add((Class<? extends ObjectCodec<?>>) type);
- } else if (!CodecRegisterer.class.equals(type)
- && CodecRegisterer.class.isAssignableFrom(type)) {
- registerers.add((Class<? extends CodecRegisterer<?>>) type);
- }
- });
ObjectCodecRegistry.Builder builder = ObjectCodecRegistry.newBuilder();
- getMatchingClasses(
- classInfos,
- classInfo ->
- classInfo
- .getSimpleName()
- .endsWith(CodecScanningConstants.REGISTERED_SINGLETON_SUFFIX))
+ getClassInfos(packagePrefix)
.forEach(
- type -> {
- if (!RegisteredSingletonDoNotUse.class.isAssignableFrom(type)) {
- return;
- }
- Field field;
- try {
- field =
- type.getDeclaredField(
- CodecScanningConstants.REGISTERED_SINGLETON_INSTANCE_VAR_NAME);
- } catch (NoSuchFieldException e) {
- throw new IllegalStateException(
- type
- + " inherits from "
- + RegisteredSingletonDoNotUse.class
- + " but does not have a field "
- + CodecScanningConstants.REGISTERED_SINGLETON_INSTANCE_VAR_NAME,
- e);
- }
- try {
- builder.addConstant(
- Preconditions.checkNotNull(field.get(null), "%s %s", field, type));
- } catch (IllegalAccessException e) {
- throw new IllegalStateException(
- "Could not access field " + field + " for " + type, e);
+ classInfo -> {
+ if (classInfo.getName().endsWith("Codec")) {
+ processLikelyCodec(classInfo.load(), codecs);
+ } else if (classInfo.getName().endsWith("CodecRegisterer")) {
+ processLikelyRegisterer(classInfo.load(), registerers);
+ } else if (classInfo
+ .getName()
+ .endsWith(CodecScanningConstants.REGISTERED_SINGLETON_SUFFIX)) {
+ processLikelyConstant(classInfo.load(), builder);
+ } else {
+ // Assumes that anything with a class name matching the above won't need to be
+ // serialized.
+ builder.addClassName(classInfo.getName().intern());
}
});
HashSet<Class<? extends ObjectCodec<?>>> alreadyRegistered =
runRegisterers(builder, registerers);
-
applyDefaultRegistration(builder, alreadyRegistered, codecs);
return builder;
}
@SuppressWarnings("unchecked")
+ private static void processLikelyCodec(
+ Class<?> type, ArrayList<Class<? extends ObjectCodec<?>>> codecs) {
+ if (!ObjectCodec.class.equals(type)
+ && ObjectCodec.class.isAssignableFrom(type)
+ && !Modifier.isAbstract(type.getModifiers())) {
+ codecs.add((Class<? extends ObjectCodec<?>>) type);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private static void processLikelyRegisterer(
+ Class<?> type, ArrayList<Class<? extends CodecRegisterer<?>>> registerers) {
+ if (!CodecRegisterer.class.equals(type) && CodecRegisterer.class.isAssignableFrom(type)) {
+ registerers.add((Class<? extends CodecRegisterer<?>>) type);
+ }
+ }
+
+ private static void processLikelyConstant(Class<?> type, ObjectCodecRegistry.Builder builder) {
+ if (!RegisteredSingletonDoNotUse.class.isAssignableFrom(type)) {
+ return;
+ }
+ Field field;
+ try {
+ field = type.getDeclaredField(CodecScanningConstants.REGISTERED_SINGLETON_INSTANCE_VAR_NAME);
+ } catch (NoSuchFieldException e) {
+ throw new IllegalStateException(
+ type
+ + " inherits from "
+ + RegisteredSingletonDoNotUse.class
+ + " but does not have a field "
+ + CodecScanningConstants.REGISTERED_SINGLETON_INSTANCE_VAR_NAME,
+ e);
+ }
+ try {
+ builder.addConstant(Preconditions.checkNotNull(field.get(null), "%s %s", field, type));
+ } catch (IllegalAccessException e) {
+ throw new IllegalStateException("Could not access field " + field + " for " + type, e);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
private static HashSet<Class<? extends ObjectCodec<?>>> runRegisterers(
ObjectCodecRegistry.Builder builder,
ArrayList<Class<? extends CodecRegisterer<?>>> registerers)
@@ -195,19 +203,4 @@ public class CodecScanner {
.filter(c -> c.getPackageName().startsWith(packagePrefix))
.sorted(Comparator.comparing(ClassInfo::getName));
}
-
- /**
- * Returns a stream of likely codec and registerer implementations.
- *
- * <p>Caller should do additional checks as this method only performs string matching.
- */
- private static Stream<Class<?>> getCodecs(List<ClassInfo> classInfos) {
- return getMatchingClasses(
- classInfos, c -> c.getName().endsWith("Codec") || c.getName().endsWith("CodecRegisterer"));
- }
-
- private static Stream<Class<?>> getMatchingClasses(
- List<ClassInfo> classInfos, Predicate<ClassInfo> predicate) {
- return classInfos.stream().filter(predicate).map(ClassInfo::load);
- }
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/EnumRuntimeCodec.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/EnumRuntimeCodec.java
deleted file mode 100644
index 0d67591077..0000000000
--- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/EnumRuntimeCodec.java
+++ /dev/null
@@ -1,42 +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.protobuf.CodedInputStream;
-import com.google.protobuf.CodedOutputStream;
-import java.io.IOException;
-
-@SuppressWarnings("rawtypes")
-class EnumRuntimeCodec implements ObjectCodec<Enum> {
-
- @Override
- public Class<Enum> getEncodedClass() {
- return Enum.class;
- }
-
- @Override
- public void serialize(SerializationContext context, Enum value, CodedOutputStream codedOut)
- throws IOException, SerializationException {
- context.serialize(value.getDeclaringClass(), codedOut);
- codedOut.writeInt32NoTag(value.ordinal());
- }
-
- @Override
- public Enum deserialize(DeserializationContext context, CodedInputStream codedIn)
- throws SerializationException, IOException {
- Class<? extends Enum> enumType = context.deserialize(codedIn);
- return enumType.getEnumConstants()[codedIn.readInt32()];
- }
-}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/ObjectCodecRegistry.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/ObjectCodecRegistry.java
index 95590143db..c963172e9f 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/ObjectCodecRegistry.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/ObjectCodecRegistry.java
@@ -16,15 +16,18 @@ package com.google.devtools.build.lib.skyframe.serialization;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.MoreObjects;
+import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSortedSet;
import com.google.protobuf.CodedInputStream;
import com.google.protobuf.CodedOutputStream;
import java.io.IOException;
import java.util.Comparator;
import java.util.IdentityHashMap;
import java.util.Map;
+import java.util.function.Supplier;
import javax.annotation.Nullable;
/**
@@ -38,19 +41,27 @@ public class ObjectCodecRegistry {
return new Builder();
}
+ private final boolean allowDefaultCodec;
+
private final ImmutableMap<Class<?>, CodecDescriptor> classMappedCodecs;
private final ImmutableList<CodecDescriptor> tagMappedCodecs;
- @Nullable
- private final CodecDescriptor defaultCodecDescriptor;
+ private final int constantsStartTag;
private final IdentityHashMap<Object, Integer> constantsMap;
private final ImmutableList<Object> constants;
- private final int constantsStartTag;
+
+ /** This is sorted, but we need index-based access. */
+ private final ImmutableList<String> classNames;
+
+ private final IdentityHashMap<String, Supplier<CodecDescriptor>> dynamicCodecs;
private ObjectCodecRegistry(
ImmutableSet<ObjectCodec<?>> memoizingCodecs,
ImmutableList<Object> constants,
+ ImmutableSortedSet<String> classNames,
boolean allowDefaultCodec) {
+ this.allowDefaultCodec = allowDefaultCodec;
+
int nextTag = 1; // 0 is reserved for null.
ImmutableMap.Builder<Class<?>, CodecDescriptor> memoizingCodecsBuilder =
ImmutableMap.builderWithExpectedSize(memoizingCodecs.size());
@@ -60,14 +71,6 @@ public class ObjectCodecRegistry {
processCodecs(
memoizingCodecs, nextTag, tagMappedMemoizingCodecsBuilder, memoizingCodecsBuilder);
- this.defaultCodecDescriptor =
- allowDefaultCodec
- ? new TypedCodecDescriptor<>(nextTag++, new JavaSerializableCodec())
- : null;
- if (allowDefaultCodec) {
- tagMappedMemoizingCodecsBuilder.add(defaultCodecDescriptor);
- }
-
this.classMappedCodecs = memoizingCodecsBuilder.build();
this.tagMappedCodecs = tagMappedMemoizingCodecsBuilder.build();
@@ -77,16 +80,35 @@ public class ObjectCodecRegistry {
constantsMap.put(constant, nextTag++);
}
this.constants = constants;
+
+ this.classNames = classNames.asList();
+ this.dynamicCodecs = createDynamicCodecs(classNames, nextTag);
+ }
+
+ public CodecDescriptor getCodecDescriptorForObject(Object obj)
+ throws SerializationException.NoCodecException {
+ Class<?> type = obj.getClass();
+ CodecDescriptor descriptor = getCodecDescriptor(type);
+ if (descriptor != null) {
+ return descriptor;
+ }
+ if (!allowDefaultCodec) {
+ throw new SerializationException.NoCodecException(
+ "No codec available for " + type + " and default fallback disabled");
+ }
+ if (obj instanceof Enum) {
+ // Enums must be serialized using declaring class.
+ type = ((Enum) obj).getDeclaringClass();
+ }
+ return getDynamicCodecDescriptor(type.getName());
}
/**
- * Returns a {@link CodecDescriptor} for the given type.
+ * Returns a {@link CodecDescriptor} for the given type or null if none found.
*
- * <p>Falls back to a codec for the nearest super type of type. Failing that, may fall back to the
- * registry's default codec.
+ * <p>Also checks if there are codecs for a superclass of the given type.
*/
- public CodecDescriptor getCodecDescriptor(Class<?> type)
- throws SerializationException.NoCodecException {
+ private @Nullable CodecDescriptor getCodecDescriptor(Class<?> type) {
// TODO(blaze-team): consider caching this traversal.
for (Class<?> nextType = type; nextType != null; nextType = nextType.getSuperclass()) {
CodecDescriptor result = classMappedCodecs.get(nextType);
@@ -94,11 +116,7 @@ public class ObjectCodecRegistry {
return result;
}
}
- if (defaultCodecDescriptor == null) {
- throw new SerializationException.NoCodecException(
- "No codec available for " + type + " and default fallback disabled");
- }
- return defaultCodecDescriptor;
+ return null;
}
@Nullable
@@ -116,17 +134,20 @@ public class ObjectCodecRegistry {
/** Returns the {@link CodecDescriptor} associated with the supplied tag. */
public CodecDescriptor getCodecDescriptorByTag(int tag)
throws SerializationException.NoCodecException {
- int tagOffset = tag - 1;
- if (tagOffset < 0 || tagOffset > tagMappedCodecs.size()) {
+ int tagOffset = tag - 1; // 0 reserved for null
+ if (tagOffset < 0) {
throw new SerializationException.NoCodecException("No codec available for tag " + tag);
}
+ if (tagOffset < tagMappedCodecs.size()) {
+ return tagMappedCodecs.get(tagOffset);
+ }
- CodecDescriptor result = tagMappedCodecs.get(tagOffset);
- if (result != null) {
- return result;
- } else {
+ tagOffset -= tagMappedCodecs.size();
+ tagOffset -= constants.size();
+ if (!allowDefaultCodec || tagOffset < 0 || tagOffset >= classNames.size()) {
throw new SerializationException.NoCodecException("No codec available for tag " + tag);
}
+ return getDynamicCodecDescriptor(classNames.get(tagOffset));
}
/**
@@ -137,7 +158,7 @@ public class ObjectCodecRegistry {
@VisibleForTesting
public Builder getBuilder() {
Builder builder = newBuilder();
- builder.setAllowDefaultCodec(defaultCodecDescriptor != null);
+ builder.setAllowDefaultCodec(allowDefaultCodec);
for (Map.Entry<Class<?>, CodecDescriptor> entry : classMappedCodecs.entrySet()) {
builder.add(entry.getValue().getCodec());
}
@@ -145,9 +166,17 @@ public class ObjectCodecRegistry {
for (Object constant : constants) {
builder.addConstant(constant);
}
+
+ for (String className : classNames) {
+ builder.addClassName(className);
+ }
return builder;
}
+ ImmutableList<String> classNames() {
+ return classNames;
+ }
+
/** Describes encoding logic. */
interface CodecDescriptor {
void serialize(SerializationContext context, Object obj, CodedOutputStream codedOut)
@@ -157,7 +186,7 @@ public class ObjectCodecRegistry {
throws IOException, SerializationException;
/**
- * Unique identifier identifying the associated codec.
+ * Unique identifier for the associated codec.
*
* <p>Intended to be used as a compact on-the-wire representation of an encoded object's type.
*
@@ -214,6 +243,7 @@ public class ObjectCodecRegistry {
public static class Builder {
private final ImmutableSet.Builder<ObjectCodec<?>> codecBuilder = ImmutableSet.builder();
private final ImmutableList.Builder<Object> constantsBuilder = ImmutableList.builder();
+ private final ImmutableSortedSet.Builder<String> classNames = ImmutableSortedSet.naturalOrder();
private boolean allowDefaultCodec = true;
public Builder add(ObjectCodec<?> codec) {
@@ -234,9 +264,14 @@ public class ObjectCodecRegistry {
return this;
}
+ public Builder addClassName(String className) {
+ classNames.add(className);
+ return this;
+ }
+
public ObjectCodecRegistry build() {
return new ObjectCodecRegistry(
- codecBuilder.build(), constantsBuilder.build(), allowDefaultCodec);
+ codecBuilder.build(), constantsBuilder.build(), classNames.build(), allowDefaultCodec);
}
}
@@ -257,4 +292,51 @@ public class ObjectCodecRegistry {
}
return nextTag;
}
+
+ private static IdentityHashMap<String, Supplier<CodecDescriptor>> createDynamicCodecs(
+ ImmutableSortedSet<String> classNames, int nextTag) {
+ IdentityHashMap<String, Supplier<CodecDescriptor>> dynamicCodecs =
+ new IdentityHashMap<>(classNames.size());
+ for (String className : classNames) {
+ int tag = nextTag++;
+ dynamicCodecs.put(
+ className, Suppliers.memoize(() -> createDynamicCodecDescriptor(tag, className)));
+ }
+ return dynamicCodecs;
+ }
+
+ /** For enums, this method must only be called for the declaring class. */
+ private static CodecDescriptor createDynamicCodecDescriptor(int tag, String className) {
+ try {
+ Class<?> type = Class.forName(className);
+ if (type.isEnum()) {
+ return createCodecDescriptorForEnum(tag, type);
+ }
+ return new TypedCodecDescriptor<>(tag, new DynamicCodec(Class.forName(className)));
+ } catch (ReflectiveOperationException e) {
+ new SerializationException("Could not create codec for type: " + className, e)
+ .printStackTrace();
+ return null;
+ }
+ }
+
+ @SuppressWarnings({"unchecked", "rawtypes"})
+ private static CodecDescriptor createCodecDescriptorForEnum(int tag, Class<?> enumType) {
+ return new TypedCodecDescriptor(tag, new EnumCodec(enumType));
+ }
+
+ private CodecDescriptor getDynamicCodecDescriptor(String className)
+ throws SerializationException.NoCodecException {
+ Supplier<CodecDescriptor> supplier = dynamicCodecs.get(className);
+ if (supplier == null) {
+ throw new SerializationException.NoCodecException(
+ "No default codec available for " + className);
+ }
+ CodecDescriptor descriptor = supplier.get();
+ if (descriptor == null) {
+ throw new SerializationException.NoCodecException(
+ "There was a problem creating a codec for " + className + " check logs for details.");
+ }
+ return descriptor;
+ }
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/SerializationContext.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/SerializationContext.java
index e06d6dba45..ba5b696128 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/SerializationContext.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/SerializationContext.java
@@ -118,7 +118,7 @@ public class SerializationContext {
if (writeNullOrConstant(object, codedOut)) {
return null;
}
- ObjectCodecRegistry.CodecDescriptor descriptor = registry.getCodecDescriptor(object.getClass());
+ ObjectCodecRegistry.CodecDescriptor descriptor = registry.getCodecDescriptorForObject(object);
codedOut.writeSInt32NoTag(descriptor.getTag());
return descriptor;
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/NotSerializableCodec.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/NotSerializableCodec.java
new file mode 100644
index 0000000000..f8b5617670
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/NotSerializableCodec.java
@@ -0,0 +1,49 @@
+// 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.testutils;
+
+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.protobuf.CodedInputStream;
+import com.google.protobuf.CodedOutputStream;
+import java.io.NotSerializableException;
+
+/** A testing helper to force serialization errors. */
+public class NotSerializableCodec implements ObjectCodec<Object> {
+ private final Class<?> type;
+
+ public NotSerializableCodec(Class<?> type) {
+ this.type = type;
+ }
+
+ @Override
+ public Class<?> getEncodedClass() {
+ return type;
+ }
+
+ @Override
+ public void serialize(
+ SerializationContext unusedContext, Object unusedObj, CodedOutputStream unusedCodedOut)
+ throws NotSerializableException {
+ throw new NotSerializableException(type + " marked not serializable");
+ }
+
+ @Override
+ public Object deserialize(DeserializationContext unusedContext, CodedInputStream unusedCodedIn)
+ throws NotSerializableException {
+ throw new NotSerializableException(type + " marked not serializable");
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Argument.java b/src/main/java/com/google/devtools/build/lib/syntax/Argument.java
index 141f763e50..a4d782a44f 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Argument.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Argument.java
@@ -14,7 +14,6 @@
package com.google.devtools.build.lib.syntax;
import com.google.common.base.Preconditions;
-import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import java.io.IOException;
import java.util.List;
import javax.annotation.Nullable;
@@ -75,7 +74,6 @@ public abstract class Argument extends ASTNode {
}
/** positional argument: Expression */
- @AutoCodec
public static final class Positional extends Passed {
public Positional(Expression value) {
@@ -94,7 +92,6 @@ public abstract class Argument extends ASTNode {
}
/** keyword argument: K = Expression */
- @AutoCodec
public static final class Keyword extends Passed {
final String name;
@@ -123,7 +120,6 @@ public abstract class Argument extends ASTNode {
}
/** positional rest (starred) argument: *Expression */
- @AutoCodec
public static final class Star extends Passed {
public Star(Expression value) {
@@ -143,7 +139,6 @@ public abstract class Argument extends ASTNode {
}
/** keyword rest (star_starred) parameter: **Expression */
- @AutoCodec
public static final class StarStar extends Passed {
public StarStar(Expression value) {
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/AssignmentStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/AssignmentStatement.java
index 2286f44d2a..4545b7cc81 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/AssignmentStatement.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/AssignmentStatement.java
@@ -14,11 +14,9 @@
package com.google.devtools.build.lib.syntax;
-import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import java.io.IOException;
/** Syntax node for an assignment statement. */
-@AutoCodec
public final class AssignmentStatement extends Statement {
private final LValue lvalue;
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/AugmentedAssignmentStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/AugmentedAssignmentStatement.java
index d23d78467c..ec23b20f86 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/AugmentedAssignmentStatement.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/AugmentedAssignmentStatement.java
@@ -14,11 +14,9 @@
package com.google.devtools.build.lib.syntax;
-import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import java.io.IOException;
/** Syntax node for an augmented assignment statement. */
-@AutoCodec
public final class AugmentedAssignmentStatement extends Statement {
private final Operator operator;
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java
index b56c9ebc90..b1f835ce63 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java
@@ -15,7 +15,6 @@ package com.google.devtools.build.lib.syntax;
import com.google.common.base.Strings;
import com.google.devtools.build.lib.events.Location;
-import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.syntax.Concatable.Concatter;
import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
@@ -23,7 +22,6 @@ import java.io.IOException;
import java.util.IllegalFormatException;
/** Syntax node for a binary operator expression. */
-@AutoCodec
public final class BinaryOperatorExpression extends Expression {
private final Expression lhs;
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/ConditionalExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/ConditionalExpression.java
index 0f016b9c58..769762895e 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/ConditionalExpression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/ConditionalExpression.java
@@ -13,11 +13,9 @@
// limitations under the License.
package com.google.devtools.build.lib.syntax;
-import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import java.io.IOException;
/** Syntax node for an if/else expression. */
-@AutoCodec
public final class ConditionalExpression extends Expression {
// Python conditional expressions: $thenCase if $condition else $elseCase
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/DictComprehension.java b/src/main/java/com/google/devtools/build/lib/syntax/DictComprehension.java
index f1125568e3..f47b80020b 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/DictComprehension.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/DictComprehension.java
@@ -15,13 +15,11 @@ package com.google.devtools.build.lib.syntax;
import com.google.common.base.Preconditions;
import com.google.devtools.build.lib.events.Location;
-import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import java.io.IOException;
import java.util.List;
import java.util.Map;
/** Syntax node for dictionary comprehension expressions. */
-@AutoCodec
public final class DictComprehension extends AbstractComprehension {
private final Expression keyExpression;
private final Expression valueExpression;
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/DictionaryLiteral.java b/src/main/java/com/google/devtools/build/lib/syntax/DictionaryLiteral.java
index 410408c060..76512d855b 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/DictionaryLiteral.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/DictionaryLiteral.java
@@ -15,16 +15,13 @@ package com.google.devtools.build.lib.syntax;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.events.Location;
-import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import java.io.IOException;
import java.util.List;
/** Syntax node for dictionary literals. */
-@AutoCodec
public final class DictionaryLiteral extends Expression {
/** Node for an individual key-value pair in a dictionary literal. */
- @AutoCodec
public static final class DictionaryEntryLiteral extends ASTNode {
private final Expression key;
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/DotExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/DotExpression.java
index 5b1045f4d4..86313c132c 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/DotExpression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/DotExpression.java
@@ -15,14 +15,12 @@ package com.google.devtools.build.lib.syntax;
import com.google.common.collect.Streams;
import com.google.devtools.build.lib.events.Location;
-import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.syntax.FuncallExpression.MethodDescriptor;
import com.google.devtools.build.lib.util.SpellChecker;
import java.io.IOException;
import java.util.Optional;
/** Syntax node for a dot expression. e.g. obj.field, but not obj.method() */
-@AutoCodec
public final class DotExpression extends Expression {
private final Expression object;
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/ExpressionStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/ExpressionStatement.java
index 971e72dd40..d0d2c22609 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/ExpressionStatement.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/ExpressionStatement.java
@@ -14,11 +14,9 @@
package com.google.devtools.build.lib.syntax;
-import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import java.io.IOException;
/** Syntax node for a function call statement. Used for build rules. */
-@AutoCodec
public final class ExpressionStatement extends Statement {
private final Expression expression;
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/FlowStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/FlowStatement.java
index 71ffe661ca..b060b78c31 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/FlowStatement.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/FlowStatement.java
@@ -13,11 +13,9 @@
// limitations under the License.
package com.google.devtools.build.lib.syntax;
-import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import java.io.IOException;
/** A class for flow statements (e.g. break and continue) */
-@AutoCodec
public final class FlowStatement extends Statement {
// TODO(laurentlb): This conflicts with Statement.Kind, maybe remove it?
public enum Kind {
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/ForStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/ForStatement.java
index d2e06a033d..cdf23d7340 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/ForStatement.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/ForStatement.java
@@ -15,12 +15,10 @@ package com.google.devtools.build.lib.syntax;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
-import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import java.io.IOException;
import java.util.List;
/** Syntax node for a for loop statement. */
-@AutoCodec
public final class ForStatement extends Statement {
private final LValue variable;
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/FuncallExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/FuncallExpression.java
index ff81eade53..7a807f5e20 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/FuncallExpression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/FuncallExpression.java
@@ -26,7 +26,6 @@ import com.google.common.collect.ImmutableSortedMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.devtools.build.lib.events.Location;
-import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.skylarkinterface.Param;
import com.google.devtools.build.lib.skylarkinterface.ParamType;
import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
@@ -54,7 +53,6 @@ import java.util.stream.Collectors;
import javax.annotation.Nullable;
/** Syntax node for a function call expression. */
-@AutoCodec
public final class FuncallExpression extends Expression {
/**
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/FunctionDefStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/FunctionDefStatement.java
index 5d856ede75..0c78eaf1e5 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/FunctionDefStatement.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/FunctionDefStatement.java
@@ -14,11 +14,9 @@
package com.google.devtools.build.lib.syntax;
import com.google.common.collect.ImmutableList;
-import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import java.io.IOException;
/** Syntax node for a function definition. */
-@AutoCodec
public final class FunctionDefStatement extends Statement {
private final Identifier identifier;
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Identifier.java b/src/main/java/com/google/devtools/build/lib/syntax/Identifier.java
index 419cc99621..db4a62dab0 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Identifier.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Identifier.java
@@ -14,7 +14,6 @@
package com.google.devtools.build.lib.syntax;
-import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.util.SpellChecker;
import java.io.IOException;
import java.util.Set;
@@ -34,7 +33,6 @@ import javax.annotation.Nullable;
* Object#hashCode} (but note that these methods ignore location information). They are needed
* because {@code Identifier}s are stored in maps when constructing {@link LoadStatement}.
*/
-@AutoCodec
public final class Identifier extends Expression {
private final String name;
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/IfStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/IfStatement.java
index b4377d0531..15e0087843 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/IfStatement.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/IfStatement.java
@@ -15,12 +15,10 @@ package com.google.devtools.build.lib.syntax;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
-import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import java.io.IOException;
import java.util.List;
/** Syntax node for an if/else statement. */
-@AutoCodec
public final class IfStatement extends Statement {
/**
@@ -29,7 +27,6 @@ public final class IfStatement extends Statement {
* <p>This extends Statement, but it is not actually an independent statement in the grammar. We
* should probably eliminate it in favor of a recursive representation of if/else chains.
*/
- @AutoCodec
public static final class ConditionalStatements extends Statement {
private final Expression condition;
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/IndexExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/IndexExpression.java
index 0c4a7f628c..efb1a64edf 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/IndexExpression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/IndexExpression.java
@@ -14,7 +14,6 @@
package com.google.devtools.build.lib.syntax;
import com.google.devtools.build.lib.events.Location;
-import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import java.io.IOException;
/**
@@ -22,7 +21,6 @@ import java.io.IOException;
* obj[from:to]}). The object may be either a sequence or an associative mapping (most commonly
* lists and dictionaries).
*/
-@AutoCodec
public final class IndexExpression extends Expression {
private final Expression object;
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/IntegerLiteral.java b/src/main/java/com/google/devtools/build/lib/syntax/IntegerLiteral.java
index b642dd8649..3f2653caf6 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/IntegerLiteral.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/IntegerLiteral.java
@@ -13,11 +13,9 @@
// limitations under the License.
package com.google.devtools.build.lib.syntax;
-import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import java.io.IOException;
/** Syntax node for an integer literal. */
-@AutoCodec
public final class IntegerLiteral extends Expression {
private final int value;
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/LValue.java b/src/main/java/com/google/devtools/build/lib/syntax/LValue.java
index 34ccaa8b36..eb3c685063 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/LValue.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/LValue.java
@@ -17,7 +17,6 @@ package com.google.devtools.build.lib.syntax;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.events.Location;
-import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
import java.io.IOException;
import java.util.Collection;
@@ -45,7 +44,6 @@ import java.util.Collection;
* cannot appear in {@code LValue}s.
*/
// TODO(bazel-team): Add support for assigning to slices (e.g. a[2:6] = [3]).
-@AutoCodec
public final class LValue extends ASTNode {
private final Expression expr;
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/ListComprehension.java b/src/main/java/com/google/devtools/build/lib/syntax/ListComprehension.java
index 8141bd9cd9..7a7e0c59b4 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/ListComprehension.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/ListComprehension.java
@@ -15,14 +15,12 @@ package com.google.devtools.build.lib.syntax;
import com.google.common.base.Preconditions;
import com.google.devtools.build.lib.events.Location;
-import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/** Syntax node for lists comprehension expressions. */
-@AutoCodec
public final class ListComprehension extends AbstractComprehension {
private final Expression outputExpression;
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/ListLiteral.java b/src/main/java/com/google/devtools/build/lib/syntax/ListLiteral.java
index ac367201e8..e18d419ecd 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/ListLiteral.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/ListLiteral.java
@@ -13,7 +13,6 @@
// limitations under the License.
package com.google.devtools.build.lib.syntax;
-import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import java.io.IOException;
@@ -27,7 +26,6 @@ import java.util.List;
* <p>(Note that during evaluation, both list and tuple values are represented by java.util.List
* objects, the only difference between them being whether or not they are mutable.)
*/
-@AutoCodec
public final class ListLiteral extends Expression {
/**
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/LoadStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/LoadStatement.java
index c9669fcd56..087333cdd5 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/LoadStatement.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/LoadStatement.java
@@ -15,12 +15,10 @@ package com.google.devtools.build.lib.syntax;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
-import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import java.io.IOException;
import java.util.Map;
/** Syntax node for an import statement. */
-@AutoCodec
public final class LoadStatement extends Statement {
private final ImmutableMap<Identifier, String> symbolMap;
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/PassStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/PassStatement.java
index f7854e8dda..e0351002ef 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/PassStatement.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/PassStatement.java
@@ -14,11 +14,9 @@
package com.google.devtools.build.lib.syntax;
-import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import java.io.IOException;
/** Syntax node for a `pass` statement. */
-@AutoCodec
public class PassStatement extends Statement {
@Override
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/ReturnStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/ReturnStatement.java
index 37d462964b..4d9c2ad20c 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/ReturnStatement.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/ReturnStatement.java
@@ -14,12 +14,10 @@
package com.google.devtools.build.lib.syntax;
import com.google.devtools.build.lib.events.Location;
-import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import java.io.IOException;
import javax.annotation.Nullable;
/** A wrapper Statement class for return expressions. */
-@AutoCodec
public final class ReturnStatement extends Statement {
/**
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkType.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkType.java
index b4729ace56..9e394d977d 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkType.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkType.java
@@ -146,64 +146,62 @@ public abstract class SkylarkType implements Serializable {
// Notable types
/** A singleton for the TOP type, that at analysis time means that any type is possible. */
- public static final Simple TOP = new Top();
+ @AutoCodec public static final Simple TOP = new Top();
/** A singleton for the BOTTOM type, that contains no element */
- public static final Simple BOTTOM = new Bottom();
+ @AutoCodec public static final Simple BOTTOM = new Bottom();
/** NONE, the Unit type, isomorphic to Void, except its unique element prints as None */
// Note that we currently consider at validation time that None is in every type,
// by declaring its type as TOP instead of NONE, even though at runtime,
// we reject None from all types but NONE, and in particular from e.g. lists of Files.
// TODO(bazel-team): resolve this inconsistency, one way or the other.
- public static final Simple NONE = Simple.forClass(Runtime.NoneType.class);
+ @AutoCodec public static final Simple NONE = Simple.forClass(Runtime.NoneType.class);
/** The STRING type, for strings */
- public static final Simple STRING = Simple.forClass(String.class);
+ @AutoCodec public static final Simple STRING = Simple.forClass(String.class);
/** The INTEGER type, for 32-bit signed integers */
- public static final Simple INT = Simple.forClass(Integer.class);
+ @AutoCodec public static final Simple INT = Simple.forClass(Integer.class);
/** The BOOLEAN type, that contains TRUE and FALSE */
- public static final Simple BOOL = Simple.forClass(Boolean.class);
+ @AutoCodec public static final Simple BOOL = Simple.forClass(Boolean.class);
/** The FUNCTION type, that contains all functions, otherwise dynamically typed at call-time */
+ @AutoCodec
public static final SkylarkFunctionType FUNCTION = new SkylarkFunctionType("unknown", TOP);
/** The DICT type, that contains SkylarkDict */
- public static final Simple DICT = Simple.forClass(SkylarkDict.class);
+ @AutoCodec public static final Simple DICT = Simple.forClass(SkylarkDict.class);
/** The SEQUENCE type, that contains lists and tuples */
// TODO(bazel-team): this was added for backward compatibility with the BUILD language,
// that doesn't make a difference between list and tuple, so that functions can be declared
// that keep not making the difference. Going forward, though, we should investigate whether
// we ever want to use this type, and if not, make sure no existing client code uses it.
- public static final Simple SEQUENCE = Simple.forClass(SkylarkList.class);
+ @AutoCodec public static final Simple SEQUENCE = Simple.forClass(SkylarkList.class);
/** The LIST type, that contains all MutableList-s */
- public static final Simple LIST = Simple.forClass(MutableList.class);
+ @AutoCodec public static final Simple LIST = Simple.forClass(MutableList.class);
/** The TUPLE type, that contains all Tuple-s */
- public static final Simple TUPLE = Simple.forClass(Tuple.class);
+ @AutoCodec public static final Simple TUPLE = Simple.forClass(Tuple.class);
/** The STRING_LIST type, a MutableList of strings */
- public static final SkylarkType STRING_LIST = Combination.of(LIST, STRING);
+ @AutoCodec public static final SkylarkType STRING_LIST = Combination.of(LIST, STRING);
/** The INT_LIST type, a MutableList of integers */
- public static final SkylarkType INT_LIST = Combination.of(LIST, INT);
+ @AutoCodec public static final SkylarkType INT_LIST = Combination.of(LIST, INT);
/** The SET type, that contains all SkylarkNestedSet-s, and the generic combinator for them */
- public static final Simple SET = Simple.forClass(SkylarkNestedSet.class);
+ @AutoCodec public static final Simple SET = Simple.forClass(SkylarkNestedSet.class);
// Common subclasses of SkylarkType
/** the Top type contains all objects */
- @AutoCodec
- @VisibleForSerialization
- static class Top extends Simple {
+ private static class Top extends Simple {
- @VisibleForSerialization
- Top() {
+ private Top() {
super(Object.class);
}
@@ -219,12 +217,9 @@ public abstract class SkylarkType implements Serializable {
}
/** the Bottom type contains no element */
- @AutoCodec
- @VisibleForSerialization
- static class Bottom extends Simple {
+ private static class Bottom extends Simple {
- @VisibleForSerialization
- Bottom() {
+ private Bottom() {
super(Empty.class);
}
@@ -237,12 +232,11 @@ public abstract class SkylarkType implements Serializable {
}
/** a Simple type contains the instance of a Java class */
- @AutoCodec
- public static class Simple extends SkylarkType {
+ @VisibleForSerialization
+ static class Simple extends SkylarkType {
private final Class<?> type;
- @VisibleForSerialization
- Simple(Class<?> type) {
+ private Simple(Class<?> type) {
this.type = type;
}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SliceExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/SliceExpression.java
index f4074e9499..54c194a021 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/SliceExpression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/SliceExpression.java
@@ -14,13 +14,11 @@
package com.google.devtools.build.lib.syntax;
import com.google.devtools.build.lib.events.Location;
-import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import java.io.IOException;
import java.util.List;
import javax.annotation.Nullable;
/** Syntax node for a slice expression, e.g. obj[:len(obj):2]. */
-@AutoCodec
public final class SliceExpression extends Expression {
private final Expression object;
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/StringLiteral.java b/src/main/java/com/google/devtools/build/lib/syntax/StringLiteral.java
index db1c23a289..b88bbb1e0d 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/StringLiteral.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/StringLiteral.java
@@ -13,11 +13,9 @@
// limitations under the License.
package com.google.devtools.build.lib.syntax;
-import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import java.io.IOException;
/** Syntax node for a string literal. */
-@AutoCodec
public final class StringLiteral extends Expression {
String value;
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/UnaryOperatorExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/UnaryOperatorExpression.java
index 08fcf457b9..824333a9d8 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/UnaryOperatorExpression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/UnaryOperatorExpression.java
@@ -14,11 +14,9 @@
package com.google.devtools.build.lib.syntax;
import com.google.devtools.build.lib.events.Location;
-import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import java.io.IOException;
/** Syntax node for a unary operator expression. */
-@AutoCodec
public final class UnaryOperatorExpression extends Expression {
private final UnaryOperator operator;
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/UserDefinedFunction.java b/src/main/java/com/google/devtools/build/lib/syntax/UserDefinedFunction.java
index fb60ca6df0..eda6c3d0b8 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/UserDefinedFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/UserDefinedFunction.java
@@ -18,7 +18,6 @@ import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.profiler.Profiler;
import com.google.devtools.build.lib.profiler.ProfilerTask;
-import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
import com.google.devtools.build.lib.syntax.Environment.LexicalFrame;
@@ -26,7 +25,6 @@ import com.google.devtools.build.lib.syntax.Environment.LexicalFrame;
* The actual function registered in the environment. This function is defined in the parsed code
* using {@link FunctionDefStatement}.
*/
-@AutoCodec
public class UserDefinedFunction extends BaseFunction {
private final ImmutableList<Statement> statements;