Automated rollback of commit 8d7f50f7c2.

PiperOrigin-RevId: 654076634
pull/17544/head
Mike Kruskal 4 months ago committed by Copybara-Service
parent 9a0c8f6113
commit 65cb2c406a
  1. 41
      src/google/protobuf/descriptor.cc
  2. 19
      src/google/protobuf/descriptor.h
  3. 11
      src/google/protobuf/descriptor_lite.h
  4. 70
      src/google/protobuf/descriptor_unittest.cc

@ -3939,6 +3939,29 @@ bool FieldDescriptor::has_optional_keyword() const {
is_optional() && !containing_oneof());
}
FieldDescriptor::CppStringType FieldDescriptor::cpp_string_type() const {
ABSL_DCHECK(cpp_type() == FieldDescriptor::CPPTYPE_STRING);
switch (features().GetExtension(pb::cpp).string_type()) {
case pb::CppFeatures::VIEW:
return CppStringType::kView;
case pb::CppFeatures::CORD:
// In open-source, protobuf CORD is only supported for singular bytes
// fields.
if (type() != FieldDescriptor::TYPE_BYTES || is_repeated() ||
is_extension()) {
return CppStringType::kString;
}
return CppStringType::kCord;
case pb::CppFeatures::STRING:
return CppStringType::kString;
default:
// If features haven't been resolved, this is a dynamic build not for C++
// codegen. Just use string type.
ABSL_DCHECK(!features().GetExtension(pb::cpp).has_string_type());
return CppStringType::kString;
}
}
// Location methods ===============================================
bool FileDescriptor::GetSourceLocation(const std::vector<int>& path,
@ -5476,8 +5499,7 @@ static void EnforceCTypeStringTypeConsistency(
Edition edition, FieldDescriptor::CppType type,
const pb::CppFeatures& cpp_features, FieldOptions& options) {
if (&options == &FieldOptions::default_instance()) return;
if (edition < Edition::EDITION_2024 &&
type == FieldDescriptor::CPPTYPE_STRING) {
if (type == FieldDescriptor::CPPTYPE_STRING) {
switch (cpp_features.string_type()) {
case pb::CppFeatures::CORD:
options.set_ctype(FieldOptions::CORD);
@ -6150,6 +6172,14 @@ FileDescriptor* DescriptorBuilder::BuildFileImpl(
});
internal::VisitDescriptors(*result, [&](const FieldDescriptor& field) {
if (result->edition() >= Edition::EDITION_2024 &&
field.options().has_ctype()) {
// "ctype" is no longer supported in edition 2024 and beyond.
AddError(
field.full_name(), proto, DescriptorPool::ErrorCollector::NAME,
"ctype option is not allowed under edition 2024 and beyond. Use "
"the feature string_type = VIEW|CORD|STRING|... instead.");
}
EnforceCTypeStringTypeConsistency(
field.file()->edition(), field.cpp_type(),
field.merged_features_->GetExtension(pb::cpp),
@ -7904,12 +7934,7 @@ void DescriptorBuilder::ValidateOptions(const FieldDescriptor* field,
auto& field_options = field->options();
if (field_options.has_ctype()) {
if (edition >= Edition::EDITION_2024) {
// "ctype" is no longer supported in edition 2024 and beyond.
AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::NAME,
"ctype option is not allowed under edition 2024 and beyond. Use "
"the feature string_type = VIEW|CORD|STRING|... instead.");
} else if (edition == Edition::EDITION_2023) {
if (edition == Edition::EDITION_2023) {
if (field->cpp_type() != FieldDescriptor::CPPTYPE_STRING) {
AddError(field->full_name(), proto,
DescriptorPool::ErrorCollector::TYPE,

@ -875,6 +875,10 @@ class PROTOBUF_EXPORT FieldDescriptor : private internal::SymbolBase,
const char* cpp_type_name() const; // Name of the C++ type.
Label label() const; // optional/required/repeated
#ifndef SWIG
CppStringType cpp_string_type() const; // The C++ string type of this field.
#endif
bool is_required() const; // shorthand for label() == LABEL_REQUIRED
bool is_optional() const; // shorthand for label() == LABEL_OPTIONAL
bool is_repeated() const; // shorthand for label() == LABEL_REPEATED
@ -2932,22 +2936,21 @@ PROTOBUF_EXPORT bool HasPreservingUnknownEnumSemantics(
PROTOBUF_EXPORT bool HasHasbit(const FieldDescriptor* field);
#ifndef SWIG
// For a string field, returns the effective ctype. If the actual ctype is
// not supported, returns the default of STRING.
template <typename FieldDesc = FieldDescriptor,
typename FieldOpts = FieldOptions>
typename FieldOpts::CType EffectiveStringCType(const FieldDesc* field) {
ABSL_DCHECK(field->cpp_type() == FieldDescriptor::CPPTYPE_STRING);
// Open-source protobuf release only supports STRING ctype and CORD for
// sinuglar bytes.
if (field->type() == FieldDescriptor::TYPE_BYTES && !field->is_repeated() &&
field->options().ctype() == FieldOpts::CORD && !field->is_extension()) {
return FieldOpts::CORD;
// TODO Replace this function with FieldDescriptor::string_type;
switch (field->cpp_string_type()) {
case FieldDescriptor::CppStringType::kCord:
return FieldOpts::CORD;
default:
return FieldOpts::STRING;
}
return FieldOpts::STRING;
}
#ifndef SWIG
enum class Utf8CheckMode : uint8_t {
kStrict = 0, // Parsing will fail if non UTF-8 data is in string fields.
kVerify = 1, // Only log an error but parsing will succeed.

@ -78,6 +78,17 @@ class FieldDescriptorLite {
MAX_LABEL = 3, // Constant useful for defining lookup tables
// indexed by Label.
};
// Identifies the storage type of a C++ string field. This corresponds to
// pb.CppFeatures.StringType, but is compatible with ctype prior to Edition
// 2024. 0 is reserved for errors.
#ifndef SWIG
enum class CppStringType {
kView = 1,
kCord = 2,
kString = 3,
};
#endif
};
} // namespace internal

@ -7594,6 +7594,9 @@ TEST_F(FeaturesTest, Proto2Features) {
EXPECT_TRUE(message->FindFieldByName("req")->is_required());
EXPECT_TRUE(file->enum_type(0)->is_closed());
EXPECT_EQ(message->FindFieldByName("str")->cpp_string_type(),
FieldDescriptor::CppStringType::kString);
// Check round-trip consistency.
FileDescriptorProto proto;
file->CopyTo(&proto);
@ -9710,6 +9713,73 @@ TEST_F(FeaturesTest, EnumFeatureHelpers) {
EXPECT_FALSE(HasPreservingUnknownEnumSemantics(field_legacy_closed));
}
TEST_F(FeaturesTest, FieldCppStringType) {
BuildDescriptorMessagesInTestPool();
const std::string file_contents = absl::Substitute(
R"pb(
name: "foo.proto"
syntax: "editions"
edition: EDITION_2024
message_type {
name: "Foo"
field {
name: "view"
number: 1
label: LABEL_OPTIONAL
type: TYPE_STRING
}
field {
name: "str"
number: 2
label: LABEL_OPTIONAL
type: TYPE_STRING
options {
features {
[pb.cpp] { string_type: STRING }
}
}
}
field {
name: "cord"
number: 3
label: LABEL_OPTIONAL
type: TYPE_STRING
options {
features {
[pb.cpp] { string_type: CORD }
}
}
}
field {
name: "cord_bytes"
number: 4
label: LABEL_OPTIONAL
type: TYPE_BYTES
options {
features {
[pb.cpp] { string_type: CORD }
}
}
} $0
}
)pb",
""
);
const FileDescriptor* file = BuildFile(file_contents);
const Descriptor* message = file->message_type(0);
const FieldDescriptor* view = message->field(0);
const FieldDescriptor* str = message->field(1);
const FieldDescriptor* cord = message->field(2);
const FieldDescriptor* cord_bytes = message->field(3);
EXPECT_EQ(view->cpp_string_type(), FieldDescriptor::CppStringType::kView);
EXPECT_EQ(str->cpp_string_type(), FieldDescriptor::CppStringType::kString);
EXPECT_EQ(cord_bytes->cpp_string_type(),
FieldDescriptor::CppStringType::kCord);
EXPECT_EQ(cord->cpp_string_type(), FieldDescriptor::CppStringType::kString);
}
TEST_F(FeaturesTest, MergeFeatureValidationFailed) {
BuildDescriptorMessagesInTestPool();
BuildFileInTestPool(pb::TestFeatures::descriptor()->file());

Loading…
Cancel
Save