From 0404e66d8beec8dc170bc3e71ebf21fb4f42fa46 Mon Sep 17 00:00:00 2001 From: Rachel Goldfinger Date: Mon, 29 Dec 2025 07:38:38 -0800 Subject: [PATCH] Add conformance test for edition unstable PiperOrigin-RevId: 850054867 --- cmake/conformance.cmake | 6 ++ conformance/BUILD | 9 +++ conformance/ConformanceJava.java | 6 ++ conformance/ConformanceJavaLite.java | 6 ++ conformance/binary_json_conformance_suite.cc | 19 ++++++ conformance/binary_json_conformance_suite.h | 2 + conformance/conformance.proto | 3 +- conformance/conformance_cpp.cc | 3 + conformance/conformance_objc.m | 6 ++ conformance/conformance_php.php | 3 + conformance/conformance_python.py | 6 ++ conformance/conformance_rust.rs | 4 ++ conformance/conformance_test.cc | 2 + conformance/naming.h | 2 + conformance/naming_test.cc | 4 ++ conformance/ruby/BUILD | 14 +++++ conformance/ruby/conformance_ruby.rb | 1 + conformance/test_protos/BUILD | 42 ++++++++++++- .../test_messages_edition_unstable.proto | 61 +++++++++++++++++++ conformance/text_format_conformance_suite.cc | 5 ++ csharp/generate_protos.sh | 1 + .../Google.Protobuf.Conformance/Program.cs | 11 ++++ .../Reflection/FeatureSetDescriptor.cs | 2 +- .../java/com/google/protobuf/Descriptors.java | 3 +- python/google/protobuf/descriptor_pool.py | 5 +- .../protobuf/compiler/code_generator.cc | 5 +- upb/reflection/file_def.c | 2 +- 27 files changed, 226 insertions(+), 7 deletions(-) create mode 100644 conformance/test_protos/test_messages_edition_unstable.proto diff --git a/cmake/conformance.cmake b/cmake/conformance.cmake index fbdda176d8..3e6ef4b429 100644 --- a/cmake/conformance.cmake +++ b/cmake/conformance.cmake @@ -38,12 +38,16 @@ add_custom_command( ${protobuf_BINARY_DIR}/conformance/conformance.pb.cc ${protobuf_BINARY_DIR}/conformance/test_protos/test_messages_edition2023.pb.h ${protobuf_BINARY_DIR}/conformance/test_protos/test_messages_edition2023.pb.cc + ${protobuf_BINARY_DIR}/conformance/test_protos/test_messages_edition_unstable.pb.h + ${protobuf_BINARY_DIR}/conformance/test_protos/test_messages_edition_unstable.pb.cc DEPENDS ${protobuf_PROTOC_EXE} ${protobuf_SOURCE_DIR}/conformance/conformance.proto ${protobuf_SOURCE_DIR}/conformance/test_protos/test_messages_edition2023.proto + ${protobuf_SOURCE_DIR}/conformance/test_protos/test_messages_edition_unstable.proto COMMAND ${protobuf_PROTOC_EXE} ${protobuf_SOURCE_DIR}/conformance/conformance.proto ${protobuf_SOURCE_DIR}/conformance/test_protos/test_messages_edition2023.proto + ${protobuf_SOURCE_DIR}/conformance/test_protos/test_messages_edition_unstable.proto --proto_path=${protobuf_SOURCE_DIR} --cpp_out=${protobuf_BINARY_DIR} ) @@ -89,6 +93,8 @@ add_library(libconformance_common STATIC ${protobuf_BINARY_DIR}/conformance/conformance.pb.cc ${protobuf_BINARY_DIR}/conformance/test_protos/test_messages_edition2023.pb.h ${protobuf_BINARY_DIR}/conformance/test_protos/test_messages_edition2023.pb.cc + ${protobuf_BINARY_DIR}/conformance/test_protos/test_messages_edition_unstable.pb.h + ${protobuf_BINARY_DIR}/conformance/test_protos/test_messages_edition_unstable.pb.cc ${protobuf_BINARY_DIR}/editions/golden/test_messages_proto3_editions.pb.h ${protobuf_BINARY_DIR}/editions/golden/test_messages_proto3_editions.pb.cc ${protobuf_BINARY_DIR}/editions/golden/test_messages_proto2_editions.pb.h diff --git a/conformance/BUILD b/conformance/BUILD index dbcb8da3d2..a8d3a1f178 100644 --- a/conformance/BUILD +++ b/conformance/BUILD @@ -138,6 +138,7 @@ cc_library( "//:test_messages_proto2_cc_proto", "//:test_messages_proto3_cc_proto", "//conformance/test_protos:test_messages_edition2023_cc_proto", + "//conformance/test_protos:test_messages_edition_unstable_cc_proto", "//editions:test_messages_proto2_editions_cc_proto", "//editions:test_messages_proto3_editions_cc_proto", "//src/google/protobuf", @@ -166,6 +167,7 @@ cc_library( "//:test_messages_proto2_cc_proto", "//:test_messages_proto3_cc_proto", "//conformance/test_protos:test_messages_edition2023_cc_proto", + "//conformance/test_protos:test_messages_edition_unstable_cc_proto", "//editions:test_messages_proto2_editions_cc_proto", "//editions:test_messages_proto3_editions_cc_proto", "//src/google/protobuf", @@ -249,6 +251,7 @@ cc_test( "//:test_messages_proto2_cc_proto", "//:test_messages_proto3_cc_proto", "//conformance/test_protos:test_messages_edition2023_cc_proto", + "//conformance/test_protos:test_messages_edition_unstable_cc_proto", "//editions:test_messages_proto2_editions_cc_proto", "//editions:test_messages_proto3_editions_cc_proto", "@googletest//:gtest", @@ -440,6 +443,7 @@ cc_binary( "//:type_cc_proto", "//:wrappers_cc_proto", "//conformance/test_protos:test_messages_edition2023_cc_proto", + "//conformance/test_protos:test_messages_edition_unstable_cc_proto", "//editions:test_messages_proto2_editions_cc_proto", "//editions:test_messages_proto3_editions_cc_proto", "//src/google/protobuf", @@ -472,6 +476,7 @@ java_binary( "//:test_messages_proto2_java_proto", "//:test_messages_proto3_java_proto", "//conformance/test_protos:test_messages_edition2023_java_proto", + "//conformance/test_protos:test_messages_edition_unstable_java_proto", "//editions:test_messages_proto2_editions_java_proto", "//editions:test_messages_proto3_editions_java_proto", ], @@ -492,6 +497,7 @@ java_binary( "//:test_messages_proto2_java_proto_lite", "//:test_messages_proto3_java_proto_lite", "//conformance/test_protos:test_messages_edition2023_java_proto_lite", + "//conformance/test_protos:test_messages_edition_unstable_java_proto_lite", "//editions:test_messages_proto2_editions_java_proto_lite", "//editions:test_messages_proto3_editions_java_proto_lite", ], @@ -511,6 +517,7 @@ py_binary( ":conformance_py_proto", "//:protobuf_python", "//conformance/test_protos:test_messages_edition2023_py_pb2", + "//conformance/test_protos:test_messages_edition_unstable_py_pb2", "//editions:test_messages_proto2_editions_py_pb2", "//editions:test_messages_proto3_editions_py_pb2", "//python:_message", # Make upb visible if we need it. @@ -572,6 +579,7 @@ inline_sh_binary( visibility = ["//csharp:__subpackages__"], deps = [ "//conformance/test_protos:test_messages_edition2023_csharp_proto", + "//conformance/test_protos:test_messages_edition_unstable_csharp_proto", "//csharp/src/Google.Protobuf.Conformance:conformance_runfiles", ], ) @@ -587,6 +595,7 @@ objc_library( "//:test_messages_proto2_objc_proto", "//:test_messages_proto3_objc_proto", "//conformance/test_protos:test_messages_edition2023_objc_proto", + "//conformance/test_protos:test_messages_edition_unstable_objc_proto", "//editions:test_messages_proto2_editions_objc_proto", "//editions:test_messages_proto3_editions_objc_proto", ], diff --git a/conformance/ConformanceJava.java b/conformance/ConformanceJava.java index ee90bf541a..84b488470f 100644 --- a/conformance/ConformanceJava.java +++ b/conformance/ConformanceJava.java @@ -17,6 +17,8 @@ import com.google.protobuf.util.JsonFormat; import com.google.protobuf.util.JsonFormat.TypeRegistry; import com.google.protobuf_test_messages.edition2023.TestAllTypesEdition2023; import com.google.protobuf_test_messages.edition2023.TestMessagesEdition2023; +import com.google.protobuf_test_messages.edition_unstable.TestAllTypesEditionUnstable; +import com.google.protobuf_test_messages.edition_unstable.TestMessagesEditionUnstableProto; import com.google.protobuf_test_messages.editions.proto2.TestMessagesProto2Editions; import com.google.protobuf_test_messages.editions.proto3.TestMessagesProto3Editions; import com.google.protobuf_test_messages.proto2.TestMessagesProto2; @@ -217,6 +219,8 @@ class ConformanceJava { return TestAllTypesProto2.class; case "protobuf_test_messages.editions.TestAllTypesEdition2023": return TestAllTypesEdition2023.class; + case "protobuf_test_messages.edition_unstable.TestAllTypesEditionUnstable": + return TestAllTypesEditionUnstable.class; case "protobuf_test_messages.editions.proto3.TestAllTypesProto3": return TestMessagesProto3Editions.TestAllTypesProto3.class; case "protobuf_test_messages.editions.proto2.TestAllTypesProto2": @@ -235,6 +239,8 @@ class ConformanceJava { return TestMessagesProto2.class; case "protobuf_test_messages.editions.TestAllTypesEdition2023": return TestMessagesEdition2023.class; + case "protobuf_test_messages.edition_unstable.TestAllTypesEditionUnstable": + return TestMessagesEditionUnstableProto.class; case "protobuf_test_messages.editions.proto3.TestAllTypesProto3": return TestMessagesProto3Editions.class; case "protobuf_test_messages.editions.proto2.TestAllTypesProto2": diff --git a/conformance/ConformanceJavaLite.java b/conformance/ConformanceJavaLite.java index 9b6c36e82a..67e275fdf6 100644 --- a/conformance/ConformanceJavaLite.java +++ b/conformance/ConformanceJavaLite.java @@ -15,6 +15,8 @@ import com.google.protobuf.Parser; import com.google.protobuf.conformance.Conformance; import com.google.protobuf_test_messages.edition2023.TestAllTypesEdition2023; import com.google.protobuf_test_messages.edition2023.TestMessagesEdition2023; +import com.google.protobuf_test_messages.edition_unstable.TestAllTypesEditionUnstable; +import com.google.protobuf_test_messages.edition_unstable.TestMessagesEditionUnstableProto; import com.google.protobuf_test_messages.editions.proto2.TestMessagesProto2Editions; import com.google.protobuf_test_messages.editions.proto3.TestMessagesProto3Editions; import com.google.protobuf_test_messages.proto2.TestMessagesProto2; @@ -216,6 +218,8 @@ class ConformanceJavaLite { return TestAllTypesProto2.class; case "protobuf_test_messages.editions.TestAllTypesEdition2023": return TestAllTypesEdition2023.class; + case "protobuf_test_messages.edition_unstable.TestAllTypesEditionUnstable": + return TestAllTypesEditionUnstable.class; case "protobuf_test_messages.editions.proto3.TestAllTypesProto3": return TestMessagesProto3Editions.TestAllTypesProto3.class; case "protobuf_test_messages.editions.proto2.TestAllTypesProto2": @@ -234,6 +238,8 @@ class ConformanceJavaLite { return TestMessagesProto2.class; case "protobuf_test_messages.editions.TestAllTypesEdition2023": return TestMessagesEdition2023.class; + case "protobuf_test_messages.edition_unstable.TestAllTypesEditionUnstable": + return TestMessagesEditionUnstableProto.class; case "protobuf_test_messages.editions.proto3.TestAllTypesProto3": return TestMessagesProto3Editions.class; case "protobuf_test_messages.editions.proto2.TestAllTypesProto2": diff --git a/conformance/binary_json_conformance_suite.cc b/conformance/binary_json_conformance_suite.cc index ca24002e39..d312b0b2d4 100644 --- a/conformance/binary_json_conformance_suite.cc +++ b/conformance/binary_json_conformance_suite.cc @@ -33,6 +33,7 @@ #include "conformance/conformance.pb.h" #include "conformance_test.h" #include "conformance/test_protos/test_messages_edition2023.pb.h" +#include "conformance/test_protos/test_messages_edition_unstable.pb.h" #include "editions/golden/test_messages_proto2_editions.pb.h" #include "editions/golden/test_messages_proto3_editions.pb.h" #include "google/protobuf/json/json.h" @@ -51,6 +52,7 @@ using google::protobuf::Descriptor; using google::protobuf::FieldDescriptor; using google::protobuf::internal::WireFormatLite; using google::protobuf::util::NewTypeResolverForDescriptorPool; +using protobuf_test_messages::edition_unstable::TestAllTypesEditionUnstable; using protobuf_test_messages::editions::TestAllTypesEdition2023; using protobuf_test_messages::proto2::TestAllTypesProto2; using protobuf_test_messages::proto3::TestAllTypesProto3; @@ -318,6 +320,7 @@ void BinaryAndJsonConformanceSuite::RunSuiteImpl() { BinaryAndJsonConformanceSuiteImpl( this, /*run_proto3_tests=*/false); RunDelimitedFieldTests(); + RunUnstableTests(); } } @@ -374,6 +377,22 @@ void BinaryAndJsonConformanceSuite::RunDelimitedFieldTests() { R"pb([protobuf_test_messages.editions.delimited_ext] { c: 99 })pb"); } +void BinaryAndJsonConformanceSuite::RunUnstableTests() { + SetTypeUrl(GetTypeUrl(TestAllTypesEditionUnstable::GetDescriptor())); + + RunValidProtobufTest( + absl::StrCat("ValidInt32"), REQUIRED, + field(1, WireFormatLite::WIRETYPE_VARINT, varint(99)), + R"pb(optional_int32: 99)pb"); + + RunValidProtobufTest( + absl::StrCat("ValidMap.Integer"), REQUIRED, + len(8, + absl::StrCat(field(1, WireFormatLite::WIRETYPE_VARINT, varint(99)), + field(2, WireFormatLite::WIRETYPE_VARINT, varint(87)))), + R"pb(map_int32_int32 { key: 99 value: 87 })pb"); +} + void BinaryAndJsonConformanceSuite::RunMessageSetTests() { RunValidBinaryProtobufTest( absl::StrCat("ValidMessageSetEncoding"), REQUIRED, diff --git a/conformance/binary_json_conformance_suite.h b/conformance/binary_json_conformance_suite.h index 23ce5a7ed3..39b8b38c95 100644 --- a/conformance/binary_json_conformance_suite.h +++ b/conformance/binary_json_conformance_suite.h @@ -57,6 +57,8 @@ class BinaryAndJsonConformanceSuite : public ConformanceTestSuite { void RunDelimitedFieldTests(); + void RunUnstableTests(); + void RunMessageSetTests(); template diff --git a/conformance/conformance.proto b/conformance/conformance.proto index e3298f0852..b4b2f315e0 100644 --- a/conformance/conformance.proto +++ b/conformance/conformance.proto @@ -101,7 +101,8 @@ message ConformanceRequest { // protobuf_test_messages.proto2.TestAllTypesProto2 or // protobuf_test_messages.editions.proto2.TestAllTypesProto2 or // protobuf_test_messages.editions.proto3.TestAllTypesProto3 or - // protobuf_test_messages.editions.TestAllTypesEdition2023. + // protobuf_test_messages.editions.TestAllTypesEdition2023 or + // protobuf_test_messages.edition_unstable.TestAllTypesEditionUnstable. string message_type = 4; // Each test is given a specific test category. Some category may need diff --git a/conformance/conformance_cpp.cc b/conformance/conformance_cpp.cc index 41239ebbd9..50becc0fc4 100644 --- a/conformance/conformance_cpp.cc +++ b/conformance/conformance_cpp.cc @@ -32,6 +32,7 @@ #include "absl/strings/str_cat.h" #include "conformance/conformance.pb.h" #include "conformance/test_protos/test_messages_edition2023.pb.h" +#include "conformance/test_protos/test_messages_edition_unstable.pb.h" #include "editions/golden/test_messages_proto2_editions.pb.h" #include "editions/golden/test_messages_proto3_editions.pb.h" #include "google/protobuf/endian.h" @@ -58,6 +59,7 @@ using ::google::protobuf::util::JsonStringToMessage; using ::google::protobuf::util::MessageToJsonString; using ::google::protobuf::util::NewTypeResolverForDescriptorPool; using ::google::protobuf::util::TypeResolver; +using ::protobuf_test_messages::edition_unstable::TestAllTypesEditionUnstable; using ::protobuf_test_messages::editions::TestAllTypesEdition2023; using ::protobuf_test_messages::proto2::TestAllTypesProto2; using ::protobuf_test_messages::proto3::TestAllTypesProto3; @@ -97,6 +99,7 @@ class Harness { google::protobuf::LinkMessageReflection(); google::protobuf::LinkMessageReflection(); google::protobuf::LinkMessageReflection(); + google::protobuf::LinkMessageReflection(); google::protobuf::LinkMessageReflection(); google::protobuf::LinkMessageReflection(); diff --git a/conformance/conformance_objc.m b/conformance/conformance_objc.m index 78c7e1ba6a..64a51a3180 100644 --- a/conformance/conformance_objc.m +++ b/conformance/conformance_objc.m @@ -13,6 +13,7 @@ #import "google/protobuf/TestMessagesProto2.pbobjc.h" #import "google/protobuf/TestMessagesProto3.pbobjc.h" #import "test_protos/TestMessagesEdition2023.pbobjc.h" +#import "test_protos/TestMessagesEditionUnstable.pbobjc.h" static void Die(NSString *format, ...) __dead2; @@ -65,6 +66,11 @@ static ConformanceResponse *DoTest(ConformanceRequest *request) { isEqual:@"protobuf_test_messages.editions.TestAllTypesEdition2023"]) { msgClass = [EditionsTestAllTypesEdition2023 class]; registry = [EditionsTestMessagesEdition2023Root extensionRegistry]; + } else if ([request.messageType + isEqual: + @"protobuf_test_messages.edition_unstable.TestAllTypesEditionUnstable"]) { + msgClass = [EditionUnstableTestAllTypesEditionUnstable class]; + registry = [EditionUnstableTestMessagesEditionUnstableRoot extensionRegistry]; } else if ([request.messageType isEqual:@"protobuf_test_messages.editions.proto2.TestAllTypesProto2"]) { msgClass = [EditionsProto2TestAllTypesProto2 class]; diff --git a/conformance/conformance_php.php b/conformance/conformance_php.php index 66af4731e4..4a0de2d3a5 100644 --- a/conformance/conformance_php.php +++ b/conformance/conformance_php.php @@ -63,6 +63,9 @@ function doTest($request) case 'protobuf_test_messages.editions.TestAllTypesEdition2023': $response->setSkipped('PHP doesn\'t support editions-specific features yet'); return $response; + case 'protobuf_test_messages.edition_unstable.TestAllTypesEditionUnstable': + $response->setSkipped('PHP doesn\'t support editions-specific features yet'); + return $response; case '': trigger_error( 'Protobuf request doesn\'t have specific payload type', diff --git a/conformance/conformance_python.py b/conformance/conformance_python.py index 29df365c31..eb0dc50573 100755 --- a/conformance/conformance_python.py +++ b/conformance/conformance_python.py @@ -20,6 +20,7 @@ from google.protobuf import test_messages_proto2_pb2 from google.protobuf import test_messages_proto3_pb2 from conformance import conformance_pb2 from conformance.test_protos import test_messages_edition2023_pb2 +from conformance.test_protos import test_messages_edition_unstable_pb2 from editions.golden import test_messages_proto2_editions_pb2 from editions.golden import test_messages_proto3_editions_pb2 @@ -42,6 +43,11 @@ def _create_test_message(type): return test_messages_proto2_editions_pb2.TestAllTypesProto2() if type == "protobuf_test_messages.editions.proto3.TestAllTypesProto3": return test_messages_proto3_editions_pb2.TestAllTypesProto3() + if ( + type + == "protobuf_test_messages.edition_unstable.TestAllTypesEditionUnstable" + ): + return test_messages_edition_unstable_pb2.TestAllTypesEditionUnstable() return None diff --git a/conformance/conformance_rust.rs b/conformance/conformance_rust.rs index 820d67cff7..7748c4d25c 100644 --- a/conformance/conformance_rust.rs +++ b/conformance/conformance_rust.rs @@ -12,6 +12,7 @@ use protobuf::{Message, ParseError}; use std::io::{self, ErrorKind, Read, Write}; use test_messages_edition2023_rust_proto::TestAllTypesEdition2023; +use test_messages_edition_unstable_rust_proto::TestAllTypesEditionUnstable; use test_messages_proto2_editions_rust_proto::TestAllTypesProto2 as EditionsTestAllTypesProto2; use test_messages_proto2_rust_proto::TestAllTypesProto2; use test_messages_proto3_editions_rust_proto::TestAllTypesProto3 as EditionsTestAllTypesProto3; @@ -83,6 +84,9 @@ fn do_test(req: &ConformanceRequest) -> ConformanceResponse { b"protobuf_test_messages.editions.TestAllTypesEdition2023" => { roundtrip::(bytes) } + b"protobuf_test_messages.edition_unstable.TestAllTypesEditionUnstable" => { + roundtrip::(bytes) + } b"protobuf_test_messages.editions.proto2.TestAllTypesProto2" => { roundtrip::(bytes) } diff --git a/conformance/conformance_test.cc b/conformance/conformance_test.cc index 17f0aa0ba2..6ad4034867 100644 --- a/conformance/conformance_test.cc +++ b/conformance/conformance_test.cc @@ -239,6 +239,8 @@ ConformanceTestSuite::ConformanceRequestSetting::GetSyntaxIdentifier() const { return "Proto3"; case Edition::EDITION_PROTO2: return "Proto2"; + case Edition::EDITION_UNSTABLE: + return "EditionUnstable"; default: { std::string id = "Editions"; if (prototype_message_.GetDescriptor()->name() == "TestAllTypesProto2") { diff --git a/conformance/naming.h b/conformance/naming.h index 98c1a302b6..44455abd3e 100644 --- a/conformance/naming.h +++ b/conformance/naming.h @@ -26,6 +26,8 @@ inline std::string GetEditionIdentifier(const Descriptor& message) { return "Proto3"; case Edition::EDITION_PROTO2: return "Proto2"; + case Edition::EDITION_UNSTABLE: + return "EditionUnstable"; default: { std::string id = "Editions"; if (message.name() == "TestAllTypesProto2") { diff --git a/conformance/naming_test.cc b/conformance/naming_test.cc index f3e629b74d..75e366b7a6 100644 --- a/conformance/naming_test.cc +++ b/conformance/naming_test.cc @@ -2,6 +2,7 @@ #include #include "conformance/test_protos/test_messages_edition2023.pb.h" +#include "conformance/test_protos/test_messages_edition_unstable.pb.h" #include "editions/golden/test_messages_proto2_editions.pb.h" #include "editions/golden/test_messages_proto3_editions.pb.h" #include "google/protobuf/test_messages_proto2.pb.h" @@ -12,6 +13,7 @@ namespace protobuf { namespace conformance { namespace { +using protobuf_test_messages::edition_unstable::TestAllTypesEditionUnstable; using protobuf_test_messages::editions::TestAllTypesEdition2023; using protobuf_test_messages::proto2::TestAllTypesProto2; using protobuf_test_messages::proto3::TestAllTypesProto3; @@ -25,6 +27,8 @@ TEST(NamingTest, GetEditionIdentifier) { EXPECT_EQ(GetEditionIdentifier(*TestAllTypesProto3::descriptor()), "Proto3"); EXPECT_EQ(GetEditionIdentifier(*TestAllTypesEdition2023::descriptor()), "Editions"); + EXPECT_EQ(GetEditionIdentifier(*TestAllTypesEditionUnstable::descriptor()), + "EditionUnstable"); EXPECT_EQ(GetEditionIdentifier(*TestAllTypesProto2Editions::descriptor()), "Editions_Proto2"); EXPECT_EQ(GetEditionIdentifier(*TestAllTypesProto3Editions::descriptor()), diff --git a/conformance/ruby/BUILD b/conformance/ruby/BUILD index 8b749cff91..405221b6b4 100644 --- a/conformance/ruby/BUILD +++ b/conformance/ruby/BUILD @@ -25,6 +25,12 @@ internal_ruby_proto_library( srcs = [":copied_test_messages_edition2023_proto"], ) +internal_ruby_proto_library( + name = "test_messages_edition_unstable_ruby_proto", + testonly = True, + srcs = [":copied_test_messages_edition_unstable_proto"], +) + rb_binary( name = "conformance_ruby", testonly = True, @@ -34,6 +40,7 @@ rb_binary( deps = [ ":conformance_ruby_proto", ":test_messages_edition2023_ruby_proto", + ":test_messages_edition_unstable_ruby_proto", "//ruby:conformance_editions_test_ruby_proto", "//ruby:conformance_test_ruby_proto", "//ruby:protobuf", @@ -55,3 +62,10 @@ internal_copy_files( srcs = ["//conformance/test_protos:test_messages_edition2023.proto"], strip_prefix = "conformance/test_protos", ) + +internal_copy_files( + name = "copied_test_messages_edition_unstable_proto", + testonly = True, + srcs = ["//conformance/test_protos:test_messages_edition_unstable.proto"], + strip_prefix = "conformance/test_protos", +) diff --git a/conformance/ruby/conformance_ruby.rb b/conformance/ruby/conformance_ruby.rb index ae68caaed6..6425c7fb9f 100755 --- a/conformance/ruby/conformance_ruby.rb +++ b/conformance/ruby/conformance_ruby.rb @@ -14,6 +14,7 @@ $LOAD_PATH.unshift File.join(ENV['PWD'], 'ruby') require 'conformance/ruby/conformance_pb' require 'conformance/ruby/test_messages_edition2023_pb' +require 'conformance/ruby/test_messages_edition_unstable_pb' require 'google/protobuf' require 'google/protobuf/test_messages_proto3_pb' require 'google/protobuf/test_messages_proto2_pb' diff --git a/conformance/test_protos/BUILD b/conformance/test_protos/BUILD index 046e66b29d..8a64e3ce2e 100644 --- a/conformance/test_protos/BUILD +++ b/conformance/test_protos/BUILD @@ -14,13 +14,21 @@ package( default_visibility = ["//conformance:__subpackages__"], ) -exports_files(["test_messages_edition2023.proto"]) +exports_files([ + "test_messages_edition2023.proto", + "test_messages_edition_unstable.proto", +]) internal_csharp_proto_library( name = "test_messages_edition2023_csharp_proto", srcs = ["test_messages_edition2023.proto"], ) +internal_csharp_proto_library( + name = "test_messages_edition_unstable_csharp_proto", + srcs = ["test_messages_edition_unstable.proto"], +) + # Aliases for older monolithic conformance test protos defined elsewhere. alias( name = "test_messages_proto2_editions_proto", @@ -52,28 +60,60 @@ proto_library( visibility = ["//visibility:public"], ) +proto_library( + name = "test_messages_edition_unstable_proto", + srcs = ["test_messages_edition_unstable.proto"], + visibility = ["//visibility:public"], +) + java_lite_proto_library( name = "test_messages_edition2023_java_proto_lite", deps = [":test_messages_edition2023_proto"], ) +java_lite_proto_library( + name = "test_messages_edition_unstable_java_proto_lite", + deps = [":test_messages_edition_unstable_proto"], +) + java_proto_library( name = "test_messages_edition2023_java_proto", deps = [":test_messages_edition2023_proto"], ) +java_proto_library( + name = "test_messages_edition_unstable_java_proto", + deps = [":test_messages_edition_unstable_proto"], +) + cc_proto_library( name = "test_messages_edition2023_cc_proto", deps = [":test_messages_edition2023_proto"], ) +cc_proto_library( + name = "test_messages_edition_unstable_cc_proto", + deps = [":test_messages_edition_unstable_proto"], +) + internal_py_proto_library( name = "test_messages_edition2023_py_pb2", srcs = [":test_messages_edition2023.proto"], srcs_version = "PY2AND3", ) +internal_py_proto_library( + name = "test_messages_edition_unstable_py_pb2", + srcs = [":test_messages_edition_unstable.proto"], + srcs_version = "PY2AND3", +) + internal_objc_proto_library( name = "test_messages_edition2023_objc_proto", srcs = [":test_messages_edition2023.proto"], ) + +internal_objc_proto_library( + name = "test_messages_edition_unstable_objc_proto", + srcs = [":test_messages_edition_unstable.proto"], +) diff --git a/conformance/test_protos/test_messages_edition_unstable.proto b/conformance/test_protos/test_messages_edition_unstable.proto new file mode 100644 index 0000000000..061116e6e1 --- /dev/null +++ b/conformance/test_protos/test_messages_edition_unstable.proto @@ -0,0 +1,61 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2024 Google Inc. 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 + +edition = "UNSTABLE"; + +package protobuf_test_messages.edition_unstable; + +option features.message_encoding = DELIMITED; +option java_package = "com.google.protobuf_test_messages.edition_unstable"; +option objc_class_prefix = "EditionUnstable"; + +message ComplexMessage { + int32 d = 1; +} + +message TestAllTypesEditionUnstable { + // Singular + int32 optional_int32 = 1; + + ForeignMessageEditionUnstable optional_foreign_message = 2 + [features.message_encoding = LENGTH_PREFIXED]; + + ForeignEnumEditionUnstable optional_foreign_enum = 3; + + TestAllTypesEditionUnstable recursive_message = 4 + [features.message_encoding = LENGTH_PREFIXED]; + + // Repeated + repeated int32 repeated_int32 = 5; + repeated ForeignMessageEditionUnstable repeated_foreign_message = 6 + [features.message_encoding = LENGTH_PREFIXED]; + repeated ForeignEnumEditionUnstable repeated_foreign_enum = 7; + + // Map + map map_int32_int32 = 8; + map map_bool_bool = 9; + map map_string_string = 10; + map map_string_foreign_message = 11; + map map_string_foreign_enum = 12; + + // extensions + extensions 120 to 200; +} + +message ForeignMessageEditionUnstable { + int32 c = 1; +} + +enum ForeignEnumEditionUnstable { + FOREIGN_FOO = 0; + FOREIGN_BAR = 1; + FOREIGN_BAZ = 2; +} + +extend TestAllTypesEditionUnstable { + int32 extension_int32 = 120; +} diff --git a/conformance/text_format_conformance_suite.cc b/conformance/text_format_conformance_suite.cc index d0cf5a68ab..9ae03a8a45 100644 --- a/conformance/text_format_conformance_suite.cc +++ b/conformance/text_format_conformance_suite.cc @@ -18,6 +18,7 @@ #include "absl/strings/str_format.h" #include "conformance_test.h" #include "conformance/test_protos/test_messages_edition2023.pb.h" +#include "conformance/test_protos/test_messages_edition_unstable.pb.h" #include "editions/golden/test_messages_proto2_editions.pb.h" #include "editions/golden/test_messages_proto3_editions.pb.h" #include "google/protobuf/test_messages_proto2.pb.h" @@ -143,6 +144,10 @@ TextFormatConformanceTestSuiteImpl:: // There are no editions-sensitive performance tests. return; } + if (MessageType::GetDescriptor()->name() == "TestAllTypesEditionUnstable") { + // There are no editions-sensitive performance tests. + return; + } RunTextFormatPerformanceTests(); } else { if (MessageType::GetDescriptor()->name() == "TestAllTypesProto2") { diff --git a/csharp/generate_protos.sh b/csharp/generate_protos.sh index fc22b7e2fb..9cad0f6ca4 100755 --- a/csharp/generate_protos.sh +++ b/csharp/generate_protos.sh @@ -59,6 +59,7 @@ $PROTOC -Isrc -I. -Ijava/core/src/main/resources/ \ --include_source_info \ --include_imports \ conformance/test_protos/test_messages_edition2023.proto \ + conformance/test_protos/test_messages_edition_unstable.proto \ csharp/protos/map_unittest_proto3.proto \ csharp/protos/unittest_issues.proto \ csharp/protos/unittest_custom_options_proto3.proto \ diff --git a/csharp/src/Google.Protobuf.Conformance/Program.cs b/csharp/src/Google.Protobuf.Conformance/Program.cs index e22a9618e9..c09aeb7c8b 100644 --- a/csharp/src/Google.Protobuf.Conformance/Program.cs +++ b/csharp/src/Google.Protobuf.Conformance/Program.cs @@ -29,6 +29,7 @@ namespace Google.Protobuf.Conformance ProtobufTestMessages.Proto3.TestAllTypesProto3.Descriptor, ProtobufTestMessages.Proto2.TestAllTypesProto2.Descriptor, ProtobufTestMessages.Editions.TestAllTypesEdition2023.Descriptor, + ProtobufTestMessages.EditionUnstable.TestAllTypesEditionUnstable.Descriptor, ProtobufTestMessages.Editions.Proto3.TestAllTypesProto3.Descriptor, ProtobufTestMessages.Editions.Proto2.TestAllTypesProto2.Descriptor); @@ -83,6 +84,9 @@ namespace Google.Protobuf.Conformance ProtobufTestMessages.Editions.TestMessagesEdition2023Extensions.DelimitedExt, ProtobufTestMessages.Editions.TestMessagesEdition2023Extensions.GroupLikeType }; + ExtensionRegistry editionUnstableExtensionRegistry = new ExtensionRegistry { + ProtobufTestMessages.EditionUnstable.TestMessagesEditionUnstableExtensions.ExtensionInt32, + }; IMessage message; try { @@ -102,6 +106,9 @@ namespace Google.Protobuf.Conformance "protobuf_test_messages.editions.TestAllTypesEdition2023" => parser.Parse( request.JsonPayload), + "protobuf_test_messages.edition_unstable.TestAllTypesEditionUnstable" => + parser.Parse( + request.JsonPayload), "protobuf_test_messages.editions.proto2.TestAllTypesProto2" => parser.Parse( request.JsonPayload), @@ -126,6 +133,10 @@ namespace Google.Protobuf.Conformance ProtobufTestMessages.Editions.TestAllTypesEdition2023.Parser .WithExtensionRegistry(edition2023ExtensionRegistry) .ParseFrom(request.ProtobufPayload), + "protobuf_test_messages.edition_unstable.TestAllTypesEditionUnstable" => + ProtobufTestMessages.EditionUnstable.TestAllTypesEditionUnstable.Parser + .WithExtensionRegistry(editionUnstableExtensionRegistry) + .ParseFrom(request.ProtobufPayload), "protobuf_test_messages.editions.proto2.TestAllTypesProto2" => ProtobufTestMessages.Editions.Proto2.TestAllTypesProto2.Parser .WithExtensionRegistry(editionsProto2ExtensionRegistry) diff --git a/csharp/src/Google.Protobuf/Reflection/FeatureSetDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/FeatureSetDescriptor.cs index 0b55005c82..3944e9cf35 100644 --- a/csharp/src/Google.Protobuf/Reflection/FeatureSetDescriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/FeatureSetDescriptor.cs @@ -45,7 +45,7 @@ internal sealed partial class FeatureSetDescriptor // based on that. var supportedEditions = ((Edition[]) Enum.GetValues(typeof(Edition))) .OrderBy(x => x) - .Where(e => e >= featureSetDefaults.MinimumEdition && e <= featureSetDefaults.MaximumEdition); + .Where(e => e >= featureSetDefaults.MinimumEdition && (e <= featureSetDefaults.MaximumEdition || e == Edition.Unstable)); // We assume the embedded defaults will always contain "legacy". var currentDescriptor = MaybeCreateDescriptor(Edition.Legacy); diff --git a/java/core/src/main/java/com/google/protobuf/Descriptors.java b/java/core/src/main/java/com/google/protobuf/Descriptors.java index 63d0667d5c..87821ebc41 100644 --- a/java/core/src/main/java/com/google/protobuf/Descriptors.java +++ b/java/core/src/main/java/com/google/protobuf/Descriptors.java @@ -120,7 +120,8 @@ public final class Descriptors { + javaEditionDefaults.getMinimumEdition() + "!"); } - if (edition.getNumber() > javaEditionDefaults.getMaximumEdition().getNumber()) { + if (edition.getNumber() > javaEditionDefaults.getMaximumEdition().getNumber() + && edition != Edition.EDITION_UNSTABLE) { throw new IllegalArgumentException( "Edition " + edition diff --git a/python/google/protobuf/descriptor_pool.py b/python/google/protobuf/descriptor_pool.py index 23ce885596..a838c508b5 100644 --- a/python/google/protobuf/descriptor_pool.py +++ b/python/google/protobuf/descriptor_pool.py @@ -738,7 +738,10 @@ class DescriptorPool(object): ), ) ) - if edition > self._edition_defaults.maximum_edition: + if ( + edition > self._edition_defaults.maximum_edition + and edition != descriptor_pb2.EDITION_UNSTABLE + ): raise TypeError( 'Edition %s is later than the maximum supported edition %s!' % ( diff --git a/src/google/protobuf/compiler/code_generator.cc b/src/google/protobuf/compiler/code_generator.cc index e943c543d5..4657417314 100644 --- a/src/google/protobuf/compiler/code_generator.cc +++ b/src/google/protobuf/compiler/code_generator.cc @@ -106,7 +106,10 @@ void GeneratorContext::GetCompilerVersion(Version* version) const { bool CanSkipEditionCheck(absl::string_view filename) { return absl::StartsWith(filename, "google/protobuf/") || absl::StartsWith(filename, "upb/") || - absl::StartsWith(filename, "com/google/protobuf/"); + absl::StartsWith(filename, "com/google/protobuf/") || + absl::StartsWith(filename, "conformance/test_protos/") || + // TODO: Remove this once internal proto rule is resolved. + absl::StartsWith(filename, "test_messages_edition_unstable"); } } // namespace compiler diff --git a/upb/reflection/file_def.c b/upb/reflection/file_def.c index 1ba5a208b7..c17c5ae936 100644 --- a/upb/reflection/file_def.c +++ b/upb/reflection/file_def.c @@ -220,7 +220,7 @@ const UPB_DESC(FeatureSet*) upb_FileDef_EditionName(min)); return NULL; } - if (edition > max) { + if (edition > max && edition != UPB_DESC(EDITION_UNSTABLE)) { _upb_DefBuilder_Errf(ctx, "Edition %s is later than the maximum edition %s " "given in the defaults",