|
|
@ -630,38 +630,40 @@ void ExtensionSet::SetAllocatedMessage(int number, FieldType type, |
|
|
|
ClearExtension(number); |
|
|
|
ClearExtension(number); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
ABSL_DCHECK(message->GetArena() == nullptr || message->GetArena() == arena_); |
|
|
|
Arena* const arena = arena_; |
|
|
|
Arena* message_arena = message->GetArena(); |
|
|
|
Arena* const message_arena = message->GetArena(); |
|
|
|
|
|
|
|
ABSL_DCHECK(message_arena == nullptr || message_arena == arena); |
|
|
|
|
|
|
|
|
|
|
|
Extension* extension; |
|
|
|
Extension* extension; |
|
|
|
if (MaybeNewExtension(number, descriptor, &extension)) { |
|
|
|
if (MaybeNewExtension(number, descriptor, &extension)) { |
|
|
|
extension->type = type; |
|
|
|
extension->type = type; |
|
|
|
ABSL_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE); |
|
|
|
ABSL_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE); |
|
|
|
extension->is_repeated = false; |
|
|
|
extension->is_repeated = false; |
|
|
|
extension->is_lazy = false; |
|
|
|
extension->is_lazy = false; |
|
|
|
if (message_arena == arena_) { |
|
|
|
if (message_arena == arena) { |
|
|
|
extension->message_value = message; |
|
|
|
extension->message_value = message; |
|
|
|
} else if (message_arena == nullptr) { |
|
|
|
} else if (message_arena == nullptr) { |
|
|
|
extension->message_value = message; |
|
|
|
extension->message_value = message; |
|
|
|
arena_->Own(message); // not nullptr because not equal to message_arena
|
|
|
|
arena->Own(message); // not nullptr because not equal to message_arena
|
|
|
|
} else { |
|
|
|
} else { |
|
|
|
extension->message_value = message->New(arena_); |
|
|
|
extension->message_value = message->New(arena); |
|
|
|
extension->message_value->CheckTypeAndMergeFrom(*message); |
|
|
|
extension->message_value->CheckTypeAndMergeFrom(*message); |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
ABSL_DCHECK_TYPE(*extension, OPTIONAL_FIELD, MESSAGE); |
|
|
|
ABSL_DCHECK_TYPE(*extension, OPTIONAL_FIELD, MESSAGE); |
|
|
|
if (extension->is_lazy) { |
|
|
|
if (extension->is_lazy) { |
|
|
|
extension->lazymessage_value->SetAllocatedMessage(message, arena_); |
|
|
|
extension->lazymessage_value->SetAllocatedMessage(message, arena); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
if (arena_ == nullptr) { |
|
|
|
if (arena == nullptr) { |
|
|
|
delete extension->message_value; |
|
|
|
delete extension->message_value; |
|
|
|
} |
|
|
|
} |
|
|
|
if (message_arena == arena_) { |
|
|
|
if (message_arena == arena) { |
|
|
|
extension->message_value = message; |
|
|
|
extension->message_value = message; |
|
|
|
} else if (message_arena == nullptr) { |
|
|
|
} else if (message_arena == nullptr) { |
|
|
|
extension->message_value = message; |
|
|
|
extension->message_value = message; |
|
|
|
arena_->Own(message); // not nullptr because not equal to message_arena
|
|
|
|
arena->Own(message); // not nullptr because not equal to message_arena
|
|
|
|
} else { |
|
|
|
} else { |
|
|
|
extension->message_value = message->New(arena_); |
|
|
|
extension->message_value = message->New(arena); |
|
|
|
extension->message_value->CheckTypeAndMergeFrom(*message); |
|
|
|
extension->message_value->CheckTypeAndMergeFrom(*message); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -708,8 +710,9 @@ MessageLite* ExtensionSet::ReleaseMessage(int number, |
|
|
|
ABSL_DCHECK_TYPE(*extension, OPTIONAL_FIELD, MESSAGE); |
|
|
|
ABSL_DCHECK_TYPE(*extension, OPTIONAL_FIELD, MESSAGE); |
|
|
|
MessageLite* ret = nullptr; |
|
|
|
MessageLite* ret = nullptr; |
|
|
|
if (extension->is_lazy) { |
|
|
|
if (extension->is_lazy) { |
|
|
|
ret = extension->lazymessage_value->ReleaseMessage(prototype, arena_); |
|
|
|
Arena* const arena = arena_; |
|
|
|
if (arena_ == nullptr) { |
|
|
|
ret = extension->lazymessage_value->ReleaseMessage(prototype, arena); |
|
|
|
|
|
|
|
if (arena == nullptr) { |
|
|
|
delete extension->lazymessage_value; |
|
|
|
delete extension->lazymessage_value; |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
@ -737,9 +740,10 @@ MessageLite* ExtensionSet::UnsafeArenaReleaseMessage( |
|
|
|
ABSL_DCHECK_TYPE(*extension, OPTIONAL_FIELD, MESSAGE); |
|
|
|
ABSL_DCHECK_TYPE(*extension, OPTIONAL_FIELD, MESSAGE); |
|
|
|
MessageLite* ret = nullptr; |
|
|
|
MessageLite* ret = nullptr; |
|
|
|
if (extension->is_lazy) { |
|
|
|
if (extension->is_lazy) { |
|
|
|
|
|
|
|
Arena* const arena = arena_; |
|
|
|
ret = extension->lazymessage_value->UnsafeArenaReleaseMessage(prototype, |
|
|
|
ret = extension->lazymessage_value->UnsafeArenaReleaseMessage(prototype, |
|
|
|
arena_); |
|
|
|
arena); |
|
|
|
if (arena_ == nullptr) { |
|
|
|
if (arena == nullptr) { |
|
|
|
delete extension->lazymessage_value; |
|
|
|
delete extension->lazymessage_value; |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
@ -994,10 +998,11 @@ void ExtensionSet::InternalExtensionMergeFrom(const MessageLite* extendee, |
|
|
|
HANDLE_TYPE(STRING, string, RepeatedPtrField<std::string>); |
|
|
|
HANDLE_TYPE(STRING, string, RepeatedPtrField<std::string>); |
|
|
|
#undef HANDLE_TYPE |
|
|
|
#undef HANDLE_TYPE |
|
|
|
|
|
|
|
|
|
|
|
case WireFormatLite::CPPTYPE_MESSAGE: |
|
|
|
case WireFormatLite::CPPTYPE_MESSAGE: { |
|
|
|
|
|
|
|
Arena* const arena = arena_; |
|
|
|
if (is_new) { |
|
|
|
if (is_new) { |
|
|
|
extension->repeated_message_value = |
|
|
|
extension->repeated_message_value = |
|
|
|
Arena::CreateMessage<RepeatedPtrField<MessageLite>>(arena_); |
|
|
|
Arena::CreateMessage<RepeatedPtrField<MessageLite>>(arena); |
|
|
|
} |
|
|
|
} |
|
|
|
// We can't call RepeatedPtrField<MessageLite>::MergeFrom() because
|
|
|
|
// We can't call RepeatedPtrField<MessageLite>::MergeFrom() because
|
|
|
|
// it would attempt to allocate new objects.
|
|
|
|
// it would attempt to allocate new objects.
|
|
|
@ -1010,12 +1015,13 @@ void ExtensionSet::InternalExtensionMergeFrom(const MessageLite* extendee, |
|
|
|
extension->repeated_message_value) |
|
|
|
extension->repeated_message_value) |
|
|
|
->AddFromCleared<GenericTypeHandler<MessageLite>>(); |
|
|
|
->AddFromCleared<GenericTypeHandler<MessageLite>>(); |
|
|
|
if (target == nullptr) { |
|
|
|
if (target == nullptr) { |
|
|
|
target = other_message.New(arena_); |
|
|
|
target = other_message.New(arena); |
|
|
|
extension->repeated_message_value->AddAllocated(target); |
|
|
|
extension->repeated_message_value->AddAllocated(target); |
|
|
|
} |
|
|
|
} |
|
|
|
target->CheckTypeAndMergeFrom(other_message); |
|
|
|
target->CheckTypeAndMergeFrom(other_message); |
|
|
|
} |
|
|
|
} |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
if (!other_extension.is_cleared) { |
|
|
|
if (!other_extension.is_cleared) { |
|
|
@ -1041,6 +1047,7 @@ void ExtensionSet::InternalExtensionMergeFrom(const MessageLite* extendee, |
|
|
|
other_extension.descriptor); |
|
|
|
other_extension.descriptor); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case WireFormatLite::CPPTYPE_MESSAGE: { |
|
|
|
case WireFormatLite::CPPTYPE_MESSAGE: { |
|
|
|
|
|
|
|
Arena* const arena = arena_; |
|
|
|
Extension* extension; |
|
|
|
Extension* extension; |
|
|
|
bool is_new = |
|
|
|
bool is_new = |
|
|
|
MaybeNewExtension(number, other_extension.descriptor, &extension); |
|
|
|
MaybeNewExtension(number, other_extension.descriptor, &extension); |
|
|
@ -1051,14 +1058,14 @@ void ExtensionSet::InternalExtensionMergeFrom(const MessageLite* extendee, |
|
|
|
if (other_extension.is_lazy) { |
|
|
|
if (other_extension.is_lazy) { |
|
|
|
extension->is_lazy = true; |
|
|
|
extension->is_lazy = true; |
|
|
|
extension->lazymessage_value = |
|
|
|
extension->lazymessage_value = |
|
|
|
other_extension.lazymessage_value->New(arena_); |
|
|
|
other_extension.lazymessage_value->New(arena); |
|
|
|
extension->lazymessage_value->MergeFrom( |
|
|
|
extension->lazymessage_value->MergeFrom( |
|
|
|
GetPrototypeForLazyMessage(extendee, number), |
|
|
|
GetPrototypeForLazyMessage(extendee, number), |
|
|
|
*other_extension.lazymessage_value, arena_); |
|
|
|
*other_extension.lazymessage_value, arena); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
extension->is_lazy = false; |
|
|
|
extension->is_lazy = false; |
|
|
|
extension->message_value = |
|
|
|
extension->message_value = |
|
|
|
other_extension.message_value->New(arena_); |
|
|
|
other_extension.message_value->New(arena); |
|
|
|
extension->message_value->CheckTypeAndMergeFrom( |
|
|
|
extension->message_value->CheckTypeAndMergeFrom( |
|
|
|
*other_extension.message_value); |
|
|
|
*other_extension.message_value); |
|
|
|
} |
|
|
|
} |
|
|
@ -1070,7 +1077,7 @@ void ExtensionSet::InternalExtensionMergeFrom(const MessageLite* extendee, |
|
|
|
if (extension->is_lazy) { |
|
|
|
if (extension->is_lazy) { |
|
|
|
extension->lazymessage_value->MergeFrom( |
|
|
|
extension->lazymessage_value->MergeFrom( |
|
|
|
GetPrototypeForLazyMessage(extendee, number), |
|
|
|
GetPrototypeForLazyMessage(extendee, number), |
|
|
|
*other_extension.lazymessage_value, arena_); |
|
|
|
*other_extension.lazymessage_value, arena); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
extension->message_value->CheckTypeAndMergeFrom( |
|
|
|
extension->message_value->CheckTypeAndMergeFrom( |
|
|
|
other_extension.lazymessage_value->GetMessage( |
|
|
|
other_extension.lazymessage_value->GetMessage( |
|
|
@ -1079,7 +1086,7 @@ void ExtensionSet::InternalExtensionMergeFrom(const MessageLite* extendee, |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
if (extension->is_lazy) { |
|
|
|
if (extension->is_lazy) { |
|
|
|
extension->lazymessage_value |
|
|
|
extension->lazymessage_value |
|
|
|
->MutableMessage(*other_extension.message_value, arena_) |
|
|
|
->MutableMessage(*other_extension.message_value, arena) |
|
|
|
->CheckTypeAndMergeFrom(*other_extension.message_value); |
|
|
|
->CheckTypeAndMergeFrom(*other_extension.message_value); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
extension->message_value->CheckTypeAndMergeFrom( |
|
|
|
extension->message_value->CheckTypeAndMergeFrom( |
|
|
@ -1097,9 +1104,9 @@ void ExtensionSet::InternalExtensionMergeFrom(const MessageLite* extendee, |
|
|
|
|
|
|
|
|
|
|
|
void ExtensionSet::Swap(const MessageLite* extendee, ExtensionSet* other) { |
|
|
|
void ExtensionSet::Swap(const MessageLite* extendee, ExtensionSet* other) { |
|
|
|
#ifdef PROTOBUF_FORCE_COPY_IN_SWAP |
|
|
|
#ifdef PROTOBUF_FORCE_COPY_IN_SWAP |
|
|
|
if (GetArena() != nullptr && GetArena() == other->GetArena()) { |
|
|
|
if (arena_ != nullptr && arena_ == other->arena_) { |
|
|
|
#else // PROTOBUF_FORCE_COPY_IN_SWAP
|
|
|
|
#else // PROTOBUF_FORCE_COPY_IN_SWAP
|
|
|
|
if (GetArena() == other->GetArena()) { |
|
|
|
if (arena_ == other->arena_) { |
|
|
|
#endif // !PROTOBUF_FORCE_COPY_IN_SWAP
|
|
|
|
#endif // !PROTOBUF_FORCE_COPY_IN_SWAP
|
|
|
|
InternalSwap(other); |
|
|
|
InternalSwap(other); |
|
|
|
} else { |
|
|
|
} else { |
|
|
@ -1127,7 +1134,9 @@ void ExtensionSet::SwapExtension(const MessageLite* extendee, |
|
|
|
ExtensionSet* other, int number) { |
|
|
|
ExtensionSet* other, int number) { |
|
|
|
if (this == other) return; |
|
|
|
if (this == other) return; |
|
|
|
|
|
|
|
|
|
|
|
if (GetArena() == other->GetArena()) { |
|
|
|
Arena* const arena = arena_; |
|
|
|
|
|
|
|
Arena* const other_arena = other->arena_; |
|
|
|
|
|
|
|
if (arena == other_arena) { |
|
|
|
UnsafeShallowSwapExtension(other, number); |
|
|
|
UnsafeShallowSwapExtension(other, number); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
@ -1144,23 +1153,20 @@ void ExtensionSet::SwapExtension(const MessageLite* extendee, |
|
|
|
// We do it this way to reuse the copy-across-arenas logic already
|
|
|
|
// We do it this way to reuse the copy-across-arenas logic already
|
|
|
|
// implemented in ExtensionSet's MergeFrom.
|
|
|
|
// implemented in ExtensionSet's MergeFrom.
|
|
|
|
ExtensionSet temp; |
|
|
|
ExtensionSet temp; |
|
|
|
temp.InternalExtensionMergeFrom(extendee, number, *other_ext, |
|
|
|
temp.InternalExtensionMergeFrom(extendee, number, *other_ext, other_arena); |
|
|
|
other->GetArena()); |
|
|
|
|
|
|
|
Extension* temp_ext = temp.FindOrNull(number); |
|
|
|
Extension* temp_ext = temp.FindOrNull(number); |
|
|
|
|
|
|
|
|
|
|
|
other_ext->Clear(); |
|
|
|
other_ext->Clear(); |
|
|
|
other->InternalExtensionMergeFrom(extendee, number, *this_ext, |
|
|
|
other->InternalExtensionMergeFrom(extendee, number, *this_ext, arena); |
|
|
|
this->GetArena()); |
|
|
|
|
|
|
|
this_ext->Clear(); |
|
|
|
this_ext->Clear(); |
|
|
|
InternalExtensionMergeFrom(extendee, number, *temp_ext, temp.GetArena()); |
|
|
|
InternalExtensionMergeFrom(extendee, number, *temp_ext, temp.GetArena()); |
|
|
|
} else if (this_ext == nullptr) { |
|
|
|
} else if (this_ext == nullptr) { |
|
|
|
InternalExtensionMergeFrom(extendee, number, *other_ext, other->GetArena()); |
|
|
|
InternalExtensionMergeFrom(extendee, number, *other_ext, other_arena); |
|
|
|
if (other->GetArena() == nullptr) other_ext->Free(); |
|
|
|
if (other_arena == nullptr) other_ext->Free(); |
|
|
|
other->Erase(number); |
|
|
|
other->Erase(number); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
other->InternalExtensionMergeFrom(extendee, number, *this_ext, |
|
|
|
other->InternalExtensionMergeFrom(extendee, number, *this_ext, arena); |
|
|
|
this->GetArena()); |
|
|
|
if (arena == nullptr) this_ext->Free(); |
|
|
|
if (GetArena() == nullptr) this_ext->Free(); |
|
|
|
|
|
|
|
Erase(number); |
|
|
|
Erase(number); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -1173,7 +1179,7 @@ void ExtensionSet::UnsafeShallowSwapExtension(ExtensionSet* other, int number) { |
|
|
|
|
|
|
|
|
|
|
|
if (this_ext == other_ext) return; |
|
|
|
if (this_ext == other_ext) return; |
|
|
|
|
|
|
|
|
|
|
|
ABSL_DCHECK_EQ(GetArena(), other->GetArena()); |
|
|
|
ABSL_DCHECK_EQ(arena_, other->arena_); |
|
|
|
|
|
|
|
|
|
|
|
if (this_ext != nullptr && other_ext != nullptr) { |
|
|
|
if (this_ext != nullptr && other_ext != nullptr) { |
|
|
|
std::swap(*this_ext, *other_ext); |
|
|
|
std::swap(*this_ext, *other_ext); |
|
|
@ -1189,16 +1195,17 @@ void ExtensionSet::UnsafeShallowSwapExtension(ExtensionSet* other, int number) { |
|
|
|
bool ExtensionSet::IsInitialized(const MessageLite* extendee) const { |
|
|
|
bool ExtensionSet::IsInitialized(const MessageLite* extendee) const { |
|
|
|
// Extensions are never required. However, we need to check that all
|
|
|
|
// Extensions are never required. However, we need to check that all
|
|
|
|
// embedded messages are initialized.
|
|
|
|
// embedded messages are initialized.
|
|
|
|
|
|
|
|
Arena* const arena = arena_; |
|
|
|
if (PROTOBUF_PREDICT_FALSE(is_large())) { |
|
|
|
if (PROTOBUF_PREDICT_FALSE(is_large())) { |
|
|
|
for (const auto& kv : *map_.large) { |
|
|
|
for (const auto& kv : *map_.large) { |
|
|
|
if (!kv.second.IsInitialized(this, extendee, kv.first, arena_)) { |
|
|
|
if (!kv.second.IsInitialized(this, extendee, kv.first, arena)) { |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
for (const KeyValue* it = flat_begin(); it != flat_end(); ++it) { |
|
|
|
for (const KeyValue* it = flat_begin(); it != flat_end(); ++it) { |
|
|
|
if (!it->second.IsInitialized(this, extendee, it->first, arena_)) { |
|
|
|
if (!it->second.IsInitialized(this, extendee, it->first, arena)) { |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -1639,8 +1646,9 @@ void ExtensionSet::GrowCapacity(size_t minimum_new_capacity) { |
|
|
|
const KeyValue* begin = flat_begin(); |
|
|
|
const KeyValue* begin = flat_begin(); |
|
|
|
const KeyValue* end = flat_end(); |
|
|
|
const KeyValue* end = flat_end(); |
|
|
|
AllocatedData new_map; |
|
|
|
AllocatedData new_map; |
|
|
|
|
|
|
|
Arena* const arena = arena_; |
|
|
|
if (new_flat_capacity > kMaximumFlatCapacity) { |
|
|
|
if (new_flat_capacity > kMaximumFlatCapacity) { |
|
|
|
new_map.large = Arena::Create<LargeMap>(arena_); |
|
|
|
new_map.large = Arena::Create<LargeMap>(arena); |
|
|
|
LargeMap::iterator hint = new_map.large->begin(); |
|
|
|
LargeMap::iterator hint = new_map.large->begin(); |
|
|
|
for (const KeyValue* it = begin; it != end; ++it) { |
|
|
|
for (const KeyValue* it = begin; it != end; ++it) { |
|
|
|
hint = new_map.large->insert(hint, {it->first, it->second}); |
|
|
|
hint = new_map.large->insert(hint, {it->first, it->second}); |
|
|
@ -1648,11 +1656,11 @@ void ExtensionSet::GrowCapacity(size_t minimum_new_capacity) { |
|
|
|
flat_size_ = static_cast<uint16_t>(-1); |
|
|
|
flat_size_ = static_cast<uint16_t>(-1); |
|
|
|
ABSL_DCHECK(is_large()); |
|
|
|
ABSL_DCHECK(is_large()); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
new_map.flat = Arena::CreateArray<KeyValue>(arena_, new_flat_capacity); |
|
|
|
new_map.flat = Arena::CreateArray<KeyValue>(arena, new_flat_capacity); |
|
|
|
std::copy(begin, end, new_map.flat); |
|
|
|
std::copy(begin, end, new_map.flat); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (arena_ == nullptr) { |
|
|
|
if (arena == nullptr) { |
|
|
|
DeleteFlatMap(begin, flat_capacity_); |
|
|
|
DeleteFlatMap(begin, flat_capacity_); |
|
|
|
} |
|
|
|
} |
|
|
|
flat_capacity_ = new_flat_capacity; |
|
|
|
flat_capacity_ = new_flat_capacity; |
|
|
|