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

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

Issue 2590803003: Revert "third_party/protobuf: Update to HEAD (83d681ee2c)" (Closed)
Patch Set: Created 4 years 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/generated_message_reflection.cc
diff --git a/third_party/protobuf/src/google/protobuf/generated_message_reflection.cc b/third_party/protobuf/src/google/protobuf/generated_message_reflection.cc
index 08742232237ef2e8994b58c6ea48936b40aad1a5..2313181cc995220fe39ce23236e365b467e05276 100644
--- a/third_party/protobuf/src/google/protobuf/generated_message_reflection.cc
+++ b/third_party/protobuf/src/google/protobuf/generated_message_reflection.cc
@@ -44,7 +44,6 @@
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/map_field.h>
#include <google/protobuf/repeated_field.h>
-// #include "google/protobuf/bridge/compatibility_mode_support.h"
#define GOOGLE_PROTOBUF_HAS_ONEOF
@@ -85,22 +84,6 @@ inline bool SupportsArenas(const Descriptor* descriptor) {
namespace {
-template <class To>
-To* GetPointerAtOffset(Message* message, uint32 offset) {
- return reinterpret_cast<To*>(reinterpret_cast<char*>(message) + offset);
-}
-
-template <class To>
-const To* GetConstPointerAtOffset(const Message* message, uint32 offset) {
- return reinterpret_cast<const To*>(reinterpret_cast<const char*>(message) +
- offset);
-}
-
-template <class To>
-const To& GetConstRefAtOffset(const Message& message, uint32 offset) {
- return *GetConstPointerAtOffset<To>(&message, offset);
-}
-
void ReportReflectionUsageError(
const Descriptor* descriptor, const FieldDescriptor* field,
const char* method, const char* description) {
@@ -190,24 +173,61 @@ static void ReportReflectionUsageEnumTypeError(
// ===================================================================
GeneratedMessageReflection::GeneratedMessageReflection(
- const Descriptor* descriptor, const ReflectionSchema& schema,
- const DescriptorPool* pool, MessageFactory* factory)
- : descriptor_(descriptor),
- schema_(schema),
- descriptor_pool_((pool == NULL) ? DescriptorPool::generated_pool()
- : pool),
- message_factory_(factory),
- // TODO(haberman) remove this when upb is using our table driven.
- default_instance_(schema_.default_instance_),
- default_oneof_instance_(schema_.default_oneof_instance_),
- offsets_(schema_.offsets_),
- has_bits_indices_(schema_.has_bit_indices_),
- has_bits_offset_(schema_.has_bits_offset_),
- oneof_case_offset_(schema_.oneof_case_offset_),
- unknown_fields_offset_(-1),
- extensions_offset_(schema_.extensions_offset_),
- arena_offset_(schema_.metadata_offset_),
- object_size_(schema_.object_size_) {
+ const Descriptor* descriptor,
+ const Message* default_instance,
+ const int offsets[],
+ int has_bits_offset,
+ int unknown_fields_offset,
+ int extensions_offset,
+ const DescriptorPool* descriptor_pool,
+ MessageFactory* factory,
+ int object_size,
+ int arena_offset,
+ int is_default_instance_offset)
+ : descriptor_ (descriptor),
+ default_instance_ (default_instance),
+ offsets_ (offsets),
+ has_bits_offset_ (has_bits_offset),
+ unknown_fields_offset_(unknown_fields_offset),
+ extensions_offset_(extensions_offset),
+ arena_offset_ (arena_offset),
+ is_default_instance_offset_(is_default_instance_offset),
+ object_size_ (object_size),
+ descriptor_pool_ ((descriptor_pool == NULL) ?
+ DescriptorPool::generated_pool() :
+ descriptor_pool),
+ message_factory_ (factory) {
+}
+
+GeneratedMessageReflection::GeneratedMessageReflection(
+ const Descriptor* descriptor,
+ const Message* default_instance,
+ const int offsets[],
+ int has_bits_offset,
+ int unknown_fields_offset,
+ int extensions_offset,
+ const void* default_oneof_instance,
+ int oneof_case_offset,
+ const DescriptorPool* descriptor_pool,
+ MessageFactory* factory,
+ int object_size,
+ int arena_offset,
+ int is_default_instance_offset)
+ : descriptor_ (descriptor),
+ default_instance_ (default_instance),
+ default_oneof_instance_ (default_oneof_instance),
+ offsets_ (offsets),
+ has_bits_offset_ (has_bits_offset),
+ oneof_case_offset_(oneof_case_offset),
+ unknown_fields_offset_(unknown_fields_offset),
+ extensions_offset_(extensions_offset),
+ arena_offset_ (arena_offset),
+ is_default_instance_offset_(is_default_instance_offset),
+ object_size_ (object_size),
+ descriptor_pool_ ((descriptor_pool == NULL) ?
+ DescriptorPool::generated_pool() :
+ descriptor_pool),
+ message_factory_ (factory) {
}
GeneratedMessageReflection::~GeneratedMessageReflection() {}
@@ -235,33 +255,39 @@ const UnknownFieldSet& GetEmptyUnknownFieldSet() {
const UnknownFieldSet& GeneratedMessageReflection::GetUnknownFields(
const Message& message) const {
if (descriptor_->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) {
- // We have to ensure that any mutations made to the return value of
- // MutableUnknownFields() are not reflected here.
return GetEmptyUnknownFieldSet();
- } else {
+ }
+ if (unknown_fields_offset_ == kUnknownFieldSetInMetadata) {
return GetInternalMetadataWithArena(message).unknown_fields();
}
+ const void* ptr = reinterpret_cast<const uint8*>(&message) +
+ unknown_fields_offset_;
+ return *reinterpret_cast<const UnknownFieldSet*>(ptr);
}
UnknownFieldSet* GeneratedMessageReflection::MutableUnknownFields(
Message* message) const {
- return MutableInternalMetadataWithArena(message)->mutable_unknown_fields();
+ if (unknown_fields_offset_ == kUnknownFieldSetInMetadata) {
+ return MutableInternalMetadataWithArena(message)->
+ mutable_unknown_fields();
+ }
+ void* ptr = reinterpret_cast<uint8*>(message) + unknown_fields_offset_;
+ return reinterpret_cast<UnknownFieldSet*>(ptr);
}
int GeneratedMessageReflection::SpaceUsed(const Message& message) const {
// object_size_ already includes the in-memory representation of each field
// in the message, so we only need to account for additional memory used by
// the fields.
- int total_size = schema_.GetObjectSize();
+ int total_size = object_size_;
total_size += GetUnknownFields(message).SpaceUsedExcludingSelf();
- if (schema_.HasExtensionSet()) {
+ if (extensions_offset_ != -1) {
total_size += GetExtensionSet(message).SpaceUsedExcludingSelf();
}
- const int field_count = descriptor_->field_count();
- for (int i = 0; i < field_count; i++) {
+ for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* field = descriptor_->field(i);
if (field->is_repeated()) {
@@ -330,9 +356,9 @@ int GeneratedMessageReflection::SpaceUsed(const Message& message) const {
// the prototype. Only count the string if it has been changed
// from the default value.
const string* default_ptr =
- &DefaultRaw<ArenaStringPtr>(field).Get();
+ &DefaultRaw<ArenaStringPtr>(field).Get(NULL);
const string* ptr =
- &GetField<ArenaStringPtr>(message, field).Get();
+ &GetField<ArenaStringPtr>(message, field).Get(default_ptr);
if (ptr != default_ptr) {
// string fields are represented by just a pointer, so also
@@ -346,7 +372,7 @@ int GeneratedMessageReflection::SpaceUsed(const Message& message) const {
}
case FieldDescriptor::CPPTYPE_MESSAGE:
- if (schema_.IsDefaultInstance(message)) {
+ if (&message == default_instance_) {
// For singular fields, the prototype just stores a pointer to the
// external type's prototype, so there is no extra memory usage.
} else {
@@ -468,9 +494,9 @@ void GeneratedMessageReflection::SwapField(
string1->Swap(string2);
} else {
const string* default_ptr =
- &DefaultRaw<ArenaStringPtr>(field).Get();
- const string temp = string1->Get();
- string1->Set(default_ptr, string2->Get(), arena1);
+ &DefaultRaw<ArenaStringPtr>(field).Get(NULL);
+ const string temp = string1->Get(default_ptr);
+ string1->Set(default_ptr, string2->Get(default_ptr), arena1);
string2->Set(default_ptr, temp, arena2);
}
}
@@ -631,16 +657,16 @@ void GeneratedMessageReflection::Swap(
// Slow copy path.
// Use our arena as temp space, if available.
Message* temp = message1->New(GetArena(message1));
- temp->MergeFrom(*message2);
- message2->CopyFrom(*message1);
- Swap(message1, temp);
+ temp->MergeFrom(*message1);
+ message1->CopyFrom(*message2);
+ message2->CopyFrom(*temp);
if (GetArena(message1) == NULL) {
delete temp;
}
return;
}
- if (schema_.HasHasbits()) {
+ if (has_bits_offset_ != -1) {
uint32* has_bits1 = MutableHasBits(message1);
uint32* has_bits2 = MutableHasBits(message2);
int has_bits_size = (descriptor_->field_count() + 31) / 32;
@@ -650,20 +676,18 @@ void GeneratedMessageReflection::Swap(
}
}
- const int field_count = descriptor_->field_count();
- for (int i = 0; i < field_count; i++) {
+ for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* field = descriptor_->field(i);
if (!field->containing_oneof()) {
SwapField(message1, message2, field);
}
}
- const int oneof_decl_count = descriptor_->oneof_decl_count();
- for (int i = 0; i < oneof_decl_count; i++) {
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
SwapOneofField(message1, message2, descriptor_->oneof_decl(i));
}
- if (schema_.HasExtensionSet()) {
+ if (extensions_offset_ != -1) {
MutableExtensionSet(message1)->Swap(MutableExtensionSet(message2));
}
@@ -673,7 +697,7 @@ void GeneratedMessageReflection::Swap(
void GeneratedMessageReflection::SwapFields(
Message* message1,
Message* message2,
- const std::vector<const FieldDescriptor*>& fields) const {
+ const vector<const FieldDescriptor*>& fields) const {
if (message1 == message2) return;
// TODO(kenton): Other Reflection methods should probably check this too.
@@ -694,8 +718,7 @@ void GeneratedMessageReflection::SwapFields(
std::set<int> swapped_oneof;
- const int fields_size = static_cast<int>(fields.size());
- for (int i = 0; i < fields_size; i++) {
+ for (int i = 0; i < fields.size(); i++) {
const FieldDescriptor* field = fields[i];
if (field->is_extension()) {
MutableExtensionSet(message1)->SwapExtension(
@@ -817,9 +840,9 @@ void GeneratedMessageReflection::ClearField(
default: // TODO(kenton): Support other string reps.
case FieldOptions::STRING: {
const string* default_ptr =
- &DefaultRaw<ArenaStringPtr>(field).Get();
- MutableRaw<ArenaStringPtr>(message, field)->SetAllocated(
- default_ptr, NULL, GetArena(message));
+ &DefaultRaw<ArenaStringPtr>(field).Get(NULL);
+ MutableRaw<ArenaStringPtr>(message, field)->Destroy(default_ptr,
+ GetArena(message));
break;
}
}
@@ -827,7 +850,7 @@ void GeneratedMessageReflection::ClearField(
}
case FieldDescriptor::CPPTYPE_MESSAGE:
- if (!schema_.HasHasbits()) {
+ if (has_bits_offset_ == -1) {
// Proto3 does not have has-bits and we need to set a message field
// to NULL in order to indicate its un-presence.
if (GetArena(message) == NULL) {
@@ -1003,60 +1026,35 @@ struct FieldNumberSorter {
return left->number() < right->number();
}
};
-
-inline bool IsIndexInHasBitSet(
- const uint32* has_bit_set, uint32 has_bit_index) {
- return ((has_bit_set[has_bit_index / 32] >> (has_bit_index % 32)) &
- static_cast<uint32>(1)) != 0;
-}
} // namespace
void GeneratedMessageReflection::ListFields(
const Message& message,
- std::vector<const FieldDescriptor*>* output) const {
+ vector<const FieldDescriptor*>* output) const {
output->clear();
// Optimization: The default instance never has any fields set.
- if (schema_.IsDefaultInstance(message)) return;
-
- // Optimization: Avoid calling GetHasBits() and HasOneofField() many times
- // within the field loop. We allow this violation of ReflectionSchema
- // encapsulation because this function takes a noticable about of CPU
- // fleetwide and properly allowing this optimization through public interfaces
- // seems more trouble than it is worth.
- const uint32* const has_bits =
- schema_.HasHasbits() ? GetHasBits(message) : NULL;
- const uint32* const has_bits_indices = schema_.has_bit_indices_;
- const uint32* const oneof_case_array =
- &GetConstRefAtOffset<uint32>(message, schema_.oneof_case_offset_);
-
- const int field_count = descriptor_->field_count();
- output->reserve(field_count);
- for (int i = 0; i < field_count; i++) {
+ if (&message == default_instance_) return;
+
+ output->reserve(descriptor_->field_count());
+ for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* field = descriptor_->field(i);
if (field->is_repeated()) {
if (FieldSize(message, field) > 0) {
output->push_back(field);
}
} else {
- const OneofDescriptor* containing_oneof = field->containing_oneof();
- if (containing_oneof) {
- // Equivalent to: HasOneofField(message, field)
- if (oneof_case_array[containing_oneof->index()] == field->number()) {
- output->push_back(field);
- }
- } else if (has_bits) {
- // Equivalent to: HasBit(message, field)
- if (IsIndexInHasBitSet(has_bits, has_bits_indices[i])) {
+ if (field->containing_oneof()) {
+ if (HasOneofField(message, field)) {
output->push_back(field);
}
- } else if (HasBit(message, field)) { // Fall back on proto3-style HasBit.
+ } else if (HasBit(message, field)) {
output->push_back(field);
}
}
}
- if (schema_.HasExtensionSet()) {
+ if (extensions_offset_ != -1) {
GetExtensionSet(message).AppendToList(descriptor_, descriptor_pool_,
output);
}
@@ -1150,7 +1148,9 @@ string GeneratedMessageReflection::GetString(
switch (field->options().ctype()) {
default: // TODO(kenton): Support other string reps.
case FieldOptions::STRING: {
- return GetField<ArenaStringPtr>(message, field).Get();
+ const string* default_ptr =
+ &DefaultRaw<ArenaStringPtr>(field).Get(NULL);
+ return GetField<ArenaStringPtr>(message, field).Get(default_ptr);
}
}
@@ -1170,7 +1170,9 @@ const string& GeneratedMessageReflection::GetStringReference(
switch (field->options().ctype()) {
default: // TODO(kenton): Support other string reps.
case FieldOptions::STRING: {
- return GetField<ArenaStringPtr>(message, field).Get();
+ const string* default_ptr =
+ &DefaultRaw<ArenaStringPtr>(field).Get(NULL);
+ return GetField<ArenaStringPtr>(message, field).Get(default_ptr);
}
}
@@ -1191,7 +1193,8 @@ void GeneratedMessageReflection::SetString(
switch (field->options().ctype()) {
default: // TODO(kenton): Support other string reps.
case FieldOptions::STRING: {
- const string* default_ptr = &DefaultRaw<ArenaStringPtr>(field).Get();
+ const string* default_ptr =
+ &DefaultRaw<ArenaStringPtr>(field).Get(NULL);
if (field->containing_oneof() && !HasOneofField(*message, field)) {
ClearOneof(message, field->containing_oneof());
MutableField<ArenaStringPtr>(message, field)->UnsafeSetDefault(
@@ -1576,8 +1579,7 @@ Message* GeneratedMessageReflection::UnsafeArenaReleaseMessage(
if (field->is_extension()) {
return static_cast<Message*>(
- MutableExtensionSet(message)->UnsafeArenaReleaseMessage(field,
- factory));
+ MutableExtensionSet(message)->ReleaseMessage(field, factory));
} else {
ClearBit(message, field);
if (field->containing_oneof()) {
@@ -1725,10 +1727,11 @@ void* GeneratedMessageReflection::MutableRawRepeatedField(
} else {
// Trigger transform for MapField
if (IsMapFieldInApi(field)) {
- return MutableRawNonOneof<MapFieldBase>(message, field)
+ return reinterpret_cast<MapFieldBase*>(reinterpret_cast<uint8*>(message) +
+ offsets_[field->index()])
->MutableRepeatedField();
}
- return MutableRawNonOneof<void>(message, field);
+ return reinterpret_cast<uint8*>(message) + offsets_[field->index()];
}
}
@@ -1755,9 +1758,11 @@ const void* GeneratedMessageReflection::GetRawRepeatedField(
} else {
// Trigger transform for MapField
if (IsMapFieldInApi(field)) {
- return &(GetRawNonOneof<MapFieldBase>(message, field).GetRepeatedField());
+ return &(reinterpret_cast<const MapFieldBase*>(
+ reinterpret_cast<const uint8*>(&message) +
+ offsets_[field->index()])->GetRepeatedField());
}
- return &GetRawNonOneof<char>(message, field);
+ return reinterpret_cast<const uint8*>(&message) + offsets_[field->index()];
}
}
@@ -1839,7 +1844,7 @@ int GeneratedMessageReflection::MapSize(
const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByName(
const string& name) const {
- if (!schema_.HasExtensionSet()) return NULL;
+ if (extensions_offset_ == -1) return NULL;
const FieldDescriptor* result = descriptor_pool_->FindExtensionByName(name);
if (result != NULL && result->containing_type() == descriptor_) {
@@ -1851,8 +1856,7 @@ const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByName(
const Descriptor* type = descriptor_pool_->FindMessageTypeByName(name);
if (type != NULL) {
// Look for a matching extension in the foreign type's scope.
- const int type_extension_count = type->extension_count();
- for (int i = 0; i < type_extension_count; i++) {
+ for (int i = 0; i < type->extension_count(); i++) {
const FieldDescriptor* extension = type->extension(i);
if (extension->containing_type() == descriptor_ &&
extension->type() == FieldDescriptor::TYPE_MESSAGE &&
@@ -1870,7 +1874,7 @@ const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByName(
const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByNumber(
int number) const {
- if (!schema_.HasExtensionSet()) return NULL;
+ if (extensions_offset_ == -1) return NULL;
return descriptor_pool_->FindExtensionByNumber(descriptor_, number);
}
@@ -1883,176 +1887,204 @@ bool GeneratedMessageReflection::SupportsUnknownEnumValues() const {
// These simple template accessors obtain pointers (or references) to
// the given field.
-
-template <class Type>
-const Type& GeneratedMessageReflection::GetRawNonOneof(
- const Message& message, const FieldDescriptor* field) const {
- return GetConstRefAtOffset<Type>(message,
- schema_.GetFieldOffsetNonOneof(field));
-}
-
-template <class Type>
-Type* GeneratedMessageReflection::MutableRawNonOneof(
- Message* message, const FieldDescriptor* field) const {
- return GetPointerAtOffset<Type>(message,
- schema_.GetFieldOffsetNonOneof(field));
-}
-
template <typename Type>
-const Type& GeneratedMessageReflection::GetRaw(
+inline const Type& GeneratedMessageReflection::GetRaw(
const Message& message, const FieldDescriptor* field) const {
if (field->containing_oneof() && !HasOneofField(message, field)) {
return DefaultRaw<Type>(field);
}
- return GetConstRefAtOffset<Type>(message, schema_.GetFieldOffset(field));
+ int index = field->containing_oneof() ?
+ descriptor_->field_count() + field->containing_oneof()->index() :
+ field->index();
+ const void* ptr = reinterpret_cast<const uint8*>(&message) +
+ offsets_[index];
+ return *reinterpret_cast<const Type*>(ptr);
}
template <typename Type>
-Type* GeneratedMessageReflection::MutableRaw(Message* message,
- const FieldDescriptor* field) const {
- return GetPointerAtOffset<Type>(message, schema_.GetFieldOffset(field));
+inline Type* GeneratedMessageReflection::MutableRaw(
+ Message* message, const FieldDescriptor* field) const {
+ int index = field->containing_oneof() ?
+ descriptor_->field_count() + field->containing_oneof()->index() :
+ field->index();
+ void* ptr = reinterpret_cast<uint8*>(message) + offsets_[index];
+ return reinterpret_cast<Type*>(ptr);
}
+template <typename Type>
+inline const Type& GeneratedMessageReflection::DefaultRaw(
+ const FieldDescriptor* field) const {
+ const void* ptr = field->containing_oneof() ?
+ reinterpret_cast<const uint8*>(default_oneof_instance_) +
+ offsets_[field->index()] :
+ reinterpret_cast<const uint8*>(default_instance_) +
+ offsets_[field->index()];
+ return *reinterpret_cast<const Type*>(ptr);
+}
inline const uint32* GeneratedMessageReflection::GetHasBits(
const Message& message) const {
- GOOGLE_DCHECK(schema_.HasHasbits());
- return &GetConstRefAtOffset<uint32>(message, schema_.HasBitsOffset());
+ if (has_bits_offset_ == -1) { // proto3 with no has-bits.
+ return NULL;
+ }
+ const void* ptr = reinterpret_cast<const uint8*>(&message) + has_bits_offset_;
+ return reinterpret_cast<const uint32*>(ptr);
}
-
inline uint32* GeneratedMessageReflection::MutableHasBits(
Message* message) const {
- GOOGLE_DCHECK(schema_.HasHasbits());
- return GetPointerAtOffset<uint32>(message, schema_.HasBitsOffset());
+ if (has_bits_offset_ == -1) {
+ return NULL;
+ }
+ void* ptr = reinterpret_cast<uint8*>(message) + has_bits_offset_;
+ return reinterpret_cast<uint32*>(ptr);
}
inline uint32 GeneratedMessageReflection::GetOneofCase(
- const Message& message, const OneofDescriptor* oneof_descriptor) const {
- return GetConstRefAtOffset<uint32>(
- message, schema_.GetOneofCaseOffset(oneof_descriptor));
+ const Message& message,
+ const OneofDescriptor* oneof_descriptor) const {
+ const void* ptr = reinterpret_cast<const uint8*>(&message)
+ + oneof_case_offset_;
+ return reinterpret_cast<const uint32*>(ptr)[oneof_descriptor->index()];
}
inline uint32* GeneratedMessageReflection::MutableOneofCase(
- Message* message, const OneofDescriptor* oneof_descriptor) const {
- return GetPointerAtOffset<uint32>(
- message, schema_.GetOneofCaseOffset(oneof_descriptor));
+ Message* message,
+ const OneofDescriptor* oneof_descriptor) const {
+ void* ptr = reinterpret_cast<uint8*>(message) + oneof_case_offset_;
+ return &(reinterpret_cast<uint32*>(ptr)[oneof_descriptor->index()]);
}
inline const ExtensionSet& GeneratedMessageReflection::GetExtensionSet(
const Message& message) const {
- return GetConstRefAtOffset<ExtensionSet>(message,
- schema_.GetExtensionSetOffset());
+ GOOGLE_DCHECK_NE(extensions_offset_, -1);
+ const void* ptr = reinterpret_cast<const uint8*>(&message) +
+ extensions_offset_;
+ return *reinterpret_cast<const ExtensionSet*>(ptr);
}
-
inline ExtensionSet* GeneratedMessageReflection::MutableExtensionSet(
Message* message) const {
- return GetPointerAtOffset<ExtensionSet>(message,
- schema_.GetExtensionSetOffset());
+ GOOGLE_DCHECK_NE(extensions_offset_, -1);
+ void* ptr = reinterpret_cast<uint8*>(message) + extensions_offset_;
+ return reinterpret_cast<ExtensionSet*>(ptr);
}
inline Arena* GeneratedMessageReflection::GetArena(Message* message) const {
- return GetInternalMetadataWithArena(*message).arena();
+ if (arena_offset_ == kNoArenaPointer) {
+ return NULL;
+ }
+
+ if (unknown_fields_offset_ == kUnknownFieldSetInMetadata) {
+ // zero-overhead arena pointer overloading UnknownFields
+ return GetInternalMetadataWithArena(*message).arena();
+ }
+
+ // Baseline case: message class has a dedicated arena pointer.
+ void* ptr = reinterpret_cast<uint8*>(message) + arena_offset_;
+ return *reinterpret_cast<Arena**>(ptr);
}
inline const InternalMetadataWithArena&
GeneratedMessageReflection::GetInternalMetadataWithArena(
const Message& message) const {
- return GetConstRefAtOffset<InternalMetadataWithArena>(
- message, schema_.GetMetadataOffset());
+ const void* ptr = reinterpret_cast<const uint8*>(&message) + arena_offset_;
+ return *reinterpret_cast<const InternalMetadataWithArena*>(ptr);
}
inline InternalMetadataWithArena*
GeneratedMessageReflection::MutableInternalMetadataWithArena(
Message* message) const {
- return GetPointerAtOffset<InternalMetadataWithArena>(
- message, schema_.GetMetadataOffset());
+ void* ptr = reinterpret_cast<uint8*>(message) + arena_offset_;
+ return reinterpret_cast<InternalMetadataWithArena*>(ptr);
}
-template <typename Type>
-inline const Type& GeneratedMessageReflection::DefaultRaw(
- const FieldDescriptor* field) const {
- return *reinterpret_cast<const Type*>(schema_.GetFieldDefault(field));
+inline bool
+GeneratedMessageReflection::GetIsDefaultInstance(
+ const Message& message) const {
+ if (is_default_instance_offset_ == kHasNoDefaultInstanceField) {
+ return false;
+ }
+ const void* ptr = reinterpret_cast<const uint8*>(&message) +
+ is_default_instance_offset_;
+ return *reinterpret_cast<const bool*>(ptr);
}
// Simple accessors for manipulating has_bits_.
inline bool GeneratedMessageReflection::HasBit(
const Message& message, const FieldDescriptor* field) const {
- if (schema_.HasHasbits()) {
- return IsIndexInHasBitSet(GetHasBits(message), schema_.HasBitIndex(field));
- }
-
- // proto3: no has-bits. All fields present except messages, which are
- // present only if their message-field pointer is non-NULL.
- if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
- return !schema_.IsDefaultInstance(message) &&
- GetRaw<const Message*>(message, field) != NULL;
- } else {
- // Non-message field (and non-oneof, since that was handled in HasField()
- // before calling us), and singular (again, checked in HasField). So, this
- // field must be a scalar.
-
- // Scalar primitive (numeric or string/bytes) fields are present if
- // their value is non-zero (numeric) or non-empty (string/bytes). N.B.:
- // we must use this definition here, rather than the "scalar fields
- // always present" in the proto3 docs, because MergeFrom() semantics
- // require presence as "present on wire", and reflection-based merge
- // (which uses HasField()) needs to be consistent with this.
- switch (field->cpp_type()) {
- case FieldDescriptor::CPPTYPE_STRING:
- switch (field->options().ctype()) {
- default: {
- return GetField<ArenaStringPtr>(message, field).Get().size() > 0;
+ if (has_bits_offset_ == -1) {
+ // proto3: no has-bits. All fields present except messages, which are
+ // present only if their message-field pointer is non-NULL.
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ return !GetIsDefaultInstance(message) &&
+ GetRaw<const Message*>(message, field) != NULL;
+ } else {
+ // Non-message field (and non-oneof, since that was handled in HasField()
+ // before calling us), and singular (again, checked in HasField). So, this
+ // field must be a scalar.
+
+ // Scalar primitive (numeric or string/bytes) fields are present if
+ // their value is non-zero (numeric) or non-empty (string/bytes). N.B.:
+ // we must use this definition here, rather than the "scalar fields
+ // always present" in the proto3 docs, because MergeFrom() semantics
+ // require presence as "present on wire", and reflection-based merge
+ // (which uses HasField()) needs to be consistent with this.
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_STRING:
+ switch (field->options().ctype()) {
+ default: {
+ const string* default_ptr =
+ &DefaultRaw<ArenaStringPtr>(field).Get(NULL);
+ return GetField<ArenaStringPtr>(message, field).Get(
+ default_ptr).size() > 0;
+ }
}
- }
- return false;
- case FieldDescriptor::CPPTYPE_BOOL:
- return GetRaw<bool>(message, field) != false;
- case FieldDescriptor::CPPTYPE_INT32:
- return GetRaw<int32>(message, field) != 0;
- case FieldDescriptor::CPPTYPE_INT64:
- return GetRaw<int64>(message, field) != 0;
- case FieldDescriptor::CPPTYPE_UINT32:
- return GetRaw<uint32>(message, field) != 0;
- case FieldDescriptor::CPPTYPE_UINT64:
- return GetRaw<uint64>(message, field) != 0;
- case FieldDescriptor::CPPTYPE_FLOAT:
- return GetRaw<float>(message, field) != 0.0;
- case FieldDescriptor::CPPTYPE_DOUBLE:
- return GetRaw<double>(message, field) != 0.0;
- case FieldDescriptor::CPPTYPE_ENUM:
- return GetRaw<int>(message, field) != 0;
- case FieldDescriptor::CPPTYPE_MESSAGE:
- // handled above; avoid warning
- break;
+ return false;
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return GetRaw<bool>(message, field) != false;
+ case FieldDescriptor::CPPTYPE_INT32:
+ return GetRaw<int32>(message, field) != 0;
+ case FieldDescriptor::CPPTYPE_INT64:
+ return GetRaw<int64>(message, field) != 0;
+ case FieldDescriptor::CPPTYPE_UINT32:
+ return GetRaw<uint32>(message, field) != 0;
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return GetRaw<uint64>(message, field) != 0;
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ return GetRaw<float>(message, field) != 0.0;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ return GetRaw<double>(message, field) != 0.0;
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return GetRaw<int>(message, field) != 0;
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ // handled above; avoid warning
+ GOOGLE_LOG(FATAL) << "Reached impossible case in HasBit().";
+ break;
+ }
}
- GOOGLE_LOG(FATAL) << "Reached impossible case in HasBit().";
- return false;
}
+ return GetHasBits(message)[field->index() / 32] &
+ (1 << (field->index() % 32));
}
inline void GeneratedMessageReflection::SetBit(
Message* message, const FieldDescriptor* field) const {
- if (!schema_.HasHasbits()) {
+ if (has_bits_offset_ == -1) {
return;
}
- const uint32 index = schema_.HasBitIndex(field);
- MutableHasBits(message)[index / 32] |=
- (static_cast<uint32>(1) << (index % 32));
+ MutableHasBits(message)[field->index() / 32] |= (1 << (field->index() % 32));
}
inline void GeneratedMessageReflection::ClearBit(
Message* message, const FieldDescriptor* field) const {
- if (!schema_.HasHasbits()) {
+ if (has_bits_offset_ == -1) {
return;
}
- const uint32 index = schema_.HasBitIndex(field);
- MutableHasBits(message)[index / 32] &=
- ~(static_cast<uint32>(1) << (index % 32));
+ MutableHasBits(message)[field->index() / 32] &= ~(1 << (field->index() % 32));
}
inline void GeneratedMessageReflection::SwapBit(
Message* message1, Message* message2, const FieldDescriptor* field) const {
- if (!schema_.HasHasbits()) {
+ if (has_bits_offset_ == -1) {
return;
}
bool temp_has_bit = HasBit(*message1, field);
@@ -2093,7 +2125,7 @@ inline void GeneratedMessageReflection::ClearOneofField(
inline void GeneratedMessageReflection::ClearOneof(
Message* message, const OneofDescriptor* oneof_descriptor) const {
// TODO(jieluo): Consider to cache the unused object instead of deleting
- // it. It will be much faster if an application switches a lot from
+ // it. It will be much faster if an aplication switches a lot from
// a few oneof fields. Time/space tradeoff
uint32 oneof_case = GetOneofCase(*message, oneof_descriptor);
if (oneof_case > 0) {
@@ -2105,7 +2137,7 @@ inline void GeneratedMessageReflection::ClearOneof(
default: // TODO(kenton): Support other string reps.
case FieldOptions::STRING: {
const string* default_ptr =
- &DefaultRaw<ArenaStringPtr>(field).Get();
+ &DefaultRaw<ArenaStringPtr>(field).Get(NULL);
MutableField<ArenaStringPtr>(message, field)->
Destroy(default_ptr, GetArena(message));
break;
@@ -2217,7 +2249,7 @@ void* GeneratedMessageReflection::RepeatedFieldData(
return MutableExtensionSet(message)->MutableRawRepeatedField(
field->number(), field->type(), field->is_packed(), field);
} else {
- return MutableRawNonOneof<char>(message, field);
+ return reinterpret_cast<uint8*>(message) + offsets_[field->index()];
}
}
@@ -2229,165 +2261,56 @@ MapFieldBase* GeneratedMessageReflection::MapData(
return MutableRaw<MapFieldBase>(message, field);
}
-namespace {
-
-// Helper function to transform migration schema into reflection schema.
-ReflectionSchema MigrationToReflectionSchema(
- const DefaultInstanceData* default_instance_data, const uint32* offsets,
- MigrationSchema migration_schema) {
- ReflectionSchema result;
- result.default_instance_ = default_instance_data->default_instance;
- // First 5 offsets are offsets to the special fields. The following offsets
- // are the proto fields.
- result.offsets_ = offsets + migration_schema.offsets_index + 4;
- result.has_bit_indices_ = offsets + migration_schema.has_bit_indices_index;
- result.has_bits_offset_ = offsets[migration_schema.offsets_index + 0];
- result.metadata_offset_ = offsets[migration_schema.offsets_index + 1];
- result.extensions_offset_ = offsets[migration_schema.offsets_index + 2];
- result.default_oneof_instance_ = default_instance_data->default_oneof_instance;
- result.oneof_case_offset_ = offsets[migration_schema.offsets_index + 3];
- result.object_size_ = migration_schema.object_size;
- return result;
-}
-
-ReflectionSchema MigrationToReflectionSchema(
- const DefaultInstanceData* default_instance_data, const uint32* offsets,
- ReflectionSchema schema) {
- return schema;
-}
-
-template<typename Schema>
-class AssignDescriptorsHelper {
- public:
- AssignDescriptorsHelper(MessageFactory* factory,
- Metadata* file_level_metadata,
- const EnumDescriptor** file_level_enum_descriptors,
- const Schema* schemas,
- const DefaultInstanceData* default_instance_data,
- const uint32* offsets)
- : factory_(factory),
- file_level_metadata_(file_level_metadata),
- file_level_enum_descriptors_(file_level_enum_descriptors),
- schemas_(schemas),
- default_instance_data_(default_instance_data),
- offsets_(offsets) {}
-
- void AssignMessageDescriptor(const Descriptor* descriptor) {
- for (int i = 0; i < descriptor->nested_type_count(); i++) {
- AssignMessageDescriptor(descriptor->nested_type(i));
- }
-
- file_level_metadata_->descriptor = descriptor;
-
- if (!descriptor->options().map_entry()) {
- // Only set reflection for non map types.
- file_level_metadata_->reflection = new GeneratedMessageReflection(
- descriptor, MigrationToReflectionSchema(default_instance_data_++,
- offsets_, *schemas_),
- ::google::protobuf::DescriptorPool::generated_pool(), factory_);
- for (int i = 0; i < descriptor->enum_type_count(); i++) {
- AssignEnumDescriptor(descriptor->enum_type(i));
- }
- schemas_++;
- }
- file_level_metadata_++;
- }
-
- void AssignEnumDescriptor(const EnumDescriptor* descriptor) {
- *file_level_enum_descriptors_ = descriptor;
- file_level_enum_descriptors_++;
- }
-
- private:
- MessageFactory* factory_;
- Metadata* file_level_metadata_;
- const EnumDescriptor** file_level_enum_descriptors_;
- const Schema* schemas_;
- const DefaultInstanceData* default_instance_data_;
- const uint32* offsets_;
-};
-
-} // namespace
-
-void AssignDescriptors(
- const string& filename, const MigrationSchema* schemas,
- const DefaultInstanceData* default_instance_data, const uint32* offsets,
- MessageFactory* factory,
- // update the following descriptor arrays.
- Metadata* file_level_metadata,
- const EnumDescriptor** file_level_enum_descriptors,
- const ServiceDescriptor** file_level_service_descriptors) {
- const ::google::protobuf::FileDescriptor* file =
- ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(filename);
- GOOGLE_CHECK(file != NULL);
-
- if (!factory) factory = MessageFactory::generated_factory();
-
- AssignDescriptorsHelper<MigrationSchema> helper(factory, file_level_metadata,
- file_level_enum_descriptors, schemas,
- default_instance_data, offsets);
-
- for (int i = 0; i < file->message_type_count(); i++) {
- helper.AssignMessageDescriptor(file->message_type(i));
- }
-
- for (int i = 0; i < file->enum_type_count(); i++) {
- helper.AssignEnumDescriptor(file->enum_type(i));
- }
- if (file->options().cc_generic_services()) {
- for (int i = 0; i < file->service_count(); i++) {
- file_level_service_descriptors[i] = file->service(i);
- }
- }
-}
-
-void AssignDescriptors(
- const string& filename, const ReflectionSchema* schemas,
- MessageFactory* factory,
- // update the following descriptor arrays.
- Metadata* file_level_metadata,
- const EnumDescriptor** file_level_enum_descriptors,
- const ServiceDescriptor** file_level_service_descriptors) {
- const ::google::protobuf::FileDescriptor* file =
- ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(filename);
- GOOGLE_CHECK(file != NULL);
-
- if (!factory) factory = MessageFactory::generated_factory();
-
- AssignDescriptorsHelper<ReflectionSchema> helper(factory, file_level_metadata,
- file_level_enum_descriptors, schemas,
- NULL, NULL);
-
- for (int i = 0; i < file->message_type_count(); i++) {
- helper.AssignMessageDescriptor(file->message_type(i));
- }
-
- for (int i = 0; i < file->enum_type_count(); i++) {
- helper.AssignEnumDescriptor(file->enum_type(i));
- }
- if (file->options().cc_generic_services()) {
- for (int i = 0; i < file->service_count(); i++) {
- file_level_service_descriptors[i] = file->service(i);
- }
- }
-}
-
-void RegisterAllTypesInternal(const Metadata* file_level_metadata, int size) {
- for (int i = 0; i < size; i++) {
- const GeneratedMessageReflection* reflection =
- static_cast<const GeneratedMessageReflection*>(
- file_level_metadata[i].reflection);
- if (reflection) {
- // It's not a map type
- ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
- file_level_metadata[i].descriptor,
- reflection->schema_.default_instance_);
- }
- }
-}
-
-void RegisterAllTypes(const Metadata* file_level_metadata, int size) {
- RegisterAllTypesInternal(file_level_metadata, size);
+GeneratedMessageReflection*
+GeneratedMessageReflection::NewGeneratedMessageReflection(
+ const Descriptor* descriptor,
+ const Message* default_instance,
+ const int offsets[],
+ int has_bits_offset,
+ int unknown_fields_offset,
+ int extensions_offset,
+ const void* default_oneof_instance,
+ int oneof_case_offset,
+ int object_size,
+ int arena_offset,
+ int is_default_instance_offset) {
+ return new GeneratedMessageReflection(descriptor,
+ default_instance,
+ offsets,
+ has_bits_offset,
+ unknown_fields_offset,
+ extensions_offset,
+ default_oneof_instance,
+ oneof_case_offset,
+ DescriptorPool::generated_pool(),
+ MessageFactory::generated_factory(),
+ object_size,
+ arena_offset,
+ is_default_instance_offset);
+}
+
+GeneratedMessageReflection*
+GeneratedMessageReflection::NewGeneratedMessageReflection(
+ const Descriptor* descriptor,
+ const Message* default_instance,
+ const int offsets[],
+ int has_bits_offset,
+ int unknown_fields_offset,
+ int extensions_offset,
+ int object_size,
+ int arena_offset,
+ int is_default_instance_offset) {
+ return new GeneratedMessageReflection(descriptor,
+ default_instance,
+ offsets,
+ has_bits_offset,
+ unknown_fields_offset,
+ extensions_offset,
+ DescriptorPool::generated_pool(),
+ MessageFactory::generated_factory(),
+ object_size,
+ arena_offset,
+ is_default_instance_offset);
}
} // namespace internal

Powered by Google App Engine
This is Rietveld 408576698