aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib
diff options
context:
space:
mode:
authorGravatar janakr <janakr@google.com>2018-03-28 11:42:37 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-03-28 11:43:53 -0700
commit84efb0967b00cc91ad74c0f263bbeedd98abb03c (patch)
tree5493530f63ddd624a96ea46b969b0a8c14c38fd7 /src/main/java/com/google/devtools/build/lib
parent9c4fa4a8e987ab4b1c90ab5ce2683bf21b9624fe (diff)
Add codecs needed to fully serialize Attributes.
PiperOrigin-RevId: 190805577
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib')
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkLateBoundDefault.java27
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/PackageValue.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/serialization/ClassCodec.java37
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/serialization/MethodCodec.java65
4 files changed, 121 insertions, 10 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkLateBoundDefault.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkLateBoundDefault.java
index 52d316259e..93fe96e32e 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkLateBoundDefault.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkLateBoundDefault.java
@@ -26,6 +26,7 @@ import com.google.devtools.build.lib.packages.Attribute.AbstractLabelLateBoundDe
import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault;
import com.google.devtools.build.lib.packages.AttributeMap;
import com.google.devtools.build.lib.packages.Rule;
+import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
@@ -47,6 +48,7 @@ import javax.annotation.concurrent.Immutable;
* target configuration.
*/
@Immutable
+@AutoCodec
public class SkylarkLateBoundDefault<FragmentT> extends AbstractLabelLateBoundDefault<FragmentT>
implements SkylarkValue {
@@ -82,13 +84,26 @@ public class SkylarkLateBoundDefault<FragmentT> extends AbstractLabelLateBoundDe
private SkylarkLateBoundDefault(SkylarkConfigurationField annotation,
Class<FragmentT> fragmentClass, String fragmentName, Method method, String toolsRepository) {
- super(false /* don't use host configuration */,
+ this(
+ getDefaultLabel(annotation, toolsRepository),
fragmentClass,
- getDefaultLabel(annotation, toolsRepository));
+ method,
+ fragmentName,
+ annotation.name());
+ }
+ @AutoCodec.VisibleForSerialization
+ @AutoCodec.Instantiator
+ SkylarkLateBoundDefault(
+ Label defaultVal,
+ Class<FragmentT> fragmentClass,
+ Method method,
+ String fragmentName,
+ String fragmentFieldName) {
+ super(/*useHostConfiguration=*/ false, fragmentClass, defaultVal);
this.method = method;
this.fragmentName = fragmentName;
- this.fragmentFieldName = annotation.name();
+ this.fragmentFieldName = fragmentFieldName;
}
/**
@@ -111,6 +126,12 @@ public class SkylarkLateBoundDefault<FragmentT> extends AbstractLabelLateBoundDe
printer.format("<late-bound default>");
}
+ /** For use by @AutoCodec since the {@link #defaultValue} field is hard for it to process. */
+ @AutoCodec.VisibleForSerialization
+ Label getDefaultVal() {
+ return getDefault();
+ }
+
/**
* An exception thrown if a user specifies an invalid configuration field identifier.
*
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PackageValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/PackageValue.java
index ba1962335b..565e4f1290 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/PackageValue.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/PackageValue.java
@@ -30,7 +30,7 @@ import java.util.ArrayList;
import java.util.List;
/** A Skyframe value representing a package. */
-@AutoCodec
+@AutoCodec(memoization = AutoCodec.Memoization.START_MEMOIZING)
@Immutable
@ThreadSafe
public class PackageValue implements NotComparableSkyValue {
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/ClassCodec.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/ClassCodec.java
index e3675ee9e8..d21f928354 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/ClassCodec.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/ClassCodec.java
@@ -14,6 +14,8 @@
package com.google.devtools.build.lib.skyframe.serialization;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableBiMap;
import com.google.protobuf.CodedInputStream;
import com.google.protobuf.CodedOutputStream;
import java.io.IOException;
@@ -29,17 +31,40 @@ class ClassCodec implements ObjectCodec<Class<?>> {
@Override
public void serialize(SerializationContext context, Class<?> obj, CodedOutputStream codedOut)
throws SerializationException, IOException {
- context.serialize(obj.getName(), codedOut);
+ codedOut.writeBoolNoTag(obj.isPrimitive());
+ if (obj.isPrimitive()) {
+ codedOut.writeInt32NoTag(Preconditions.checkNotNull(PRIMITIVE_CLASS_INDEX_MAP.get(obj), obj));
+ } else {
+ context.serialize(obj.getName(), codedOut);
+ }
}
@Override
public Class<?> deserialize(DeserializationContext context, CodedInputStream codedIn)
throws SerializationException, IOException {
- String className = context.deserialize(codedIn);
- try {
- return Class.forName(className);
- } catch (ClassNotFoundException e) {
- throw new SerializationException("Couldn't find class for " + className, e);
+ boolean isPrimitive = codedIn.readBool();
+ if (isPrimitive) {
+ return PRIMITIVE_CLASS_INDEX_MAP.inverse().get(codedIn.readInt32());
+ } else {
+ String className = context.deserialize(codedIn);
+ try {
+ return Class.forName(className);
+ } catch (ClassNotFoundException e) {
+ throw new SerializationException("Couldn't find class for " + className, e);
+ }
}
}
+
+ private static final ImmutableBiMap<Class<?>, Integer> PRIMITIVE_CLASS_INDEX_MAP =
+ ImmutableBiMap.<Class<?>, Integer>builder()
+ .put(byte.class, 1)
+ .put(short.class, 2)
+ .put(int.class, 3)
+ .put(long.class, 4)
+ .put(char.class, 5)
+ .put(float.class, 6)
+ .put(double.class, 7)
+ .put(boolean.class, 8)
+ .put(void.class, 9)
+ .build();
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/MethodCodec.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/MethodCodec.java
new file mode 100644
index 0000000000..5fc68d5db4
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/MethodCodec.java
@@ -0,0 +1,65 @@
+// 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.lang.reflect.Method;
+import java.util.Arrays;
+
+/** {@link ObjectCodec} for {@link Method}. */
+class MethodCodec implements ObjectCodec<Method> {
+ @Override
+ public Class<Method> getEncodedClass() {
+ return Method.class;
+ }
+
+ @Override
+ public void serialize(SerializationContext context, Method obj, CodedOutputStream codedOut)
+ throws SerializationException, IOException {
+ context.serialize(obj.getDeclaringClass(), codedOut);
+ context.serialize(obj.getName(), codedOut);
+ Class<?>[] parameterTypes = obj.getParameterTypes();
+ codedOut.writeInt32NoTag(parameterTypes.length);
+ for (Class<?> parameter : parameterTypes) {
+ context.serialize(parameter, codedOut);
+ }
+ }
+
+ @Override
+ public Method deserialize(DeserializationContext context, CodedInputStream codedIn)
+ throws SerializationException, IOException {
+ Class<?> clazz = context.deserialize(codedIn);
+ String name = context.deserialize(codedIn);
+
+ Class<?>[] parameters = new Class<?>[codedIn.readInt32()];
+ for (int i = 0; i < parameters.length; i++) {
+ parameters[i] = context.deserialize(codedIn);
+ }
+ try {
+ return clazz.getDeclaredMethod(name, parameters);
+ } catch (NoSuchMethodException e) {
+ throw new SerializationException(
+ "Couldn't get method "
+ + name
+ + " in "
+ + clazz
+ + " with parameters "
+ + Arrays.toString(parameters),
+ e);
+ }
+ }
+}