1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31 // Author: kenton@google.com (Kenton Varda)
32 // Based on original Protocol Buffers design by
33 // Sanjay Ghemawat, Jeff Dean, and others.
34 //
35 // DynamicMessage is implemented by constructing a data structure which
36 // has roughly the same memory layout as a generated message would have.
37 // Then, we use Reflection to implement our reflection interface. All
38 // the other operations we need to implement (e.g. parsing, copying,
39 // etc.) are already implemented in terms of Reflection, so the rest is
40 // easy.
41 //
42 // The up side of this strategy is that it's very efficient. We don't
43 // need to use hash_maps or generic representations of fields. The
44 // down side is that this is a low-level memory management hack which
45 // can be tricky to get right.
46 //
47 // As mentioned in the header, we only expose a DynamicMessageFactory
48 // publicly, not the DynamicMessage class itself. This is because
49 // GenericMessageReflection wants to have a pointer to a "default"
50 // copy of the class, with all fields initialized to their default
51 // values. We only want to construct one of these per message type,
52 // so DynamicMessageFactory stores a cache of default messages for
53 // each type it sees (each unique Descriptor pointer). The code
54 // refers to the "default" copy of the class as the "prototype".
55 //
56 // Note on memory allocation: This module often calls "operator new()"
57 // to allocate untyped memory, rather than calling something like
58 // "new uint8[]". This is because "operator new()" means "Give me some
59 // space which I can use as I please." while "new uint8[]" means "Give
60 // me an array of 8-bit integers.". In practice, the later may return
61 // a pointer that is not aligned correctly for general use. I believe
62 // Item 8 of "More Effective C++" discusses this in more detail, though
63 // I don't have the book on me right now so I'm not sure.
64
65 #include <google/protobuf/dynamic_message.h>
66
67 #include <algorithm>
68 #include <cstddef>
69 #include <memory>
70 #include <unordered_map>
71
72 #include <google/protobuf/descriptor.pb.h>
73 #include <google/protobuf/descriptor.h>
74 #include <google/protobuf/generated_message_reflection.h>
75 #include <google/protobuf/generated_message_util.h>
76 #include <google/protobuf/unknown_field_set.h>
77 #include <google/protobuf/stubs/hash.h>
78 #include <google/protobuf/arenastring.h>
79 #include <google/protobuf/extension_set.h>
80 #include <google/protobuf/map_field.h>
81 #include <google/protobuf/map_field_inl.h>
82 #include <google/protobuf/map_type_handler.h>
83 #include <google/protobuf/reflection_ops.h>
84 #include <google/protobuf/repeated_field.h>
85 #include <google/protobuf/wire_format.h>
86
87 #include <google/protobuf/port_def.inc> // NOLINT
88
89 namespace google {
90 namespace protobuf {
91
92 using internal::DynamicMapField;
93 using internal::ExtensionSet;
94 using internal::MapField;
95
96
97 using internal::ArenaStringPtr;
98
99 // ===================================================================
100 // Some helper tables and functions...
101
102 namespace {
103
IsMapFieldInApi(const FieldDescriptor * field)104 bool IsMapFieldInApi(const FieldDescriptor* field) { return field->is_map(); }
105
106 // Sync with helpers.h.
HasHasbit(const FieldDescriptor * field)107 inline bool HasHasbit(const FieldDescriptor* field) {
108 // This predicate includes proto3 message fields only if they have "optional".
109 // Foo submsg1 = 1; // HasHasbit() == false
110 // optional Foo submsg2 = 2; // HasHasbit() == true
111 // This is slightly odd, as adding "optional" to a singular proto3 field does
112 // not change the semantics or API. However whenever any field in a message
113 // has a hasbit, it forces reflection to include hasbit offsets for *all*
114 // fields, even if almost all of them are set to -1 (no hasbit). So to avoid
115 // causing a sudden size regression for ~all proto3 messages, we give proto3
116 // message fields a hasbit only if "optional" is present. If the user is
117 // explicitly writing "optional", it is likely they are writing it on
118 // primitive fields also.
119 return (field->has_optional_keyword() || field->is_required()) &&
120 !field->options().weak();
121 }
122
InRealOneof(const FieldDescriptor * field)123 inline bool InRealOneof(const FieldDescriptor* field) {
124 return field->containing_oneof() &&
125 !field->containing_oneof()->is_synthetic();
126 }
127
128 // Compute the byte size of the in-memory representation of the field.
FieldSpaceUsed(const FieldDescriptor * field)129 int FieldSpaceUsed(const FieldDescriptor* field) {
130 typedef FieldDescriptor FD; // avoid line wrapping
131 if (field->label() == FD::LABEL_REPEATED) {
132 switch (field->cpp_type()) {
133 case FD::CPPTYPE_INT32:
134 return sizeof(RepeatedField<int32>);
135 case FD::CPPTYPE_INT64:
136 return sizeof(RepeatedField<int64>);
137 case FD::CPPTYPE_UINT32:
138 return sizeof(RepeatedField<uint32>);
139 case FD::CPPTYPE_UINT64:
140 return sizeof(RepeatedField<uint64>);
141 case FD::CPPTYPE_DOUBLE:
142 return sizeof(RepeatedField<double>);
143 case FD::CPPTYPE_FLOAT:
144 return sizeof(RepeatedField<float>);
145 case FD::CPPTYPE_BOOL:
146 return sizeof(RepeatedField<bool>);
147 case FD::CPPTYPE_ENUM:
148 return sizeof(RepeatedField<int>);
149 case FD::CPPTYPE_MESSAGE:
150 if (IsMapFieldInApi(field)) {
151 return sizeof(DynamicMapField);
152 } else {
153 return sizeof(RepeatedPtrField<Message>);
154 }
155
156 case FD::CPPTYPE_STRING:
157 switch (field->options().ctype()) {
158 default: // TODO(kenton): Support other string reps.
159 case FieldOptions::STRING:
160 return sizeof(RepeatedPtrField<std::string>);
161 }
162 break;
163 }
164 } else {
165 switch (field->cpp_type()) {
166 case FD::CPPTYPE_INT32:
167 return sizeof(int32);
168 case FD::CPPTYPE_INT64:
169 return sizeof(int64);
170 case FD::CPPTYPE_UINT32:
171 return sizeof(uint32);
172 case FD::CPPTYPE_UINT64:
173 return sizeof(uint64);
174 case FD::CPPTYPE_DOUBLE:
175 return sizeof(double);
176 case FD::CPPTYPE_FLOAT:
177 return sizeof(float);
178 case FD::CPPTYPE_BOOL:
179 return sizeof(bool);
180 case FD::CPPTYPE_ENUM:
181 return sizeof(int);
182
183 case FD::CPPTYPE_MESSAGE:
184 return sizeof(Message*);
185
186 case FD::CPPTYPE_STRING:
187 switch (field->options().ctype()) {
188 default: // TODO(kenton): Support other string reps.
189 case FieldOptions::STRING:
190 return sizeof(ArenaStringPtr);
191 }
192 break;
193 }
194 }
195
196 GOOGLE_LOG(DFATAL) << "Can't get here.";
197 return 0;
198 }
199
200 // Compute the byte size of in-memory representation of the oneof fields
201 // in default oneof instance.
OneofFieldSpaceUsed(const FieldDescriptor * field)202 int OneofFieldSpaceUsed(const FieldDescriptor* field) {
203 typedef FieldDescriptor FD; // avoid line wrapping
204 switch (field->cpp_type()) {
205 case FD::CPPTYPE_INT32:
206 return sizeof(int32);
207 case FD::CPPTYPE_INT64:
208 return sizeof(int64);
209 case FD::CPPTYPE_UINT32:
210 return sizeof(uint32);
211 case FD::CPPTYPE_UINT64:
212 return sizeof(uint64);
213 case FD::CPPTYPE_DOUBLE:
214 return sizeof(double);
215 case FD::CPPTYPE_FLOAT:
216 return sizeof(float);
217 case FD::CPPTYPE_BOOL:
218 return sizeof(bool);
219 case FD::CPPTYPE_ENUM:
220 return sizeof(int);
221
222 case FD::CPPTYPE_MESSAGE:
223 return sizeof(Message*);
224
225 case FD::CPPTYPE_STRING:
226 switch (field->options().ctype()) {
227 default:
228 case FieldOptions::STRING:
229 return sizeof(ArenaStringPtr);
230 }
231 break;
232 }
233
234 GOOGLE_LOG(DFATAL) << "Can't get here.";
235 return 0;
236 }
237
DivideRoundingUp(int i,int j)238 inline int DivideRoundingUp(int i, int j) { return (i + (j - 1)) / j; }
239
240 static const int kSafeAlignment = sizeof(uint64);
241 static const int kMaxOneofUnionSize = sizeof(uint64);
242
AlignTo(int offset,int alignment)243 inline int AlignTo(int offset, int alignment) {
244 return DivideRoundingUp(offset, alignment) * alignment;
245 }
246
247 // Rounds the given byte offset up to the next offset aligned such that any
248 // type may be stored at it.
AlignOffset(int offset)249 inline int AlignOffset(int offset) { return AlignTo(offset, kSafeAlignment); }
250
251 #define bitsizeof(T) (sizeof(T) * 8)
252
253 } // namespace
254
255 // ===================================================================
256
257 class DynamicMessage : public Message {
258 public:
259 struct TypeInfo {
260 int size;
261 int has_bits_offset;
262 int oneof_case_offset;
263 int extensions_offset;
264
265 // Not owned by the TypeInfo.
266 DynamicMessageFactory* factory; // The factory that created this object.
267 const DescriptorPool* pool; // The factory's DescriptorPool.
268 const Descriptor* type; // Type of this DynamicMessage.
269
270 // Warning: The order in which the following pointers are defined is
271 // important (the prototype must be deleted *before* the offsets).
272 std::unique_ptr<uint32[]> offsets;
273 std::unique_ptr<uint32[]> has_bits_indices;
274 std::unique_ptr<const Reflection> reflection;
275 // Don't use a unique_ptr to hold the prototype: the destructor for
276 // DynamicMessage needs to know whether it is the prototype, and does so by
277 // looking back at this field. This would assume details about the
278 // implementation of unique_ptr.
279 const DynamicMessage* prototype;
280 int weak_field_map_offset; // The offset for the weak_field_map;
281
TypeInfogoogle::protobuf::DynamicMessage::TypeInfo282 TypeInfo() : prototype(NULL) {}
283
~TypeInfogoogle::protobuf::DynamicMessage::TypeInfo284 ~TypeInfo() { delete prototype; }
285 };
286
287 DynamicMessage(const TypeInfo* type_info);
288
289 // This should only be used by GetPrototypeNoLock() to avoid dead lock.
290 DynamicMessage(TypeInfo* type_info, bool lock_factory);
291
292 ~DynamicMessage();
293
294 // Called on the prototype after construction to initialize message fields.
295 // Cross linking the default instances allows for fast reflection access of
296 // unset message fields. Without it we would have to go to the MessageFactory
297 // to get the prototype, which is a much more expensive operation.
298 //
299 // Generated messages do not cross-link to avoid dynamic initialization of the
300 // global instances.
301 // Instead, they keep the default instances in the FieldDescriptor objects.
302 void CrossLinkPrototypes();
303
304 // implements Message ----------------------------------------------
305
306 Message* New() const override;
307 Message* New(Arena* arena) const override;
308
309 int GetCachedSize() const override;
310 void SetCachedSize(int size) const override;
311
312 Metadata GetMetadata() const override;
313
314 // We actually allocate more memory than sizeof(*this) when this
315 // class's memory is allocated via the global operator new. Thus, we need to
316 // manually call the global operator delete. Calling the destructor is taken
317 // care of for us. This makes DynamicMessage compatible with -fsized-delete.
318 // It doesn't work for MSVC though.
319 #ifndef _MSC_VER
operator delete(void * ptr)320 static void operator delete(void* ptr) { ::operator delete(ptr); }
321 #endif // !_MSC_VER
322
323 private:
324 DynamicMessage(const TypeInfo* type_info, Arena* arena);
325
326 void SharedCtor(bool lock_factory);
327
328 // Needed to get the offset of the internal metadata member.
329 friend class DynamicMessageFactory;
330
is_prototype() const331 inline bool is_prototype() const {
332 return type_info_->prototype == this ||
333 // If type_info_->prototype is NULL, then we must be constructing
334 // the prototype now, which means we must be the prototype.
335 type_info_->prototype == NULL;
336 }
337
OffsetToPointer(int offset)338 inline void* OffsetToPointer(int offset) {
339 return reinterpret_cast<uint8*>(this) + offset;
340 }
OffsetToPointer(int offset) const341 inline const void* OffsetToPointer(int offset) const {
342 return reinterpret_cast<const uint8*>(this) + offset;
343 }
344
345 const TypeInfo* type_info_;
346 mutable std::atomic<int> cached_byte_size_;
347 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessage);
348 };
349
DynamicMessage(const TypeInfo * type_info)350 DynamicMessage::DynamicMessage(const TypeInfo* type_info)
351 : type_info_(type_info), cached_byte_size_(0) {
352 SharedCtor(true);
353 }
354
DynamicMessage(const TypeInfo * type_info,Arena * arena)355 DynamicMessage::DynamicMessage(const TypeInfo* type_info, Arena* arena)
356 : Message(arena),
357 type_info_(type_info),
358 cached_byte_size_(0) {
359 SharedCtor(true);
360 }
361
DynamicMessage(TypeInfo * type_info,bool lock_factory)362 DynamicMessage::DynamicMessage(TypeInfo* type_info, bool lock_factory)
363 : type_info_(type_info), cached_byte_size_(0) {
364 // The prototype in type_info has to be set before creating the prototype
365 // instance on memory. e.g., message Foo { map<int32, Foo> a = 1; }. When
366 // creating prototype for Foo, prototype of the map entry will also be
367 // created, which needs the address of the prototype of Foo (the value in
368 // map). To break the cyclic dependency, we have to assign the address of
369 // prototype into type_info first.
370 type_info->prototype = this;
371 SharedCtor(lock_factory);
372 }
373
SharedCtor(bool lock_factory)374 void DynamicMessage::SharedCtor(bool lock_factory) {
375 // We need to call constructors for various fields manually and set
376 // default values where appropriate. We use placement new to call
377 // constructors. If you haven't heard of placement new, I suggest Googling
378 // it now. We use placement new even for primitive types that don't have
379 // constructors for consistency. (In theory, placement new should be used
380 // any time you are trying to convert untyped memory to typed memory, though
381 // in practice that's not strictly necessary for types that don't have a
382 // constructor.)
383
384 const Descriptor* descriptor = type_info_->type;
385 // Initialize oneof cases.
386 int oneof_count = 0;
387 for (int i = 0; i < descriptor->oneof_decl_count(); ++i) {
388 if (descriptor->oneof_decl(i)->is_synthetic()) continue;
389 new (OffsetToPointer(type_info_->oneof_case_offset +
390 sizeof(uint32) * oneof_count++)) uint32(0);
391 }
392
393 if (type_info_->extensions_offset != -1) {
394 new (OffsetToPointer(type_info_->extensions_offset))
395 ExtensionSet(GetArena());
396 }
397 for (int i = 0; i < descriptor->field_count(); i++) {
398 const FieldDescriptor* field = descriptor->field(i);
399 void* field_ptr = OffsetToPointer(type_info_->offsets[i]);
400 if (InRealOneof(field)) {
401 continue;
402 }
403 switch (field->cpp_type()) {
404 #define HANDLE_TYPE(CPPTYPE, TYPE) \
405 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
406 if (!field->is_repeated()) { \
407 new (field_ptr) TYPE(field->default_value_##TYPE()); \
408 } else { \
409 new (field_ptr) RepeatedField<TYPE>(GetArena()); \
410 } \
411 break;
412
413 HANDLE_TYPE(INT32, int32);
414 HANDLE_TYPE(INT64, int64);
415 HANDLE_TYPE(UINT32, uint32);
416 HANDLE_TYPE(UINT64, uint64);
417 HANDLE_TYPE(DOUBLE, double);
418 HANDLE_TYPE(FLOAT, float);
419 HANDLE_TYPE(BOOL, bool);
420 #undef HANDLE_TYPE
421
422 case FieldDescriptor::CPPTYPE_ENUM:
423 if (!field->is_repeated()) {
424 new (field_ptr) int(field->default_value_enum()->number());
425 } else {
426 new (field_ptr) RepeatedField<int>(GetArena());
427 }
428 break;
429
430 case FieldDescriptor::CPPTYPE_STRING:
431 switch (field->options().ctype()) {
432 default: // TODO(kenton): Support other string reps.
433 case FieldOptions::STRING:
434 if (!field->is_repeated()) {
435 const std::string* default_value =
436 field->default_value_string().empty()
437 ? &internal::GetEmptyStringAlreadyInited()
438 : nullptr;
439 ArenaStringPtr* asp = new (field_ptr) ArenaStringPtr();
440 asp->UnsafeSetDefault(default_value);
441 } else {
442 new (field_ptr) RepeatedPtrField<std::string>(GetArena());
443 }
444 break;
445 }
446 break;
447
448 case FieldDescriptor::CPPTYPE_MESSAGE: {
449 if (!field->is_repeated()) {
450 new (field_ptr) Message*(NULL);
451 } else {
452 if (IsMapFieldInApi(field)) {
453 // We need to lock in most cases to avoid data racing. Only not lock
454 // when the constructor is called inside GetPrototype(), in which
455 // case we have already locked the factory.
456 if (lock_factory) {
457 if (GetArena() != nullptr) {
458 new (field_ptr) DynamicMapField(
459 type_info_->factory->GetPrototype(field->message_type()),
460 GetArena());
461 } else {
462 new (field_ptr) DynamicMapField(
463 type_info_->factory->GetPrototype(field->message_type()));
464 }
465 } else {
466 if (GetArena() != nullptr) {
467 new (field_ptr)
468 DynamicMapField(type_info_->factory->GetPrototypeNoLock(
469 field->message_type()),
470 GetArena());
471 } else {
472 new (field_ptr)
473 DynamicMapField(type_info_->factory->GetPrototypeNoLock(
474 field->message_type()));
475 }
476 }
477 } else {
478 new (field_ptr) RepeatedPtrField<Message>(GetArena());
479 }
480 }
481 break;
482 }
483 }
484 }
485 }
486
~DynamicMessage()487 DynamicMessage::~DynamicMessage() {
488 const Descriptor* descriptor = type_info_->type;
489
490 _internal_metadata_.Delete<UnknownFieldSet>();
491
492 if (type_info_->extensions_offset != -1) {
493 reinterpret_cast<ExtensionSet*>(
494 OffsetToPointer(type_info_->extensions_offset))
495 ->~ExtensionSet();
496 }
497
498 // We need to manually run the destructors for repeated fields and strings,
499 // just as we ran their constructors in the DynamicMessage constructor.
500 // We also need to manually delete oneof fields if it is set and is string
501 // or message.
502 // Additionally, if any singular embedded messages have been allocated, we
503 // need to delete them, UNLESS we are the prototype message of this type,
504 // in which case any embedded messages are other prototypes and shouldn't
505 // be touched.
506 for (int i = 0; i < descriptor->field_count(); i++) {
507 const FieldDescriptor* field = descriptor->field(i);
508 if (InRealOneof(field)) {
509 void* field_ptr =
510 OffsetToPointer(type_info_->oneof_case_offset +
511 sizeof(uint32) * field->containing_oneof()->index());
512 if (*(reinterpret_cast<const uint32*>(field_ptr)) == field->number()) {
513 field_ptr = OffsetToPointer(
514 type_info_->offsets[descriptor->field_count() +
515 field->containing_oneof()->index()]);
516 if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
517 switch (field->options().ctype()) {
518 default:
519 case FieldOptions::STRING: {
520 const std::string* default_value =
521 reinterpret_cast<const ArenaStringPtr*>(
522 reinterpret_cast<const uint8*>(type_info_->prototype) +
523 type_info_->offsets[i])
524 ->GetPointer();
525 reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy(
526 default_value, NULL);
527 break;
528 }
529 }
530 } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
531 delete *reinterpret_cast<Message**>(field_ptr);
532 }
533 }
534 continue;
535 }
536 void* field_ptr = OffsetToPointer(type_info_->offsets[i]);
537
538 if (field->is_repeated()) {
539 switch (field->cpp_type()) {
540 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
541 case FieldDescriptor::CPPTYPE_##UPPERCASE: \
542 reinterpret_cast<RepeatedField<LOWERCASE>*>(field_ptr) \
543 ->~RepeatedField<LOWERCASE>(); \
544 break
545
546 HANDLE_TYPE(INT32, int32);
547 HANDLE_TYPE(INT64, int64);
548 HANDLE_TYPE(UINT32, uint32);
549 HANDLE_TYPE(UINT64, uint64);
550 HANDLE_TYPE(DOUBLE, double);
551 HANDLE_TYPE(FLOAT, float);
552 HANDLE_TYPE(BOOL, bool);
553 HANDLE_TYPE(ENUM, int);
554 #undef HANDLE_TYPE
555
556 case FieldDescriptor::CPPTYPE_STRING:
557 switch (field->options().ctype()) {
558 default: // TODO(kenton): Support other string reps.
559 case FieldOptions::STRING:
560 reinterpret_cast<RepeatedPtrField<std::string>*>(field_ptr)
561 ->~RepeatedPtrField<std::string>();
562 break;
563 }
564 break;
565
566 case FieldDescriptor::CPPTYPE_MESSAGE:
567 if (IsMapFieldInApi(field)) {
568 reinterpret_cast<DynamicMapField*>(field_ptr)->~DynamicMapField();
569 } else {
570 reinterpret_cast<RepeatedPtrField<Message>*>(field_ptr)
571 ->~RepeatedPtrField<Message>();
572 }
573 break;
574 }
575
576 } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
577 switch (field->options().ctype()) {
578 default: // TODO(kenton): Support other string reps.
579 case FieldOptions::STRING: {
580 const std::string* default_value =
581 reinterpret_cast<const ArenaStringPtr*>(
582 type_info_->prototype->OffsetToPointer(
583 type_info_->offsets[i]))
584 ->GetPointer();
585 reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy(default_value,
586 NULL);
587 break;
588 }
589 }
590 } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
591 if (!is_prototype()) {
592 Message* message = *reinterpret_cast<Message**>(field_ptr);
593 if (message != NULL) {
594 delete message;
595 }
596 }
597 }
598 }
599 }
600
CrossLinkPrototypes()601 void DynamicMessage::CrossLinkPrototypes() {
602 // This should only be called on the prototype message.
603 GOOGLE_CHECK(is_prototype());
604
605 DynamicMessageFactory* factory = type_info_->factory;
606 const Descriptor* descriptor = type_info_->type;
607
608 // Cross-link default messages.
609 for (int i = 0; i < descriptor->field_count(); i++) {
610 const FieldDescriptor* field = descriptor->field(i);
611 void* field_ptr = OffsetToPointer(type_info_->offsets[i]);
612 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
613 !field->is_repeated()) {
614 // For fields with message types, we need to cross-link with the
615 // prototype for the field's type.
616 // For singular fields, the field is just a pointer which should
617 // point to the prototype.
618 *reinterpret_cast<const Message**>(field_ptr) =
619 factory->GetPrototypeNoLock(field->message_type());
620 }
621 }
622 }
623
New() const624 Message* DynamicMessage::New() const { return New(NULL); }
625
New(Arena * arena) const626 Message* DynamicMessage::New(Arena* arena) const {
627 if (arena != NULL) {
628 void* new_base = Arena::CreateArray<char>(arena, type_info_->size);
629 memset(new_base, 0, type_info_->size);
630 return new (new_base) DynamicMessage(type_info_, arena);
631 } else {
632 void* new_base = operator new(type_info_->size);
633 memset(new_base, 0, type_info_->size);
634 return new (new_base) DynamicMessage(type_info_);
635 }
636 }
637
GetCachedSize() const638 int DynamicMessage::GetCachedSize() const {
639 return cached_byte_size_.load(std::memory_order_relaxed);
640 }
641
SetCachedSize(int size) const642 void DynamicMessage::SetCachedSize(int size) const {
643 cached_byte_size_.store(size, std::memory_order_relaxed);
644 }
645
GetMetadata() const646 Metadata DynamicMessage::GetMetadata() const {
647 Metadata metadata;
648 metadata.descriptor = type_info_->type;
649 metadata.reflection = type_info_->reflection.get();
650 return metadata;
651 }
652
653 // ===================================================================
654
655 struct DynamicMessageFactory::PrototypeMap {
656 typedef std::unordered_map<const Descriptor*, const DynamicMessage::TypeInfo*>
657 Map;
658 Map map_;
659 };
660
DynamicMessageFactory()661 DynamicMessageFactory::DynamicMessageFactory()
662 : pool_(NULL),
663 delegate_to_generated_factory_(false),
664 prototypes_(new PrototypeMap) {}
665
DynamicMessageFactory(const DescriptorPool * pool)666 DynamicMessageFactory::DynamicMessageFactory(const DescriptorPool* pool)
667 : pool_(pool),
668 delegate_to_generated_factory_(false),
669 prototypes_(new PrototypeMap) {}
670
~DynamicMessageFactory()671 DynamicMessageFactory::~DynamicMessageFactory() {
672 for (PrototypeMap::Map::iterator iter = prototypes_->map_.begin();
673 iter != prototypes_->map_.end(); ++iter) {
674 DeleteDefaultOneofInstance(iter->second->type, iter->second->offsets.get(),
675 iter->second->prototype);
676 delete iter->second;
677 }
678 }
679
GetPrototype(const Descriptor * type)680 const Message* DynamicMessageFactory::GetPrototype(const Descriptor* type) {
681 MutexLock lock(&prototypes_mutex_);
682 return GetPrototypeNoLock(type);
683 }
684
GetPrototypeNoLock(const Descriptor * type)685 const Message* DynamicMessageFactory::GetPrototypeNoLock(
686 const Descriptor* type) {
687 if (delegate_to_generated_factory_ &&
688 type->file()->pool() == DescriptorPool::generated_pool()) {
689 return MessageFactory::generated_factory()->GetPrototype(type);
690 }
691
692 const DynamicMessage::TypeInfo** target = &prototypes_->map_[type];
693 if (*target != NULL) {
694 // Already exists.
695 return (*target)->prototype;
696 }
697
698 DynamicMessage::TypeInfo* type_info = new DynamicMessage::TypeInfo;
699 *target = type_info;
700
701 type_info->type = type;
702 type_info->pool = (pool_ == NULL) ? type->file()->pool() : pool_;
703 type_info->factory = this;
704
705 // We need to construct all the structures passed to Reflection's constructor.
706 // This includes:
707 // - A block of memory that contains space for all the message's fields.
708 // - An array of integers indicating the byte offset of each field within
709 // this block.
710 // - A big bitfield containing a bit for each field indicating whether
711 // or not that field is set.
712 int real_oneof_count = 0;
713 for (int i = 0; i < type->oneof_decl_count(); i++) {
714 if (!type->oneof_decl(i)->is_synthetic()) {
715 real_oneof_count++;
716 }
717 }
718
719 // Compute size and offsets.
720 uint32* offsets = new uint32[type->field_count() + real_oneof_count];
721 type_info->offsets.reset(offsets);
722
723 // Decide all field offsets by packing in order.
724 // We place the DynamicMessage object itself at the beginning of the allocated
725 // space.
726 int size = sizeof(DynamicMessage);
727 size = AlignOffset(size);
728
729 // Next the has_bits, which is an array of uint32s.
730 type_info->has_bits_offset = -1;
731 int max_hasbit = 0;
732 for (int i = 0; i < type->field_count(); i++) {
733 if (HasHasbit(type->field(i))) {
734 if (type_info->has_bits_offset == -1) {
735 // At least one field in the message requires a hasbit, so allocate
736 // hasbits.
737 type_info->has_bits_offset = size;
738 uint32* has_bits_indices = new uint32[type->field_count()];
739 for (int i = 0; i < type->field_count(); i++) {
740 // Initialize to -1, fields that need a hasbit will overwrite.
741 has_bits_indices[i] = static_cast<uint32>(-1);
742 }
743 type_info->has_bits_indices.reset(has_bits_indices);
744 }
745 type_info->has_bits_indices[i] = max_hasbit++;
746 }
747 }
748
749 if (max_hasbit > 0) {
750 int has_bits_array_size = DivideRoundingUp(max_hasbit, bitsizeof(uint32));
751 size += has_bits_array_size * sizeof(uint32);
752 size = AlignOffset(size);
753 }
754
755 // The oneof_case, if any. It is an array of uint32s.
756 if (real_oneof_count > 0) {
757 type_info->oneof_case_offset = size;
758 size += real_oneof_count * sizeof(uint32);
759 size = AlignOffset(size);
760 }
761
762 // The ExtensionSet, if any.
763 if (type->extension_range_count() > 0) {
764 type_info->extensions_offset = size;
765 size += sizeof(ExtensionSet);
766 size = AlignOffset(size);
767 } else {
768 // No extensions.
769 type_info->extensions_offset = -1;
770 }
771
772 // All the fields.
773 //
774 // TODO(b/31226269): Optimize the order of fields to minimize padding.
775 int num_weak_fields = 0;
776 for (int i = 0; i < type->field_count(); i++) {
777 // Make sure field is aligned to avoid bus errors.
778 // Oneof fields do not use any space.
779 if (!InRealOneof(type->field(i))) {
780 int field_size = FieldSpaceUsed(type->field(i));
781 size = AlignTo(size, std::min(kSafeAlignment, field_size));
782 offsets[i] = size;
783 size += field_size;
784 }
785 }
786
787 // The oneofs.
788 for (int i = 0; i < type->oneof_decl_count(); i++) {
789 if (!type->oneof_decl(i)->is_synthetic()) {
790 size = AlignTo(size, kSafeAlignment);
791 offsets[type->field_count() + i] = size;
792 size += kMaxOneofUnionSize;
793 }
794 }
795
796 type_info->weak_field_map_offset = -1;
797
798 // Align the final size to make sure no clever allocators think that
799 // alignment is not necessary.
800 type_info->size = size;
801
802 // Construct the reflection object.
803
804 // Compute the size of default oneof instance and offsets of default
805 // oneof fields.
806 for (int i = 0; i < type->oneof_decl_count(); i++) {
807 if (type->oneof_decl(i)->is_synthetic()) continue;
808 for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) {
809 const FieldDescriptor* field = type->oneof_decl(i)->field(j);
810 int field_size = OneofFieldSpaceUsed(field);
811 size = AlignTo(size, std::min(kSafeAlignment, field_size));
812 offsets[field->index()] = size;
813 size += field_size;
814 }
815 }
816 size = AlignOffset(size);
817 // Allocate the prototype + oneof fields.
818 void* base = operator new(size);
819 memset(base, 0, size);
820
821 // We have already locked the factory so we should not lock in the constructor
822 // of dynamic message to avoid dead lock.
823 DynamicMessage* prototype = new (base) DynamicMessage(type_info, false);
824
825 if (real_oneof_count > 0 || num_weak_fields > 0) {
826 // Construct default oneof instance.
827 ConstructDefaultOneofInstance(type_info->type, type_info->offsets.get(),
828 prototype);
829 }
830
831 internal::ReflectionSchema schema = {
832 type_info->prototype,
833 type_info->offsets.get(),
834 type_info->has_bits_indices.get(),
835 type_info->has_bits_offset,
836 PROTOBUF_FIELD_OFFSET(DynamicMessage, _internal_metadata_),
837 type_info->extensions_offset,
838 type_info->oneof_case_offset,
839 type_info->size,
840 type_info->weak_field_map_offset};
841
842 type_info->reflection.reset(
843 new Reflection(type_info->type, schema, type_info->pool, this));
844
845 // Cross link prototypes.
846 prototype->CrossLinkPrototypes();
847
848 return prototype;
849 }
850
ConstructDefaultOneofInstance(const Descriptor * type,const uint32 offsets[],void * default_oneof_or_weak_instance)851 void DynamicMessageFactory::ConstructDefaultOneofInstance(
852 const Descriptor* type, const uint32 offsets[],
853 void* default_oneof_or_weak_instance) {
854 for (int i = 0; i < type->oneof_decl_count(); i++) {
855 if (type->oneof_decl(i)->is_synthetic()) continue;
856 for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) {
857 const FieldDescriptor* field = type->oneof_decl(i)->field(j);
858 void* field_ptr =
859 reinterpret_cast<uint8*>(default_oneof_or_weak_instance) +
860 offsets[field->index()];
861 switch (field->cpp_type()) {
862 #define HANDLE_TYPE(CPPTYPE, TYPE) \
863 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
864 new (field_ptr) TYPE(field->default_value_##TYPE()); \
865 break;
866
867 HANDLE_TYPE(INT32, int32);
868 HANDLE_TYPE(INT64, int64);
869 HANDLE_TYPE(UINT32, uint32);
870 HANDLE_TYPE(UINT64, uint64);
871 HANDLE_TYPE(DOUBLE, double);
872 HANDLE_TYPE(FLOAT, float);
873 HANDLE_TYPE(BOOL, bool);
874 #undef HANDLE_TYPE
875
876 case FieldDescriptor::CPPTYPE_ENUM:
877 new (field_ptr) int(field->default_value_enum()->number());
878 break;
879 case FieldDescriptor::CPPTYPE_STRING:
880 switch (field->options().ctype()) {
881 default:
882 case FieldOptions::STRING:
883 ArenaStringPtr* asp = new (field_ptr) ArenaStringPtr();
884 asp->UnsafeSetDefault(&field->default_value_string());
885 break;
886 }
887 break;
888
889 case FieldDescriptor::CPPTYPE_MESSAGE: {
890 new (field_ptr) Message*(NULL);
891 break;
892 }
893 }
894 }
895 }
896 }
897
DeleteDefaultOneofInstance(const Descriptor * type,const uint32 offsets[],const void * default_oneof_instance)898 void DynamicMessageFactory::DeleteDefaultOneofInstance(
899 const Descriptor* type, const uint32 offsets[],
900 const void* default_oneof_instance) {
901 for (int i = 0; i < type->oneof_decl_count(); i++) {
902 if (type->oneof_decl(i)->is_synthetic()) continue;
903 for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) {
904 const FieldDescriptor* field = type->oneof_decl(i)->field(j);
905 if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
906 switch (field->options().ctype()) {
907 default:
908 case FieldOptions::STRING:
909 break;
910 }
911 }
912 }
913 }
914 }
915
916 } // namespace protobuf
917 } // namespace google
918
919 #include <google/protobuf/port_undef.inc> // NOLINT
920