1717#include < cstddef>
1818#include < cstdint>
1919#include < string>
20- #include < tuple>
2120#include < type_traits>
2221#include < utility>
2322#include < variant>
@@ -375,11 +374,18 @@ void* ExtensionSet::MutableRawRepeatedField(int number) {
375374// -------------------------------------------------------------------
376375// Enums
377376
378- size_t ExtensionSet::GetMessageByteSizeLong (int number) const {
377+ size_t ExtensionSet::GetMessageByteSizeLong (const MessageLite* extendee,
378+ int number) const {
379379 const Extension* extension = FindOrNull (number);
380380 ABSL_CHECK (extension != nullptr ) << " not present" ;
381381 ABSL_DCHECK_TYPE (*extension, OPTIONAL_FIELD, MESSAGE);
382- return extension->is_lazy ? extension->ptr .lazymessage_value ->ByteSizeLong ()
382+ ABSL_DCHECK (!extension->is_lazy ||
383+ GetOrFindPrototypeForLazyMessage (*extension, extendee, number) !=
384+ nullptr );
385+ return extension->is_lazy ? extension->ptr .lazymessage_value ->ByteSizeLong (
386+ GetOrFindPrototypeForLazyMessage (
387+ *extension, extendee, number),
388+ extendee->GetArena ())
383389 : extension->ptr .message_value ->ByteSizeLong ();
384390}
385391
@@ -946,8 +952,8 @@ void ExtensionSet::InternalExtensionMergeFrom(Arena* arena,
946952 Arena* other_arena) {
947953 DebugAssertArenaMatches (arena);
948954 Extension* dst_extension;
949- bool is_new = MaybeNewExtension (arena, number, other_extension. descriptor ,
950- &dst_extension);
955+ bool is_new = MaybeNewExtension (
956+ arena, number, other_extension. descriptor_or_prototype , &dst_extension);
951957 if (is_new) {
952958 InternalExtensionMergeFromIntoUninitializedExtension (
953959 arena, *dst_extension, extendee, number, other_extension, other_arena);
@@ -1009,9 +1015,12 @@ void ExtensionSet::InternalExtensionMergeFrom(Arena* arena,
10091015 ABSL_DCHECK (!dst_extension->is_repeated );
10101016 if (other_extension.is_lazy ) {
10111017 if (dst_extension->is_lazy ) {
1018+ const MessageLite* prototype = GetOrFindPrototypeForLazyMessage (
1019+ other_extension, extendee, number);
1020+ ABSL_DCHECK_NE (prototype, nullptr );
10121021 dst_extension->ptr .lazymessage_value ->MergeFrom (
1013- GetPrototypeForLazyMessage (extendee, number) ,
1014- *other_extension. ptr . lazymessage_value , arena, other_arena);
1022+ prototype, *other_extension. ptr . lazymessage_value , arena ,
1023+ other_arena);
10151024 } else {
10161025 dst_extension->ptr .message_value ->CheckTypeAndMergeFrom (
10171026 other_extension.ptr .lazymessage_value ->GetMessage (
@@ -1236,11 +1245,11 @@ uint8_t* ExtensionSet::InternalSerializeMessageSetWithCachedSizesToArray(
12361245 return target;
12371246}
12381247
1239- size_t ExtensionSet::ByteSize () const {
1248+ size_t ExtensionSet::ByteSize (const MessageLite* extendee ) const {
12401249 size_t total_size = 0 ;
12411250 ForEach (
1242- [&total_size ](int number, const Extension& ext) {
1243- total_size += ext.ByteSize (number);
1251+ [&](int number, const Extension& ext) {
1252+ total_size += ext.ByteSize (extendee, number, extendee-> GetArena () );
12441253 },
12451254 Prefetch{});
12461255 return total_size;
@@ -1250,12 +1259,15 @@ size_t ExtensionSet::ByteSize() const {
12501259// Defined in extension_set_heavy.cc.
12511260// int ExtensionSet::SpaceUsedExcludingSelf() const
12521261
1253- bool ExtensionSet::MaybeNewExtension (Arena* arena, int number,
1254- const FieldDescriptor* descriptor,
1255- Extension** result) {
1256- bool extension_is_new = false ;
1257- std::tie (*result, extension_is_new) = Insert (arena, number);
1258- (*result)->descriptor = descriptor;
1262+ bool ExtensionSet::MaybeNewExtension (
1263+ Arena* arena, int number,
1264+ Extension::DescriptorOrPrototype descriptor_or_prototype,
1265+ Extension** result_ptr) {
1266+ auto [result, extension_is_new] = Insert (arena, number);
1267+ *result_ptr = result;
1268+ if (extension_is_new) {
1269+ result->descriptor_or_prototype = descriptor_or_prototype;
1270+ }
12591271 return extension_is_new;
12601272}
12611273
@@ -1327,7 +1339,8 @@ void ExtensionSet::Extension::Clear() {
13271339 }
13281340}
13291341
1330- size_t ExtensionSet::Extension::ByteSize (int number) const {
1342+ size_t ExtensionSet::Extension::ByteSize (const MessageLite* extendee,
1343+ int number, Arena* arena) const {
13311344 size_t result = 0 ;
13321345
13331346 if (is_repeated) {
@@ -1443,7 +1456,10 @@ size_t ExtensionSet::Extension::ByteSize(int number) const {
14431456#undef HANDLE_TYPE
14441457 case WireFormatLite::TYPE_MESSAGE: {
14451458 result += WireFormatLite::LengthDelimitedSize (
1446- is_lazy ? ptr.lazymessage_value ->ByteSizeLong ()
1459+ is_lazy ? ptr.lazymessage_value ->ByteSizeLong (
1460+ ExtensionSet::GetOrFindPrototypeForLazyMessage (
1461+ *this , extendee, number),
1462+ arena)
14471463 : ptr.message_value ->ByteSizeLong ());
14481464 break ;
14491465 }
@@ -1554,7 +1570,7 @@ bool ExtensionSet::Extension::IsInitialized(const ExtensionSet* ext_set,
15541570 if (!is_lazy) return ptr.message_value ->IsInitialized ();
15551571
15561572 const MessageLite* prototype =
1557- ext_set->GetPrototypeForLazyMessage ( extendee, number);
1573+ ext_set->GetOrFindPrototypeForLazyMessage (* this , extendee, number);
15581574 ABSL_DCHECK_NE (prototype, nullptr )
15591575 << " extendee: " << extendee->GetTypeName () << " ; number: " << number;
15601576 return ptr.lazymessage_value ->IsInitialized (prototype, arena);
@@ -1857,7 +1873,9 @@ uint8_t* ExtensionSet::Extension::InternalSerializeFieldWithCachedSizesToArray(
18571873 case WireFormatLite::TYPE_MESSAGE:
18581874 if (is_lazy) {
18591875 const auto * prototype =
1860- extension_set->GetPrototypeForLazyMessage (extendee, number);
1876+ extension_set->GetOrFindPrototypeForLazyMessage (*this , extendee,
1877+ number);
1878+ ABSL_DCHECK_NE (prototype, nullptr );
18611879 target = ptr.lazymessage_value ->WriteMessageToArray (prototype, number,
18621880 target, stream);
18631881 } else {
@@ -1871,7 +1889,8 @@ uint8_t* ExtensionSet::Extension::InternalSerializeFieldWithCachedSizesToArray(
18711889 return target;
18721890}
18731891
1874- const MessageLite* ExtensionSet::GetPrototypeForLazyMessage (
1892+ template <bool mustBeGenerated>
1893+ const MessageLite* ExtensionSet::FindPrototypeForLazyMessageImpl (
18751894 const MessageLite* extendee, int number) {
18761895 GeneratedExtensionFinder finder (extendee);
18771896 bool was_packed_on_wire = false ;
@@ -1881,9 +1900,25 @@ const MessageLite* ExtensionSet::GetPrototypeForLazyMessage(
18811900 &extension_info, &was_packed_on_wire)) {
18821901 return nullptr ;
18831902 }
1903+ if constexpr (mustBeGenerated) {
1904+ if (!extension_info.IsGenerated ()) return nullptr ;
1905+ }
18841906 return extension_info.message_info .prototype ;
18851907}
18861908
1909+ const MessageLite* ExtensionSet::FindPrototypeForLazyMessage (
1910+ const MessageLite* extendee, int number) {
1911+ return FindPrototypeForLazyMessageImpl</* mustBeGenerated=*/ false >(extendee,
1912+ number);
1913+ }
1914+
1915+ const MessageLite*
1916+ ExtensionSet::FindPrototypeFromGeneratedFactoryForLazyMessage (
1917+ const MessageLite* extendee, int number) {
1918+ return FindPrototypeForLazyMessageImpl</* mustBeGenerated=*/ true >(extendee,
1919+ number);
1920+ }
1921+
18871922uint8_t *
18881923ExtensionSet::Extension::InternalSerializeMessageSetItemWithCachedSizesToArray (
18891924 const MessageLite* extendee, const ExtensionSet* extension_set, int number,
@@ -1906,8 +1941,9 @@ ExtensionSet::Extension::InternalSerializeMessageSetItemWithCachedSizesToArray(
19061941 WireFormatLite::kMessageSetTypeIdNumber , number, target);
19071942 // Write message.
19081943 if (is_lazy) {
1909- const auto * prototype =
1910- extension_set->GetPrototypeForLazyMessage (extendee, number);
1944+ const auto * prototype = extension_set->GetOrFindPrototypeForLazyMessage (
1945+ *this , extendee, number);
1946+ ABSL_DCHECK_NE (prototype, nullptr );
19111947 target = ptr.lazymessage_value ->WriteMessageToArray (
19121948 prototype, WireFormatLite::kMessageSetMessageNumber , target, stream);
19131949 } else {
@@ -1922,11 +1958,12 @@ ExtensionSet::Extension::InternalSerializeMessageSetItemWithCachedSizesToArray(
19221958 return target;
19231959}
19241960
1925- size_t ExtensionSet::Extension::MessageSetItemByteSize (int number) const {
1961+ size_t ExtensionSet::Extension::MessageSetItemByteSize (
1962+ const MessageLite* extendee, int number, Arena* arena) const {
19261963 if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
19271964 // Not a valid MessageSet extension, but compute the byte size for it the
19281965 // normal way.
1929- return ByteSize (number);
1966+ return ByteSize (extendee, number, arena );
19301967 }
19311968
19321969 if (is_cleared) return 0 ;
@@ -1938,17 +1975,21 @@ size_t ExtensionSet::Extension::MessageSetItemByteSize(int number) const {
19381975
19391976 // message
19401977 our_size += WireFormatLite::LengthDelimitedSize (
1941- is_lazy ? ptr.lazymessage_value ->ByteSizeLong ()
1978+ is_lazy ? ptr.lazymessage_value ->ByteSizeLong (
1979+ ExtensionSet::GetOrFindPrototypeForLazyMessage (
1980+ *this , extendee, number),
1981+ arena)
19421982 : ptr.message_value ->ByteSizeLong ());
19431983
19441984 return our_size;
19451985}
19461986
1947- size_t ExtensionSet::MessageSetByteSize () const {
1987+ size_t ExtensionSet::MessageSetByteSize (const MessageLite* extendee ) const {
19481988 size_t total_size = 0 ;
19491989 ForEach (
1950- [&total_size](int number, const Extension& ext) {
1951- total_size += ext.MessageSetItemByteSize (number);
1990+ [&](int number, const Extension& ext) {
1991+ total_size +=
1992+ ext.MessageSetItemByteSize (extendee, number, extendee->GetArena ());
19521993 },
19531994 Prefetch{});
19541995 return total_size;
0 commit comments