Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(104)

Unified Diff: third_party/protobuf/src/google/protobuf/extension_set.cc

Issue 1842653006: Update //third_party/protobuf to version 3. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: merge Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/protobuf/src/google/protobuf/extension_set.cc
diff --git a/third_party/protobuf/src/google/protobuf/extension_set.cc b/third_party/protobuf/src/google/protobuf/extension_set.cc
index 418e068407b03f61231840fa43a586458bfb547d..9afb236147c0cfd60c4d60b5d3bd55a833052161 100644
--- a/third_party/protobuf/src/google/protobuf/extension_set.cc
+++ b/third_party/protobuf/src/google/protobuf/extension_set.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// http://code.google.com/p/protobuf/
+// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -38,10 +38,9 @@
#include <google/protobuf/extension_set.h>
#include <google/protobuf/message_lite.h>
#include <google/protobuf/io/coded_stream.h>
-#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/wire_format_lite_inl.h>
#include <google/protobuf/repeated_field.h>
-#include <google/protobuf/stubs/map-util.h>
+#include <google/protobuf/stubs/map_util.h>
namespace google {
namespace protobuf {
@@ -58,6 +57,24 @@ inline WireFormatLite::CppType cpp_type(FieldType type) {
return WireFormatLite::FieldTypeToCppType(real_type(type));
}
+inline bool is_packable(WireFormatLite::WireType type) {
+ switch (type) {
+ case WireFormatLite::WIRETYPE_VARINT:
+ case WireFormatLite::WIRETYPE_FIXED64:
+ case WireFormatLite::WIRETYPE_FIXED32:
+ return true;
+ case WireFormatLite::WIRETYPE_LENGTH_DELIMITED:
+ case WireFormatLite::WIRETYPE_START_GROUP:
+ case WireFormatLite::WIRETYPE_END_GROUP:
+ return false;
+
+ // Do not add a default statement. Let the compiler complain when someone
+ // adds a new wire type.
+ }
+ GOOGLE_LOG(FATAL) << "can't reach here.";
+ return false;
+}
+
// Registry stuff.
typedef hash_map<pair<const MessageLite*, int>,
ExtensionInfo> ExtensionRegistry;
@@ -80,7 +97,7 @@ void Register(const MessageLite* containing_type,
int number, ExtensionInfo info) {
::google::protobuf::GoogleOnceInit(&registry_init_, &InitRegistry);
- if (!InsertIfNotPresent(registry_, make_pair(containing_type, number),
+ if (!InsertIfNotPresent(registry_, std::make_pair(containing_type, number),
info)) {
GOOGLE_LOG(FATAL) << "Multiple extension registrations for type \""
<< containing_type->GetTypeName()
@@ -90,8 +107,9 @@ void Register(const MessageLite* containing_type,
const ExtensionInfo* FindRegisteredExtension(
const MessageLite* containing_type, int number) {
- return (registry_ == NULL) ? NULL :
- FindOrNull(*registry_, make_pair(containing_type, number));
+ return (registry_ == NULL)
+ ? NULL
+ : FindOrNull(*registry_, std::make_pair(containing_type, number));
}
} // namespace
@@ -159,12 +177,21 @@ void ExtensionSet::RegisterMessageExtension(const MessageLite* containing_type,
// ===================================================================
// Constructors and basic methods.
-ExtensionSet::ExtensionSet() {}
+ExtensionSet::ExtensionSet(::google::protobuf::Arena* arena) : arena_(arena) {
+ if (arena_ != NULL) {
+ arena_->OwnDestructor(&extensions_);
+ }
+}
+
+ExtensionSet::ExtensionSet() : arena_(NULL) {}
ExtensionSet::~ExtensionSet() {
- for (map<int, Extension>::iterator iter = extensions_.begin();
- iter != extensions_.end(); ++iter) {
- iter->second.Free();
+ // Deletes all allocated extensions.
+ if (arena_ == NULL) {
+ for (map<int, Extension>::iterator iter = extensions_.begin();
+ iter != extensions_.end(); ++iter) {
+ iter->second.Free();
+ }
}
}
@@ -286,7 +313,8 @@ void ExtensionSet::Add##CAMELCASE(int number, FieldType type, \
GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \
extension->is_repeated = true; \
extension->is_packed = packed; \
- extension->repeated_##LOWERCASE##_value = new RepeatedField<LOWERCASE>(); \
+ extension->repeated_##LOWERCASE##_value = \
+ Arena::CreateMessage<RepeatedField<LOWERCASE> >(arena_); \
} else { \
GOOGLE_DCHECK_TYPE(*extension, REPEATED, UPPERCASE); \
GOOGLE_DCHECK_EQ(extension->is_packed, packed); \
@@ -304,14 +332,90 @@ PRIMITIVE_ACCESSORS( BOOL, bool, Bool)
#undef PRIMITIVE_ACCESSORS
+const void* ExtensionSet::GetRawRepeatedField(int number,
+ const void* default_value) const {
+ map<int, Extension>::const_iterator iter = extensions_.find(number);
+ if (iter == extensions_.end()) {
+ return default_value;
+ }
+ // We assume that all the RepeatedField<>* pointers have the same
+ // size and alignment within the anonymous union in Extension.
+ return iter->second.repeated_int32_value;
+}
+
+void* ExtensionSet::MutableRawRepeatedField(int number, FieldType field_type,
+ bool packed,
+ const FieldDescriptor* desc) {
+ Extension* extension;
+
+ // We instantiate an empty Repeated{,Ptr}Field if one doesn't exist for this
+ // extension.
+ if (MaybeNewExtension(number, desc, &extension)) {
+ extension->is_repeated = true;
+ extension->type = field_type;
+ extension->is_packed = packed;
+
+ switch (WireFormatLite::FieldTypeToCppType(
+ static_cast<WireFormatLite::FieldType>(field_type))) {
+ case WireFormatLite::CPPTYPE_INT32:
+ extension->repeated_int32_value =
+ Arena::CreateMessage<RepeatedField<int32> >(arena_);
+ break;
+ case WireFormatLite::CPPTYPE_INT64:
+ extension->repeated_int64_value =
+ Arena::CreateMessage<RepeatedField<int64> >(arena_);
+ break;
+ case WireFormatLite::CPPTYPE_UINT32:
+ extension->repeated_uint32_value =
+ Arena::CreateMessage<RepeatedField<uint32> >(arena_);
+ break;
+ case WireFormatLite::CPPTYPE_UINT64:
+ extension->repeated_uint64_value =
+ Arena::CreateMessage<RepeatedField<uint64> >(arena_);
+ break;
+ case WireFormatLite::CPPTYPE_DOUBLE:
+ extension->repeated_double_value =
+ Arena::CreateMessage<RepeatedField<double> >(arena_);
+ break;
+ case WireFormatLite::CPPTYPE_FLOAT:
+ extension->repeated_float_value =
+ Arena::CreateMessage<RepeatedField<float> >(arena_);
+ break;
+ case WireFormatLite::CPPTYPE_BOOL:
+ extension->repeated_bool_value =
+ Arena::CreateMessage<RepeatedField<bool> >(arena_);
+ break;
+ case WireFormatLite::CPPTYPE_ENUM:
+ extension->repeated_enum_value =
+ Arena::CreateMessage<RepeatedField<int> >(arena_);
+ break;
+ case WireFormatLite::CPPTYPE_STRING:
+ extension->repeated_string_value =
+ Arena::CreateMessage<RepeatedPtrField< ::std::string> >(arena_);
+ break;
+ case WireFormatLite::CPPTYPE_MESSAGE:
+ extension->repeated_message_value =
+ Arena::CreateMessage<RepeatedPtrField<MessageLite> >(arena_);
+ break;
+ }
+ }
+
+ // We assume that all the RepeatedField<>* pointers have the same
+ // size and alignment within the anonymous union in Extension.
+ return extension->repeated_int32_value;
+}
+
+// Compatible version using old call signature. Does not create extensions when
+// the don't already exist; instead, just GOOGLE_CHECK-fails.
void* ExtensionSet::MutableRawRepeatedField(int number) {
+ map<int, Extension>::iterator iter = extensions_.find(number);
+ GOOGLE_CHECK(iter == extensions_.end()) << "Extension not found.";
// We assume that all the RepeatedField<>* pointers have the same
// size and alignment within the anonymous union in Extension.
- map<int, Extension>::const_iterator iter = extensions_.find(number);
- GOOGLE_CHECK(iter != extensions_.end()) << "no extension numbered " << number;
return iter->second.repeated_int32_value;
}
+
// -------------------------------------------------------------------
// Enums
@@ -363,7 +467,8 @@ void ExtensionSet::AddEnum(int number, FieldType type,
GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM);
extension->is_repeated = true;
extension->is_packed = packed;
- extension->repeated_enum_value = new RepeatedField<int>();
+ extension->repeated_enum_value =
+ Arena::CreateMessage<RepeatedField<int> >(arena_);
} else {
GOOGLE_DCHECK_TYPE(*extension, REPEATED, ENUM);
GOOGLE_DCHECK_EQ(extension->is_packed, packed);
@@ -393,7 +498,7 @@ string* ExtensionSet::MutableString(int number, FieldType type,
extension->type = type;
GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING);
extension->is_repeated = false;
- extension->string_value = new string;
+ extension->string_value = Arena::Create<string>(arena_);
} else {
GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, STRING);
}
@@ -423,7 +528,8 @@ string* ExtensionSet::AddString(int number, FieldType type,
GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING);
extension->is_repeated = true;
extension->is_packed = false;
- extension->repeated_string_value = new RepeatedPtrField<string>();
+ extension->repeated_string_value =
+ Arena::CreateMessage<RepeatedPtrField<string> >(arena_);
} else {
GOOGLE_DCHECK_TYPE(*extension, REPEATED, STRING);
}
@@ -463,7 +569,7 @@ MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
extension->is_repeated = false;
extension->is_lazy = false;
- extension->message_value = prototype.New();
+ extension->message_value = prototype.New(arena_);
extension->is_cleared = false;
return extension->message_value;
} else {
@@ -489,25 +595,73 @@ void ExtensionSet::SetAllocatedMessage(int number, FieldType type,
ClearExtension(number);
return;
}
+ ::google::protobuf::Arena* message_arena = message->GetArena();
Extension* extension;
if (MaybeNewExtension(number, descriptor, &extension)) {
extension->type = type;
GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
extension->is_repeated = false;
extension->is_lazy = false;
- extension->message_value = message;
+ if (message_arena == arena_) {
+ extension->message_value = message;
+ } else if (message_arena == NULL) {
+ extension->message_value = message;
+ arena_->Own(message); // not NULL because not equal to message_arena
+ } else {
+ extension->message_value = message->New(arena_);
+ extension->message_value->CheckTypeAndMergeFrom(*message);
+ }
} else {
GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
if (extension->is_lazy) {
extension->lazymessage_value->SetAllocatedMessage(message);
} else {
- delete extension->message_value;
+ if (arena_ == NULL) {
+ delete extension->message_value;
+ }
+ if (message_arena == arena_) {
+ extension->message_value = message;
+ } else if (message_arena == NULL) {
+ extension->message_value = message;
+ arena_->Own(message); // not NULL because not equal to message_arena
+ } else {
+ extension->message_value = message->New(arena_);
+ extension->message_value->CheckTypeAndMergeFrom(*message);
+ }
+ }
+ }
+ extension->is_cleared = false;
+}
+
+void ExtensionSet::UnsafeArenaSetAllocatedMessage(
+ int number, FieldType type, const FieldDescriptor* descriptor,
+ MessageLite* message) {
+ if (message == NULL) {
+ ClearExtension(number);
+ return;
+ }
+ Extension* extension;
+ if (MaybeNewExtension(number, descriptor, &extension)) {
+ extension->type = type;
+ GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
+ extension->is_repeated = false;
+ extension->is_lazy = false;
+ extension->message_value = message;
+ } else {
+ GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
+ if (extension->is_lazy) {
+ extension->lazymessage_value->UnsafeArenaSetAllocatedMessage(message);
+ } else {
+ if (arena_ == NULL) {
+ delete extension->message_value;
+ }
extension->message_value = message;
}
}
extension->is_cleared = false;
}
+
MessageLite* ExtensionSet::ReleaseMessage(int number,
const MessageLite& prototype) {
map<int, Extension>::iterator iter = extensions_.find(number);
@@ -519,7 +673,39 @@ MessageLite* ExtensionSet::ReleaseMessage(int number,
MessageLite* ret = NULL;
if (iter->second.is_lazy) {
ret = iter->second.lazymessage_value->ReleaseMessage(prototype);
- delete iter->second.lazymessage_value;
+ if (arena_ == NULL) {
+ delete iter->second.lazymessage_value;
+ }
+ } else {
+ if (arena_ == NULL) {
+ ret = iter->second.message_value;
+ } else {
+ // ReleaseMessage() always returns a heap-allocated message, and we are
+ // on an arena, so we need to make a copy of this message to return.
+ ret = (iter->second.message_value)->New();
+ ret->CheckTypeAndMergeFrom(*iter->second.message_value);
+ }
+ }
+ extensions_.erase(number);
+ return ret;
+ }
+}
+
+MessageLite* ExtensionSet::UnsafeArenaReleaseMessage(
+ int number, const MessageLite& prototype) {
+ map<int, Extension>::iterator iter = extensions_.find(number);
+ if (iter == extensions_.end()) {
+ // Not present. Return NULL.
+ return NULL;
+ } else {
+ GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
+ MessageLite* ret = NULL;
+ if (iter->second.is_lazy) {
+ ret =
+ iter->second.lazymessage_value->UnsafeArenaReleaseMessage(prototype);
+ if (arena_ == NULL) {
+ delete iter->second.lazymessage_value;
+ }
} else {
ret = iter->second.message_value;
}
@@ -556,7 +742,7 @@ MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
extension->is_repeated = true;
extension->repeated_message_value =
- new RepeatedPtrField<MessageLite>();
+ Arena::CreateMessage<RepeatedPtrField<MessageLite> >(arena_);
} else {
GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE);
}
@@ -566,7 +752,7 @@ MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
MessageLite* result = extension->repeated_message_value
->AddFromCleared<GenericTypeHandler<MessageLite> >();
if (result == NULL) {
- result = prototype.New();
+ result = prototype.New(arena_);
extension->repeated_message_value->AddAllocated(result);
}
return result;
@@ -684,138 +870,142 @@ void ExtensionSet::MergeFrom(const ExtensionSet& other) {
for (map<int, Extension>::const_iterator iter = other.extensions_.begin();
iter != other.extensions_.end(); ++iter) {
const Extension& other_extension = iter->second;
+ InternalExtensionMergeFrom(iter->first, other_extension);
+ }
+}
- if (other_extension.is_repeated) {
- Extension* extension;
- bool is_new = MaybeNewExtension(iter->first, other_extension.descriptor,
- &extension);
- if (is_new) {
- // Extension did not already exist in set.
- extension->type = other_extension.type;
- extension->is_packed = other_extension.is_packed;
- extension->is_repeated = true;
- } else {
- GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
- GOOGLE_DCHECK_EQ(extension->is_packed, other_extension.is_packed);
- GOOGLE_DCHECK(extension->is_repeated);
- }
+void ExtensionSet::InternalExtensionMergeFrom(
+ int number, const Extension& other_extension) {
+ if (other_extension.is_repeated) {
+ Extension* extension;
+ bool is_new = MaybeNewExtension(number, other_extension.descriptor,
+ &extension);
+ if (is_new) {
+ // Extension did not already exist in set.
+ extension->type = other_extension.type;
+ extension->is_packed = other_extension.is_packed;
+ extension->is_repeated = true;
+ } else {
+ GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
+ GOOGLE_DCHECK_EQ(extension->is_packed, other_extension.is_packed);
+ GOOGLE_DCHECK(extension->is_repeated);
+ }
- switch (cpp_type(other_extension.type)) {
-#define HANDLE_TYPE(UPPERCASE, LOWERCASE, REPEATED_TYPE) \
- case WireFormatLite::CPPTYPE_##UPPERCASE: \
- if (is_new) { \
- extension->repeated_##LOWERCASE##_value = \
- new REPEATED_TYPE; \
- } \
- extension->repeated_##LOWERCASE##_value->MergeFrom( \
- *other_extension.repeated_##LOWERCASE##_value); \
- break;
+ switch (cpp_type(other_extension.type)) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE, REPEATED_TYPE) \
+ case WireFormatLite::CPPTYPE_##UPPERCASE: \
+ if (is_new) { \
+ extension->repeated_##LOWERCASE##_value = \
+ Arena::CreateMessage<REPEATED_TYPE >(arena_); \
+ } \
+ extension->repeated_##LOWERCASE##_value->MergeFrom( \
+ *other_extension.repeated_##LOWERCASE##_value); \
+ break;
- HANDLE_TYPE( INT32, int32, RepeatedField < int32>);
- HANDLE_TYPE( INT64, int64, RepeatedField < int64>);
- HANDLE_TYPE( UINT32, uint32, RepeatedField < uint32>);
- HANDLE_TYPE( UINT64, uint64, RepeatedField < uint64>);
- HANDLE_TYPE( FLOAT, float, RepeatedField < float>);
- HANDLE_TYPE( DOUBLE, double, RepeatedField < double>);
- HANDLE_TYPE( BOOL, bool, RepeatedField < bool>);
- HANDLE_TYPE( ENUM, enum, RepeatedField < int>);
- HANDLE_TYPE( STRING, string, RepeatedPtrField< string>);
+ HANDLE_TYPE( INT32, int32, RepeatedField < int32>);
+ HANDLE_TYPE( INT64, int64, RepeatedField < int64>);
+ HANDLE_TYPE( UINT32, uint32, RepeatedField < uint32>);
+ HANDLE_TYPE( UINT64, uint64, RepeatedField < uint64>);
+ HANDLE_TYPE( FLOAT, float, RepeatedField < float>);
+ HANDLE_TYPE( DOUBLE, double, RepeatedField < double>);
+ HANDLE_TYPE( BOOL, bool, RepeatedField < bool>);
+ HANDLE_TYPE( ENUM, enum, RepeatedField < int>);
+ HANDLE_TYPE( STRING, string, RepeatedPtrField< string>);
#undef HANDLE_TYPE
- case WireFormatLite::CPPTYPE_MESSAGE:
- if (is_new) {
- extension->repeated_message_value =
- new RepeatedPtrField<MessageLite>();
- }
- // We can't call RepeatedPtrField<MessageLite>::MergeFrom() because
- // it would attempt to allocate new objects.
- RepeatedPtrField<MessageLite>* other_repeated_message =
- other_extension.repeated_message_value;
- for (int i = 0; i < other_repeated_message->size(); i++) {
- const MessageLite& other_message = other_repeated_message->Get(i);
- MessageLite* target = extension->repeated_message_value
- ->AddFromCleared<GenericTypeHandler<MessageLite> >();
- if (target == NULL) {
- target = other_message.New();
- extension->repeated_message_value->AddAllocated(target);
- }
- target->CheckTypeAndMergeFrom(other_message);
+ case WireFormatLite::CPPTYPE_MESSAGE:
+ if (is_new) {
+ extension->repeated_message_value =
+ Arena::CreateMessage<RepeatedPtrField<MessageLite> >(arena_);
+ }
+ // We can't call RepeatedPtrField<MessageLite>::MergeFrom() because
+ // it would attempt to allocate new objects.
+ RepeatedPtrField<MessageLite>* other_repeated_message =
+ other_extension.repeated_message_value;
+ for (int i = 0; i < other_repeated_message->size(); i++) {
+ const MessageLite& other_message = other_repeated_message->Get(i);
+ MessageLite* target = extension->repeated_message_value
+ ->AddFromCleared<GenericTypeHandler<MessageLite> >();
+ if (target == NULL) {
+ target = other_message.New(arena_);
+ extension->repeated_message_value->AddAllocated(target);
}
+ target->CheckTypeAndMergeFrom(other_message);
+ }
+ break;
+ }
+ } else {
+ if (!other_extension.is_cleared) {
+ switch (cpp_type(other_extension.type)) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE, CAMELCASE) \
+ case WireFormatLite::CPPTYPE_##UPPERCASE: \
+ Set##CAMELCASE(number, other_extension.type, \
+ other_extension.LOWERCASE##_value, \
+ other_extension.descriptor); \
break;
- }
- } else {
- if (!other_extension.is_cleared) {
- switch (cpp_type(other_extension.type)) {
-#define HANDLE_TYPE(UPPERCASE, LOWERCASE, CAMELCASE) \
- case WireFormatLite::CPPTYPE_##UPPERCASE: \
- Set##CAMELCASE(iter->first, other_extension.type, \
- other_extension.LOWERCASE##_value, \
- other_extension.descriptor); \
- break;
-
- HANDLE_TYPE( INT32, int32, Int32);
- HANDLE_TYPE( INT64, int64, Int64);
- HANDLE_TYPE(UINT32, uint32, UInt32);
- HANDLE_TYPE(UINT64, uint64, UInt64);
- HANDLE_TYPE( FLOAT, float, Float);
- HANDLE_TYPE(DOUBLE, double, Double);
- HANDLE_TYPE( BOOL, bool, Bool);
- HANDLE_TYPE( ENUM, enum, Enum);
+
+ HANDLE_TYPE( INT32, int32, Int32);
+ HANDLE_TYPE( INT64, int64, Int64);
+ HANDLE_TYPE(UINT32, uint32, UInt32);
+ HANDLE_TYPE(UINT64, uint64, UInt64);
+ HANDLE_TYPE( FLOAT, float, Float);
+ HANDLE_TYPE(DOUBLE, double, Double);
+ HANDLE_TYPE( BOOL, bool, Bool);
+ HANDLE_TYPE( ENUM, enum, Enum);
#undef HANDLE_TYPE
- case WireFormatLite::CPPTYPE_STRING:
- SetString(iter->first, other_extension.type,
- *other_extension.string_value,
- other_extension.descriptor);
- break;
- case WireFormatLite::CPPTYPE_MESSAGE: {
- Extension* extension;
- bool is_new = MaybeNewExtension(iter->first,
- other_extension.descriptor,
- &extension);
- if (is_new) {
- extension->type = other_extension.type;
- extension->is_packed = other_extension.is_packed;
- extension->is_repeated = false;
- if (other_extension.is_lazy) {
- extension->is_lazy = true;
- extension->lazymessage_value =
- other_extension.lazymessage_value->New();
+ case WireFormatLite::CPPTYPE_STRING:
+ SetString(number, other_extension.type,
+ *other_extension.string_value,
+ other_extension.descriptor);
+ break;
+ case WireFormatLite::CPPTYPE_MESSAGE: {
+ Extension* extension;
+ bool is_new = MaybeNewExtension(number,
+ other_extension.descriptor,
+ &extension);
+ if (is_new) {
+ extension->type = other_extension.type;
+ extension->is_packed = other_extension.is_packed;
+ extension->is_repeated = false;
+ if (other_extension.is_lazy) {
+ extension->is_lazy = true;
+ extension->lazymessage_value =
+ other_extension.lazymessage_value->New(arena_);
+ extension->lazymessage_value->MergeFrom(
+ *other_extension.lazymessage_value);
+ } else {
+ extension->is_lazy = false;
+ extension->message_value =
+ other_extension.message_value->New(arena_);
+ extension->message_value->CheckTypeAndMergeFrom(
+ *other_extension.message_value);
+ }
+ } else {
+ GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
+ GOOGLE_DCHECK_EQ(extension->is_packed,other_extension.is_packed);
+ GOOGLE_DCHECK(!extension->is_repeated);
+ if (other_extension.is_lazy) {
+ if (extension->is_lazy) {
extension->lazymessage_value->MergeFrom(
*other_extension.lazymessage_value);
} else {
- extension->is_lazy = false;
- extension->message_value =
- other_extension.message_value->New();
extension->message_value->CheckTypeAndMergeFrom(
- *other_extension.message_value);
+ other_extension.lazymessage_value->GetMessage(
+ *extension->message_value));
}
} else {
- GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
- GOOGLE_DCHECK_EQ(extension->is_packed,other_extension.is_packed);
- GOOGLE_DCHECK(!extension->is_repeated);
- if (other_extension.is_lazy) {
- if (extension->is_lazy) {
- extension->lazymessage_value->MergeFrom(
- *other_extension.lazymessage_value);
- } else {
- extension->message_value->CheckTypeAndMergeFrom(
- other_extension.lazymessage_value->GetMessage(
- *extension->message_value));
- }
+ if (extension->is_lazy) {
+ extension->lazymessage_value->MutableMessage(
+ *other_extension.message_value)->CheckTypeAndMergeFrom(
+ *other_extension.message_value);
} else {
- if (extension->is_lazy) {
- extension->lazymessage_value->MutableMessage(
- *other_extension.message_value)->CheckTypeAndMergeFrom(
- *other_extension.message_value);
- } else {
- extension->message_value->CheckTypeAndMergeFrom(
- *other_extension.message_value);
- }
+ extension->message_value->CheckTypeAndMergeFrom(
+ *other_extension.message_value);
}
}
- extension->is_cleared = false;
- break;
}
+ extension->is_cleared = false;
+ break;
}
}
}
@@ -823,7 +1013,73 @@ void ExtensionSet::MergeFrom(const ExtensionSet& other) {
}
void ExtensionSet::Swap(ExtensionSet* x) {
- extensions_.swap(x->extensions_);
+ if (GetArenaNoVirtual() == x->GetArenaNoVirtual()) {
+ extensions_.swap(x->extensions_);
+ } else {
+ // TODO(cfallin, rohananil): We maybe able to optimize a case where we are
+ // swapping from heap to arena-allocated extension set, by just Own()'ing
+ // the extensions.
+ ExtensionSet extension_set;
+ extension_set.MergeFrom(*x);
+ x->Clear();
+ x->MergeFrom(*this);
+ Clear();
+ MergeFrom(extension_set);
+ }
+}
+
+void ExtensionSet::SwapExtension(ExtensionSet* other,
+ int number) {
+ if (this == other) return;
+ map<int, Extension>::iterator this_iter = extensions_.find(number);
+ map<int, Extension>::iterator other_iter = other->extensions_.find(number);
+
+ if (this_iter == extensions_.end() &&
+ other_iter == other->extensions_.end()) {
+ return;
+ }
+
+ if (this_iter != extensions_.end() &&
+ other_iter != other->extensions_.end()) {
+ if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
+ using std::swap;
+ swap(this_iter->second, other_iter->second);
+ } else {
+ // TODO(cfallin, rohananil): We could further optimize these cases,
+ // especially avoid creation of ExtensionSet, and move MergeFrom logic
+ // into Extensions itself (which takes arena as an argument).
+ // We do it this way to reuse the copy-across-arenas logic already
+ // implemented in ExtensionSet's MergeFrom.
+ ExtensionSet temp;
+ temp.InternalExtensionMergeFrom(number, other_iter->second);
+ map<int, Extension>::iterator temp_iter = temp.extensions_.find(number);
+ other_iter->second.Clear();
+ other->InternalExtensionMergeFrom(number, this_iter->second);
+ this_iter->second.Clear();
+ InternalExtensionMergeFrom(number, temp_iter->second);
+ }
+ return;
+ }
+
+ if (this_iter == extensions_.end()) {
+ if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
+ extensions_.insert(std::make_pair(number, other_iter->second));
+ } else {
+ InternalExtensionMergeFrom(number, other_iter->second);
+ }
+ other->extensions_.erase(number);
+ return;
+ }
+
+ if (other_iter == other->extensions_.end()) {
+ if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
+ other->extensions_.insert(std::make_pair(number, this_iter->second));
+ } else {
+ other->InternalExtensionMergeFrom(number, this_iter->second);
+ }
+ extensions_.erase(number);
+ return;
+ }
}
bool ExtensionSet::IsInitialized() const {
@@ -855,41 +1111,59 @@ bool ExtensionSet::IsInitialized() const {
}
bool ExtensionSet::FindExtensionInfoFromTag(
- uint32 tag, ExtensionFinder* extension_finder,
- int* field_number, ExtensionInfo* extension) {
+ uint32 tag, ExtensionFinder* extension_finder, int* field_number,
+ ExtensionInfo* extension, bool* was_packed_on_wire) {
*field_number = WireFormatLite::GetTagFieldNumber(tag);
WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
+ return FindExtensionInfoFromFieldNumber(wire_type, *field_number,
+ extension_finder, extension,
+ was_packed_on_wire);
+}
- bool is_unknown;
- if (!extension_finder->Find(*field_number, extension)) {
- is_unknown = true;
- } else if (extension->is_packed) {
- is_unknown = (wire_type != WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
- } else {
- WireFormatLite::WireType expected_wire_type =
- WireFormatLite::WireTypeForFieldType(real_type(extension->type));
- is_unknown = (wire_type != expected_wire_type);
+bool ExtensionSet::FindExtensionInfoFromFieldNumber(
+ int wire_type, int field_number, ExtensionFinder* extension_finder,
+ ExtensionInfo* extension, bool* was_packed_on_wire) {
+ if (!extension_finder->Find(field_number, extension)) {
+ return false;
+ }
+
+ WireFormatLite::WireType expected_wire_type =
+ WireFormatLite::WireTypeForFieldType(real_type(extension->type));
+
+ // Check if this is a packed field.
+ *was_packed_on_wire = false;
+ if (extension->is_repeated &&
+ wire_type == WireFormatLite::WIRETYPE_LENGTH_DELIMITED &&
+ is_packable(expected_wire_type)) {
+ *was_packed_on_wire = true;
+ return true;
}
- return !is_unknown;
+ // Otherwise the wire type must match.
+ return expected_wire_type == wire_type;
}
bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
ExtensionFinder* extension_finder,
FieldSkipper* field_skipper) {
int number;
+ bool was_packed_on_wire;
ExtensionInfo extension;
- if (!FindExtensionInfoFromTag(tag, extension_finder, &number, &extension)) {
+ if (!FindExtensionInfoFromTag(
+ tag, extension_finder, &number, &extension, &was_packed_on_wire)) {
return field_skipper->SkipField(input, tag);
} else {
- return ParseFieldWithExtensionInfo(number, extension, input, field_skipper);
+ return ParseFieldWithExtensionInfo(
+ number, was_packed_on_wire, extension, input, field_skipper);
}
}
bool ExtensionSet::ParseFieldWithExtensionInfo(
- int number, const ExtensionInfo& extension,
+ int number, bool was_packed_on_wire, const ExtensionInfo& extension,
io::CodedInputStream* input,
FieldSkipper* field_skipper) {
- if (extension.is_packed) {
+ // Explicitly not read extension.is_packed, instead check whether the field
+ // was encoded in packed form on the wire.
+ if (was_packed_on_wire) {
uint32 size;
if (!input->ReadVarint32(&size)) return false;
io::CodedInputStream::Limit limit = input->PushLimit(size);
@@ -903,7 +1177,8 @@ bool ExtensionSet::ParseFieldWithExtensionInfo(
CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>( \
input, &value)) return false; \
Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \
- true, value, extension.descriptor); \
+ extension.is_packed, value, \
+ extension.descriptor); \
} \
break
@@ -929,8 +1204,11 @@ bool ExtensionSet::ParseFieldWithExtensionInfo(
input, &value)) return false;
if (extension.enum_validity_check.func(
extension.enum_validity_check.arg, value)) {
- AddEnum(number, WireFormatLite::TYPE_ENUM, true, value,
- extension.descriptor);
+ AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed,
+ value, extension.descriptor);
+ } else {
+ // Invalid value. Treat as unknown.
+ field_skipper->SkipUnknownEnum(number, value);
}
}
break;
@@ -952,9 +1230,10 @@ bool ExtensionSet::ParseFieldWithExtensionInfo(
if (!WireFormatLite::ReadPrimitive< \
CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>( \
input, &value)) return false; \
- if (extension.is_repeated) { \
+ if (extension.is_repeated) { \
Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \
- false, value, extension.descriptor); \
+ extension.is_packed, value, \
+ extension.descriptor); \
} else { \
Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value, \
extension.descriptor); \
@@ -986,7 +1265,7 @@ bool ExtensionSet::ParseFieldWithExtensionInfo(
// Invalid value. Treat as unknown.
field_skipper->SkipUnknownEnum(number, value);
} else if (extension.is_repeated) {
- AddEnum(number, WireFormatLite::TYPE_ENUM, false, value,
+ AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed, value,
extension.descriptor);
} else {
SetEnum(number, WireFormatLite::TYPE_ENUM, value,
@@ -1039,22 +1318,29 @@ bool ExtensionSet::ParseFieldWithExtensionInfo(
}
bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
+ const MessageLite* containing_type) {
+ FieldSkipper skipper;
+ GeneratedExtensionFinder finder(containing_type);
+ return ParseField(tag, input, &finder, &skipper);
+}
+
+bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
const MessageLite* containing_type,
- UnknownFieldSet* unknown_fields) {
- FieldSkipper skipper(unknown_fields);
+ io::CodedOutputStream* unknown_fields) {
+ CodedOutputStreamFieldSkipper skipper(unknown_fields);
GeneratedExtensionFinder finder(containing_type);
return ParseField(tag, input, &finder, &skipper);
}
// Defined in extension_set_heavy.cc.
-// bool ExtensionSet::ParseFieldHeavy(uint32 tag, io::CodedInputStream* input,
-// const Message* containing_type,
-// UnknownFieldSet* unknown_fields)
+// bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
+// const MessageLite* containing_type,
+// UnknownFieldSet* unknown_fields)
// Defined in extension_set_heavy.cc.
-// bool ExtensionSet::ParseMessageSetHeavy(io::CodedInputStream* input,
-// const Message* containing_type,
-// UnknownFieldSet* unknown_fields);
+// bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
+// const MessageLite* containing_type,
+// UnknownFieldSet* unknown_fields);
void ExtensionSet::SerializeWithCachedSizes(
int start_field_number, int end_field_number,
@@ -1085,7 +1371,7 @@ bool ExtensionSet::MaybeNewExtension(int number,
const FieldDescriptor* descriptor,
Extension** result) {
pair<map<int, Extension>::iterator, bool> insert_result =
- extensions_.insert(make_pair(number, Extension()));
+ extensions_.insert(std::make_pair(number, Extension()));
*result = &insert_result.first->second;
(*result)->descriptor = descriptor;
return insert_result.second;
@@ -1416,6 +1702,8 @@ int ExtensionSet::Extension::GetSize() const {
return 0;
}
+// This function deletes all allocated objects. This function should be only
+// called if the Extension was created with an arena.
void ExtensionSet::Extension::Free() {
if (is_repeated) {
switch (cpp_type(type)) {
@@ -1457,6 +1745,71 @@ void ExtensionSet::Extension::Free() {
// Defined in extension_set_heavy.cc.
// int ExtensionSet::Extension::SpaceUsedExcludingSelf() const
+// ==================================================================
+// Default repeated field instances for iterator-compatible accessors
+
+GOOGLE_PROTOBUF_DECLARE_ONCE(repeated_primitive_generic_type_traits_once_init_);
+GOOGLE_PROTOBUF_DECLARE_ONCE(repeated_string_type_traits_once_init_);
+GOOGLE_PROTOBUF_DECLARE_ONCE(repeated_message_generic_type_traits_once_init_);
+
+void RepeatedPrimitiveGenericTypeTraits::InitializeDefaultRepeatedFields() {
+ default_repeated_field_int32_ = new RepeatedField<int32>;
+ default_repeated_field_int64_ = new RepeatedField<int64>;
+ default_repeated_field_uint32_ = new RepeatedField<uint32>;
+ default_repeated_field_uint64_ = new RepeatedField<uint64>;
+ default_repeated_field_double_ = new RepeatedField<double>;
+ default_repeated_field_float_ = new RepeatedField<float>;
+ default_repeated_field_bool_ = new RepeatedField<bool>;
+ OnShutdown(&DestroyDefaultRepeatedFields);
+}
+
+void RepeatedPrimitiveGenericTypeTraits::DestroyDefaultRepeatedFields() {
+ delete default_repeated_field_int32_;
+ delete default_repeated_field_int64_;
+ delete default_repeated_field_uint32_;
+ delete default_repeated_field_uint64_;
+ delete default_repeated_field_double_;
+ delete default_repeated_field_float_;
+ delete default_repeated_field_bool_;
+}
+
+void RepeatedStringTypeTraits::InitializeDefaultRepeatedFields() {
+ default_repeated_field_ = new RepeatedFieldType;
+ OnShutdown(&DestroyDefaultRepeatedFields);
+}
+
+void RepeatedStringTypeTraits::DestroyDefaultRepeatedFields() {
+ delete default_repeated_field_;
+}
+
+void RepeatedMessageGenericTypeTraits::InitializeDefaultRepeatedFields() {
+ default_repeated_field_ = new RepeatedFieldType;
+ OnShutdown(&DestroyDefaultRepeatedFields);
+}
+
+void RepeatedMessageGenericTypeTraits::DestroyDefaultRepeatedFields() {
+ delete default_repeated_field_;
+}
+
+const RepeatedField<int32>*
+RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int32_ = NULL;
+const RepeatedField<int64>*
+RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int64_ = NULL;
+const RepeatedField<uint32>*
+RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint32_ = NULL;
+const RepeatedField<uint64>*
+RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint64_ = NULL;
+const RepeatedField<double>*
+RepeatedPrimitiveGenericTypeTraits::default_repeated_field_double_ = NULL;
+const RepeatedField<float>*
+RepeatedPrimitiveGenericTypeTraits::default_repeated_field_float_ = NULL;
+const RepeatedField<bool>*
+RepeatedPrimitiveGenericTypeTraits::default_repeated_field_bool_ = NULL;
+const RepeatedStringTypeTraits::RepeatedFieldType*
+RepeatedStringTypeTraits::default_repeated_field_ = NULL;
+const RepeatedMessageGenericTypeTraits::RepeatedFieldType*
+RepeatedMessageGenericTypeTraits::default_repeated_field_ = NULL;
+
} // namespace internal
} // namespace protobuf
} // namespace google

Powered by Google App Engine
This is Rietveld 408576698