From 8f3ae17b3d248456691334de7a3901003acae387 Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Fri, 3 Mar 2023 18:44:46 -0800 Subject: [PATCH] Automated rollback of commit 208f0ad4556bbf32249b6b9b367750f9f31903f8. PiperOrigin-RevId: 513973094 --- src/google/protobuf/descriptor.cc | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc index 9827ac1376..efcd86e358 100644 --- a/src/google/protobuf/descriptor.cc +++ b/src/google/protobuf/descriptor.cc @@ -8417,7 +8417,18 @@ bool HasPreservingUnknownEnumSemantics(const FieldDescriptor* field) { } bool HasHasbit(const FieldDescriptor* field) { - return field->has_presence() && !field->real_containing_oneof() && + // This predicate includes proto3 message fields only if they have "optional". + // Foo submsg1 = 1; // HasHasbit() == false + // optional Foo submsg2 = 2; // HasHasbit() == true + // This is slightly odd, as adding "optional" to a singular proto3 field does + // not change the semantics or API. However whenever any field in a message + // has a hasbit, it forces reflection to include hasbit offsets for *all* + // fields, even if almost all of them are set to -1 (no hasbit). So to avoid + // causing a sudden size regression for ~all proto3 messages, we give proto3 + // message fields a hasbit only if "optional" is present. If the user is + // explicitly writing "optional", it is likely they are writing it on + // primitive fields also. + return (field->has_optional_keyword() || field->is_required()) && !field->options().weak(); }