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

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

Issue 2495533002: third_party/protobuf: Update to HEAD (83d681ee2c) (Closed)
Patch Set: Make chrome settings proto generated file a component 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 2313181cc995220fe39ce23236e365b467e05276..08742232237ef2e8994b58c6ea48936b40aad1a5 100644
--- a/third_party/protobuf/src/google/protobuf/generated_message_reflection.cc
+++ b/third_party/protobuf/src/google/protobuf/generated_message_reflection.cc
@@ -44,6 +44,7 @@
#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
@@ -84,6 +85,22 @@ 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) {
@@ -173,61 +190,24 @@ static void ReportReflectionUsageEnumTypeError(
// ===================================================================
GeneratedMessageReflection::GeneratedMessageReflection(
- 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) {
+ 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_) {
}
GeneratedMessageReflection::~GeneratedMessageReflection() {}
@@ -255,39 +235,33 @@ 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();
- }
- if (unknown_fields_offset_ == kUnknownFieldSetInMetadata) {
+ } else {
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 {
- 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);
+ return MutableInternalMetadataWithArena(message)->mutable_unknown_fields();
}
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 = object_size_;
+ int total_size = schema_.GetObjectSize();
total_size += GetUnknownFields(message).SpaceUsedExcludingSelf();
- if (extensions_offset_ != -1) {
+ if (schema_.HasExtensionSet()) {
total_size += GetExtensionSet(message).SpaceUsedExcludingSelf();
}
- for (int i = 0; i < descriptor_->field_count(); i++) {
+ const int field_count = descriptor_->field_count();
+ for (int i = 0; i < field_count; i++) {
const FieldDescriptor* field = descriptor_->field(i);
if (field->is_repeated()) {
@@ -356,9 +330,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(NULL);
+ &DefaultRaw<ArenaStringPtr>(field).Get();
const string* ptr =
- &GetField<ArenaStringPtr>(message, field).Get(default_ptr);
+ &GetField<ArenaStringPtr>(message, field).Get();
if (ptr != default_ptr) {
// string fields are represented by just a pointer, so also
@@ -372,7 +346,7 @@ int GeneratedMessageReflection::SpaceUsed(const Message& message) const {
}
case FieldDescriptor::CPPTYPE_MESSAGE:
- if (&message == default_instance_) {
+ if (schema_.IsDefaultInstance(message)) {
// For singular fields, the prototype just stores a pointer to the
// external type's prototype, so there is no extra memory usage.
} else {
@@ -494,9 +468,9 @@ void GeneratedMessageReflection::SwapField(
string1->Swap(string2);
} else {
const string* default_ptr =
- &DefaultRaw<ArenaStringPtr>(field).Get(NULL);
- const string temp = string1->Get(default_ptr);
- string1->Set(default_ptr, string2->Get(default_ptr), arena1);
+ &DefaultRaw<ArenaStringPtr>(field).Get();
+ const string temp = string1->Get();
+ string1->Set(default_ptr, string2->Get(), arena1);
string2->Set(default_ptr, temp, arena2);
}
}
@@ -657,16 +631,16 @@ void GeneratedMessageReflection::Swap(
// Slow copy path.
// Use our arena as temp space, if available.
Message* temp = message1->New(GetArena(message1));
- temp->MergeFrom(*message1);
- message1->CopyFrom(*message2);
- message2->CopyFrom(*temp);
+ temp->MergeFrom(*message2);
+ message2->CopyFrom(*message1);
+ Swap(message1, temp);
if (GetArena(message1) == NULL) {
delete temp;
}
return;
}
- if (has_bits_offset_ != -1) {
+ if (schema_.HasHasbits()) {
uint32* has_bits1 = MutableHasBits(message1);
uint32* has_bits2 = MutableHasBits(message2);
int has_bits_size = (descriptor_->field_count() + 31) / 32;
@@ -676,18 +650,20 @@ void GeneratedMessageReflection::Swap(
}
}
- for (int i = 0; i < descriptor_->field_count(); i++) {
+ const int field_count = descriptor_->field_count();
+ for (int i = 0; i < field_count; i++) {
const FieldDescriptor* field = descriptor_->field(i);
if (!field->containing_oneof()) {
SwapField(message1, message2, field);
}
}
- for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ const int oneof_decl_count = descriptor_->oneof_decl_count();
+ for (int i = 0; i < oneof_decl_count; i++) {
SwapOneofField(message1, message2, descriptor_->oneof_decl(i));
}
- if (extensions_offset_ != -1) {
+ if (schema_.HasExtensionSet()) {
MutableExtensionSet(message1)->Swap(MutableExtensionSet(message2));
}
@@ -697,7 +673,7 @@ void GeneratedMessageReflection::Swap(
void GeneratedMessageReflection::SwapFields(
Message* message1,
Message* message2,
- const vector<const FieldDescriptor*>& fields) const {
+ const std::vector<const FieldDescriptor*>& fields) const {
if (message1 == message2) return;
// TODO(kenton): Other Reflection methods should probably check this too.
@@ -718,7 +694,8 @@ void GeneratedMessageReflection::SwapFields(
std::set<int> swapped_oneof;
- for (int i = 0; i < fields.size(); i++) {
+ const int fields_size = static_cast<int>(fields.size());
+ for (int i = 0; i < fields_size; i++) {
const FieldDescriptor* field = fields[i];
if (field->is_extension()) {
MutableExtensionSet(message1)->SwapExtension(
@@ -840,9 +817,9 @@ void GeneratedMessageReflection::ClearField(
default: // TODO(kenton): Support other string reps.
case FieldOptions::STRING: {
const string* default_ptr =
- &DefaultRaw<ArenaStringPtr>(field).Get(NULL);
- MutableRaw<ArenaStringPtr>(message, field)->Destroy(default_ptr,
- GetArena(message));
+ &DefaultRaw<ArenaStringPtr>(field).Get();
+ MutableRaw<ArenaStringPtr>(message, field)->SetAllocated(
+ default_ptr, NULL, GetArena(message));
break;
}
}
@@ -850,7 +827,7 @@ void GeneratedMessageReflection::ClearField(
}
case FieldDescriptor::CPPTYPE_MESSAGE:
- if (has_bits_offset_ == -1) {
+ if (!schema_.HasHasbits()) {
// 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) {
@@ -1026,35 +1003,60 @@ 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,
- vector<const FieldDescriptor*>* output) const {
+ std::vector<const FieldDescriptor*>* output) const {
output->clear();
// Optimization: The default instance never has any fields set.
- if (&message == default_instance_) return;
-
- output->reserve(descriptor_->field_count());
- for (int i = 0; i < descriptor_->field_count(); i++) {
+ 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++) {
const FieldDescriptor* field = descriptor_->field(i);
if (field->is_repeated()) {
if (FieldSize(message, field) > 0) {
output->push_back(field);
}
} else {
- if (field->containing_oneof()) {
- if (HasOneofField(message, field)) {
+ 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])) {
output->push_back(field);
}
- } else if (HasBit(message, field)) {
+ } else if (HasBit(message, field)) { // Fall back on proto3-style HasBit.
output->push_back(field);
}
}
}
- if (extensions_offset_ != -1) {
+ if (schema_.HasExtensionSet()) {
GetExtensionSet(message).AppendToList(descriptor_, descriptor_pool_,
output);
}
@@ -1148,9 +1150,7 @@ string GeneratedMessageReflection::GetString(
switch (field->options().ctype()) {
default: // TODO(kenton): Support other string reps.
case FieldOptions::STRING: {
- const string* default_ptr =
- &DefaultRaw<ArenaStringPtr>(field).Get(NULL);
- return GetField<ArenaStringPtr>(message, field).Get(default_ptr);
+ return GetField<ArenaStringPtr>(message, field).Get();
}
}
@@ -1170,9 +1170,7 @@ const string& GeneratedMessageReflection::GetStringReference(
switch (field->options().ctype()) {
default: // TODO(kenton): Support other string reps.
case FieldOptions::STRING: {
- const string* default_ptr =
- &DefaultRaw<ArenaStringPtr>(field).Get(NULL);
- return GetField<ArenaStringPtr>(message, field).Get(default_ptr);
+ return GetField<ArenaStringPtr>(message, field).Get();
}
}
@@ -1193,8 +1191,7 @@ 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(NULL);
+ const string* default_ptr = &DefaultRaw<ArenaStringPtr>(field).Get();
if (field->containing_oneof() && !HasOneofField(*message, field)) {
ClearOneof(message, field->containing_oneof());
MutableField<ArenaStringPtr>(message, field)->UnsafeSetDefault(
@@ -1579,7 +1576,8 @@ Message* GeneratedMessageReflection::UnsafeArenaReleaseMessage(
if (field->is_extension()) {
return static_cast<Message*>(
- MutableExtensionSet(message)->ReleaseMessage(field, factory));
+ MutableExtensionSet(message)->UnsafeArenaReleaseMessage(field,
+ factory));
} else {
ClearBit(message, field);
if (field->containing_oneof()) {
@@ -1727,11 +1725,10 @@ void* GeneratedMessageReflection::MutableRawRepeatedField(
} else {
// Trigger transform for MapField
if (IsMapFieldInApi(field)) {
- return reinterpret_cast<MapFieldBase*>(reinterpret_cast<uint8*>(message) +
- offsets_[field->index()])
+ return MutableRawNonOneof<MapFieldBase>(message, field)
->MutableRepeatedField();
}
- return reinterpret_cast<uint8*>(message) + offsets_[field->index()];
+ return MutableRawNonOneof<void>(message, field);
}
}
@@ -1758,11 +1755,9 @@ const void* GeneratedMessageReflection::GetRawRepeatedField(
} else {
// Trigger transform for MapField
if (IsMapFieldInApi(field)) {
- return &(reinterpret_cast<const MapFieldBase*>(
- reinterpret_cast<const uint8*>(&message) +
- offsets_[field->index()])->GetRepeatedField());
+ return &(GetRawNonOneof<MapFieldBase>(message, field).GetRepeatedField());
}
- return reinterpret_cast<const uint8*>(&message) + offsets_[field->index()];
+ return &GetRawNonOneof<char>(message, field);
}
}
@@ -1844,7 +1839,7 @@ int GeneratedMessageReflection::MapSize(
const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByName(
const string& name) const {
- if (extensions_offset_ == -1) return NULL;
+ if (!schema_.HasExtensionSet()) return NULL;
const FieldDescriptor* result = descriptor_pool_->FindExtensionByName(name);
if (result != NULL && result->containing_type() == descriptor_) {
@@ -1856,7 +1851,8 @@ 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.
- for (int i = 0; i < type->extension_count(); i++) {
+ const int type_extension_count = type->extension_count();
+ 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 &&
@@ -1874,7 +1870,7 @@ const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByName(
const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByNumber(
int number) const {
- if (extensions_offset_ == -1) return NULL;
+ if (!schema_.HasExtensionSet()) return NULL;
return descriptor_pool_->FindExtensionByNumber(descriptor_, number);
}
@@ -1887,204 +1883,176 @@ 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>
-inline const Type& GeneratedMessageReflection::GetRaw(
+const Type& GeneratedMessageReflection::GetRaw(
const Message& message, const FieldDescriptor* field) const {
if (field->containing_oneof() && !HasOneofField(message, field)) {
return DefaultRaw<Type>(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);
+ return GetConstRefAtOffset<Type>(message, schema_.GetFieldOffset(field));
}
template <typename Type>
-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);
+Type* GeneratedMessageReflection::MutableRaw(Message* message,
+ const FieldDescriptor* field) const {
+ return GetPointerAtOffset<Type>(message, schema_.GetFieldOffset(field));
}
-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 {
- 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);
+ GOOGLE_DCHECK(schema_.HasHasbits());
+ return &GetConstRefAtOffset<uint32>(message, schema_.HasBitsOffset());
}
+
inline uint32* GeneratedMessageReflection::MutableHasBits(
Message* message) const {
- if (has_bits_offset_ == -1) {
- return NULL;
- }
- void* ptr = reinterpret_cast<uint8*>(message) + has_bits_offset_;
- return reinterpret_cast<uint32*>(ptr);
+ GOOGLE_DCHECK(schema_.HasHasbits());
+ return GetPointerAtOffset<uint32>(message, schema_.HasBitsOffset());
}
inline uint32 GeneratedMessageReflection::GetOneofCase(
- 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()];
+ const Message& message, const OneofDescriptor* oneof_descriptor) const {
+ return GetConstRefAtOffset<uint32>(
+ message, schema_.GetOneofCaseOffset(oneof_descriptor));
}
inline uint32* GeneratedMessageReflection::MutableOneofCase(
- Message* message,
- const OneofDescriptor* oneof_descriptor) const {
- void* ptr = reinterpret_cast<uint8*>(message) + oneof_case_offset_;
- return &(reinterpret_cast<uint32*>(ptr)[oneof_descriptor->index()]);
+ Message* message, const OneofDescriptor* oneof_descriptor) const {
+ return GetPointerAtOffset<uint32>(
+ message, schema_.GetOneofCaseOffset(oneof_descriptor));
}
inline const ExtensionSet& GeneratedMessageReflection::GetExtensionSet(
const Message& message) const {
- GOOGLE_DCHECK_NE(extensions_offset_, -1);
- const void* ptr = reinterpret_cast<const uint8*>(&message) +
- extensions_offset_;
- return *reinterpret_cast<const ExtensionSet*>(ptr);
+ return GetConstRefAtOffset<ExtensionSet>(message,
+ schema_.GetExtensionSetOffset());
}
+
inline ExtensionSet* GeneratedMessageReflection::MutableExtensionSet(
Message* message) const {
- GOOGLE_DCHECK_NE(extensions_offset_, -1);
- void* ptr = reinterpret_cast<uint8*>(message) + extensions_offset_;
- return reinterpret_cast<ExtensionSet*>(ptr);
+ return GetPointerAtOffset<ExtensionSet>(message,
+ schema_.GetExtensionSetOffset());
}
inline Arena* GeneratedMessageReflection::GetArena(Message* message) const {
- 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);
+ return GetInternalMetadataWithArena(*message).arena();
}
inline const InternalMetadataWithArena&
GeneratedMessageReflection::GetInternalMetadataWithArena(
const Message& message) const {
- const void* ptr = reinterpret_cast<const uint8*>(&message) + arena_offset_;
- return *reinterpret_cast<const InternalMetadataWithArena*>(ptr);
+ return GetConstRefAtOffset<InternalMetadataWithArena>(
+ message, schema_.GetMetadataOffset());
}
inline InternalMetadataWithArena*
GeneratedMessageReflection::MutableInternalMetadataWithArena(
Message* message) const {
- void* ptr = reinterpret_cast<uint8*>(message) + arena_offset_;
- return reinterpret_cast<InternalMetadataWithArena*>(ptr);
+ return GetPointerAtOffset<InternalMetadataWithArena>(
+ message, schema_.GetMetadataOffset());
}
-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);
+template <typename Type>
+inline const Type& GeneratedMessageReflection::DefaultRaw(
+ const FieldDescriptor* field) const {
+ return *reinterpret_cast<const Type*>(schema_.GetFieldDefault(field));
}
// Simple accessors for manipulating has_bits_.
inline bool GeneratedMessageReflection::HasBit(
const Message& message, const FieldDescriptor* field) const {
- 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;
- }
+ 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;
}
- 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;
- }
+ }
+ 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;
}
+ 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 (has_bits_offset_ == -1) {
+ if (!schema_.HasHasbits()) {
return;
}
- MutableHasBits(message)[field->index() / 32] |= (1 << (field->index() % 32));
+ const uint32 index = schema_.HasBitIndex(field);
+ MutableHasBits(message)[index / 32] |=
+ (static_cast<uint32>(1) << (index % 32));
}
inline void GeneratedMessageReflection::ClearBit(
Message* message, const FieldDescriptor* field) const {
- if (has_bits_offset_ == -1) {
+ if (!schema_.HasHasbits()) {
return;
}
- MutableHasBits(message)[field->index() / 32] &= ~(1 << (field->index() % 32));
+ const uint32 index = schema_.HasBitIndex(field);
+ MutableHasBits(message)[index / 32] &=
+ ~(static_cast<uint32>(1) << (index % 32));
}
inline void GeneratedMessageReflection::SwapBit(
Message* message1, Message* message2, const FieldDescriptor* field) const {
- if (has_bits_offset_ == -1) {
+ if (!schema_.HasHasbits()) {
return;
}
bool temp_has_bit = HasBit(*message1, field);
@@ -2125,7 +2093,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 aplication switches a lot from
+ // it. It will be much faster if an application switches a lot from
// a few oneof fields. Time/space tradeoff
uint32 oneof_case = GetOneofCase(*message, oneof_descriptor);
if (oneof_case > 0) {
@@ -2137,7 +2105,7 @@ inline void GeneratedMessageReflection::ClearOneof(
default: // TODO(kenton): Support other string reps.
case FieldOptions::STRING: {
const string* default_ptr =
- &DefaultRaw<ArenaStringPtr>(field).Get(NULL);
+ &DefaultRaw<ArenaStringPtr>(field).Get();
MutableField<ArenaStringPtr>(message, field)->
Destroy(default_ptr, GetArena(message));
break;
@@ -2249,7 +2217,7 @@ void* GeneratedMessageReflection::RepeatedFieldData(
return MutableExtensionSet(message)->MutableRawRepeatedField(
field->number(), field->type(), field->is_packed(), field);
} else {
- return reinterpret_cast<uint8*>(message) + offsets_[field->index()];
+ return MutableRawNonOneof<char>(message, field);
}
}
@@ -2261,56 +2229,165 @@ MapFieldBase* GeneratedMessageReflection::MapData(
return MutableRaw<MapFieldBase>(message, field);
}
-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 {
+
+// 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);
}
} // namespace internal

Powered by Google App Engine
This is Rietveld 408576698