Allow custom Package serialization logic to be injected. Also fix incorrect comment in PackageSerializer.
--
MOS_MIGRATED_REVID=103693274
diff --git a/src/main/java/com/google/devtools/build/lib/packages/Package.java b/src/main/java/com/google/devtools/build/lib/packages/Package.java
index b3f75d9..042a511 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/Package.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/Package.java
@@ -238,7 +238,7 @@
private void writeObject(ObjectOutputStream out) {
try {
- PackageSerializer.DEFAULT.serialize(this, out);
+ new PackageSerializer().serialize(this, out);
} catch (IOException ioe) {
throw new IllegalStateException(ioe);
}
diff --git a/src/main/java/com/google/devtools/build/lib/packages/PackageSerializer.java b/src/main/java/com/google/devtools/build/lib/packages/PackageSerializer.java
index cfc90d5..51f2077 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/PackageSerializer.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/PackageSerializer.java
@@ -34,6 +34,7 @@
import static com.google.devtools.build.lib.syntax.Type.STRING_LIST;
import static com.google.devtools.build.lib.syntax.Type.STRING_LIST_DICT;
+import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.cmdline.Label;
@@ -41,6 +42,7 @@
import com.google.devtools.build.lib.packages.License.DistributionType;
import com.google.devtools.build.lib.packages.MakeEnvironment.Binding;
import com.google.devtools.build.lib.query2.proto.proto2api.Build;
+import com.google.devtools.build.lib.query2.proto.proto2api.Build.Rule.Builder;
import com.google.devtools.build.lib.syntax.GlobCriteria;
import com.google.devtools.build.lib.syntax.GlobList;
@@ -56,8 +58,34 @@
* Functionality to serialize loaded packages.
*/
public class PackageSerializer {
+ /** Allows custom serialization logic to be injected. */
+ public interface PackageSerializationEnvironment {
+ /**
+ * Called right before the given builder's {@link Build.Rule.Builder#build} method is called.
+ * Implementations can use this hook to serialize additional data in the proto.
+ */
+ void maybeSerializeAdditionalDataForRule(Rule rule, Build.Rule.Builder builder);
+ }
- public static final PackageSerializer DEFAULT = new PackageSerializer();
+ // Workaround for Java serialization making it tough to pass in a serialization environment
+ // manually.
+ // volatile is needed to ensure that the objects are published safely.
+ public static volatile PackageSerializationEnvironment defaultPackageSerializationEnvironment =
+ new PackageSerializationEnvironment() {
+ @Override
+ public void maybeSerializeAdditionalDataForRule(Rule rule, Builder builder) {
+ }
+ };
+
+ private final PackageSerializationEnvironment env;
+
+ public PackageSerializer() {
+ this(defaultPackageSerializationEnvironment);
+ }
+
+ public PackageSerializer(PackageSerializationEnvironment env) {
+ this.env = Preconditions.checkNotNull(env);
+ }
/**
* Get protocol buffer representation of the specified attribute.
@@ -69,7 +97,8 @@
*/
public static Build.Attribute getAttributeProto(Attribute attr, Iterable<Object> values,
Boolean explicitlySpecified) {
- return DEFAULT.serializeAttribute(attr, values, explicitlySpecified, /*includeGlobs=*/ false);
+ return new PackageSerializer().serializeAttribute(attr, values, explicitlySpecified,
+ /*includeGlobs=*/ false);
}
/**
@@ -446,6 +475,7 @@
serializeAttribute(attribute, getAttributeValues(rule, attribute),
rule.isAttributeValueExplicitlySpecified(attribute), /*includeGlobs=*/ true));
}
+ env.maybeSerializeAdditionalDataForRule(rule, builder);
return Build.Target.newBuilder()
.setType(Build.Target.Discriminator.RULE)
@@ -516,7 +546,7 @@
if (target instanceof InputFile) {
emitTarget(serializeInputFile((InputFile) target), out);
} else if (target instanceof OutputFile) {
- // Output files are ignored; they are recorded in rules.
+ // Output files are not serialized; they are recreated by the RuleClass on deserialization.
} else if (target instanceof PackageGroup) {
emitTarget(serializePackageGroup((PackageGroup) target), out);
} else if (target instanceof Rule) {