diff options
author | 2017-12-11 15:32:29 -0800 | |
---|---|---|
committer | 2017-12-11 15:33:56 -0800 | |
commit | ab5f233e572ed5d774a2830f82e3142672b4728d (patch) | |
tree | 2bbfd9eaf55f07d6cb3961a140d248bfd101bbdf /src/main/java/com/google/devtools/build/lib/cmdline | |
parent | 66693e77d0df7ab3ea1f4e8a3b7b66fabbc2af77 (diff) |
Removes skyframe/serialization's dependency on cmdline and vfs. Instead, make cmdline and vfs depend on serialization. This allows a class to have a pointer to its codec, which simplifies automatic recursive composite codecs.
PiperOrigin-RevId: 178683500
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/cmdline')
4 files changed, 176 insertions, 0 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/cmdline/BUILD b/src/main/java/com/google/devtools/build/lib/cmdline/BUILD index 306eba1bec..2883d4277a 100644 --- a/src/main/java/com/google/devtools/build/lib/cmdline/BUILD +++ b/src/main/java/com/google/devtools/build/lib/cmdline/BUILD @@ -21,9 +21,11 @@ java_library( "//src/main/java/com/google/devtools/build/lib:skylarkinterface", "//src/main/java/com/google/devtools/build/lib:util", "//src/main/java/com/google/devtools/build/lib/concurrent", + "//src/main/java/com/google/devtools/build/lib/skyframe/serialization", "//src/main/java/com/google/devtools/build/lib/vfs:pathfragment", "//src/main/java/com/google/devtools/build/skyframe:skyframe-objects", "//third_party:guava", "//third_party:jsr305", + "//third_party/protobuf:protobuf_java", ], ) diff --git a/src/main/java/com/google/devtools/build/lib/cmdline/LabelCodec.java b/src/main/java/com/google/devtools/build/lib/cmdline/LabelCodec.java new file mode 100644 index 0000000000..cda83dbf82 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/cmdline/LabelCodec.java @@ -0,0 +1,50 @@ +// Copyright 2017 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.cmdline; + +import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec; +import com.google.devtools.build.lib.skyframe.serialization.SerializationException; +import com.google.devtools.build.lib.skyframe.serialization.strings.StringCodecs; +import com.google.protobuf.CodedInputStream; +import com.google.protobuf.CodedOutputStream; +import java.io.IOException; + +/** Custom serialization logic for {@link Label}s. */ +public class LabelCodec implements ObjectCodec<Label> { + public static final LabelCodec INSTANCE = new LabelCodec(); + + // TODO(michajlo): Share single instance of package id codec among all the codecs. + private final PackageIdentifierCodec packageIdCodec = new PackageIdentifierCodec(); + private final ObjectCodec<String> stringCodec = StringCodecs.asciiOptimized(); + + @Override + public Class<Label> getEncodedClass() { + return Label.class; + } + + @Override + public void serialize(Label label, CodedOutputStream codedOut) + throws IOException, SerializationException { + packageIdCodec.serialize(label.getPackageIdentifier(), codedOut); + stringCodec.serialize(label.getName(), codedOut); + } + + @Override + public Label deserialize(CodedInputStream codedIn) throws SerializationException, IOException { + PackageIdentifier packageId = packageIdCodec.deserialize(codedIn); + String name = stringCodec.deserialize(codedIn); + return Label.createUnvalidated(packageId, name); + } +} diff --git a/src/main/java/com/google/devtools/build/lib/cmdline/PackageIdentifierCodec.java b/src/main/java/com/google/devtools/build/lib/cmdline/PackageIdentifierCodec.java new file mode 100644 index 0000000000..8107714e33 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/cmdline/PackageIdentifierCodec.java @@ -0,0 +1,50 @@ +// Copyright 2017 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.cmdline; + +import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec; +import com.google.devtools.build.lib.skyframe.serialization.SerializationException; +import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.PathFragmentCodec; +import com.google.protobuf.CodedInputStream; +import com.google.protobuf.CodedOutputStream; +import java.io.IOException; + +/** Custom serialization logic for {@link PackageIdentifier}s. */ +public class PackageIdentifierCodec implements ObjectCodec<PackageIdentifier> { + + private final RepositoryNameCodec repoNameCodec = new RepositoryNameCodec(); + private final PathFragmentCodec pathFragmentCodec = new PathFragmentCodec(); + + @Override + public Class<PackageIdentifier> getEncodedClass() { + return PackageIdentifier.class; + } + + @Override + public void serialize(PackageIdentifier pkgId, CodedOutputStream codedOut) + throws IOException, SerializationException { + repoNameCodec.serialize(pkgId.getRepository(), codedOut); + pathFragmentCodec.serialize(pkgId.getPackageFragment(), codedOut); + } + + @Override + public PackageIdentifier deserialize(CodedInputStream codedIn) + throws IOException, SerializationException { + RepositoryName repoName = repoNameCodec.deserialize(codedIn); + PathFragment pathFragment = pathFragmentCodec.deserialize(codedIn); + return PackageIdentifier.create(repoName, pathFragment); + } +} diff --git a/src/main/java/com/google/devtools/build/lib/cmdline/RepositoryNameCodec.java b/src/main/java/com/google/devtools/build/lib/cmdline/RepositoryNameCodec.java new file mode 100644 index 0000000000..67a6c55eab --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/cmdline/RepositoryNameCodec.java @@ -0,0 +1,74 @@ +// Copyright 2017 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.cmdline; + +import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec; +import com.google.devtools.build.lib.skyframe.serialization.SerializationException; +import com.google.protobuf.ByteString; +import com.google.protobuf.CodedInputStream; +import com.google.protobuf.CodedOutputStream; +import java.io.IOException; + +/** Custom serialization for {@link RepositoryName}. */ +public class RepositoryNameCodec implements ObjectCodec<RepositoryName> { + + @Override + public Class<RepositoryName> getEncodedClass() { + return RepositoryName.class; + } + + @Override + public void serialize(RepositoryName repoName, CodedOutputStream codedOut) throws IOException { + boolean isMain = repoName.isMain(); + // Main is by far the most common. Use boolean to short-circuit string encoding on + // serialization and byte[]/ByteString creation on deserialization. + codedOut.writeBoolNoTag(isMain); + if (!isMain) { + codedOut.writeStringNoTag(repoName.getName()); + } + } + + @Override + public RepositoryName deserialize(CodedInputStream codedIn) + throws SerializationException, IOException { + boolean isMain = codedIn.readBool(); + if (isMain) { + return RepositoryName.MAIN; + } + try { + // We can read the string we wrote back as bytes to avoid string decoding/copying. + return deserializeRepoName(codedIn.readBytes()); + } catch (LabelSyntaxException e) { + throw new SerializationException("Failed to deserialize RepositoryName", e); + } + } + + private static final ByteString DEFAULT_REPOSITORY = + ByteString.copyFromUtf8(RepositoryName.DEFAULT.getName()); + private static final ByteString MAIN_REPOSITORY = + ByteString.copyFromUtf8(RepositoryName.MAIN.getName()); + + public static RepositoryName deserializeRepoName(ByteString repoNameBytes) + throws LabelSyntaxException { + // We expect MAIN_REPOSITORY the vast majority of the time, so check for it first. + if (repoNameBytes.equals(MAIN_REPOSITORY)) { + return RepositoryName.MAIN; + } else if (repoNameBytes.equals(DEFAULT_REPOSITORY)) { + return RepositoryName.DEFAULT; + } else { + return RepositoryName.create(repoNameBytes.toStringUtf8()); + } + } +} |