diff --git a/csharp/protos/unittest.proto b/csharp/protos/unittest.proto index 03e1978ac9..03527f76d9 100644 --- a/csharp/protos/unittest.proto +++ b/csharp/protos/unittest.proto @@ -258,7 +258,7 @@ extend TestAllExtensions { optional_import_enum_extension = 23; optional string optional_string_piece_extension = 24 [ctype = STRING_PIECE]; - optional string optional_cord_extension = 25 [ctype = CORD]; + optional string optional_cord_extension = 25; optional protobuf_unittest_import_proto2.PublicImportMessage optional_public_import_message_extension = 26; @@ -298,7 +298,7 @@ extend TestAllExtensions { repeated_import_enum_extension = 53; repeated string repeated_string_piece_extension = 54 [ctype = STRING_PIECE]; - repeated string repeated_cord_extension = 55 [ctype = CORD]; + repeated string repeated_cord_extension = 55; repeated TestAllTypes.NestedMessage repeated_lazy_message_extension = 57 [lazy = true]; @@ -329,7 +329,7 @@ extend TestAllExtensions { optional string default_string_piece_extension = 84 [ctype = STRING_PIECE, default = "abc"]; - optional string default_cord_extension = 85 [ctype = CORD, default = "123"]; + optional string default_cord_extension = 85 [default = "123"]; // For oneof test optional uint32 oneof_uint32_extension = 111; diff --git a/objectivec/Tests/unittest.proto b/objectivec/Tests/unittest.proto index 3c90fd9117..9550c558a4 100644 --- a/objectivec/Tests/unittest.proto +++ b/objectivec/Tests/unittest.proto @@ -244,7 +244,7 @@ extend TestAllExtensions { optional_import_enum_extension = 23; optional string optional_string_piece_extension = 24 [ctype=STRING_PIECE]; - optional string optional_cord_extension = 25 [ctype=CORD]; + optional string optional_cord_extension = 25; optional objc.protobuf.tests.public_import.Message optional_public_import_message_extension = 26; @@ -286,7 +286,7 @@ extend TestAllExtensions { repeated_import_enum_extension = 53; repeated string repeated_string_piece_extension = 54 [ctype=STRING_PIECE]; - repeated string repeated_cord_extension = 55 [ctype=CORD]; + repeated string repeated_cord_extension = 55; repeated TestAllTypes.NestedMessage repeated_lazy_message_extension = 57 [lazy=true]; @@ -317,7 +317,7 @@ extend TestAllExtensions { optional string default_string_piece_extension = 84 [ctype=STRING_PIECE, default="abc"]; - optional string default_cord_extension = 85 [ctype=CORD, default="123"]; + optional string default_cord_extension = 85 [default="123"]; // For oneof test optional uint32 oneof_uint32_extension = 111; diff --git a/src/google/protobuf/compiler/cpp/generator.cc b/src/google/protobuf/compiler/cpp/generator.cc index c23a71b8a2..d5b39aa984 100644 --- a/src/google/protobuf/compiler/cpp/generator.cc +++ b/src/google/protobuf/compiler/cpp/generator.cc @@ -379,6 +379,22 @@ absl::Status CppGenerator::ValidateFeatures(const FileDescriptor* file) const { absl::StrCat("Field ", field.full_name(), " has a closed enum type with implicit presence.")); } +#ifdef PROTOBUF_FUTURE_REMOVE_WRONG_CTYPE + if (field.options().has_ctype()) { + if (field.cpp_type() != FieldDescriptor::CPPTYPE_STRING) { + status = absl::FailedPreconditionError(absl::StrCat( + "Field ", field.full_name(), + " specifies ctype, but is not a string nor bytes field.")); + } + if (field.options().ctype() == FieldOptions::CORD) { + if (field.is_extension()) { + status = absl::FailedPreconditionError(absl::StrCat( + "Extension ", field.full_name(), + " specifies ctype=CORD which is not supported for extensions.")); + } + } + } +#endif // !PROTOBUF_FUTURE_REMOVE_WRONG_CTYPE }); return status; } diff --git a/src/google/protobuf/compiler/cpp/generator_unittest.cc b/src/google/protobuf/compiler/cpp/generator_unittest.cc index 0eabb094ce..b5ac6bc1b4 100644 --- a/src/google/protobuf/compiler/cpp/generator_unittest.cc +++ b/src/google/protobuf/compiler/cpp/generator_unittest.cc @@ -172,6 +172,40 @@ TEST_F(CppGeneratorTest, LegacyClosedEnumImplicit) { "Field Foo.bar has a closed enum type with implicit presence."); } +#ifdef PROTOBUF_FUTURE_REMOVE_WRONG_CTYPE +TEST_F(CppGeneratorTest, CtypeOnNoneStringFieldTest) { + CreateTempFile("foo.proto", + R"schema( + edition = "2023"; + message Foo { + int32 bar = 1 [ctype=STRING]; + })schema"); + RunProtoc( + "protocol_compiler --proto_path=$tmpdir --cpp_out=$tmpdir " + "--experimental_editions foo.proto"); + ExpectErrorSubstring( + "Field Foo.bar specifies ctype, but is not " + "a string nor bytes field."); +} + +TEST_F(CppGeneratorTest, CtypeOnExtensionTest) { + CreateTempFile("foo.proto", + R"schema( + edition = "2023"; + message Foo { + extensions 1 to max; + } + extend Foo { + bytes bar = 1 [ctype=CORD]; + })schema"); + RunProtoc( + "protocol_compiler --proto_path=$tmpdir --cpp_out=$tmpdir " + "--experimental_editions foo.proto"); + ExpectErrorSubstring( + "Extension bar specifies ctype=CORD which is " + "not supported for extensions."); +} +#endif // !PROTOBUF_FUTURE_REMOVE_WRONG_CTYPE } // namespace } // namespace cpp } // namespace compiler diff --git a/src/google/protobuf/port_def.inc b/src/google/protobuf/port_def.inc index 155997f16b..a8312657e3 100644 --- a/src/google/protobuf/port_def.inc +++ b/src/google/protobuf/port_def.inc @@ -246,6 +246,10 @@ static_assert(PROTOBUF_ABSL_MIN(20230125, 3), // Owner: mkruskal@ #define PROTOBUF_FUTURE_EXTENSION_RANGE_CLASS 1 +// Used to lock down wrong ctype usages in proto file. +// Owner: jieluo@ +#define PROTOBUF_FUTURE_REMOVE_WRONG_CTYPE 1 + #endif #ifdef PROTOBUF_VERSION diff --git a/src/google/protobuf/unittest.proto b/src/google/protobuf/unittest.proto index b40749a077..ec71dc77ed 100644 --- a/src/google/protobuf/unittest.proto +++ b/src/google/protobuf/unittest.proto @@ -267,7 +267,9 @@ extend TestAllExtensions { optional_import_enum_extension = 23; optional string optional_string_piece_extension = 24 [ctype=STRING_PIECE]; - optional string optional_cord_extension = 25 [ctype=CORD]; + // TODO(b/294946958): ctype=CORD is not supported for extension. Add + // ctype=CORD option back after it is supported. + optional string optional_cord_extension = 25; optional protobuf_unittest_import.PublicImportMessage optional_public_import_message_extension = 26; @@ -309,7 +311,9 @@ extend TestAllExtensions { repeated_import_enum_extension = 53; repeated string repeated_string_piece_extension = 54 [ctype=STRING_PIECE]; - repeated string repeated_cord_extension = 55 [ctype=CORD]; + // TODO(b/294946958): ctype=CORD is not supported for extension. Add + // ctype=CORD option back after it is supported. + repeated string repeated_cord_extension = 55; repeated TestAllTypes.NestedMessage repeated_lazy_message_extension = 57 [lazy=true]; @@ -340,7 +344,9 @@ extend TestAllExtensions { optional string default_string_piece_extension = 84 [ctype=STRING_PIECE, default="abc"]; - optional string default_cord_extension = 85 [ctype=CORD, default="123"]; + // TODO(b/294946958): ctype=CORD is not supported for extension. Add + // ctype=CORD option back after it is supported. + optional string default_cord_extension = 85 [default="123"]; // For oneof test optional uint32 oneof_uint32_extension = 111; diff --git a/src/google/protobuf/unittest_lite.proto b/src/google/protobuf/unittest_lite.proto index b594b6f6ad..7cfba282cc 100644 --- a/src/google/protobuf/unittest_lite.proto +++ b/src/google/protobuf/unittest_lite.proto @@ -243,7 +243,9 @@ extend TestAllExtensionsLite { optional string optional_string_piece_extension_lite = 24 [ctype = STRING_PIECE]; - optional string optional_cord_extension_lite = 25 [ctype = CORD]; + // TODO(b/294946958): ctype=CORD is not supported for extension. Add + // ctype=CORD option back after it is supported. + optional string optional_cord_extension_lite = 25; optional protobuf_unittest_import.PublicImportMessageLite optional_public_import_message_extension_lite = 26; @@ -288,7 +290,9 @@ extend TestAllExtensionsLite { repeated string repeated_string_piece_extension_lite = 54 [ctype = STRING_PIECE]; - repeated string repeated_cord_extension_lite = 55 [ctype = CORD]; + // TODO(b/294946958): ctype=CORD is not supported for extension. Add + // ctype=CORD option back after it is supported. + repeated string repeated_cord_extension_lite = 55; repeated TestAllTypesLite.NestedMessage repeated_lazy_message_extension_lite = 57 [lazy = true]; @@ -319,8 +323,9 @@ extend TestAllExtensionsLite { optional string default_string_piece_extension_lite = 84 [ctype = STRING_PIECE, default = "abc"]; - optional string default_cord_extension_lite = 85 - [ctype = CORD, default = "123"]; + // TODO(b/294946958): ctype=CORD is not supported for extension. Add + // ctype=CORD option back after it is supported. + optional string default_cord_extension_lite = 85 [default = "123"]; // For oneof test optional uint32 oneof_uint32_extension_lite = 111;