diff --git a/.github/workflows/test_java.yml b/.github/workflows/test_java.yml index a9abfacaec0b1..e0cb69558f029 100644 --- a/.github/workflows/test_java.yml +++ b/.github/workflows/test_java.yml @@ -22,19 +22,19 @@ jobs: image: us-docker.pkg.dev/protobuf-build/containers/test/linux/java:8-1fdbb997433cb22c1e49ef75ad374a8d6bb88702 # TODO: b/318555165 - enable the layering check. Currently it does # not work correctly with the toolchain in this Docker image. - targets: //java/... //java/internal:java_version --features=-layering_check + targets: //java/... //java/internal:java_version //compatibility/... --features=-layering_check - name: OpenJDK 11 version: '11' image: us-docker.pkg.dev/protobuf-build/containers/test/linux/java:11-1fdbb997433cb22c1e49ef75ad374a8d6bb88702 - targets: //java/... //java/internal:java_version + targets: //java/... //java/internal:java_version //compatibility/... - name: OpenJDK 17 version: '17' image: us-docker.pkg.dev/protobuf-build/containers/test/linux/java:17-1fdbb997433cb22c1e49ef75ad374a8d6bb88702 - targets: //java/... //java/internal:java_version + targets: //java/... //java/internal:java_version //compatibility/... - name: aarch64 version: 'aarch64' image: us-docker.pkg.dev/protobuf-build/containers/test/linux/emulation:aarch64-63dd26c0c7a808d92673a3e52e848189d4ab0f17 - targets: //java/... //src/google/protobuf/compiler:protoc_aarch64_test + targets: //java/... //compatibility/... //src/google/protobuf/compiler:protoc_aarch64_test name: Linux ${{ matrix.name }} runs-on: ubuntu-latest diff --git a/WORKSPACE b/WORKSPACE index 0e620deda3885..26bb91dc78a1c 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -225,3 +225,18 @@ crates_repository( load("@crate_index//:defs.bzl", "crate_repositories") crate_repositories() + +# For testing runtime against old gencode from a previous major version. +http_archive( + name = "com_google_protobuf_v25.0", + strip_prefix = "protobuf-25.0", + url = "https://github.com/protocolbuffers/protobuf/releases/download/v25.0/protobuf-25.0.tar.gz", +) + +# Needed as a dependency of @com_google_protobuf_v25.x, which was before +# utf8_range was merged in. +http_archive( + name = "utf8_range", + strip_prefix = "utf8_range-d863bc33e15cba6d873c878dcca9e6fe52b2f8cb", + url = "https://github.com/protocolbuffers/utf8_range/archive/d863bc33e15cba6d873c878dcca9e6fe52b2f8cb.zip", +) diff --git a/compatibility/BUILD.bazel b/compatibility/BUILD.bazel new file mode 100644 index 0000000000000..d55f61956e464 --- /dev/null +++ b/compatibility/BUILD.bazel @@ -0,0 +1,19 @@ +# Simple build tests for compatibility of gencode from previous major versions +# with the current runtime. +# +# To add more test cases in Java, use java_runtime_conformance as below, and add +# the corresponding http_archive in the WORKSPACE file for the version. + +load("//compatibility:runtime_conformance.bzl", "java_runtime_conformance") + +# main gencode builds with main runtime as a proof of concept. +java_runtime_conformance( + name = "java_conformance_main", + gencode_version = "main", +) + +# Generates a build_test named "conformance_v3.25.0" +java_runtime_conformance( + name = "java_conformance_v3.25.0", + gencode_version = "3.25.0", +) diff --git a/compatibility/runtime_conformance.bzl b/compatibility/runtime_conformance.bzl new file mode 100644 index 0000000000000..7f1d41641299e --- /dev/null +++ b/compatibility/runtime_conformance.bzl @@ -0,0 +1,53 @@ +"""Provides a rule to generate a conformance test for a given version of the gencode.""" + +load("@bazel_skylib//rules:build_test.bzl", "build_test") + +def java_runtime_conformance(name, gencode_version, tags = []): + """Generates a conformance test for the given version of the runtime. + + For example, runtime_conformance("3.19.4") will generate a build test named "conformance_v3.19.4" + that will fail if the runtime at that version fails to compile the unittest proto. + + Args: + name: The name of the test. + gencode_version: The version of the runtime to test. + tags: Any tags to apply to the generated test. + """ + + if gencode_version == "main": + protoc = "//:protoc" + else: + minor = gencode_version[gencode_version.find(".") + 1:] + protoc = Label("@com_google_protobuf_v%s//:protoc" % minor) + + gencode = [ + "v%s/protobuf_unittest/UnittestProto.java" % gencode_version, + "v%s/com/google/protobuf/test/UnittestImport.java" % gencode_version, + "v%s/com/google/protobuf/test/UnittestImportPublic.java" % gencode_version, + ] + native.genrule( + name = "unittest_proto_gencode_v" + gencode_version, + srcs = [ + "//src/google/protobuf:unittest_proto_srcs", + ], + outs = gencode, + cmd = "$(location %s) " % protoc + + "$(locations //src/google/protobuf:unittest_proto_srcs) " + + " -Isrc/ --java_out=$(@D)/v%s" % gencode_version, + tools = [protoc], + ) + + conformance_name = "conformance_v" + gencode_version + conformance_lib_name = conformance_name + "_lib" + native.java_library( + name = conformance_lib_name, + srcs = gencode, + deps = ["//java/core"], + tags = tags, + ) + + build_test( + name = name, + targets = [":" + conformance_lib_name], + tags = tags, + ) diff --git a/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java b/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java new file mode 100644 index 0000000000000..90714958661ac --- /dev/null +++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java @@ -0,0 +1,83 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2024 Google LLC. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +package com.google.protobuf; + +import java.util.List; + +/** + * Stub for GeneratedMessageV3 wrapping GeneratedMessage for compatibility with older gencode. + * + * @deprecated This class is deprecated, and slated for removal in the next Java breaking change + * (5.x in 2025 Q1). Users should update gencode to >= 4.26.x which uses GeneratedMessage + * instead of GeneratedMessageV3. + */ +@Deprecated +public abstract class GeneratedMessageV3 extends GeneratedMessage { + private static final long serialVersionUID = 1L; + + protected GeneratedMessageV3() { + super(); + } + + protected GeneratedMessageV3(Builder builder) { + super(builder); + } + + /** + * Stub for GeneratedMessageV3.ExtendableBuilder wrapping GeneratedMessage.ExtendableBuilder for + * compatibility with older gencode. + * + * @deprecated This class is deprecated, and slated for removal in the next Java breaking change + * (5.x in 2025 Q1). Users should update gencode to >= 4.26.x which uses + * GeneratedMessage.ExtendableBuilder instead of GeneratedMessageV3.ExtendableBuilder. + */ + @Deprecated + public abstract static class ExtendableBuilder< + MessageT extends ExtendableMessage, + BuilderT extends ExtendableBuilder> + extends GeneratedMessage.ExtendableBuilder + implements GeneratedMessage.ExtendableMessageOrBuilder { + protected ExtendableBuilder() { + super(); + } + + protected ExtendableBuilder(BuilderParent parent) { + super(parent); + } + + // Support old gencode override method removed in + // https://github.com/protocolbuffers/protobuf/commit/7bff169d32710b143951ec6ce2c4ea9a56e2ad24 + public BuilderT setExtension( + final GeneratedMessage.GeneratedExtension extension, final T value) { + return setExtension((ExtensionLite) extension, value); + } + + // Support old gencode override method removed in + // https://github.com/protocolbuffers/protobuf/commit/7bff169d32710b143951ec6ce2c4ea9a56e2ad24 + public BuilderT setExtension( + final GeneratedMessage.GeneratedExtension> extension, + final int index, + final T value) { + return setExtension((ExtensionLite>) extension, index, value); + } + + // Support old gencode override method removed in + // https://github.com/protocolbuffers/protobuf/commit/7bff169d32710b143951ec6ce2c4ea9a56e2ad24 + public BuilderT addExtension( + final GeneratedMessage.GeneratedExtension> extension, final T value) { + return addExtension((ExtensionLite>) extension, value); + } + + // Support old gencode override method removed in + // https://github.com/protocolbuffers/protobuf/commit/7bff169d32710b143951ec6ce2c4ea9a56e2ad24 + public BuilderT clearExtension( + final GeneratedMessage.GeneratedExtension extension) { + return clearExtension((ExtensionLite) extension); + } + } +} diff --git a/java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilderV3.java b/java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilderV3.java new file mode 100644 index 0000000000000..14a47a5d465a0 --- /dev/null +++ b/java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilderV3.java @@ -0,0 +1,34 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2024 Google LLC. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +package com.google.protobuf; + +import java.util.List; + +/** + * Stub for RepeatedFieldBuilderV3 wrapping RepeatedFieldBuilder for compatibility with older + * gencode. + * + * @deprecated This class is deprecated, and slated for removal in the next breaking change. Users + * should update gencode to >= 4.26.x which replaces RepeatedFieldBuilderV3 with + * RepeatedFieldBuilder. + */ +@Deprecated +public class RepeatedFieldBuilderV3< + MType extends GeneratedMessage, + BType extends GeneratedMessage.Builder, + IType extends MessageOrBuilder> + extends RepeatedFieldBuilder { + + public RepeatedFieldBuilderV3( + List messages, + boolean isMessagesListMutable, + GeneratedMessage.BuilderParent parent, + boolean isClean) { + super(messages, isMessagesListMutable, parent, isClean); + } +} diff --git a/java/core/src/main/java/com/google/protobuf/SingleFieldBuilderV3.java b/java/core/src/main/java/com/google/protobuf/SingleFieldBuilderV3.java new file mode 100644 index 0000000000000..3c6b151de25ba --- /dev/null +++ b/java/core/src/main/java/com/google/protobuf/SingleFieldBuilderV3.java @@ -0,0 +1,28 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2024 Google LLC. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +package com.google.protobuf; + +/** + * Stub for SingleFieldBuilderV3 wrapping SingleFieldBuilder for compatibility with older gencode. + * + * @deprecated This class is deprecated, and slated for removal in the next breaking change. Users + * should update gencode to >= 4.26.x which replaces SingleFieldBuilderV3 with + * SingleFieldBuilder. + */ +@Deprecated +public class SingleFieldBuilderV3< + MType extends GeneratedMessage, + BType extends GeneratedMessage.Builder, + IType extends MessageOrBuilder> + extends SingleFieldBuilder { + + public SingleFieldBuilderV3( + MType message, GeneratedMessage.BuilderParent parent, boolean isClean) { + super(message, parent, isClean); + } +} diff --git a/src/google/protobuf/BUILD.bazel b/src/google/protobuf/BUILD.bazel index 917d9d35d08bb..358a2e94b6b1f 100644 --- a/src/google/protobuf/BUILD.bazel +++ b/src/google/protobuf/BUILD.bazel @@ -840,6 +840,16 @@ filegroup( visibility = ["//:__subpackages__"], ) +filegroup( + name = "unittest_proto_srcs", + srcs = [ + "unittest.proto", + "unittest_import.proto", + "unittest_import_public.proto", + ], + visibility = ["//:__subpackages__"], +) + filegroup( name = "test_proto_editions_srcs", srcs = [