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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
63 // I don't have the book on me right now so I'm not sure. | 63 // I don't have the book on me right now so I'm not sure. |
64 | 64 |
65 #include <algorithm> | 65 #include <algorithm> |
66 #include <google/protobuf/stubs/hash.h> | 66 #include <google/protobuf/stubs/hash.h> |
67 #include <memory> | 67 #include <memory> |
68 #ifndef _SHARED_PTR_H | 68 #ifndef _SHARED_PTR_H |
69 #include <google/protobuf/stubs/shared_ptr.h> | 69 #include <google/protobuf/stubs/shared_ptr.h> |
70 #endif | 70 #endif |
71 | 71 |
72 #include <google/protobuf/stubs/common.h> | 72 #include <google/protobuf/stubs/common.h> |
73 #include <google/protobuf/stubs/scoped_ptr.h> | |
74 | 73 |
75 #include <google/protobuf/dynamic_message.h> | 74 #include <google/protobuf/dynamic_message.h> |
76 #include <google/protobuf/descriptor.h> | 75 #include <google/protobuf/descriptor.h> |
77 #include <google/protobuf/descriptor.pb.h> | 76 #include <google/protobuf/descriptor.pb.h> |
78 #include <google/protobuf/generated_message_util.h> | 77 #include <google/protobuf/generated_message_util.h> |
79 #include <google/protobuf/generated_message_reflection.h> | 78 #include <google/protobuf/generated_message_reflection.h> |
80 #include <google/protobuf/arenastring.h> | 79 #include <google/protobuf/arenastring.h> |
81 #include <google/protobuf/map_field_inl.h> | 80 #include <google/protobuf/map_field_inl.h> |
82 #include <google/protobuf/reflection_ops.h> | 81 #include <google/protobuf/reflection_ops.h> |
83 #include <google/protobuf/repeated_field.h> | 82 #include <google/protobuf/repeated_field.h> |
84 #include <google/protobuf/map_type_handler.h> | 83 #include <google/protobuf/map_type_handler.h> |
85 #include <google/protobuf/extension_set.h> | 84 #include <google/protobuf/extension_set.h> |
86 #include <google/protobuf/wire_format.h> | 85 #include <google/protobuf/wire_format.h> |
87 #include <google/protobuf/map_field.h> | 86 #include <google/protobuf/map_field.h> |
88 | 87 |
89 namespace google { | 88 namespace google { |
90 namespace protobuf { | 89 namespace protobuf { |
91 | 90 |
92 using internal::WireFormat; | 91 using internal::DynamicMapField; |
93 using internal::ExtensionSet; | 92 using internal::ExtensionSet; |
94 using internal::GeneratedMessageReflection; | 93 using internal::GeneratedMessageReflection; |
| 94 using internal::InternalMetadataWithArena; |
95 using internal::MapField; | 95 using internal::MapField; |
96 using internal::DynamicMapField; | |
97 | 96 |
98 | 97 |
99 using internal::ArenaStringPtr; | 98 using internal::ArenaStringPtr; |
100 | 99 |
101 // =================================================================== | 100 // =================================================================== |
102 // Some helper tables and functions... | 101 // Some helper tables and functions... |
103 | 102 |
104 namespace { | 103 namespace { |
105 | 104 |
106 bool IsMapFieldInApi(const FieldDescriptor* field) { | 105 bool IsMapFieldInApi(const FieldDescriptor* field) { |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 } // namespace | 214 } // namespace |
216 | 215 |
217 // =================================================================== | 216 // =================================================================== |
218 | 217 |
219 class DynamicMessage : public Message { | 218 class DynamicMessage : public Message { |
220 public: | 219 public: |
221 struct TypeInfo { | 220 struct TypeInfo { |
222 int size; | 221 int size; |
223 int has_bits_offset; | 222 int has_bits_offset; |
224 int oneof_case_offset; | 223 int oneof_case_offset; |
225 int unknown_fields_offset; | 224 int internal_metadata_offset; |
226 int extensions_offset; | 225 int extensions_offset; |
227 int is_default_instance_offset; | |
228 | 226 |
229 // Not owned by the TypeInfo. | 227 // Not owned by the TypeInfo. |
230 DynamicMessageFactory* factory; // The factory that created this object. | 228 DynamicMessageFactory* factory; // The factory that created this object. |
231 const DescriptorPool* pool; // The factory's DescriptorPool. | 229 const DescriptorPool* pool; // The factory's DescriptorPool. |
232 const Descriptor* type; // Type of this DynamicMessage. | 230 const Descriptor* type; // Type of this DynamicMessage. |
233 | 231 |
234 // Warning: The order in which the following pointers are defined is | 232 // Warning: The order in which the following pointers are defined is |
235 // important (the prototype must be deleted *before* the offsets). | 233 // important (the prototype must be deleted *before* the offsets). |
236 google::protobuf::scoped_array<int> offsets; | 234 google::protobuf::scoped_array<uint32> offsets; |
| 235 google::protobuf::scoped_array<uint32> has_bits_indices; |
237 google::protobuf::scoped_ptr<const GeneratedMessageReflection> reflection; | 236 google::protobuf::scoped_ptr<const GeneratedMessageReflection> reflection; |
238 // Don't use a scoped_ptr to hold the prototype: the destructor for | 237 // Don't use a scoped_ptr to hold the prototype: the destructor for |
239 // DynamicMessage needs to know whether it is the prototype, and does so by | 238 // DynamicMessage needs to know whether it is the prototype, and does so by |
240 // looking back at this field. This would assume details about the | 239 // looking back at this field. This would assume details about the |
241 // implementation of scoped_ptr. | 240 // implementation of scoped_ptr. |
242 const DynamicMessage* prototype; | 241 const DynamicMessage* prototype; |
243 void* default_oneof_instance; | 242 void* default_oneof_instance; |
244 | 243 |
245 TypeInfo() : prototype(NULL), default_oneof_instance(NULL) {} | 244 TypeInfo() : prototype(NULL), default_oneof_instance(NULL) {} |
246 | 245 |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 // it now. We use placement new even for primitive types that don't have | 321 // it now. We use placement new even for primitive types that don't have |
323 // constructors for consistency. (In theory, placement new should be used | 322 // constructors for consistency. (In theory, placement new should be used |
324 // any time you are trying to convert untyped memory to typed memory, though | 323 // any time you are trying to convert untyped memory to typed memory, though |
325 // in practice that's not strictly necessary for types that don't have a | 324 // in practice that's not strictly necessary for types that don't have a |
326 // constructor.) | 325 // constructor.) |
327 | 326 |
328 const Descriptor* descriptor = type_info_->type; | 327 const Descriptor* descriptor = type_info_->type; |
329 | 328 |
330 // Initialize oneof cases. | 329 // Initialize oneof cases. |
331 for (int i = 0 ; i < descriptor->oneof_decl_count(); ++i) { | 330 for (int i = 0 ; i < descriptor->oneof_decl_count(); ++i) { |
332 new(OffsetToPointer(type_info_->oneof_case_offset + sizeof(uint32) * i)) | 331 new (OffsetToPointer(type_info_->oneof_case_offset + sizeof(uint32) * i)) |
333 uint32(0); | 332 uint32(0); |
334 } | 333 } |
335 | 334 |
336 if (type_info_->is_default_instance_offset != -1) { | 335 new (OffsetToPointer(type_info_->internal_metadata_offset)) |
337 *reinterpret_cast<bool*>( | 336 InternalMetadataWithArena; |
338 OffsetToPointer(type_info_->is_default_instance_offset)) = false; | |
339 } | |
340 | |
341 new(OffsetToPointer(type_info_->unknown_fields_offset)) UnknownFieldSet; | |
342 | 337 |
343 if (type_info_->extensions_offset != -1) { | 338 if (type_info_->extensions_offset != -1) { |
344 new(OffsetToPointer(type_info_->extensions_offset)) ExtensionSet; | 339 new (OffsetToPointer(type_info_->extensions_offset)) ExtensionSet; |
345 } | 340 } |
346 | 341 |
347 for (int i = 0; i < descriptor->field_count(); i++) { | 342 for (int i = 0; i < descriptor->field_count(); i++) { |
348 const FieldDescriptor* field = descriptor->field(i); | 343 const FieldDescriptor* field = descriptor->field(i); |
349 void* field_ptr = OffsetToPointer(type_info_->offsets[i]); | 344 void* field_ptr = OffsetToPointer(type_info_->offsets[i]); |
350 if (field->containing_oneof()) { | 345 if (field->containing_oneof()) { |
351 continue; | 346 continue; |
352 } | 347 } |
353 switch (field->cpp_type()) { | 348 switch (field->cpp_type()) { |
354 #define HANDLE_TYPE(CPPTYPE, TYPE) \ | 349 #define HANDLE_TYPE(CPPTYPE, TYPE) \ |
(...skipping 24 matching lines...) Expand all Loading... |
379 | 374 |
380 case FieldDescriptor::CPPTYPE_STRING: | 375 case FieldDescriptor::CPPTYPE_STRING: |
381 switch (field->options().ctype()) { | 376 switch (field->options().ctype()) { |
382 default: // TODO(kenton): Support other string reps. | 377 default: // TODO(kenton): Support other string reps. |
383 case FieldOptions::STRING: | 378 case FieldOptions::STRING: |
384 if (!field->is_repeated()) { | 379 if (!field->is_repeated()) { |
385 const string* default_value; | 380 const string* default_value; |
386 if (is_prototype()) { | 381 if (is_prototype()) { |
387 default_value = &field->default_value_string(); | 382 default_value = &field->default_value_string(); |
388 } else { | 383 } else { |
389 default_value = | 384 default_value = &(reinterpret_cast<const ArenaStringPtr*>( |
390 &(reinterpret_cast<const ArenaStringPtr*>( | 385 type_info_->prototype->OffsetToPointer( |
391 type_info_->prototype->OffsetToPointer( | 386 type_info_->offsets[i])) |
392 type_info_->offsets[i]))->Get(NULL)); | 387 ->Get()); |
393 } | 388 } |
394 ArenaStringPtr* asp = new(field_ptr) ArenaStringPtr(); | 389 ArenaStringPtr* asp = new(field_ptr) ArenaStringPtr(); |
395 asp->UnsafeSetDefault(default_value); | 390 asp->UnsafeSetDefault(default_value); |
396 } else { | 391 } else { |
397 new(field_ptr) RepeatedPtrField<string>(); | 392 new(field_ptr) RepeatedPtrField<string>(); |
398 } | 393 } |
399 break; | 394 break; |
400 } | 395 } |
401 break; | 396 break; |
402 | 397 |
(...skipping 10 matching lines...) Expand all Loading... |
413 } | 408 } |
414 break; | 409 break; |
415 } | 410 } |
416 } | 411 } |
417 } | 412 } |
418 } | 413 } |
419 | 414 |
420 DynamicMessage::~DynamicMessage() { | 415 DynamicMessage::~DynamicMessage() { |
421 const Descriptor* descriptor = type_info_->type; | 416 const Descriptor* descriptor = type_info_->type; |
422 | 417 |
423 reinterpret_cast<UnknownFieldSet*>( | 418 reinterpret_cast<InternalMetadataWithArena*>( |
424 OffsetToPointer(type_info_->unknown_fields_offset))->~UnknownFieldSet(); | 419 OffsetToPointer(type_info_->internal_metadata_offset)) |
| 420 ->~InternalMetadataWithArena(); |
425 | 421 |
426 if (type_info_->extensions_offset != -1) { | 422 if (type_info_->extensions_offset != -1) { |
427 reinterpret_cast<ExtensionSet*>( | 423 reinterpret_cast<ExtensionSet*>( |
428 OffsetToPointer(type_info_->extensions_offset))->~ExtensionSet(); | 424 OffsetToPointer(type_info_->extensions_offset))->~ExtensionSet(); |
429 } | 425 } |
430 | 426 |
431 // We need to manually run the destructors for repeated fields and strings, | 427 // We need to manually run the destructors for repeated fields and strings, |
432 // just as we ran their constructors in the DynamicMessage constructor. | 428 // just as we ran their constructors in the DynamicMessage constructor. |
433 // We also need to manually delete oneof fields if it is set and is string | 429 // We also need to manually delete oneof fields if it is set and is string |
434 // or message. | 430 // or message. |
(...skipping 10 matching lines...) Expand all Loading... |
445 if (*(reinterpret_cast<const uint32*>(field_ptr)) == | 441 if (*(reinterpret_cast<const uint32*>(field_ptr)) == |
446 field->number()) { | 442 field->number()) { |
447 field_ptr = OffsetToPointer(type_info_->offsets[ | 443 field_ptr = OffsetToPointer(type_info_->offsets[ |
448 descriptor->field_count() + field->containing_oneof()->index()]); | 444 descriptor->field_count() + field->containing_oneof()->index()]); |
449 if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { | 445 if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { |
450 switch (field->options().ctype()) { | 446 switch (field->options().ctype()) { |
451 default: | 447 default: |
452 case FieldOptions::STRING: { | 448 case FieldOptions::STRING: { |
453 const ::std::string* default_value = | 449 const ::std::string* default_value = |
454 &(reinterpret_cast<const ArenaStringPtr*>( | 450 &(reinterpret_cast<const ArenaStringPtr*>( |
455 reinterpret_cast<uint8*>( | 451 reinterpret_cast<uint8*>( |
456 type_info_->default_oneof_instance) | 452 type_info_->default_oneof_instance) + |
457 + type_info_->offsets[i]) | 453 type_info_->offsets[i]) |
458 ->Get(NULL)); | 454 ->Get()); |
459 reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy( | 455 reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy( |
460 default_value, NULL); | 456 default_value, NULL); |
461 break; | 457 break; |
462 } | 458 } |
463 } | 459 } |
464 } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { | 460 } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { |
465 delete *reinterpret_cast<Message**>(field_ptr); | 461 delete *reinterpret_cast<Message**>(field_ptr); |
466 } | 462 } |
467 } | 463 } |
468 continue; | 464 continue; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
506 } | 502 } |
507 break; | 503 break; |
508 } | 504 } |
509 | 505 |
510 } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { | 506 } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { |
511 switch (field->options().ctype()) { | 507 switch (field->options().ctype()) { |
512 default: // TODO(kenton): Support other string reps. | 508 default: // TODO(kenton): Support other string reps. |
513 case FieldOptions::STRING: { | 509 case FieldOptions::STRING: { |
514 const ::std::string* default_value = | 510 const ::std::string* default_value = |
515 &(reinterpret_cast<const ArenaStringPtr*>( | 511 &(reinterpret_cast<const ArenaStringPtr*>( |
516 type_info_->prototype->OffsetToPointer( | 512 type_info_->prototype->OffsetToPointer( |
517 type_info_->offsets[i]))->Get(NULL)); | 513 type_info_->offsets[i])) |
| 514 ->Get()); |
518 reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy( | 515 reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy( |
519 default_value, NULL); | 516 default_value, NULL); |
520 break; | 517 break; |
521 } | 518 } |
522 } | 519 } |
523 } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { | 520 } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { |
524 if (!is_prototype()) { | 521 if (!is_prototype()) { |
525 Message* message = *reinterpret_cast<Message**>(field_ptr); | 522 Message* message = *reinterpret_cast<Message**>(field_ptr); |
526 if (message != NULL) { | 523 if (message != NULL) { |
527 delete message; | 524 delete message; |
(...skipping 22 matching lines...) Expand all Loading... |
550 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && | 547 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && |
551 !field->is_repeated()) { | 548 !field->is_repeated()) { |
552 // For fields with message types, we need to cross-link with the | 549 // For fields with message types, we need to cross-link with the |
553 // prototype for the field's type. | 550 // prototype for the field's type. |
554 // For singular fields, the field is just a pointer which should | 551 // For singular fields, the field is just a pointer which should |
555 // point to the prototype. | 552 // point to the prototype. |
556 *reinterpret_cast<const Message**>(field_ptr) = | 553 *reinterpret_cast<const Message**>(field_ptr) = |
557 factory->GetPrototypeNoLock(field->message_type()); | 554 factory->GetPrototypeNoLock(field->message_type()); |
558 } | 555 } |
559 } | 556 } |
560 | |
561 // Set as the default instance -- this affects field-presence semantics for | |
562 // proto3. | |
563 if (type_info_->is_default_instance_offset != -1) { | |
564 void* is_default_instance_ptr = | |
565 OffsetToPointer(type_info_->is_default_instance_offset); | |
566 *reinterpret_cast<bool*>(is_default_instance_ptr) = true; | |
567 } | |
568 } | 557 } |
569 | 558 |
570 Message* DynamicMessage::New() const { | 559 Message* DynamicMessage::New() const { |
571 void* new_base = operator new(type_info_->size); | 560 void* new_base = operator new(type_info_->size); |
572 memset(new_base, 0, type_info_->size); | 561 memset(new_base, 0, type_info_->size); |
573 return new(new_base) DynamicMessage(type_info_); | 562 return new(new_base) DynamicMessage(type_info_); |
574 } | 563 } |
575 | 564 |
576 Message* DynamicMessage::New(::google::protobuf::Arena* arena) const { | 565 Message* DynamicMessage::New(::google::protobuf::Arena* arena) const { |
577 if (arena != NULL) { | 566 if (arena != NULL) { |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
657 | 646 |
658 // We need to construct all the structures passed to | 647 // We need to construct all the structures passed to |
659 // GeneratedMessageReflection's constructor. This includes: | 648 // GeneratedMessageReflection's constructor. This includes: |
660 // - A block of memory that contains space for all the message's fields. | 649 // - A block of memory that contains space for all the message's fields. |
661 // - An array of integers indicating the byte offset of each field within | 650 // - An array of integers indicating the byte offset of each field within |
662 // this block. | 651 // this block. |
663 // - A big bitfield containing a bit for each field indicating whether | 652 // - A big bitfield containing a bit for each field indicating whether |
664 // or not that field is set. | 653 // or not that field is set. |
665 | 654 |
666 // Compute size and offsets. | 655 // Compute size and offsets. |
667 int* offsets = new int[type->field_count() + type->oneof_decl_count()]; | 656 uint32* offsets = |
| 657 new uint32[type->field_count() + type->oneof_decl_count()]; |
668 type_info->offsets.reset(offsets); | 658 type_info->offsets.reset(offsets); |
669 | 659 |
670 // Decide all field offsets by packing in order. | 660 // Decide all field offsets by packing in order. |
671 // We place the DynamicMessage object itself at the beginning of the allocated | 661 // We place the DynamicMessage object itself at the beginning of the allocated |
672 // space. | 662 // space. |
673 int size = sizeof(DynamicMessage); | 663 int size = sizeof(DynamicMessage); |
674 size = AlignOffset(size); | 664 size = AlignOffset(size); |
675 | 665 |
676 // Next the has_bits, which is an array of uint32s. | 666 // Next the has_bits, which is an array of uint32s. |
677 if (type->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) { | 667 if (type->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) { |
678 type_info->has_bits_offset = -1; | 668 type_info->has_bits_offset = -1; |
679 } else { | 669 } else { |
680 type_info->has_bits_offset = size; | 670 type_info->has_bits_offset = size; |
681 int has_bits_array_size = | 671 int has_bits_array_size = |
682 DivideRoundingUp(type->field_count(), bitsizeof(uint32)); | 672 DivideRoundingUp(type->field_count(), bitsizeof(uint32)); |
683 size += has_bits_array_size * sizeof(uint32); | 673 size += has_bits_array_size * sizeof(uint32); |
684 size = AlignOffset(size); | 674 size = AlignOffset(size); |
685 } | |
686 | 675 |
687 // The is_default_instance member, if any. | 676 uint32* has_bits_indices = new uint32[type->field_count()]; |
688 if (type->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) { | 677 for (int i = 0; i < type->field_count(); i++) { |
689 type_info->is_default_instance_offset = size; | 678 has_bits_indices[i] = i; |
690 size += sizeof(bool); | 679 } |
691 size = AlignOffset(size); | 680 type_info->has_bits_indices.reset(has_bits_indices); |
692 } else { | |
693 type_info->is_default_instance_offset = -1; | |
694 } | 681 } |
695 | 682 |
696 // The oneof_case, if any. It is an array of uint32s. | 683 // The oneof_case, if any. It is an array of uint32s. |
697 if (type->oneof_decl_count() > 0) { | 684 if (type->oneof_decl_count() > 0) { |
698 type_info->oneof_case_offset = size; | 685 type_info->oneof_case_offset = size; |
699 size += type->oneof_decl_count() * sizeof(uint32); | 686 size += type->oneof_decl_count() * sizeof(uint32); |
700 size = AlignOffset(size); | 687 size = AlignOffset(size); |
701 } | 688 } |
702 | 689 |
703 // The ExtensionSet, if any. | 690 // The ExtensionSet, if any. |
704 if (type->extension_range_count() > 0) { | 691 if (type->extension_range_count() > 0) { |
705 type_info->extensions_offset = size; | 692 type_info->extensions_offset = size; |
706 size += sizeof(ExtensionSet); | 693 size += sizeof(ExtensionSet); |
707 size = AlignOffset(size); | 694 size = AlignOffset(size); |
708 } else { | 695 } else { |
709 // No extensions. | 696 // No extensions. |
710 type_info->extensions_offset = -1; | 697 type_info->extensions_offset = -1; |
711 } | 698 } |
712 | 699 |
713 // All the fields. | 700 // All the fields. |
| 701 // |
| 702 // TODO(b/31226269): Optimize the order of fields to minimize padding. |
714 for (int i = 0; i < type->field_count(); i++) { | 703 for (int i = 0; i < type->field_count(); i++) { |
715 // Make sure field is aligned to avoid bus errors. | 704 // Make sure field is aligned to avoid bus errors. |
716 // Oneof fields do not use any space. | 705 // Oneof fields do not use any space. |
717 if (!type->field(i)->containing_oneof()) { | 706 if (!type->field(i)->containing_oneof()) { |
718 int field_size = FieldSpaceUsed(type->field(i)); | 707 int field_size = FieldSpaceUsed(type->field(i)); |
719 size = AlignTo(size, std::min(kSafeAlignment, field_size)); | 708 size = AlignTo(size, std::min(kSafeAlignment, field_size)); |
720 offsets[i] = size; | 709 offsets[i] = size; |
721 size += field_size; | 710 size += field_size; |
722 } | 711 } |
723 } | 712 } |
724 | 713 |
725 // The oneofs. | 714 // The oneofs. |
726 for (int i = 0; i < type->oneof_decl_count(); i++) { | 715 for (int i = 0; i < type->oneof_decl_count(); i++) { |
727 size = AlignTo(size, kSafeAlignment); | 716 size = AlignTo(size, kSafeAlignment); |
728 offsets[type->field_count() + i] = size; | 717 offsets[type->field_count() + i] = size; |
729 size += kMaxOneofUnionSize; | 718 size += kMaxOneofUnionSize; |
730 } | 719 } |
731 | 720 |
732 // Add the UnknownFieldSet to the end. | 721 // Add the InternalMetadataWithArena to the end. |
733 size = AlignOffset(size); | 722 size = AlignOffset(size); |
734 type_info->unknown_fields_offset = size; | 723 type_info->internal_metadata_offset = size; |
735 size += sizeof(UnknownFieldSet); | 724 size += sizeof(InternalMetadataWithArena); |
736 | 725 |
737 // Align the final size to make sure no clever allocators think that | 726 // Align the final size to make sure no clever allocators think that |
738 // alignment is not necessary. | 727 // alignment is not necessary. |
739 size = AlignOffset(size); | 728 size = AlignOffset(size); |
740 type_info->size = size; | 729 type_info->size = size; |
741 | 730 |
742 // Allocate the prototype. | 731 // Allocate the prototype. |
743 void* base = operator new(size); | 732 void* base = operator new(size); |
744 memset(base, 0, size); | 733 memset(base, 0, size); |
745 // The prototype in type_info has to be set before creating the prototype | 734 // The prototype in type_info has to be set before creating the prototype |
746 // instance on memory. e.g., message Foo { map<int32, Foo> a = 1; }. When | 735 // instance on memory. e.g., message Foo { map<int32, Foo> a = 1; }. When |
747 // creating prototype for Foo, prototype of the map entry will also be | 736 // creating prototype for Foo, prototype of the map entry will also be |
748 // created, which needs the address of the prototype of Foo (the value in | 737 // created, which needs the address of the prototype of Foo (the value in |
749 // map). To break the cyclic dependency, we have to assgin the address of | 738 // map). To break the cyclic dependency, we have to assgin the address of |
750 // prototype into type_info first. | 739 // prototype into type_info first. |
751 type_info->prototype = static_cast<DynamicMessage*>(base); | 740 type_info->prototype = static_cast<DynamicMessage*>(base); |
752 DynamicMessage* prototype = new(base) DynamicMessage(type_info); | 741 DynamicMessage* prototype = new(base) DynamicMessage(type_info); |
753 | 742 |
754 // Construct the reflection object. | 743 // Construct the reflection object. |
| 744 |
| 745 void* default_oneof_instance = NULL; |
| 746 int oneof_case_offset = -1; |
| 747 |
755 if (type->oneof_decl_count() > 0) { | 748 if (type->oneof_decl_count() > 0) { |
756 // Compute the size of default oneof instance and offsets of default | 749 // Compute the size of default oneof instance and offsets of default |
757 // oneof fields. | 750 // oneof fields. |
758 int oneof_size = 0; | 751 int oneof_size = 0; |
759 for (int i = 0; i < type->oneof_decl_count(); i++) { | 752 for (int i = 0; i < type->oneof_decl_count(); i++) { |
760 for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) { | 753 for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) { |
761 const FieldDescriptor* field = type->oneof_decl(i)->field(j); | 754 const FieldDescriptor* field = type->oneof_decl(i)->field(j); |
762 int field_size = OneofFieldSpaceUsed(field); | 755 int field_size = OneofFieldSpaceUsed(field); |
763 oneof_size = AlignTo(oneof_size, std::min(kSafeAlignment, field_size)); | 756 oneof_size = AlignTo(oneof_size, std::min(kSafeAlignment, field_size)); |
764 offsets[field->index()] = oneof_size; | 757 offsets[field->index()] = oneof_size; |
765 oneof_size += field_size; | 758 oneof_size += field_size; |
766 } | 759 } |
767 } | 760 } |
768 // Construct default oneof instance. | 761 // Construct default oneof instance. |
769 type_info->default_oneof_instance = ::operator new(oneof_size); | 762 type_info->default_oneof_instance = ::operator new(oneof_size); |
770 ConstructDefaultOneofInstance(type_info->type, | 763 ConstructDefaultOneofInstance(type_info->type, |
771 type_info->offsets.get(), | 764 type_info->offsets.get(), |
772 type_info->default_oneof_instance); | 765 type_info->default_oneof_instance); |
773 type_info->reflection.reset( | 766 default_oneof_instance = type_info->default_oneof_instance; |
774 new GeneratedMessageReflection( | 767 oneof_case_offset = type_info->oneof_case_offset; |
775 type_info->type, | |
776 type_info->prototype, | |
777 type_info->offsets.get(), | |
778 type_info->has_bits_offset, | |
779 type_info->unknown_fields_offset, | |
780 type_info->extensions_offset, | |
781 type_info->default_oneof_instance, | |
782 type_info->oneof_case_offset, | |
783 type_info->pool, | |
784 this, | |
785 type_info->size, | |
786 -1 /* arena_offset */, | |
787 type_info->is_default_instance_offset)); | |
788 } else { | |
789 type_info->reflection.reset( | |
790 new GeneratedMessageReflection( | |
791 type_info->type, | |
792 type_info->prototype, | |
793 type_info->offsets.get(), | |
794 type_info->has_bits_offset, | |
795 type_info->unknown_fields_offset, | |
796 type_info->extensions_offset, | |
797 type_info->pool, | |
798 this, | |
799 type_info->size, | |
800 -1 /* arena_offset */, | |
801 type_info->is_default_instance_offset)); | |
802 } | 768 } |
| 769 |
| 770 internal::ReflectionSchema schema = { |
| 771 type_info->prototype, |
| 772 type_info->offsets.get(), |
| 773 type_info->has_bits_indices.get(), |
| 774 type_info->has_bits_offset, |
| 775 type_info->internal_metadata_offset, |
| 776 type_info->extensions_offset, |
| 777 default_oneof_instance, |
| 778 oneof_case_offset, |
| 779 type_info->size}; |
| 780 |
| 781 type_info->reflection.reset(new GeneratedMessageReflection( |
| 782 type_info->type, schema, type_info->pool, this)); |
| 783 |
803 // Cross link prototypes. | 784 // Cross link prototypes. |
804 prototype->CrossLinkPrototypes(); | 785 prototype->CrossLinkPrototypes(); |
805 | 786 |
806 return prototype; | 787 return prototype; |
807 } | 788 } |
808 | 789 |
809 void DynamicMessageFactory::ConstructDefaultOneofInstance( | 790 void DynamicMessageFactory::ConstructDefaultOneofInstance( |
810 const Descriptor* type, | 791 const Descriptor* type, |
811 const int offsets[], | 792 const uint32 offsets[], |
812 void* default_oneof_instance) { | 793 void* default_oneof_instance) { |
813 for (int i = 0; i < type->oneof_decl_count(); i++) { | 794 for (int i = 0; i < type->oneof_decl_count(); i++) { |
814 for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) { | 795 for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) { |
815 const FieldDescriptor* field = type->oneof_decl(i)->field(j); | 796 const FieldDescriptor* field = type->oneof_decl(i)->field(j); |
816 void* field_ptr = reinterpret_cast<uint8*>( | 797 void* field_ptr = reinterpret_cast<uint8*>( |
817 default_oneof_instance) + offsets[field->index()]; | 798 default_oneof_instance) + offsets[field->index()]; |
818 switch (field->cpp_type()) { | 799 switch (field->cpp_type()) { |
819 #define HANDLE_TYPE(CPPTYPE, TYPE) \ | 800 #define HANDLE_TYPE(CPPTYPE, TYPE) \ |
820 case FieldDescriptor::CPPTYPE_##CPPTYPE: \ | 801 case FieldDescriptor::CPPTYPE_##CPPTYPE: \ |
821 new(field_ptr) TYPE(field->default_value_##TYPE()); \ | 802 new(field_ptr) TYPE(field->default_value_##TYPE()); \ |
(...skipping 25 matching lines...) Expand all Loading... |
847 new(field_ptr) Message*(NULL); | 828 new(field_ptr) Message*(NULL); |
848 break; | 829 break; |
849 } | 830 } |
850 } | 831 } |
851 } | 832 } |
852 } | 833 } |
853 } | 834 } |
854 | 835 |
855 void DynamicMessageFactory::DeleteDefaultOneofInstance( | 836 void DynamicMessageFactory::DeleteDefaultOneofInstance( |
856 const Descriptor* type, | 837 const Descriptor* type, |
857 const int offsets[], | 838 const uint32 offsets[], |
858 void* default_oneof_instance) { | 839 void* default_oneof_instance) { |
859 for (int i = 0; i < type->oneof_decl_count(); i++) { | 840 for (int i = 0; i < type->oneof_decl_count(); i++) { |
860 for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) { | 841 for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) { |
861 const FieldDescriptor* field = type->oneof_decl(i)->field(j); | 842 const FieldDescriptor* field = type->oneof_decl(i)->field(j); |
862 if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { | 843 if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { |
863 switch (field->options().ctype()) { | 844 switch (field->options().ctype()) { |
864 default: | 845 default: |
865 case FieldOptions::STRING: | 846 case FieldOptions::STRING: |
866 break; | 847 break; |
867 } | 848 } |
868 } | 849 } |
869 } | 850 } |
870 } | 851 } |
871 } | 852 } |
872 | 853 |
873 } // namespace protobuf | 854 } // namespace protobuf |
874 } // namespace google | 855 } // namespace google |
OLD | NEW |