OLD | NEW |
1 // Protocol Buffers - Google's data interchange format | 1 // Protocol Buffers - Google's data interchange format |
2 // Copyright 2008 Google Inc. All rights reserved. | 2 // Copyright 2008 Google Inc. All rights reserved. |
3 // https://developers.google.com/protocol-buffers/ | 3 // https://developers.google.com/protocol-buffers/ |
4 // | 4 // |
5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
7 // met: | 7 // met: |
8 // | 8 // |
9 // * Redistributions of source code must retain the above copyright | 9 // * Redistributions of source code must retain the above copyright |
10 // notice, this list of conditions and the following disclaimer. | 10 // notice, this list of conditions and the following disclaimer. |
(...skipping 26 matching lines...) Expand all Loading... |
37 | 37 |
38 #include <google/protobuf/stubs/logging.h> | 38 #include <google/protobuf/stubs/logging.h> |
39 #include <google/protobuf/stubs/common.h> | 39 #include <google/protobuf/stubs/common.h> |
40 #include <google/protobuf/descriptor.pb.h> | 40 #include <google/protobuf/descriptor.pb.h> |
41 #include <google/protobuf/descriptor.h> | 41 #include <google/protobuf/descriptor.h> |
42 #include <google/protobuf/extension_set.h> | 42 #include <google/protobuf/extension_set.h> |
43 #include <google/protobuf/generated_message_reflection.h> | 43 #include <google/protobuf/generated_message_reflection.h> |
44 #include <google/protobuf/generated_message_util.h> | 44 #include <google/protobuf/generated_message_util.h> |
45 #include <google/protobuf/map_field.h> | 45 #include <google/protobuf/map_field.h> |
46 #include <google/protobuf/repeated_field.h> | 46 #include <google/protobuf/repeated_field.h> |
47 // #include "google/protobuf/bridge/compatibility_mode_support.h" | |
48 | 47 |
49 | 48 |
50 #define GOOGLE_PROTOBUF_HAS_ONEOF | 49 #define GOOGLE_PROTOBUF_HAS_ONEOF |
51 | 50 |
52 namespace google { | 51 namespace google { |
53 namespace protobuf { | 52 namespace protobuf { |
54 namespace internal { | 53 namespace internal { |
55 | 54 |
56 namespace { | 55 namespace { |
57 bool IsMapFieldInApi(const FieldDescriptor* field) { | 56 bool IsMapFieldInApi(const FieldDescriptor* field) { |
(...skipping 20 matching lines...) Expand all Loading... |
78 return descriptor->file()->options().cc_enable_arenas(); | 77 return descriptor->file()->options().cc_enable_arenas(); |
79 } | 78 } |
80 } // anonymous namespace | 79 } // anonymous namespace |
81 | 80 |
82 // =================================================================== | 81 // =================================================================== |
83 // Helpers for reporting usage errors (e.g. trying to use GetInt32() on | 82 // Helpers for reporting usage errors (e.g. trying to use GetInt32() on |
84 // a string field). | 83 // a string field). |
85 | 84 |
86 namespace { | 85 namespace { |
87 | 86 |
88 template <class To> | |
89 To* GetPointerAtOffset(Message* message, uint32 offset) { | |
90 return reinterpret_cast<To*>(reinterpret_cast<char*>(message) + offset); | |
91 } | |
92 | |
93 template <class To> | |
94 const To* GetConstPointerAtOffset(const Message* message, uint32 offset) { | |
95 return reinterpret_cast<const To*>(reinterpret_cast<const char*>(message) + | |
96 offset); | |
97 } | |
98 | |
99 template <class To> | |
100 const To& GetConstRefAtOffset(const Message& message, uint32 offset) { | |
101 return *GetConstPointerAtOffset<To>(&message, offset); | |
102 } | |
103 | |
104 void ReportReflectionUsageError( | 87 void ReportReflectionUsageError( |
105 const Descriptor* descriptor, const FieldDescriptor* field, | 88 const Descriptor* descriptor, const FieldDescriptor* field, |
106 const char* method, const char* description) { | 89 const char* method, const char* description) { |
107 GOOGLE_LOG(FATAL) | 90 GOOGLE_LOG(FATAL) |
108 << "Protocol Buffer reflection usage error:\n" | 91 << "Protocol Buffer reflection usage error:\n" |
109 " Method : google::protobuf::Reflection::" << method << "\n" | 92 " Method : google::protobuf::Reflection::" << method << "\n" |
110 " Message type: " << descriptor->full_name() << "\n" | 93 " Message type: " << descriptor->full_name() << "\n" |
111 " Field : " << field->full_name() << "\n" | 94 " Field : " << field->full_name() << "\n" |
112 " Problem : " << description; | 95 " Problem : " << description; |
113 } | 96 } |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 #define USAGE_CHECK_ALL(METHOD, LABEL, CPPTYPE) \ | 166 #define USAGE_CHECK_ALL(METHOD, LABEL, CPPTYPE) \ |
184 USAGE_CHECK_MESSAGE_TYPE(METHOD); \ | 167 USAGE_CHECK_MESSAGE_TYPE(METHOD); \ |
185 USAGE_CHECK_##LABEL(METHOD); \ | 168 USAGE_CHECK_##LABEL(METHOD); \ |
186 USAGE_CHECK_TYPE(METHOD, CPPTYPE) | 169 USAGE_CHECK_TYPE(METHOD, CPPTYPE) |
187 | 170 |
188 } // namespace | 171 } // namespace |
189 | 172 |
190 // =================================================================== | 173 // =================================================================== |
191 | 174 |
192 GeneratedMessageReflection::GeneratedMessageReflection( | 175 GeneratedMessageReflection::GeneratedMessageReflection( |
193 const Descriptor* descriptor, const ReflectionSchema& schema, | 176 const Descriptor* descriptor, |
194 const DescriptorPool* pool, MessageFactory* factory) | 177 const Message* default_instance, |
195 : descriptor_(descriptor), | 178 const int offsets[], |
196 schema_(schema), | 179 int has_bits_offset, |
197 descriptor_pool_((pool == NULL) ? DescriptorPool::generated_pool() | 180 int unknown_fields_offset, |
198 : pool), | 181 int extensions_offset, |
199 message_factory_(factory), | 182 const DescriptorPool* descriptor_pool, |
200 // TODO(haberman) remove this when upb is using our table driven. | 183 MessageFactory* factory, |
201 default_instance_(schema_.default_instance_), | 184 int object_size, |
202 default_oneof_instance_(schema_.default_oneof_instance_), | 185 int arena_offset, |
203 offsets_(schema_.offsets_), | 186 int is_default_instance_offset) |
204 has_bits_indices_(schema_.has_bit_indices_), | 187 : descriptor_ (descriptor), |
205 has_bits_offset_(schema_.has_bits_offset_), | 188 default_instance_ (default_instance), |
206 oneof_case_offset_(schema_.oneof_case_offset_), | 189 offsets_ (offsets), |
207 unknown_fields_offset_(-1), | 190 has_bits_offset_ (has_bits_offset), |
208 extensions_offset_(schema_.extensions_offset_), | 191 unknown_fields_offset_(unknown_fields_offset), |
209 arena_offset_(schema_.metadata_offset_), | 192 extensions_offset_(extensions_offset), |
210 object_size_(schema_.object_size_) { | 193 arena_offset_ (arena_offset), |
| 194 is_default_instance_offset_(is_default_instance_offset), |
| 195 object_size_ (object_size), |
| 196 descriptor_pool_ ((descriptor_pool == NULL) ? |
| 197 DescriptorPool::generated_pool() : |
| 198 descriptor_pool), |
| 199 message_factory_ (factory) { |
| 200 } |
| 201 |
| 202 GeneratedMessageReflection::GeneratedMessageReflection( |
| 203 const Descriptor* descriptor, |
| 204 const Message* default_instance, |
| 205 const int offsets[], |
| 206 int has_bits_offset, |
| 207 int unknown_fields_offset, |
| 208 int extensions_offset, |
| 209 const void* default_oneof_instance, |
| 210 int oneof_case_offset, |
| 211 const DescriptorPool* descriptor_pool, |
| 212 MessageFactory* factory, |
| 213 int object_size, |
| 214 int arena_offset, |
| 215 int is_default_instance_offset) |
| 216 : descriptor_ (descriptor), |
| 217 default_instance_ (default_instance), |
| 218 default_oneof_instance_ (default_oneof_instance), |
| 219 offsets_ (offsets), |
| 220 has_bits_offset_ (has_bits_offset), |
| 221 oneof_case_offset_(oneof_case_offset), |
| 222 unknown_fields_offset_(unknown_fields_offset), |
| 223 extensions_offset_(extensions_offset), |
| 224 arena_offset_ (arena_offset), |
| 225 is_default_instance_offset_(is_default_instance_offset), |
| 226 object_size_ (object_size), |
| 227 descriptor_pool_ ((descriptor_pool == NULL) ? |
| 228 DescriptorPool::generated_pool() : |
| 229 descriptor_pool), |
| 230 message_factory_ (factory) { |
211 } | 231 } |
212 | 232 |
213 GeneratedMessageReflection::~GeneratedMessageReflection() {} | 233 GeneratedMessageReflection::~GeneratedMessageReflection() {} |
214 | 234 |
215 namespace { | 235 namespace { |
216 UnknownFieldSet* empty_unknown_field_set_ = NULL; | 236 UnknownFieldSet* empty_unknown_field_set_ = NULL; |
217 GOOGLE_PROTOBUF_DECLARE_ONCE(empty_unknown_field_set_once_); | 237 GOOGLE_PROTOBUF_DECLARE_ONCE(empty_unknown_field_set_once_); |
218 | 238 |
219 void DeleteEmptyUnknownFieldSet() { | 239 void DeleteEmptyUnknownFieldSet() { |
220 delete empty_unknown_field_set_; | 240 delete empty_unknown_field_set_; |
221 empty_unknown_field_set_ = NULL; | 241 empty_unknown_field_set_ = NULL; |
222 } | 242 } |
223 | 243 |
224 void InitEmptyUnknownFieldSet() { | 244 void InitEmptyUnknownFieldSet() { |
225 empty_unknown_field_set_ = new UnknownFieldSet; | 245 empty_unknown_field_set_ = new UnknownFieldSet; |
226 internal::OnShutdown(&DeleteEmptyUnknownFieldSet); | 246 internal::OnShutdown(&DeleteEmptyUnknownFieldSet); |
227 } | 247 } |
228 | 248 |
229 const UnknownFieldSet& GetEmptyUnknownFieldSet() { | 249 const UnknownFieldSet& GetEmptyUnknownFieldSet() { |
230 ::google::protobuf::GoogleOnceInit(&empty_unknown_field_set_once_, &InitEmptyU
nknownFieldSet); | 250 ::google::protobuf::GoogleOnceInit(&empty_unknown_field_set_once_, &InitEmptyU
nknownFieldSet); |
231 return *empty_unknown_field_set_; | 251 return *empty_unknown_field_set_; |
232 } | 252 } |
233 } // namespace | 253 } // namespace |
234 | 254 |
235 const UnknownFieldSet& GeneratedMessageReflection::GetUnknownFields( | 255 const UnknownFieldSet& GeneratedMessageReflection::GetUnknownFields( |
236 const Message& message) const { | 256 const Message& message) const { |
237 if (descriptor_->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) { | 257 if (descriptor_->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) { |
238 // We have to ensure that any mutations made to the return value of | |
239 // MutableUnknownFields() are not reflected here. | |
240 return GetEmptyUnknownFieldSet(); | 258 return GetEmptyUnknownFieldSet(); |
241 } else { | 259 } |
| 260 if (unknown_fields_offset_ == kUnknownFieldSetInMetadata) { |
242 return GetInternalMetadataWithArena(message).unknown_fields(); | 261 return GetInternalMetadataWithArena(message).unknown_fields(); |
243 } | 262 } |
| 263 const void* ptr = reinterpret_cast<const uint8*>(&message) + |
| 264 unknown_fields_offset_; |
| 265 return *reinterpret_cast<const UnknownFieldSet*>(ptr); |
244 } | 266 } |
245 | 267 |
246 UnknownFieldSet* GeneratedMessageReflection::MutableUnknownFields( | 268 UnknownFieldSet* GeneratedMessageReflection::MutableUnknownFields( |
247 Message* message) const { | 269 Message* message) const { |
248 return MutableInternalMetadataWithArena(message)->mutable_unknown_fields(); | 270 if (unknown_fields_offset_ == kUnknownFieldSetInMetadata) { |
| 271 return MutableInternalMetadataWithArena(message)-> |
| 272 mutable_unknown_fields(); |
| 273 } |
| 274 void* ptr = reinterpret_cast<uint8*>(message) + unknown_fields_offset_; |
| 275 return reinterpret_cast<UnknownFieldSet*>(ptr); |
249 } | 276 } |
250 | 277 |
251 int GeneratedMessageReflection::SpaceUsed(const Message& message) const { | 278 int GeneratedMessageReflection::SpaceUsed(const Message& message) const { |
252 // object_size_ already includes the in-memory representation of each field | 279 // object_size_ already includes the in-memory representation of each field |
253 // in the message, so we only need to account for additional memory used by | 280 // in the message, so we only need to account for additional memory used by |
254 // the fields. | 281 // the fields. |
255 int total_size = schema_.GetObjectSize(); | 282 int total_size = object_size_; |
256 | 283 |
257 total_size += GetUnknownFields(message).SpaceUsedExcludingSelf(); | 284 total_size += GetUnknownFields(message).SpaceUsedExcludingSelf(); |
258 | 285 |
259 if (schema_.HasExtensionSet()) { | 286 if (extensions_offset_ != -1) { |
260 total_size += GetExtensionSet(message).SpaceUsedExcludingSelf(); | 287 total_size += GetExtensionSet(message).SpaceUsedExcludingSelf(); |
261 } | 288 } |
262 | 289 |
263 const int field_count = descriptor_->field_count(); | 290 for (int i = 0; i < descriptor_->field_count(); i++) { |
264 for (int i = 0; i < field_count; i++) { | |
265 const FieldDescriptor* field = descriptor_->field(i); | 291 const FieldDescriptor* field = descriptor_->field(i); |
266 | 292 |
267 if (field->is_repeated()) { | 293 if (field->is_repeated()) { |
268 switch (field->cpp_type()) { | 294 switch (field->cpp_type()) { |
269 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ | 295 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ |
270 case FieldDescriptor::CPPTYPE_##UPPERCASE : \ | 296 case FieldDescriptor::CPPTYPE_##UPPERCASE : \ |
271 total_size += GetRaw<RepeatedField<LOWERCASE> >(message, field) \ | 297 total_size += GetRaw<RepeatedField<LOWERCASE> >(message, field) \ |
272 .SpaceUsedExcludingSelf(); \ | 298 .SpaceUsedExcludingSelf(); \ |
273 break | 299 break |
274 | 300 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
323 break; | 349 break; |
324 | 350 |
325 case FieldDescriptor::CPPTYPE_STRING: { | 351 case FieldDescriptor::CPPTYPE_STRING: { |
326 switch (field->options().ctype()) { | 352 switch (field->options().ctype()) { |
327 default: // TODO(kenton): Support other string reps. | 353 default: // TODO(kenton): Support other string reps. |
328 case FieldOptions::STRING: { | 354 case FieldOptions::STRING: { |
329 // Initially, the string points to the default value stored in | 355 // Initially, the string points to the default value stored in |
330 // the prototype. Only count the string if it has been changed | 356 // the prototype. Only count the string if it has been changed |
331 // from the default value. | 357 // from the default value. |
332 const string* default_ptr = | 358 const string* default_ptr = |
333 &DefaultRaw<ArenaStringPtr>(field).Get(); | 359 &DefaultRaw<ArenaStringPtr>(field).Get(NULL); |
334 const string* ptr = | 360 const string* ptr = |
335 &GetField<ArenaStringPtr>(message, field).Get(); | 361 &GetField<ArenaStringPtr>(message, field).Get(default_ptr); |
336 | 362 |
337 if (ptr != default_ptr) { | 363 if (ptr != default_ptr) { |
338 // string fields are represented by just a pointer, so also | 364 // string fields are represented by just a pointer, so also |
339 // include sizeof(string) as well. | 365 // include sizeof(string) as well. |
340 total_size += sizeof(*ptr) + StringSpaceUsedExcludingSelf(*ptr); | 366 total_size += sizeof(*ptr) + StringSpaceUsedExcludingSelf(*ptr); |
341 } | 367 } |
342 break; | 368 break; |
343 } | 369 } |
344 } | 370 } |
345 break; | 371 break; |
346 } | 372 } |
347 | 373 |
348 case FieldDescriptor::CPPTYPE_MESSAGE: | 374 case FieldDescriptor::CPPTYPE_MESSAGE: |
349 if (schema_.IsDefaultInstance(message)) { | 375 if (&message == default_instance_) { |
350 // For singular fields, the prototype just stores a pointer to the | 376 // For singular fields, the prototype just stores a pointer to the |
351 // external type's prototype, so there is no extra memory usage. | 377 // external type's prototype, so there is no extra memory usage. |
352 } else { | 378 } else { |
353 const Message* sub_message = GetRaw<const Message*>(message, field); | 379 const Message* sub_message = GetRaw<const Message*>(message, field); |
354 if (sub_message != NULL) { | 380 if (sub_message != NULL) { |
355 total_size += sub_message->SpaceUsed(); | 381 total_size += sub_message->SpaceUsed(); |
356 } | 382 } |
357 } | 383 } |
358 break; | 384 break; |
359 } | 385 } |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
461 Arena* arena1 = GetArena(message1); | 487 Arena* arena1 = GetArena(message1); |
462 Arena* arena2 = GetArena(message2); | 488 Arena* arena2 = GetArena(message2); |
463 ArenaStringPtr* string1 = | 489 ArenaStringPtr* string1 = |
464 MutableRaw<ArenaStringPtr>(message1, field); | 490 MutableRaw<ArenaStringPtr>(message1, field); |
465 ArenaStringPtr* string2 = | 491 ArenaStringPtr* string2 = |
466 MutableRaw<ArenaStringPtr>(message2, field); | 492 MutableRaw<ArenaStringPtr>(message2, field); |
467 if (arena1 == arena2) { | 493 if (arena1 == arena2) { |
468 string1->Swap(string2); | 494 string1->Swap(string2); |
469 } else { | 495 } else { |
470 const string* default_ptr = | 496 const string* default_ptr = |
471 &DefaultRaw<ArenaStringPtr>(field).Get(); | 497 &DefaultRaw<ArenaStringPtr>(field).Get(NULL); |
472 const string temp = string1->Get(); | 498 const string temp = string1->Get(default_ptr); |
473 string1->Set(default_ptr, string2->Get(), arena1); | 499 string1->Set(default_ptr, string2->Get(default_ptr), arena1); |
474 string2->Set(default_ptr, temp, arena2); | 500 string2->Set(default_ptr, temp, arena2); |
475 } | 501 } |
476 } | 502 } |
477 break; | 503 break; |
478 } | 504 } |
479 break; | 505 break; |
480 | 506 |
481 default: | 507 default: |
482 GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type(); | 508 GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type(); |
483 } | 509 } |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
624 << descriptor_->full_name() | 650 << descriptor_->full_name() |
625 << "\"). Note that the exact same class is required; not just the same " | 651 << "\"). Note that the exact same class is required; not just the same " |
626 "descriptor."; | 652 "descriptor."; |
627 | 653 |
628 // Check that both messages are in the same arena (or both on the heap). We | 654 // Check that both messages are in the same arena (or both on the heap). We |
629 // need to copy all data if not, due to ownership semantics. | 655 // need to copy all data if not, due to ownership semantics. |
630 if (GetArena(message1) != GetArena(message2)) { | 656 if (GetArena(message1) != GetArena(message2)) { |
631 // Slow copy path. | 657 // Slow copy path. |
632 // Use our arena as temp space, if available. | 658 // Use our arena as temp space, if available. |
633 Message* temp = message1->New(GetArena(message1)); | 659 Message* temp = message1->New(GetArena(message1)); |
634 temp->MergeFrom(*message2); | 660 temp->MergeFrom(*message1); |
635 message2->CopyFrom(*message1); | 661 message1->CopyFrom(*message2); |
636 Swap(message1, temp); | 662 message2->CopyFrom(*temp); |
637 if (GetArena(message1) == NULL) { | 663 if (GetArena(message1) == NULL) { |
638 delete temp; | 664 delete temp; |
639 } | 665 } |
640 return; | 666 return; |
641 } | 667 } |
642 | 668 |
643 if (schema_.HasHasbits()) { | 669 if (has_bits_offset_ != -1) { |
644 uint32* has_bits1 = MutableHasBits(message1); | 670 uint32* has_bits1 = MutableHasBits(message1); |
645 uint32* has_bits2 = MutableHasBits(message2); | 671 uint32* has_bits2 = MutableHasBits(message2); |
646 int has_bits_size = (descriptor_->field_count() + 31) / 32; | 672 int has_bits_size = (descriptor_->field_count() + 31) / 32; |
647 | 673 |
648 for (int i = 0; i < has_bits_size; i++) { | 674 for (int i = 0; i < has_bits_size; i++) { |
649 std::swap(has_bits1[i], has_bits2[i]); | 675 std::swap(has_bits1[i], has_bits2[i]); |
650 } | 676 } |
651 } | 677 } |
652 | 678 |
653 const int field_count = descriptor_->field_count(); | 679 for (int i = 0; i < descriptor_->field_count(); i++) { |
654 for (int i = 0; i < field_count; i++) { | |
655 const FieldDescriptor* field = descriptor_->field(i); | 680 const FieldDescriptor* field = descriptor_->field(i); |
656 if (!field->containing_oneof()) { | 681 if (!field->containing_oneof()) { |
657 SwapField(message1, message2, field); | 682 SwapField(message1, message2, field); |
658 } | 683 } |
659 } | 684 } |
660 | 685 |
661 const int oneof_decl_count = descriptor_->oneof_decl_count(); | 686 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { |
662 for (int i = 0; i < oneof_decl_count; i++) { | |
663 SwapOneofField(message1, message2, descriptor_->oneof_decl(i)); | 687 SwapOneofField(message1, message2, descriptor_->oneof_decl(i)); |
664 } | 688 } |
665 | 689 |
666 if (schema_.HasExtensionSet()) { | 690 if (extensions_offset_ != -1) { |
667 MutableExtensionSet(message1)->Swap(MutableExtensionSet(message2)); | 691 MutableExtensionSet(message1)->Swap(MutableExtensionSet(message2)); |
668 } | 692 } |
669 | 693 |
670 MutableUnknownFields(message1)->Swap(MutableUnknownFields(message2)); | 694 MutableUnknownFields(message1)->Swap(MutableUnknownFields(message2)); |
671 } | 695 } |
672 | 696 |
673 void GeneratedMessageReflection::SwapFields( | 697 void GeneratedMessageReflection::SwapFields( |
674 Message* message1, | 698 Message* message1, |
675 Message* message2, | 699 Message* message2, |
676 const std::vector<const FieldDescriptor*>& fields) const { | 700 const vector<const FieldDescriptor*>& fields) const { |
677 if (message1 == message2) return; | 701 if (message1 == message2) return; |
678 | 702 |
679 // TODO(kenton): Other Reflection methods should probably check this too. | 703 // TODO(kenton): Other Reflection methods should probably check this too. |
680 GOOGLE_CHECK_EQ(message1->GetReflection(), this) | 704 GOOGLE_CHECK_EQ(message1->GetReflection(), this) |
681 << "First argument to SwapFields() (of type \"" | 705 << "First argument to SwapFields() (of type \"" |
682 << message1->GetDescriptor()->full_name() | 706 << message1->GetDescriptor()->full_name() |
683 << "\") is not compatible with this reflection object (which is for type \"" | 707 << "\") is not compatible with this reflection object (which is for type \"" |
684 << descriptor_->full_name() | 708 << descriptor_->full_name() |
685 << "\"). Note that the exact same class is required; not just the same " | 709 << "\"). Note that the exact same class is required; not just the same " |
686 "descriptor."; | 710 "descriptor."; |
687 GOOGLE_CHECK_EQ(message2->GetReflection(), this) | 711 GOOGLE_CHECK_EQ(message2->GetReflection(), this) |
688 << "Second argument to SwapFields() (of type \"" | 712 << "Second argument to SwapFields() (of type \"" |
689 << message2->GetDescriptor()->full_name() | 713 << message2->GetDescriptor()->full_name() |
690 << "\") is not compatible with this reflection object (which is for type \"" | 714 << "\") is not compatible with this reflection object (which is for type \"" |
691 << descriptor_->full_name() | 715 << descriptor_->full_name() |
692 << "\"). Note that the exact same class is required; not just the same " | 716 << "\"). Note that the exact same class is required; not just the same " |
693 "descriptor."; | 717 "descriptor."; |
694 | 718 |
695 std::set<int> swapped_oneof; | 719 std::set<int> swapped_oneof; |
696 | 720 |
697 const int fields_size = static_cast<int>(fields.size()); | 721 for (int i = 0; i < fields.size(); i++) { |
698 for (int i = 0; i < fields_size; i++) { | |
699 const FieldDescriptor* field = fields[i]; | 722 const FieldDescriptor* field = fields[i]; |
700 if (field->is_extension()) { | 723 if (field->is_extension()) { |
701 MutableExtensionSet(message1)->SwapExtension( | 724 MutableExtensionSet(message1)->SwapExtension( |
702 MutableExtensionSet(message2), | 725 MutableExtensionSet(message2), |
703 field->number()); | 726 field->number()); |
704 } else { | 727 } else { |
705 if (field->containing_oneof()) { | 728 if (field->containing_oneof()) { |
706 int oneof_index = field->containing_oneof()->index(); | 729 int oneof_index = field->containing_oneof()->index(); |
707 // Only swap the oneof field once. | 730 // Only swap the oneof field once. |
708 if (swapped_oneof.find(oneof_index) != swapped_oneof.end()) { | 731 if (swapped_oneof.find(oneof_index) != swapped_oneof.end()) { |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
810 case FieldDescriptor::CPPTYPE_ENUM: | 833 case FieldDescriptor::CPPTYPE_ENUM: |
811 *MutableRaw<int>(message, field) = | 834 *MutableRaw<int>(message, field) = |
812 field->default_value_enum()->number(); | 835 field->default_value_enum()->number(); |
813 break; | 836 break; |
814 | 837 |
815 case FieldDescriptor::CPPTYPE_STRING: { | 838 case FieldDescriptor::CPPTYPE_STRING: { |
816 switch (field->options().ctype()) { | 839 switch (field->options().ctype()) { |
817 default: // TODO(kenton): Support other string reps. | 840 default: // TODO(kenton): Support other string reps. |
818 case FieldOptions::STRING: { | 841 case FieldOptions::STRING: { |
819 const string* default_ptr = | 842 const string* default_ptr = |
820 &DefaultRaw<ArenaStringPtr>(field).Get(); | 843 &DefaultRaw<ArenaStringPtr>(field).Get(NULL); |
821 MutableRaw<ArenaStringPtr>(message, field)->SetAllocated( | 844 MutableRaw<ArenaStringPtr>(message, field)->Destroy(default_ptr, |
822 default_ptr, NULL, GetArena(message)); | 845 GetArena(message)); |
823 break; | 846 break; |
824 } | 847 } |
825 } | 848 } |
826 break; | 849 break; |
827 } | 850 } |
828 | 851 |
829 case FieldDescriptor::CPPTYPE_MESSAGE: | 852 case FieldDescriptor::CPPTYPE_MESSAGE: |
830 if (!schema_.HasHasbits()) { | 853 if (has_bits_offset_ == -1) { |
831 // Proto3 does not have has-bits and we need to set a message field | 854 // Proto3 does not have has-bits and we need to set a message field |
832 // to NULL in order to indicate its un-presence. | 855 // to NULL in order to indicate its un-presence. |
833 if (GetArena(message) == NULL) { | 856 if (GetArena(message) == NULL) { |
834 delete *MutableRaw<Message*>(message, field); | 857 delete *MutableRaw<Message*>(message, field); |
835 } | 858 } |
836 *MutableRaw<Message*>(message, field) = NULL; | 859 *MutableRaw<Message*>(message, field) = NULL; |
837 } else { | 860 } else { |
838 (*MutableRaw<Message*>(message, field))->Clear(); | 861 (*MutableRaw<Message*>(message, field))->Clear(); |
839 } | 862 } |
840 break; | 863 break; |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
996 } | 1019 } |
997 | 1020 |
998 namespace { | 1021 namespace { |
999 // Comparison functor for sorting FieldDescriptors by field number. | 1022 // Comparison functor for sorting FieldDescriptors by field number. |
1000 struct FieldNumberSorter { | 1023 struct FieldNumberSorter { |
1001 bool operator()(const FieldDescriptor* left, | 1024 bool operator()(const FieldDescriptor* left, |
1002 const FieldDescriptor* right) const { | 1025 const FieldDescriptor* right) const { |
1003 return left->number() < right->number(); | 1026 return left->number() < right->number(); |
1004 } | 1027 } |
1005 }; | 1028 }; |
1006 | |
1007 inline bool IsIndexInHasBitSet( | |
1008 const uint32* has_bit_set, uint32 has_bit_index) { | |
1009 return ((has_bit_set[has_bit_index / 32] >> (has_bit_index % 32)) & | |
1010 static_cast<uint32>(1)) != 0; | |
1011 } | |
1012 } // namespace | 1029 } // namespace |
1013 | 1030 |
1014 void GeneratedMessageReflection::ListFields( | 1031 void GeneratedMessageReflection::ListFields( |
1015 const Message& message, | 1032 const Message& message, |
1016 std::vector<const FieldDescriptor*>* output) const { | 1033 vector<const FieldDescriptor*>* output) const { |
1017 output->clear(); | 1034 output->clear(); |
1018 | 1035 |
1019 // Optimization: The default instance never has any fields set. | 1036 // Optimization: The default instance never has any fields set. |
1020 if (schema_.IsDefaultInstance(message)) return; | 1037 if (&message == default_instance_) return; |
1021 | 1038 |
1022 // Optimization: Avoid calling GetHasBits() and HasOneofField() many times | 1039 output->reserve(descriptor_->field_count()); |
1023 // within the field loop. We allow this violation of ReflectionSchema | 1040 for (int i = 0; i < descriptor_->field_count(); i++) { |
1024 // encapsulation because this function takes a noticable about of CPU | |
1025 // fleetwide and properly allowing this optimization through public interfaces | |
1026 // seems more trouble than it is worth. | |
1027 const uint32* const has_bits = | |
1028 schema_.HasHasbits() ? GetHasBits(message) : NULL; | |
1029 const uint32* const has_bits_indices = schema_.has_bit_indices_; | |
1030 const uint32* const oneof_case_array = | |
1031 &GetConstRefAtOffset<uint32>(message, schema_.oneof_case_offset_); | |
1032 | |
1033 const int field_count = descriptor_->field_count(); | |
1034 output->reserve(field_count); | |
1035 for (int i = 0; i < field_count; i++) { | |
1036 const FieldDescriptor* field = descriptor_->field(i); | 1041 const FieldDescriptor* field = descriptor_->field(i); |
1037 if (field->is_repeated()) { | 1042 if (field->is_repeated()) { |
1038 if (FieldSize(message, field) > 0) { | 1043 if (FieldSize(message, field) > 0) { |
1039 output->push_back(field); | 1044 output->push_back(field); |
1040 } | 1045 } |
1041 } else { | 1046 } else { |
1042 const OneofDescriptor* containing_oneof = field->containing_oneof(); | 1047 if (field->containing_oneof()) { |
1043 if (containing_oneof) { | 1048 if (HasOneofField(message, field)) { |
1044 // Equivalent to: HasOneofField(message, field) | |
1045 if (oneof_case_array[containing_oneof->index()] == field->number()) { | |
1046 output->push_back(field); | 1049 output->push_back(field); |
1047 } | 1050 } |
1048 } else if (has_bits) { | 1051 } else if (HasBit(message, field)) { |
1049 // Equivalent to: HasBit(message, field) | |
1050 if (IsIndexInHasBitSet(has_bits, has_bits_indices[i])) { | |
1051 output->push_back(field); | |
1052 } | |
1053 } else if (HasBit(message, field)) { // Fall back on proto3-style HasBit. | |
1054 output->push_back(field); | 1052 output->push_back(field); |
1055 } | 1053 } |
1056 } | 1054 } |
1057 } | 1055 } |
1058 | 1056 |
1059 if (schema_.HasExtensionSet()) { | 1057 if (extensions_offset_ != -1) { |
1060 GetExtensionSet(message).AppendToList(descriptor_, descriptor_pool_, | 1058 GetExtensionSet(message).AppendToList(descriptor_, descriptor_pool_, |
1061 output); | 1059 output); |
1062 } | 1060 } |
1063 | 1061 |
1064 // ListFields() must sort output by field number. | 1062 // ListFields() must sort output by field number. |
1065 std::sort(output->begin(), output->end(), FieldNumberSorter()); | 1063 std::sort(output->begin(), output->end(), FieldNumberSorter()); |
1066 } | 1064 } |
1067 | 1065 |
1068 // ------------------------------------------------------------------- | 1066 // ------------------------------------------------------------------- |
1069 | 1067 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1143 string GeneratedMessageReflection::GetString( | 1141 string GeneratedMessageReflection::GetString( |
1144 const Message& message, const FieldDescriptor* field) const { | 1142 const Message& message, const FieldDescriptor* field) const { |
1145 USAGE_CHECK_ALL(GetString, SINGULAR, STRING); | 1143 USAGE_CHECK_ALL(GetString, SINGULAR, STRING); |
1146 if (field->is_extension()) { | 1144 if (field->is_extension()) { |
1147 return GetExtensionSet(message).GetString(field->number(), | 1145 return GetExtensionSet(message).GetString(field->number(), |
1148 field->default_value_string()); | 1146 field->default_value_string()); |
1149 } else { | 1147 } else { |
1150 switch (field->options().ctype()) { | 1148 switch (field->options().ctype()) { |
1151 default: // TODO(kenton): Support other string reps. | 1149 default: // TODO(kenton): Support other string reps. |
1152 case FieldOptions::STRING: { | 1150 case FieldOptions::STRING: { |
1153 return GetField<ArenaStringPtr>(message, field).Get(); | 1151 const string* default_ptr = |
| 1152 &DefaultRaw<ArenaStringPtr>(field).Get(NULL); |
| 1153 return GetField<ArenaStringPtr>(message, field).Get(default_ptr); |
1154 } | 1154 } |
1155 } | 1155 } |
1156 | 1156 |
1157 GOOGLE_LOG(FATAL) << "Can't get here."; | 1157 GOOGLE_LOG(FATAL) << "Can't get here."; |
1158 return GetEmptyString(); // Make compiler happy. | 1158 return GetEmptyString(); // Make compiler happy. |
1159 } | 1159 } |
1160 } | 1160 } |
1161 | 1161 |
1162 const string& GeneratedMessageReflection::GetStringReference( | 1162 const string& GeneratedMessageReflection::GetStringReference( |
1163 const Message& message, | 1163 const Message& message, |
1164 const FieldDescriptor* field, string* scratch) const { | 1164 const FieldDescriptor* field, string* scratch) const { |
1165 USAGE_CHECK_ALL(GetStringReference, SINGULAR, STRING); | 1165 USAGE_CHECK_ALL(GetStringReference, SINGULAR, STRING); |
1166 if (field->is_extension()) { | 1166 if (field->is_extension()) { |
1167 return GetExtensionSet(message).GetString(field->number(), | 1167 return GetExtensionSet(message).GetString(field->number(), |
1168 field->default_value_string()); | 1168 field->default_value_string()); |
1169 } else { | 1169 } else { |
1170 switch (field->options().ctype()) { | 1170 switch (field->options().ctype()) { |
1171 default: // TODO(kenton): Support other string reps. | 1171 default: // TODO(kenton): Support other string reps. |
1172 case FieldOptions::STRING: { | 1172 case FieldOptions::STRING: { |
1173 return GetField<ArenaStringPtr>(message, field).Get(); | 1173 const string* default_ptr = |
| 1174 &DefaultRaw<ArenaStringPtr>(field).Get(NULL); |
| 1175 return GetField<ArenaStringPtr>(message, field).Get(default_ptr); |
1174 } | 1176 } |
1175 } | 1177 } |
1176 | 1178 |
1177 GOOGLE_LOG(FATAL) << "Can't get here."; | 1179 GOOGLE_LOG(FATAL) << "Can't get here."; |
1178 return GetEmptyString(); // Make compiler happy. | 1180 return GetEmptyString(); // Make compiler happy. |
1179 } | 1181 } |
1180 } | 1182 } |
1181 | 1183 |
1182 | 1184 |
1183 void GeneratedMessageReflection::SetString( | 1185 void GeneratedMessageReflection::SetString( |
1184 Message* message, const FieldDescriptor* field, | 1186 Message* message, const FieldDescriptor* field, |
1185 const string& value) const { | 1187 const string& value) const { |
1186 USAGE_CHECK_ALL(SetString, SINGULAR, STRING); | 1188 USAGE_CHECK_ALL(SetString, SINGULAR, STRING); |
1187 if (field->is_extension()) { | 1189 if (field->is_extension()) { |
1188 return MutableExtensionSet(message)->SetString(field->number(), | 1190 return MutableExtensionSet(message)->SetString(field->number(), |
1189 field->type(), value, field); | 1191 field->type(), value, field); |
1190 } else { | 1192 } else { |
1191 switch (field->options().ctype()) { | 1193 switch (field->options().ctype()) { |
1192 default: // TODO(kenton): Support other string reps. | 1194 default: // TODO(kenton): Support other string reps. |
1193 case FieldOptions::STRING: { | 1195 case FieldOptions::STRING: { |
1194 const string* default_ptr = &DefaultRaw<ArenaStringPtr>(field).Get(); | 1196 const string* default_ptr = |
| 1197 &DefaultRaw<ArenaStringPtr>(field).Get(NULL); |
1195 if (field->containing_oneof() && !HasOneofField(*message, field)) { | 1198 if (field->containing_oneof() && !HasOneofField(*message, field)) { |
1196 ClearOneof(message, field->containing_oneof()); | 1199 ClearOneof(message, field->containing_oneof()); |
1197 MutableField<ArenaStringPtr>(message, field)->UnsafeSetDefault( | 1200 MutableField<ArenaStringPtr>(message, field)->UnsafeSetDefault( |
1198 default_ptr); | 1201 default_ptr); |
1199 } | 1202 } |
1200 MutableField<ArenaStringPtr>(message, field)->Set(default_ptr, | 1203 MutableField<ArenaStringPtr>(message, field)->Set(default_ptr, |
1201 value, GetArena(message)); | 1204 value, GetArena(message)); |
1202 break; | 1205 break; |
1203 } | 1206 } |
1204 } | 1207 } |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1569 Message* GeneratedMessageReflection::UnsafeArenaReleaseMessage( | 1572 Message* GeneratedMessageReflection::UnsafeArenaReleaseMessage( |
1570 Message* message, | 1573 Message* message, |
1571 const FieldDescriptor* field, | 1574 const FieldDescriptor* field, |
1572 MessageFactory* factory) const { | 1575 MessageFactory* factory) const { |
1573 USAGE_CHECK_ALL(ReleaseMessage, SINGULAR, MESSAGE); | 1576 USAGE_CHECK_ALL(ReleaseMessage, SINGULAR, MESSAGE); |
1574 | 1577 |
1575 if (factory == NULL) factory = message_factory_; | 1578 if (factory == NULL) factory = message_factory_; |
1576 | 1579 |
1577 if (field->is_extension()) { | 1580 if (field->is_extension()) { |
1578 return static_cast<Message*>( | 1581 return static_cast<Message*>( |
1579 MutableExtensionSet(message)->UnsafeArenaReleaseMessage(field, | 1582 MutableExtensionSet(message)->ReleaseMessage(field, factory)); |
1580 factory)); | |
1581 } else { | 1583 } else { |
1582 ClearBit(message, field); | 1584 ClearBit(message, field); |
1583 if (field->containing_oneof()) { | 1585 if (field->containing_oneof()) { |
1584 if (HasOneofField(*message, field)) { | 1586 if (HasOneofField(*message, field)) { |
1585 *MutableOneofCase(message, field->containing_oneof()) = 0; | 1587 *MutableOneofCase(message, field->containing_oneof()) = 0; |
1586 } else { | 1588 } else { |
1587 return NULL; | 1589 return NULL; |
1588 } | 1590 } |
1589 } | 1591 } |
1590 Message** result = MutableRaw<Message*>(message, field); | 1592 Message** result = MutableRaw<Message*>(message, field); |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1718 if (ctype >= 0) | 1720 if (ctype >= 0) |
1719 GOOGLE_CHECK_EQ(field->options().ctype(), ctype) << "subtype mismatch"; | 1721 GOOGLE_CHECK_EQ(field->options().ctype(), ctype) << "subtype mismatch"; |
1720 if (desc != NULL) | 1722 if (desc != NULL) |
1721 GOOGLE_CHECK_EQ(field->message_type(), desc) << "wrong submessage type"; | 1723 GOOGLE_CHECK_EQ(field->message_type(), desc) << "wrong submessage type"; |
1722 if (field->is_extension()) { | 1724 if (field->is_extension()) { |
1723 return MutableExtensionSet(message)->MutableRawRepeatedField( | 1725 return MutableExtensionSet(message)->MutableRawRepeatedField( |
1724 field->number(), field->type(), field->is_packed(), field); | 1726 field->number(), field->type(), field->is_packed(), field); |
1725 } else { | 1727 } else { |
1726 // Trigger transform for MapField | 1728 // Trigger transform for MapField |
1727 if (IsMapFieldInApi(field)) { | 1729 if (IsMapFieldInApi(field)) { |
1728 return MutableRawNonOneof<MapFieldBase>(message, field) | 1730 return reinterpret_cast<MapFieldBase*>(reinterpret_cast<uint8*>(message) + |
| 1731 offsets_[field->index()]) |
1729 ->MutableRepeatedField(); | 1732 ->MutableRepeatedField(); |
1730 } | 1733 } |
1731 return MutableRawNonOneof<void>(message, field); | 1734 return reinterpret_cast<uint8*>(message) + offsets_[field->index()]; |
1732 } | 1735 } |
1733 } | 1736 } |
1734 | 1737 |
1735 const void* GeneratedMessageReflection::GetRawRepeatedField( | 1738 const void* GeneratedMessageReflection::GetRawRepeatedField( |
1736 const Message& message, const FieldDescriptor* field, | 1739 const Message& message, const FieldDescriptor* field, |
1737 FieldDescriptor::CppType cpptype, | 1740 FieldDescriptor::CppType cpptype, |
1738 int ctype, const Descriptor* desc) const { | 1741 int ctype, const Descriptor* desc) const { |
1739 USAGE_CHECK_REPEATED("GetRawRepeatedField"); | 1742 USAGE_CHECK_REPEATED("GetRawRepeatedField"); |
1740 if (field->cpp_type() != cpptype) | 1743 if (field->cpp_type() != cpptype) |
1741 ReportReflectionUsageTypeError(descriptor_, | 1744 ReportReflectionUsageTypeError(descriptor_, |
1742 field, "GetRawRepeatedField", cpptype); | 1745 field, "GetRawRepeatedField", cpptype); |
1743 if (ctype >= 0) | 1746 if (ctype >= 0) |
1744 GOOGLE_CHECK_EQ(field->options().ctype(), ctype) << "subtype mismatch"; | 1747 GOOGLE_CHECK_EQ(field->options().ctype(), ctype) << "subtype mismatch"; |
1745 if (desc != NULL) | 1748 if (desc != NULL) |
1746 GOOGLE_CHECK_EQ(field->message_type(), desc) << "wrong submessage type"; | 1749 GOOGLE_CHECK_EQ(field->message_type(), desc) << "wrong submessage type"; |
1747 if (field->is_extension()) { | 1750 if (field->is_extension()) { |
1748 // Should use extension_set::GetRawRepeatedField. However, the required | 1751 // Should use extension_set::GetRawRepeatedField. However, the required |
1749 // parameter "default repeated value" is not very easy to get here. | 1752 // parameter "default repeated value" is not very easy to get here. |
1750 // Map is not supported in extensions, it is acceptable to use | 1753 // Map is not supported in extensions, it is acceptable to use |
1751 // extension_set::MutableRawRepeatedField which does not change the message. | 1754 // extension_set::MutableRawRepeatedField which does not change the message. |
1752 return MutableExtensionSet(const_cast<Message*>(&message)) | 1755 return MutableExtensionSet(const_cast<Message*>(&message)) |
1753 ->MutableRawRepeatedField( | 1756 ->MutableRawRepeatedField( |
1754 field->number(), field->type(), field->is_packed(), field); | 1757 field->number(), field->type(), field->is_packed(), field); |
1755 } else { | 1758 } else { |
1756 // Trigger transform for MapField | 1759 // Trigger transform for MapField |
1757 if (IsMapFieldInApi(field)) { | 1760 if (IsMapFieldInApi(field)) { |
1758 return &(GetRawNonOneof<MapFieldBase>(message, field).GetRepeatedField()); | 1761 return &(reinterpret_cast<const MapFieldBase*>( |
| 1762 reinterpret_cast<const uint8*>(&message) + |
| 1763 offsets_[field->index()])->GetRepeatedField()); |
1759 } | 1764 } |
1760 return &GetRawNonOneof<char>(message, field); | 1765 return reinterpret_cast<const uint8*>(&message) + offsets_[field->index()]; |
1761 } | 1766 } |
1762 } | 1767 } |
1763 | 1768 |
1764 const FieldDescriptor* GeneratedMessageReflection::GetOneofFieldDescriptor( | 1769 const FieldDescriptor* GeneratedMessageReflection::GetOneofFieldDescriptor( |
1765 const Message& message, | 1770 const Message& message, |
1766 const OneofDescriptor* oneof_descriptor) const { | 1771 const OneofDescriptor* oneof_descriptor) const { |
1767 uint32 field_number = GetOneofCase(message, oneof_descriptor); | 1772 uint32 field_number = GetOneofCase(message, oneof_descriptor); |
1768 if (field_number == 0) { | 1773 if (field_number == 0) { |
1769 return NULL; | 1774 return NULL; |
1770 } | 1775 } |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1832 USAGE_CHECK(IsMapFieldInApi(field), | 1837 USAGE_CHECK(IsMapFieldInApi(field), |
1833 "MapSize", | 1838 "MapSize", |
1834 "Field is not a map field."); | 1839 "Field is not a map field."); |
1835 return GetRaw<MapFieldBase>(message, field).size(); | 1840 return GetRaw<MapFieldBase>(message, field).size(); |
1836 } | 1841 } |
1837 | 1842 |
1838 // ----------------------------------------------------------------------------- | 1843 // ----------------------------------------------------------------------------- |
1839 | 1844 |
1840 const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByName( | 1845 const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByName( |
1841 const string& name) const { | 1846 const string& name) const { |
1842 if (!schema_.HasExtensionSet()) return NULL; | 1847 if (extensions_offset_ == -1) return NULL; |
1843 | 1848 |
1844 const FieldDescriptor* result = descriptor_pool_->FindExtensionByName(name); | 1849 const FieldDescriptor* result = descriptor_pool_->FindExtensionByName(name); |
1845 if (result != NULL && result->containing_type() == descriptor_) { | 1850 if (result != NULL && result->containing_type() == descriptor_) { |
1846 return result; | 1851 return result; |
1847 } | 1852 } |
1848 | 1853 |
1849 if (descriptor_->options().message_set_wire_format()) { | 1854 if (descriptor_->options().message_set_wire_format()) { |
1850 // MessageSet extensions may be identified by type name. | 1855 // MessageSet extensions may be identified by type name. |
1851 const Descriptor* type = descriptor_pool_->FindMessageTypeByName(name); | 1856 const Descriptor* type = descriptor_pool_->FindMessageTypeByName(name); |
1852 if (type != NULL) { | 1857 if (type != NULL) { |
1853 // Look for a matching extension in the foreign type's scope. | 1858 // Look for a matching extension in the foreign type's scope. |
1854 const int type_extension_count = type->extension_count(); | 1859 for (int i = 0; i < type->extension_count(); i++) { |
1855 for (int i = 0; i < type_extension_count; i++) { | |
1856 const FieldDescriptor* extension = type->extension(i); | 1860 const FieldDescriptor* extension = type->extension(i); |
1857 if (extension->containing_type() == descriptor_ && | 1861 if (extension->containing_type() == descriptor_ && |
1858 extension->type() == FieldDescriptor::TYPE_MESSAGE && | 1862 extension->type() == FieldDescriptor::TYPE_MESSAGE && |
1859 extension->is_optional() && | 1863 extension->is_optional() && |
1860 extension->message_type() == type) { | 1864 extension->message_type() == type) { |
1861 // Found it. | 1865 // Found it. |
1862 return extension; | 1866 return extension; |
1863 } | 1867 } |
1864 } | 1868 } |
1865 } | 1869 } |
1866 } | 1870 } |
1867 | 1871 |
1868 return NULL; | 1872 return NULL; |
1869 } | 1873 } |
1870 | 1874 |
1871 const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByNumber( | 1875 const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByNumber( |
1872 int number) const { | 1876 int number) const { |
1873 if (!schema_.HasExtensionSet()) return NULL; | 1877 if (extensions_offset_ == -1) return NULL; |
1874 return descriptor_pool_->FindExtensionByNumber(descriptor_, number); | 1878 return descriptor_pool_->FindExtensionByNumber(descriptor_, number); |
1875 } | 1879 } |
1876 | 1880 |
1877 bool GeneratedMessageReflection::SupportsUnknownEnumValues() const { | 1881 bool GeneratedMessageReflection::SupportsUnknownEnumValues() const { |
1878 return CreateUnknownEnumValues(descriptor_->file()); | 1882 return CreateUnknownEnumValues(descriptor_->file()); |
1879 } | 1883 } |
1880 | 1884 |
1881 // =================================================================== | 1885 // =================================================================== |
1882 // Some private helpers. | 1886 // Some private helpers. |
1883 | 1887 |
1884 // These simple template accessors obtain pointers (or references) to | 1888 // These simple template accessors obtain pointers (or references) to |
1885 // the given field. | 1889 // the given field. |
1886 | |
1887 template <class Type> | |
1888 const Type& GeneratedMessageReflection::GetRawNonOneof( | |
1889 const Message& message, const FieldDescriptor* field) const { | |
1890 return GetConstRefAtOffset<Type>(message, | |
1891 schema_.GetFieldOffsetNonOneof(field)); | |
1892 } | |
1893 | |
1894 template <class Type> | |
1895 Type* GeneratedMessageReflection::MutableRawNonOneof( | |
1896 Message* message, const FieldDescriptor* field) const { | |
1897 return GetPointerAtOffset<Type>(message, | |
1898 schema_.GetFieldOffsetNonOneof(field)); | |
1899 } | |
1900 | |
1901 template <typename Type> | 1890 template <typename Type> |
1902 const Type& GeneratedMessageReflection::GetRaw( | 1891 inline const Type& GeneratedMessageReflection::GetRaw( |
1903 const Message& message, const FieldDescriptor* field) const { | 1892 const Message& message, const FieldDescriptor* field) const { |
1904 if (field->containing_oneof() && !HasOneofField(message, field)) { | 1893 if (field->containing_oneof() && !HasOneofField(message, field)) { |
1905 return DefaultRaw<Type>(field); | 1894 return DefaultRaw<Type>(field); |
1906 } | 1895 } |
1907 return GetConstRefAtOffset<Type>(message, schema_.GetFieldOffset(field)); | 1896 int index = field->containing_oneof() ? |
| 1897 descriptor_->field_count() + field->containing_oneof()->index() : |
| 1898 field->index(); |
| 1899 const void* ptr = reinterpret_cast<const uint8*>(&message) + |
| 1900 offsets_[index]; |
| 1901 return *reinterpret_cast<const Type*>(ptr); |
1908 } | 1902 } |
1909 | 1903 |
1910 template <typename Type> | 1904 template <typename Type> |
1911 Type* GeneratedMessageReflection::MutableRaw(Message* message, | 1905 inline Type* GeneratedMessageReflection::MutableRaw( |
1912 const FieldDescriptor* field) const { | 1906 Message* message, const FieldDescriptor* field) const { |
1913 return GetPointerAtOffset<Type>(message, schema_.GetFieldOffset(field)); | 1907 int index = field->containing_oneof() ? |
1914 } | 1908 descriptor_->field_count() + field->containing_oneof()->index() : |
1915 | 1909 field->index(); |
| 1910 void* ptr = reinterpret_cast<uint8*>(message) + offsets_[index]; |
| 1911 return reinterpret_cast<Type*>(ptr); |
| 1912 } |
| 1913 |
| 1914 template <typename Type> |
| 1915 inline const Type& GeneratedMessageReflection::DefaultRaw( |
| 1916 const FieldDescriptor* field) const { |
| 1917 const void* ptr = field->containing_oneof() ? |
| 1918 reinterpret_cast<const uint8*>(default_oneof_instance_) + |
| 1919 offsets_[field->index()] : |
| 1920 reinterpret_cast<const uint8*>(default_instance_) + |
| 1921 offsets_[field->index()]; |
| 1922 return *reinterpret_cast<const Type*>(ptr); |
| 1923 } |
1916 | 1924 |
1917 inline const uint32* GeneratedMessageReflection::GetHasBits( | 1925 inline const uint32* GeneratedMessageReflection::GetHasBits( |
1918 const Message& message) const { | 1926 const Message& message) const { |
1919 GOOGLE_DCHECK(schema_.HasHasbits()); | 1927 if (has_bits_offset_ == -1) { // proto3 with no has-bits. |
1920 return &GetConstRefAtOffset<uint32>(message, schema_.HasBitsOffset()); | 1928 return NULL; |
1921 } | 1929 } |
1922 | 1930 const void* ptr = reinterpret_cast<const uint8*>(&message) + has_bits_offset_; |
| 1931 return reinterpret_cast<const uint32*>(ptr); |
| 1932 } |
1923 inline uint32* GeneratedMessageReflection::MutableHasBits( | 1933 inline uint32* GeneratedMessageReflection::MutableHasBits( |
1924 Message* message) const { | 1934 Message* message) const { |
1925 GOOGLE_DCHECK(schema_.HasHasbits()); | 1935 if (has_bits_offset_ == -1) { |
1926 return GetPointerAtOffset<uint32>(message, schema_.HasBitsOffset()); | 1936 return NULL; |
| 1937 } |
| 1938 void* ptr = reinterpret_cast<uint8*>(message) + has_bits_offset_; |
| 1939 return reinterpret_cast<uint32*>(ptr); |
1927 } | 1940 } |
1928 | 1941 |
1929 inline uint32 GeneratedMessageReflection::GetOneofCase( | 1942 inline uint32 GeneratedMessageReflection::GetOneofCase( |
1930 const Message& message, const OneofDescriptor* oneof_descriptor) const { | 1943 const Message& message, |
1931 return GetConstRefAtOffset<uint32>( | 1944 const OneofDescriptor* oneof_descriptor) const { |
1932 message, schema_.GetOneofCaseOffset(oneof_descriptor)); | 1945 const void* ptr = reinterpret_cast<const uint8*>(&message) |
| 1946 + oneof_case_offset_; |
| 1947 return reinterpret_cast<const uint32*>(ptr)[oneof_descriptor->index()]; |
1933 } | 1948 } |
1934 | 1949 |
1935 inline uint32* GeneratedMessageReflection::MutableOneofCase( | 1950 inline uint32* GeneratedMessageReflection::MutableOneofCase( |
1936 Message* message, const OneofDescriptor* oneof_descriptor) const { | 1951 Message* message, |
1937 return GetPointerAtOffset<uint32>( | 1952 const OneofDescriptor* oneof_descriptor) const { |
1938 message, schema_.GetOneofCaseOffset(oneof_descriptor)); | 1953 void* ptr = reinterpret_cast<uint8*>(message) + oneof_case_offset_; |
| 1954 return &(reinterpret_cast<uint32*>(ptr)[oneof_descriptor->index()]); |
1939 } | 1955 } |
1940 | 1956 |
1941 inline const ExtensionSet& GeneratedMessageReflection::GetExtensionSet( | 1957 inline const ExtensionSet& GeneratedMessageReflection::GetExtensionSet( |
1942 const Message& message) const { | 1958 const Message& message) const { |
1943 return GetConstRefAtOffset<ExtensionSet>(message, | 1959 GOOGLE_DCHECK_NE(extensions_offset_, -1); |
1944 schema_.GetExtensionSetOffset()); | 1960 const void* ptr = reinterpret_cast<const uint8*>(&message) + |
1945 } | 1961 extensions_offset_; |
1946 | 1962 return *reinterpret_cast<const ExtensionSet*>(ptr); |
| 1963 } |
1947 inline ExtensionSet* GeneratedMessageReflection::MutableExtensionSet( | 1964 inline ExtensionSet* GeneratedMessageReflection::MutableExtensionSet( |
1948 Message* message) const { | 1965 Message* message) const { |
1949 return GetPointerAtOffset<ExtensionSet>(message, | 1966 GOOGLE_DCHECK_NE(extensions_offset_, -1); |
1950 schema_.GetExtensionSetOffset()); | 1967 void* ptr = reinterpret_cast<uint8*>(message) + extensions_offset_; |
| 1968 return reinterpret_cast<ExtensionSet*>(ptr); |
1951 } | 1969 } |
1952 | 1970 |
1953 inline Arena* GeneratedMessageReflection::GetArena(Message* message) const { | 1971 inline Arena* GeneratedMessageReflection::GetArena(Message* message) const { |
1954 return GetInternalMetadataWithArena(*message).arena(); | 1972 if (arena_offset_ == kNoArenaPointer) { |
| 1973 return NULL; |
| 1974 } |
| 1975 |
| 1976 if (unknown_fields_offset_ == kUnknownFieldSetInMetadata) { |
| 1977 // zero-overhead arena pointer overloading UnknownFields |
| 1978 return GetInternalMetadataWithArena(*message).arena(); |
| 1979 } |
| 1980 |
| 1981 // Baseline case: message class has a dedicated arena pointer. |
| 1982 void* ptr = reinterpret_cast<uint8*>(message) + arena_offset_; |
| 1983 return *reinterpret_cast<Arena**>(ptr); |
1955 } | 1984 } |
1956 | 1985 |
1957 inline const InternalMetadataWithArena& | 1986 inline const InternalMetadataWithArena& |
1958 GeneratedMessageReflection::GetInternalMetadataWithArena( | 1987 GeneratedMessageReflection::GetInternalMetadataWithArena( |
1959 const Message& message) const { | 1988 const Message& message) const { |
1960 return GetConstRefAtOffset<InternalMetadataWithArena>( | 1989 const void* ptr = reinterpret_cast<const uint8*>(&message) + arena_offset_; |
1961 message, schema_.GetMetadataOffset()); | 1990 return *reinterpret_cast<const InternalMetadataWithArena*>(ptr); |
1962 } | 1991 } |
1963 | 1992 |
1964 inline InternalMetadataWithArena* | 1993 inline InternalMetadataWithArena* |
1965 GeneratedMessageReflection::MutableInternalMetadataWithArena( | 1994 GeneratedMessageReflection::MutableInternalMetadataWithArena( |
1966 Message* message) const { | 1995 Message* message) const { |
1967 return GetPointerAtOffset<InternalMetadataWithArena>( | 1996 void* ptr = reinterpret_cast<uint8*>(message) + arena_offset_; |
1968 message, schema_.GetMetadataOffset()); | 1997 return reinterpret_cast<InternalMetadataWithArena*>(ptr); |
1969 } | 1998 } |
1970 | 1999 |
1971 template <typename Type> | 2000 inline bool |
1972 inline const Type& GeneratedMessageReflection::DefaultRaw( | 2001 GeneratedMessageReflection::GetIsDefaultInstance( |
1973 const FieldDescriptor* field) const { | 2002 const Message& message) const { |
1974 return *reinterpret_cast<const Type*>(schema_.GetFieldDefault(field)); | 2003 if (is_default_instance_offset_ == kHasNoDefaultInstanceField) { |
| 2004 return false; |
| 2005 } |
| 2006 const void* ptr = reinterpret_cast<const uint8*>(&message) + |
| 2007 is_default_instance_offset_; |
| 2008 return *reinterpret_cast<const bool*>(ptr); |
1975 } | 2009 } |
1976 | 2010 |
1977 // Simple accessors for manipulating has_bits_. | 2011 // Simple accessors for manipulating has_bits_. |
1978 inline bool GeneratedMessageReflection::HasBit( | 2012 inline bool GeneratedMessageReflection::HasBit( |
1979 const Message& message, const FieldDescriptor* field) const { | 2013 const Message& message, const FieldDescriptor* field) const { |
1980 if (schema_.HasHasbits()) { | 2014 if (has_bits_offset_ == -1) { |
1981 return IsIndexInHasBitSet(GetHasBits(message), schema_.HasBitIndex(field)); | 2015 // proto3: no has-bits. All fields present except messages, which are |
1982 } | 2016 // present only if their message-field pointer is non-NULL. |
1983 | 2017 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { |
1984 // proto3: no has-bits. All fields present except messages, which are | 2018 return !GetIsDefaultInstance(message) && |
1985 // present only if their message-field pointer is non-NULL. | 2019 GetRaw<const Message*>(message, field) != NULL; |
1986 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { | 2020 } else { |
1987 return !schema_.IsDefaultInstance(message) && | 2021 // Non-message field (and non-oneof, since that was handled in HasField() |
1988 GetRaw<const Message*>(message, field) != NULL; | 2022 // before calling us), and singular (again, checked in HasField). So, this |
1989 } else { | 2023 // field must be a scalar. |
1990 // Non-message field (and non-oneof, since that was handled in HasField() | 2024 |
1991 // before calling us), and singular (again, checked in HasField). So, this | 2025 // Scalar primitive (numeric or string/bytes) fields are present if |
1992 // field must be a scalar. | 2026 // their value is non-zero (numeric) or non-empty (string/bytes). N.B.: |
1993 | 2027 // we must use this definition here, rather than the "scalar fields |
1994 // Scalar primitive (numeric or string/bytes) fields are present if | 2028 // always present" in the proto3 docs, because MergeFrom() semantics |
1995 // their value is non-zero (numeric) or non-empty (string/bytes). N.B.: | 2029 // require presence as "present on wire", and reflection-based merge |
1996 // we must use this definition here, rather than the "scalar fields | 2030 // (which uses HasField()) needs to be consistent with this. |
1997 // always present" in the proto3 docs, because MergeFrom() semantics | 2031 switch (field->cpp_type()) { |
1998 // require presence as "present on wire", and reflection-based merge | 2032 case FieldDescriptor::CPPTYPE_STRING: |
1999 // (which uses HasField()) needs to be consistent with this. | 2033 switch (field->options().ctype()) { |
2000 switch (field->cpp_type()) { | 2034 default: { |
2001 case FieldDescriptor::CPPTYPE_STRING: | 2035 const string* default_ptr = |
2002 switch (field->options().ctype()) { | 2036 &DefaultRaw<ArenaStringPtr>(field).Get(NULL); |
2003 default: { | 2037 return GetField<ArenaStringPtr>(message, field).Get( |
2004 return GetField<ArenaStringPtr>(message, field).Get().size() > 0; | 2038 default_ptr).size() > 0; |
| 2039 } |
2005 } | 2040 } |
2006 } | 2041 return false; |
2007 return false; | 2042 case FieldDescriptor::CPPTYPE_BOOL: |
2008 case FieldDescriptor::CPPTYPE_BOOL: | 2043 return GetRaw<bool>(message, field) != false; |
2009 return GetRaw<bool>(message, field) != false; | 2044 case FieldDescriptor::CPPTYPE_INT32: |
2010 case FieldDescriptor::CPPTYPE_INT32: | 2045 return GetRaw<int32>(message, field) != 0; |
2011 return GetRaw<int32>(message, field) != 0; | 2046 case FieldDescriptor::CPPTYPE_INT64: |
2012 case FieldDescriptor::CPPTYPE_INT64: | 2047 return GetRaw<int64>(message, field) != 0; |
2013 return GetRaw<int64>(message, field) != 0; | 2048 case FieldDescriptor::CPPTYPE_UINT32: |
2014 case FieldDescriptor::CPPTYPE_UINT32: | 2049 return GetRaw<uint32>(message, field) != 0; |
2015 return GetRaw<uint32>(message, field) != 0; | 2050 case FieldDescriptor::CPPTYPE_UINT64: |
2016 case FieldDescriptor::CPPTYPE_UINT64: | 2051 return GetRaw<uint64>(message, field) != 0; |
2017 return GetRaw<uint64>(message, field) != 0; | 2052 case FieldDescriptor::CPPTYPE_FLOAT: |
2018 case FieldDescriptor::CPPTYPE_FLOAT: | 2053 return GetRaw<float>(message, field) != 0.0; |
2019 return GetRaw<float>(message, field) != 0.0; | 2054 case FieldDescriptor::CPPTYPE_DOUBLE: |
2020 case FieldDescriptor::CPPTYPE_DOUBLE: | 2055 return GetRaw<double>(message, field) != 0.0; |
2021 return GetRaw<double>(message, field) != 0.0; | 2056 case FieldDescriptor::CPPTYPE_ENUM: |
2022 case FieldDescriptor::CPPTYPE_ENUM: | 2057 return GetRaw<int>(message, field) != 0; |
2023 return GetRaw<int>(message, field) != 0; | 2058 case FieldDescriptor::CPPTYPE_MESSAGE: |
2024 case FieldDescriptor::CPPTYPE_MESSAGE: | 2059 // handled above; avoid warning |
2025 // handled above; avoid warning | 2060 GOOGLE_LOG(FATAL) << "Reached impossible case in HasBit()."; |
2026 break; | 2061 break; |
| 2062 } |
2027 } | 2063 } |
2028 GOOGLE_LOG(FATAL) << "Reached impossible case in HasBit()."; | 2064 } |
2029 return false; | 2065 return GetHasBits(message)[field->index() / 32] & |
2030 } | 2066 (1 << (field->index() % 32)); |
2031 } | 2067 } |
2032 | 2068 |
2033 inline void GeneratedMessageReflection::SetBit( | 2069 inline void GeneratedMessageReflection::SetBit( |
2034 Message* message, const FieldDescriptor* field) const { | 2070 Message* message, const FieldDescriptor* field) const { |
2035 if (!schema_.HasHasbits()) { | 2071 if (has_bits_offset_ == -1) { |
2036 return; | 2072 return; |
2037 } | 2073 } |
2038 const uint32 index = schema_.HasBitIndex(field); | 2074 MutableHasBits(message)[field->index() / 32] |= (1 << (field->index() % 32)); |
2039 MutableHasBits(message)[index / 32] |= | |
2040 (static_cast<uint32>(1) << (index % 32)); | |
2041 } | 2075 } |
2042 | 2076 |
2043 inline void GeneratedMessageReflection::ClearBit( | 2077 inline void GeneratedMessageReflection::ClearBit( |
2044 Message* message, const FieldDescriptor* field) const { | 2078 Message* message, const FieldDescriptor* field) const { |
2045 if (!schema_.HasHasbits()) { | 2079 if (has_bits_offset_ == -1) { |
2046 return; | 2080 return; |
2047 } | 2081 } |
2048 const uint32 index = schema_.HasBitIndex(field); | 2082 MutableHasBits(message)[field->index() / 32] &= ~(1 << (field->index() % 32)); |
2049 MutableHasBits(message)[index / 32] &= | |
2050 ~(static_cast<uint32>(1) << (index % 32)); | |
2051 } | 2083 } |
2052 | 2084 |
2053 inline void GeneratedMessageReflection::SwapBit( | 2085 inline void GeneratedMessageReflection::SwapBit( |
2054 Message* message1, Message* message2, const FieldDescriptor* field) const { | 2086 Message* message1, Message* message2, const FieldDescriptor* field) const { |
2055 if (!schema_.HasHasbits()) { | 2087 if (has_bits_offset_ == -1) { |
2056 return; | 2088 return; |
2057 } | 2089 } |
2058 bool temp_has_bit = HasBit(*message1, field); | 2090 bool temp_has_bit = HasBit(*message1, field); |
2059 if (HasBit(*message2, field)) { | 2091 if (HasBit(*message2, field)) { |
2060 SetBit(message1, field); | 2092 SetBit(message1, field); |
2061 } else { | 2093 } else { |
2062 ClearBit(message1, field); | 2094 ClearBit(message1, field); |
2063 } | 2095 } |
2064 if (temp_has_bit) { | 2096 if (temp_has_bit) { |
2065 SetBit(message2, field); | 2097 SetBit(message2, field); |
(...skipping 20 matching lines...) Expand all Loading... |
2086 inline void GeneratedMessageReflection::ClearOneofField( | 2118 inline void GeneratedMessageReflection::ClearOneofField( |
2087 Message* message, const FieldDescriptor* field) const { | 2119 Message* message, const FieldDescriptor* field) const { |
2088 if (HasOneofField(*message, field)) { | 2120 if (HasOneofField(*message, field)) { |
2089 ClearOneof(message, field->containing_oneof()); | 2121 ClearOneof(message, field->containing_oneof()); |
2090 } | 2122 } |
2091 } | 2123 } |
2092 | 2124 |
2093 inline void GeneratedMessageReflection::ClearOneof( | 2125 inline void GeneratedMessageReflection::ClearOneof( |
2094 Message* message, const OneofDescriptor* oneof_descriptor) const { | 2126 Message* message, const OneofDescriptor* oneof_descriptor) const { |
2095 // TODO(jieluo): Consider to cache the unused object instead of deleting | 2127 // TODO(jieluo): Consider to cache the unused object instead of deleting |
2096 // it. It will be much faster if an application switches a lot from | 2128 // it. It will be much faster if an aplication switches a lot from |
2097 // a few oneof fields. Time/space tradeoff | 2129 // a few oneof fields. Time/space tradeoff |
2098 uint32 oneof_case = GetOneofCase(*message, oneof_descriptor); | 2130 uint32 oneof_case = GetOneofCase(*message, oneof_descriptor); |
2099 if (oneof_case > 0) { | 2131 if (oneof_case > 0) { |
2100 const FieldDescriptor* field = descriptor_->FindFieldByNumber(oneof_case); | 2132 const FieldDescriptor* field = descriptor_->FindFieldByNumber(oneof_case); |
2101 if (GetArena(message) == NULL) { | 2133 if (GetArena(message) == NULL) { |
2102 switch (field->cpp_type()) { | 2134 switch (field->cpp_type()) { |
2103 case FieldDescriptor::CPPTYPE_STRING: { | 2135 case FieldDescriptor::CPPTYPE_STRING: { |
2104 switch (field->options().ctype()) { | 2136 switch (field->options().ctype()) { |
2105 default: // TODO(kenton): Support other string reps. | 2137 default: // TODO(kenton): Support other string reps. |
2106 case FieldOptions::STRING: { | 2138 case FieldOptions::STRING: { |
2107 const string* default_ptr = | 2139 const string* default_ptr = |
2108 &DefaultRaw<ArenaStringPtr>(field).Get(); | 2140 &DefaultRaw<ArenaStringPtr>(field).Get(NULL); |
2109 MutableField<ArenaStringPtr>(message, field)-> | 2141 MutableField<ArenaStringPtr>(message, field)-> |
2110 Destroy(default_ptr, GetArena(message)); | 2142 Destroy(default_ptr, GetArena(message)); |
2111 break; | 2143 break; |
2112 } | 2144 } |
2113 } | 2145 } |
2114 break; | 2146 break; |
2115 } | 2147 } |
2116 | 2148 |
2117 case FieldDescriptor::CPPTYPE_MESSAGE: | 2149 case FieldDescriptor::CPPTYPE_MESSAGE: |
2118 delete *MutableRaw<Message*>(message, field); | 2150 delete *MutableRaw<Message*>(message, field); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2210 << "The type parameter T in RepeatedFieldRef<T> API doesn't match " | 2242 << "The type parameter T in RepeatedFieldRef<T> API doesn't match " |
2211 << "the actual field type (for enums T should be the generated enum " | 2243 << "the actual field type (for enums T should be the generated enum " |
2212 << "type or int32)."; | 2244 << "type or int32)."; |
2213 if (message_type != NULL) { | 2245 if (message_type != NULL) { |
2214 GOOGLE_CHECK_EQ(message_type, field->message_type()); | 2246 GOOGLE_CHECK_EQ(message_type, field->message_type()); |
2215 } | 2247 } |
2216 if (field->is_extension()) { | 2248 if (field->is_extension()) { |
2217 return MutableExtensionSet(message)->MutableRawRepeatedField( | 2249 return MutableExtensionSet(message)->MutableRawRepeatedField( |
2218 field->number(), field->type(), field->is_packed(), field); | 2250 field->number(), field->type(), field->is_packed(), field); |
2219 } else { | 2251 } else { |
2220 return MutableRawNonOneof<char>(message, field); | 2252 return reinterpret_cast<uint8*>(message) + offsets_[field->index()]; |
2221 } | 2253 } |
2222 } | 2254 } |
2223 | 2255 |
2224 MapFieldBase* GeneratedMessageReflection::MapData( | 2256 MapFieldBase* GeneratedMessageReflection::MapData( |
2225 Message* message, const FieldDescriptor* field) const { | 2257 Message* message, const FieldDescriptor* field) const { |
2226 USAGE_CHECK(IsMapFieldInApi(field), | 2258 USAGE_CHECK(IsMapFieldInApi(field), |
2227 "GetMapData", | 2259 "GetMapData", |
2228 "Field is not a map field."); | 2260 "Field is not a map field."); |
2229 return MutableRaw<MapFieldBase>(message, field); | 2261 return MutableRaw<MapFieldBase>(message, field); |
2230 } | 2262 } |
2231 | 2263 |
2232 namespace { | 2264 GeneratedMessageReflection* |
2233 | 2265 GeneratedMessageReflection::NewGeneratedMessageReflection( |
2234 // Helper function to transform migration schema into reflection schema. | 2266 const Descriptor* descriptor, |
2235 ReflectionSchema MigrationToReflectionSchema( | 2267 const Message* default_instance, |
2236 const DefaultInstanceData* default_instance_data, const uint32* offsets, | 2268 const int offsets[], |
2237 MigrationSchema migration_schema) { | 2269 int has_bits_offset, |
2238 ReflectionSchema result; | 2270 int unknown_fields_offset, |
2239 result.default_instance_ = default_instance_data->default_instance; | 2271 int extensions_offset, |
2240 // First 5 offsets are offsets to the special fields. The following offsets | 2272 const void* default_oneof_instance, |
2241 // are the proto fields. | 2273 int oneof_case_offset, |
2242 result.offsets_ = offsets + migration_schema.offsets_index + 4; | 2274 int object_size, |
2243 result.has_bit_indices_ = offsets + migration_schema.has_bit_indices_index; | 2275 int arena_offset, |
2244 result.has_bits_offset_ = offsets[migration_schema.offsets_index + 0]; | 2276 int is_default_instance_offset) { |
2245 result.metadata_offset_ = offsets[migration_schema.offsets_index + 1]; | 2277 return new GeneratedMessageReflection(descriptor, |
2246 result.extensions_offset_ = offsets[migration_schema.offsets_index + 2]; | 2278 default_instance, |
2247 result.default_oneof_instance_ = default_instance_data->default_oneof_instance
; | 2279 offsets, |
2248 result.oneof_case_offset_ = offsets[migration_schema.offsets_index + 3]; | 2280 has_bits_offset, |
2249 result.object_size_ = migration_schema.object_size; | 2281 unknown_fields_offset, |
2250 return result; | 2282 extensions_offset, |
| 2283 default_oneof_instance, |
| 2284 oneof_case_offset, |
| 2285 DescriptorPool::generated_pool(), |
| 2286 MessageFactory::generated_factory(), |
| 2287 object_size, |
| 2288 arena_offset, |
| 2289 is_default_instance_offset); |
2251 } | 2290 } |
2252 | 2291 |
2253 ReflectionSchema MigrationToReflectionSchema( | 2292 GeneratedMessageReflection* |
2254 const DefaultInstanceData* default_instance_data, const uint32* offsets, | 2293 GeneratedMessageReflection::NewGeneratedMessageReflection( |
2255 ReflectionSchema schema) { | 2294 const Descriptor* descriptor, |
2256 return schema; | 2295 const Message* default_instance, |
2257 } | 2296 const int offsets[], |
2258 | 2297 int has_bits_offset, |
2259 template<typename Schema> | 2298 int unknown_fields_offset, |
2260 class AssignDescriptorsHelper { | 2299 int extensions_offset, |
2261 public: | 2300 int object_size, |
2262 AssignDescriptorsHelper(MessageFactory* factory, | 2301 int arena_offset, |
2263 Metadata* file_level_metadata, | 2302 int is_default_instance_offset) { |
2264 const EnumDescriptor** file_level_enum_descriptors, | 2303 return new GeneratedMessageReflection(descriptor, |
2265 const Schema* schemas, | 2304 default_instance, |
2266 const DefaultInstanceData* default_instance_data, | 2305 offsets, |
2267 const uint32* offsets) | 2306 has_bits_offset, |
2268 : factory_(factory), | 2307 unknown_fields_offset, |
2269 file_level_metadata_(file_level_metadata), | 2308 extensions_offset, |
2270 file_level_enum_descriptors_(file_level_enum_descriptors), | 2309 DescriptorPool::generated_pool(), |
2271 schemas_(schemas), | 2310 MessageFactory::generated_factory(), |
2272 default_instance_data_(default_instance_data), | 2311 object_size, |
2273 offsets_(offsets) {} | 2312 arena_offset, |
2274 | 2313 is_default_instance_offset); |
2275 void AssignMessageDescriptor(const Descriptor* descriptor) { | |
2276 for (int i = 0; i < descriptor->nested_type_count(); i++) { | |
2277 AssignMessageDescriptor(descriptor->nested_type(i)); | |
2278 } | |
2279 | |
2280 file_level_metadata_->descriptor = descriptor; | |
2281 | |
2282 if (!descriptor->options().map_entry()) { | |
2283 // Only set reflection for non map types. | |
2284 file_level_metadata_->reflection = new GeneratedMessageReflection( | |
2285 descriptor, MigrationToReflectionSchema(default_instance_data_++, | |
2286 offsets_, *schemas_), | |
2287 ::google::protobuf::DescriptorPool::generated_pool(), factory_); | |
2288 for (int i = 0; i < descriptor->enum_type_count(); i++) { | |
2289 AssignEnumDescriptor(descriptor->enum_type(i)); | |
2290 } | |
2291 schemas_++; | |
2292 } | |
2293 file_level_metadata_++; | |
2294 } | |
2295 | |
2296 void AssignEnumDescriptor(const EnumDescriptor* descriptor) { | |
2297 *file_level_enum_descriptors_ = descriptor; | |
2298 file_level_enum_descriptors_++; | |
2299 } | |
2300 | |
2301 private: | |
2302 MessageFactory* factory_; | |
2303 Metadata* file_level_metadata_; | |
2304 const EnumDescriptor** file_level_enum_descriptors_; | |
2305 const Schema* schemas_; | |
2306 const DefaultInstanceData* default_instance_data_; | |
2307 const uint32* offsets_; | |
2308 }; | |
2309 | |
2310 } // namespace | |
2311 | |
2312 void AssignDescriptors( | |
2313 const string& filename, const MigrationSchema* schemas, | |
2314 const DefaultInstanceData* default_instance_data, const uint32* offsets, | |
2315 MessageFactory* factory, | |
2316 // update the following descriptor arrays. | |
2317 Metadata* file_level_metadata, | |
2318 const EnumDescriptor** file_level_enum_descriptors, | |
2319 const ServiceDescriptor** file_level_service_descriptors) { | |
2320 const ::google::protobuf::FileDescriptor* file = | |
2321 ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(filen
ame); | |
2322 GOOGLE_CHECK(file != NULL); | |
2323 | |
2324 if (!factory) factory = MessageFactory::generated_factory(); | |
2325 | |
2326 AssignDescriptorsHelper<MigrationSchema> helper(factory, file_level_metadata, | |
2327 file_level_enum_descriptors, schemas, | |
2328 default_instance_data, offsets); | |
2329 | |
2330 for (int i = 0; i < file->message_type_count(); i++) { | |
2331 helper.AssignMessageDescriptor(file->message_type(i)); | |
2332 } | |
2333 | |
2334 for (int i = 0; i < file->enum_type_count(); i++) { | |
2335 helper.AssignEnumDescriptor(file->enum_type(i)); | |
2336 } | |
2337 if (file->options().cc_generic_services()) { | |
2338 for (int i = 0; i < file->service_count(); i++) { | |
2339 file_level_service_descriptors[i] = file->service(i); | |
2340 } | |
2341 } | |
2342 } | |
2343 | |
2344 void AssignDescriptors( | |
2345 const string& filename, const ReflectionSchema* schemas, | |
2346 MessageFactory* factory, | |
2347 // update the following descriptor arrays. | |
2348 Metadata* file_level_metadata, | |
2349 const EnumDescriptor** file_level_enum_descriptors, | |
2350 const ServiceDescriptor** file_level_service_descriptors) { | |
2351 const ::google::protobuf::FileDescriptor* file = | |
2352 ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(filen
ame); | |
2353 GOOGLE_CHECK(file != NULL); | |
2354 | |
2355 if (!factory) factory = MessageFactory::generated_factory(); | |
2356 | |
2357 AssignDescriptorsHelper<ReflectionSchema> helper(factory, file_level_metadata, | |
2358 file_level_enum_descriptors, schemas, | |
2359 NULL, NULL); | |
2360 | |
2361 for (int i = 0; i < file->message_type_count(); i++) { | |
2362 helper.AssignMessageDescriptor(file->message_type(i)); | |
2363 } | |
2364 | |
2365 for (int i = 0; i < file->enum_type_count(); i++) { | |
2366 helper.AssignEnumDescriptor(file->enum_type(i)); | |
2367 } | |
2368 if (file->options().cc_generic_services()) { | |
2369 for (int i = 0; i < file->service_count(); i++) { | |
2370 file_level_service_descriptors[i] = file->service(i); | |
2371 } | |
2372 } | |
2373 } | |
2374 | |
2375 void RegisterAllTypesInternal(const Metadata* file_level_metadata, int size) { | |
2376 for (int i = 0; i < size; i++) { | |
2377 const GeneratedMessageReflection* reflection = | |
2378 static_cast<const GeneratedMessageReflection*>( | |
2379 file_level_metadata[i].reflection); | |
2380 if (reflection) { | |
2381 // It's not a map type | |
2382 ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( | |
2383 file_level_metadata[i].descriptor, | |
2384 reflection->schema_.default_instance_); | |
2385 } | |
2386 } | |
2387 } | |
2388 | |
2389 void RegisterAllTypes(const Metadata* file_level_metadata, int size) { | |
2390 RegisterAllTypesInternal(file_level_metadata, size); | |
2391 } | 2314 } |
2392 | 2315 |
2393 } // namespace internal | 2316 } // namespace internal |
2394 } // namespace protobuf | 2317 } // namespace protobuf |
2395 } // namespace google | 2318 } // namespace google |
OLD | NEW |