From 988dd9653745ca27297e8f1b61ce1416d0ddf812 Mon Sep 17 00:00:00 2001 From: Mike Kruskal Date: Thu, 9 Mar 2023 15:22:13 -0800 Subject: [PATCH] Migrate syntax reflection to new feature-based system. As part of go/protobuf-editions, we will be abandoning `syntax` in place of the new editions framework. The first edition will turn each difference between proto2 and proto3 into a more targeted *feature* placed on proto descriptors. In preparation for this, we want to migrate everyone off direct inspection of `syntax`. PiperOrigin-RevId: 515457103 --- .../compiler/cpp/parse_function_generator.cc | 2 +- src/google/protobuf/descriptor.cc | 7 ++++++- src/google/protobuf/descriptor.h | 5 ----- .../protobuf/generated_message_reflection.cc | 2 +- src/google/protobuf/wire_format.cc | 17 +++++------------ 5 files changed, 13 insertions(+), 20 deletions(-) diff --git a/src/google/protobuf/compiler/cpp/parse_function_generator.cc b/src/google/protobuf/compiler/cpp/parse_function_generator.cc index 5b365cb0ae..2de1f078ce 100644 --- a/src/google/protobuf/compiler/cpp/parse_function_generator.cc +++ b/src/google/protobuf/compiler/cpp/parse_function_generator.cc @@ -1051,7 +1051,7 @@ void ParseFunctionGenerator::GenerateLengthDelim(Formatter& format, const FieldDescriptor* val = field->message_type()->map_value(); ABSL_CHECK(val); if (val->type() == FieldDescriptor::TYPE_ENUM && - !internal::cpp::HasPreservingUnknownEnumSemantics(field)) { + !internal::cpp::HasPreservingUnknownEnumSemantics(val)) { format( "auto object = " "::$proto_ns$::internal::InitEnumParseWrapper<" diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc index 9a38da5286..329d779280 100644 --- a/src/google/protobuf/descriptor.cc +++ b/src/google/protobuf/descriptor.cc @@ -3521,6 +3521,11 @@ bool FieldDescriptor::is_packed() const { } } +bool FieldDescriptor::requires_utf8_validation() const { + return type() == TYPE_STRING && + file()->syntax() == FileDescriptor::SYNTAX_PROTO3; +} + bool Descriptor::GetSourceLocation(SourceLocation* out_location) const { std::vector path; GetLocationPath(&path); @@ -8415,7 +8420,7 @@ void LazyDescriptor::Once(const ServiceDescriptor* service) { namespace cpp { bool HasPreservingUnknownEnumSemantics(const FieldDescriptor* field) { - return field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3; + return !field->legacy_enum_field_treated_as_closed(); } bool HasHasbit(const FieldDescriptor* field) { diff --git a/src/google/protobuf/descriptor.h b/src/google/protobuf/descriptor.h index f1d2032be0..4a4462aa04 100644 --- a/src/google/protobuf/descriptor.h +++ b/src/google/protobuf/descriptor.h @@ -2457,11 +2457,6 @@ inline bool FieldDescriptor::has_presence() const { file()->syntax() == FileDescriptor::SYNTAX_PROTO2; } -inline bool FieldDescriptor::requires_utf8_validation() const { - return type() == TYPE_STRING && - file()->syntax() == FileDescriptor::SYNTAX_PROTO3; -} - inline bool FieldDescriptor::legacy_enum_field_treated_as_closed() const { return type() == TYPE_ENUM && file()->syntax() == FileDescriptor::SYNTAX_PROTO2; diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc index 74ab33ec5b..176be5dfd1 100644 --- a/src/google/protobuf/generated_message_reflection.cc +++ b/src/google/protobuf/generated_message_reflection.cc @@ -1551,7 +1551,7 @@ void CheckInOrder(const FieldDescriptor* field, uint32_t* last) { namespace internal { bool CreateUnknownEnumValues(const FieldDescriptor* field) { bool open_enum = false; - return field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 || open_enum; + return !field->legacy_enum_field_treated_as_closed() || open_enum; } } // namespace internal using internal::CreateUnknownEnumValues; diff --git a/src/google/protobuf/wire_format.cc b/src/google/protobuf/wire_format.cc index fe62d1c622..f70f224730 100644 --- a/src/google/protobuf/wire_format.cc +++ b/src/google/protobuf/wire_format.cc @@ -411,10 +411,6 @@ bool WireFormat::ParseAndMergeMessageSetField(uint32_t field_number, } } -static bool StrictUtf8Check(const FieldDescriptor* field) { - return field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3; -} - bool WireFormat::ParseAndMergeField( uint32_t tag, const FieldDescriptor* field, // May be nullptr for unknown @@ -484,8 +480,7 @@ bool WireFormat::ParseAndMergeField( if (!WireFormatLite::ReadPrimitive( input, &value)) return false; - if (message->GetDescriptor()->file()->syntax() == - FileDescriptor::SYNTAX_PROTO3) { + if (!field->legacy_enum_field_treated_as_closed()) { message_reflection->AddEnumValue(message, field, value); } else { const EnumValueDescriptor* enum_value = @@ -566,7 +561,7 @@ bool WireFormat::ParseAndMergeField( // Handle strings separately so that we can optimize the ctype=CORD case. case FieldDescriptor::TYPE_STRING: { - bool strict_utf8_check = StrictUtf8Check(field); + bool strict_utf8_check = field->requires_utf8_validation(); std::string value; if (!WireFormatLite::ReadString(input, &value)) return false; if (strict_utf8_check) { @@ -868,9 +863,7 @@ const char* WireFormat::_InternalParseAndMergeField( case FieldDescriptor::TYPE_ENUM: { auto rep_enum = reflection->MutableRepeatedFieldInternal(msg, field); - bool open_enum = false; - if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 || - open_enum) { + if (!field->legacy_enum_field_treated_as_closed()) { ptr = internal::PackedEnumParser(rep_enum, ptr, ctx); } else { return ctx->ReadPackedVarint( @@ -982,7 +975,7 @@ const char* WireFormat::_InternalParseAndMergeField( // Handle strings separately so that we can optimize the ctype=CORD case. case FieldDescriptor::TYPE_STRING: utf8_check = true; - strict_utf8_check = StrictUtf8Check(field); + strict_utf8_check = field->requires_utf8_validation(); PROTOBUF_FALLTHROUGH_INTENDED; case FieldDescriptor::TYPE_BYTES: { int size = ReadSize(&ptr); @@ -1418,7 +1411,7 @@ uint8_t* WireFormat::InternalSerializeField(const FieldDescriptor* field, // Handle strings separately so that we can get string references // instead of copying. case FieldDescriptor::TYPE_STRING: { - bool strict_utf8_check = StrictUtf8Check(field); + bool strict_utf8_check = field->requires_utf8_validation(); std::string scratch; const std::string& value = field->is_repeated()