诸暨麻将添加redis
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

877 line
32 KiB

  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. // Author: kenton@google.com (Kenton Varda)
  31. // Based on original Protocol Buffers design by
  32. // Sanjay Ghemawat, Jeff Dean, and others.
  33. //
  34. // DynamicMessage is implemented by constructing a data structure which
  35. // has roughly the same memory layout as a generated message would have.
  36. // Then, we use Reflection to implement our reflection interface. All
  37. // the other operations we need to implement (e.g. parsing, copying,
  38. // etc.) are already implemented in terms of Reflection, so the rest is
  39. // easy.
  40. //
  41. // The up side of this strategy is that it's very efficient. We don't
  42. // need to use hash_maps or generic representations of fields. The
  43. // down side is that this is a low-level memory management hack which
  44. // can be tricky to get right.
  45. //
  46. // As mentioned in the header, we only expose a DynamicMessageFactory
  47. // publicly, not the DynamicMessage class itself. This is because
  48. // GenericMessageReflection wants to have a pointer to a "default"
  49. // copy of the class, with all fields initialized to their default
  50. // values. We only want to construct one of these per message type,
  51. // so DynamicMessageFactory stores a cache of default messages for
  52. // each type it sees (each unique Descriptor pointer). The code
  53. // refers to the "default" copy of the class as the "prototype".
  54. //
  55. // Note on memory allocation: This module often calls "operator new()"
  56. // to allocate untyped memory, rather than calling something like
  57. // "new uint8[]". This is because "operator new()" means "Give me some
  58. // space which I can use as I please." while "new uint8[]" means "Give
  59. // me an array of 8-bit integers.". In practice, the later may return
  60. // a pointer that is not aligned correctly for general use. I believe
  61. // Item 8 of "More Effective C++" discusses this in more detail, though
  62. // I don't have the book on me right now so I'm not sure.
  63. #include <algorithm>
  64. #include <memory>
  65. #include <unordered_map>
  66. #include <google/protobuf/stubs/hash.h>
  67. #include <google/protobuf/descriptor.pb.h>
  68. #include <google/protobuf/descriptor.h>
  69. #include <google/protobuf/dynamic_message.h>
  70. #include <google/protobuf/generated_message_reflection.h>
  71. #include <google/protobuf/generated_message_util.h>
  72. #include <google/protobuf/arenastring.h>
  73. #include <google/protobuf/extension_set.h>
  74. #include <google/protobuf/map_field.h>
  75. #include <google/protobuf/map_field_inl.h>
  76. #include <google/protobuf/map_type_handler.h>
  77. #include <google/protobuf/reflection_ops.h>
  78. #include <google/protobuf/repeated_field.h>
  79. #include <google/protobuf/wire_format.h>
  80. namespace google {
  81. namespace protobuf {
  82. using internal::DynamicMapField;
  83. using internal::ExtensionSet;
  84. using internal::InternalMetadataWithArena;
  85. using internal::MapField;
  86. using internal::ArenaStringPtr;
  87. // ===================================================================
  88. // Some helper tables and functions...
  89. namespace {
  90. bool IsMapFieldInApi(const FieldDescriptor* field) { return field->is_map(); }
  91. // Compute the byte size of the in-memory representation of the field.
  92. int FieldSpaceUsed(const FieldDescriptor* field) {
  93. typedef FieldDescriptor FD; // avoid line wrapping
  94. if (field->label() == FD::LABEL_REPEATED) {
  95. switch (field->cpp_type()) {
  96. case FD::CPPTYPE_INT32:
  97. return sizeof(RepeatedField<int32>);
  98. case FD::CPPTYPE_INT64:
  99. return sizeof(RepeatedField<int64>);
  100. case FD::CPPTYPE_UINT32:
  101. return sizeof(RepeatedField<uint32>);
  102. case FD::CPPTYPE_UINT64:
  103. return sizeof(RepeatedField<uint64>);
  104. case FD::CPPTYPE_DOUBLE:
  105. return sizeof(RepeatedField<double>);
  106. case FD::CPPTYPE_FLOAT:
  107. return sizeof(RepeatedField<float>);
  108. case FD::CPPTYPE_BOOL:
  109. return sizeof(RepeatedField<bool>);
  110. case FD::CPPTYPE_ENUM:
  111. return sizeof(RepeatedField<int>);
  112. case FD::CPPTYPE_MESSAGE:
  113. if (IsMapFieldInApi(field)) {
  114. return sizeof(DynamicMapField);
  115. } else {
  116. return sizeof(RepeatedPtrField<Message>);
  117. }
  118. case FD::CPPTYPE_STRING:
  119. switch (field->options().ctype()) {
  120. default: // TODO(kenton): Support other string reps.
  121. case FieldOptions::STRING:
  122. return sizeof(RepeatedPtrField<std::string>);
  123. }
  124. break;
  125. }
  126. } else {
  127. switch (field->cpp_type()) {
  128. case FD::CPPTYPE_INT32:
  129. return sizeof(int32);
  130. case FD::CPPTYPE_INT64:
  131. return sizeof(int64);
  132. case FD::CPPTYPE_UINT32:
  133. return sizeof(uint32);
  134. case FD::CPPTYPE_UINT64:
  135. return sizeof(uint64);
  136. case FD::CPPTYPE_DOUBLE:
  137. return sizeof(double);
  138. case FD::CPPTYPE_FLOAT:
  139. return sizeof(float);
  140. case FD::CPPTYPE_BOOL:
  141. return sizeof(bool);
  142. case FD::CPPTYPE_ENUM:
  143. return sizeof(int);
  144. case FD::CPPTYPE_MESSAGE:
  145. return sizeof(Message*);
  146. case FD::CPPTYPE_STRING:
  147. switch (field->options().ctype()) {
  148. default: // TODO(kenton): Support other string reps.
  149. case FieldOptions::STRING:
  150. return sizeof(ArenaStringPtr);
  151. }
  152. break;
  153. }
  154. }
  155. GOOGLE_LOG(DFATAL) << "Can't get here.";
  156. return 0;
  157. }
  158. // Compute the byte size of in-memory representation of the oneof fields
  159. // in default oneof instance.
  160. int OneofFieldSpaceUsed(const FieldDescriptor* field) {
  161. typedef FieldDescriptor FD; // avoid line wrapping
  162. switch (field->cpp_type()) {
  163. case FD::CPPTYPE_INT32:
  164. return sizeof(int32);
  165. case FD::CPPTYPE_INT64:
  166. return sizeof(int64);
  167. case FD::CPPTYPE_UINT32:
  168. return sizeof(uint32);
  169. case FD::CPPTYPE_UINT64:
  170. return sizeof(uint64);
  171. case FD::CPPTYPE_DOUBLE:
  172. return sizeof(double);
  173. case FD::CPPTYPE_FLOAT:
  174. return sizeof(float);
  175. case FD::CPPTYPE_BOOL:
  176. return sizeof(bool);
  177. case FD::CPPTYPE_ENUM:
  178. return sizeof(int);
  179. case FD::CPPTYPE_MESSAGE:
  180. return sizeof(Message*);
  181. case FD::CPPTYPE_STRING:
  182. switch (field->options().ctype()) {
  183. default:
  184. case FieldOptions::STRING:
  185. return sizeof(ArenaStringPtr);
  186. }
  187. break;
  188. }
  189. GOOGLE_LOG(DFATAL) << "Can't get here.";
  190. return 0;
  191. }
  192. inline int DivideRoundingUp(int i, int j) { return (i + (j - 1)) / j; }
  193. static const int kSafeAlignment = sizeof(uint64);
  194. static const int kMaxOneofUnionSize = sizeof(uint64);
  195. inline int AlignTo(int offset, int alignment) {
  196. return DivideRoundingUp(offset, alignment) * alignment;
  197. }
  198. // Rounds the given byte offset up to the next offset aligned such that any
  199. // type may be stored at it.
  200. inline int AlignOffset(int offset) { return AlignTo(offset, kSafeAlignment); }
  201. #define bitsizeof(T) (sizeof(T) * 8)
  202. } // namespace
  203. // ===================================================================
  204. class DynamicMessage : public Message {
  205. public:
  206. struct TypeInfo {
  207. int size;
  208. int has_bits_offset;
  209. int oneof_case_offset;
  210. int internal_metadata_offset;
  211. int extensions_offset;
  212. // Not owned by the TypeInfo.
  213. DynamicMessageFactory* factory; // The factory that created this object.
  214. const DescriptorPool* pool; // The factory's DescriptorPool.
  215. const Descriptor* type; // Type of this DynamicMessage.
  216. // Warning: The order in which the following pointers are defined is
  217. // important (the prototype must be deleted *before* the offsets).
  218. std::unique_ptr<uint32[]> offsets;
  219. std::unique_ptr<uint32[]> has_bits_indices;
  220. std::unique_ptr<const Reflection> reflection;
  221. // Don't use a unique_ptr to hold the prototype: the destructor for
  222. // DynamicMessage needs to know whether it is the prototype, and does so by
  223. // looking back at this field. This would assume details about the
  224. // implementation of unique_ptr.
  225. const DynamicMessage* prototype;
  226. int weak_field_map_offset; // The offset for the weak_field_map;
  227. TypeInfo() : prototype(NULL) {}
  228. ~TypeInfo() { delete prototype; }
  229. };
  230. DynamicMessage(const TypeInfo* type_info);
  231. // This should only be used by GetPrototypeNoLock() to avoid dead lock.
  232. DynamicMessage(TypeInfo* type_info, bool lock_factory);
  233. ~DynamicMessage();
  234. // Called on the prototype after construction to initialize message fields.
  235. void CrossLinkPrototypes();
  236. // implements Message ----------------------------------------------
  237. Message* New() const override;
  238. Message* New(Arena* arena) const override;
  239. Arena* GetArena() const override { return arena_; }
  240. int GetCachedSize() const override;
  241. void SetCachedSize(int size) const override;
  242. Metadata GetMetadata() const override;
  243. // We actually allocate more memory than sizeof(*this) when this
  244. // class's memory is allocated via the global operator new. Thus, we need to
  245. // manually call the global operator delete. Calling the destructor is taken
  246. // care of for us. This makes DynamicMessage compatible with -fsized-delete.
  247. // It doesn't work for MSVC though.
  248. #ifndef _MSC_VER
  249. static void operator delete(void* ptr) { ::operator delete(ptr); }
  250. #endif // !_MSC_VER
  251. private:
  252. DynamicMessage(const TypeInfo* type_info, Arena* arena);
  253. void SharedCtor(bool lock_factory);
  254. inline bool is_prototype() const {
  255. return type_info_->prototype == this ||
  256. // If type_info_->prototype is NULL, then we must be constructing
  257. // the prototype now, which means we must be the prototype.
  258. type_info_->prototype == NULL;
  259. }
  260. inline void* OffsetToPointer(int offset) {
  261. return reinterpret_cast<uint8*>(this) + offset;
  262. }
  263. inline const void* OffsetToPointer(int offset) const {
  264. return reinterpret_cast<const uint8*>(this) + offset;
  265. }
  266. const TypeInfo* type_info_;
  267. Arena* const arena_;
  268. mutable std::atomic<int> cached_byte_size_;
  269. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessage);
  270. };
  271. DynamicMessage::DynamicMessage(const TypeInfo* type_info)
  272. : type_info_(type_info), arena_(NULL), cached_byte_size_(0) {
  273. SharedCtor(true);
  274. }
  275. DynamicMessage::DynamicMessage(const TypeInfo* type_info, Arena* arena)
  276. : type_info_(type_info), arena_(arena), cached_byte_size_(0) {
  277. SharedCtor(true);
  278. }
  279. DynamicMessage::DynamicMessage(TypeInfo* type_info, bool lock_factory)
  280. : type_info_(type_info), arena_(NULL), cached_byte_size_(0) {
  281. // The prototype in type_info has to be set before creating the prototype
  282. // instance on memory. e.g., message Foo { map<int32, Foo> a = 1; }. When
  283. // creating prototype for Foo, prototype of the map entry will also be
  284. // created, which needs the address of the prototype of Foo (the value in
  285. // map). To break the cyclic dependency, we have to assign the address of
  286. // prototype into type_info first.
  287. type_info->prototype = this;
  288. SharedCtor(lock_factory);
  289. }
  290. void DynamicMessage::SharedCtor(bool lock_factory) {
  291. // We need to call constructors for various fields manually and set
  292. // default values where appropriate. We use placement new to call
  293. // constructors. If you haven't heard of placement new, I suggest Googling
  294. // it now. We use placement new even for primitive types that don't have
  295. // constructors for consistency. (In theory, placement new should be used
  296. // any time you are trying to convert untyped memory to typed memory, though
  297. // in practice that's not strictly necessary for types that don't have a
  298. // constructor.)
  299. const Descriptor* descriptor = type_info_->type;
  300. // Initialize oneof cases.
  301. for (int i = 0; i < descriptor->oneof_decl_count(); ++i) {
  302. new (OffsetToPointer(type_info_->oneof_case_offset + sizeof(uint32) * i))
  303. uint32(0);
  304. }
  305. new (OffsetToPointer(type_info_->internal_metadata_offset))
  306. InternalMetadataWithArena(arena_);
  307. if (type_info_->extensions_offset != -1) {
  308. new (OffsetToPointer(type_info_->extensions_offset)) ExtensionSet(arena_);
  309. }
  310. for (int i = 0; i < descriptor->field_count(); i++) {
  311. const FieldDescriptor* field = descriptor->field(i);
  312. void* field_ptr = OffsetToPointer(type_info_->offsets[i]);
  313. if (field->containing_oneof()) {
  314. continue;
  315. }
  316. switch (field->cpp_type()) {
  317. #define HANDLE_TYPE(CPPTYPE, TYPE) \
  318. case FieldDescriptor::CPPTYPE_##CPPTYPE: \
  319. if (!field->is_repeated()) { \
  320. new (field_ptr) TYPE(field->default_value_##TYPE()); \
  321. } else { \
  322. new (field_ptr) RepeatedField<TYPE>(arena_); \
  323. } \
  324. break;
  325. HANDLE_TYPE(INT32, int32);
  326. HANDLE_TYPE(INT64, int64);
  327. HANDLE_TYPE(UINT32, uint32);
  328. HANDLE_TYPE(UINT64, uint64);
  329. HANDLE_TYPE(DOUBLE, double);
  330. HANDLE_TYPE(FLOAT, float);
  331. HANDLE_TYPE(BOOL, bool);
  332. #undef HANDLE_TYPE
  333. case FieldDescriptor::CPPTYPE_ENUM:
  334. if (!field->is_repeated()) {
  335. new (field_ptr) int(field->default_value_enum()->number());
  336. } else {
  337. new (field_ptr) RepeatedField<int>(arena_);
  338. }
  339. break;
  340. case FieldDescriptor::CPPTYPE_STRING:
  341. switch (field->options().ctype()) {
  342. default: // TODO(kenton): Support other string reps.
  343. case FieldOptions::STRING:
  344. if (!field->is_repeated()) {
  345. const std::string* default_value;
  346. if (is_prototype()) {
  347. default_value = &field->default_value_string();
  348. } else {
  349. default_value = &(reinterpret_cast<const ArenaStringPtr*>(
  350. type_info_->prototype->OffsetToPointer(
  351. type_info_->offsets[i]))
  352. ->Get());
  353. }
  354. ArenaStringPtr* asp = new (field_ptr) ArenaStringPtr();
  355. asp->UnsafeSetDefault(default_value);
  356. } else {
  357. new (field_ptr) RepeatedPtrField<std::string>(arena_);
  358. }
  359. break;
  360. }
  361. break;
  362. case FieldDescriptor::CPPTYPE_MESSAGE: {
  363. if (!field->is_repeated()) {
  364. new (field_ptr) Message*(NULL);
  365. } else {
  366. if (IsMapFieldInApi(field)) {
  367. // We need to lock in most cases to avoid data racing. Only not lock
  368. // when the constructor is called inside GetPrototype(), in which
  369. // case we have already locked the factory.
  370. if (lock_factory) {
  371. if (arena_ != NULL) {
  372. new (field_ptr) DynamicMapField(
  373. type_info_->factory->GetPrototype(field->message_type()),
  374. arena_);
  375. } else {
  376. new (field_ptr) DynamicMapField(
  377. type_info_->factory->GetPrototype(field->message_type()));
  378. }
  379. } else {
  380. if (arena_ != NULL) {
  381. new (field_ptr)
  382. DynamicMapField(type_info_->factory->GetPrototypeNoLock(
  383. field->message_type()),
  384. arena_);
  385. } else {
  386. new (field_ptr)
  387. DynamicMapField(type_info_->factory->GetPrototypeNoLock(
  388. field->message_type()));
  389. }
  390. }
  391. } else {
  392. new (field_ptr) RepeatedPtrField<Message>(arena_);
  393. }
  394. }
  395. break;
  396. }
  397. }
  398. }
  399. }
  400. DynamicMessage::~DynamicMessage() {
  401. const Descriptor* descriptor = type_info_->type;
  402. reinterpret_cast<InternalMetadataWithArena*>(
  403. OffsetToPointer(type_info_->internal_metadata_offset))
  404. ->~InternalMetadataWithArena();
  405. if (type_info_->extensions_offset != -1) {
  406. reinterpret_cast<ExtensionSet*>(
  407. OffsetToPointer(type_info_->extensions_offset))
  408. ->~ExtensionSet();
  409. }
  410. // We need to manually run the destructors for repeated fields and strings,
  411. // just as we ran their constructors in the DynamicMessage constructor.
  412. // We also need to manually delete oneof fields if it is set and is string
  413. // or message.
  414. // Additionally, if any singular embedded messages have been allocated, we
  415. // need to delete them, UNLESS we are the prototype message of this type,
  416. // in which case any embedded messages are other prototypes and shouldn't
  417. // be touched.
  418. for (int i = 0; i < descriptor->field_count(); i++) {
  419. const FieldDescriptor* field = descriptor->field(i);
  420. if (field->containing_oneof()) {
  421. void* field_ptr =
  422. OffsetToPointer(type_info_->oneof_case_offset +
  423. sizeof(uint32) * field->containing_oneof()->index());
  424. if (*(reinterpret_cast<const uint32*>(field_ptr)) == field->number()) {
  425. field_ptr = OffsetToPointer(
  426. type_info_->offsets[descriptor->field_count() +
  427. field->containing_oneof()->index()]);
  428. if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
  429. switch (field->options().ctype()) {
  430. default:
  431. case FieldOptions::STRING: {
  432. const std::string* default_value =
  433. &(reinterpret_cast<const ArenaStringPtr*>(
  434. reinterpret_cast<const uint8*>(type_info_->prototype) +
  435. type_info_->offsets[i])
  436. ->Get());
  437. reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy(
  438. default_value, NULL);
  439. break;
  440. }
  441. }
  442. } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
  443. delete *reinterpret_cast<Message**>(field_ptr);
  444. }
  445. }
  446. continue;
  447. }
  448. void* field_ptr = OffsetToPointer(type_info_->offsets[i]);
  449. if (field->is_repeated()) {
  450. switch (field->cpp_type()) {
  451. #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
  452. case FieldDescriptor::CPPTYPE_##UPPERCASE: \
  453. reinterpret_cast<RepeatedField<LOWERCASE>*>(field_ptr) \
  454. ->~RepeatedField<LOWERCASE>(); \
  455. break
  456. HANDLE_TYPE(INT32, int32);
  457. HANDLE_TYPE(INT64, int64);
  458. HANDLE_TYPE(UINT32, uint32);
  459. HANDLE_TYPE(UINT64, uint64);
  460. HANDLE_TYPE(DOUBLE, double);
  461. HANDLE_TYPE(FLOAT, float);
  462. HANDLE_TYPE(BOOL, bool);
  463. HANDLE_TYPE(ENUM, int);
  464. #undef HANDLE_TYPE
  465. case FieldDescriptor::CPPTYPE_STRING:
  466. switch (field->options().ctype()) {
  467. default: // TODO(kenton): Support other string reps.
  468. case FieldOptions::STRING:
  469. reinterpret_cast<RepeatedPtrField<std::string>*>(field_ptr)
  470. ->~RepeatedPtrField<std::string>();
  471. break;
  472. }
  473. break;
  474. case FieldDescriptor::CPPTYPE_MESSAGE:
  475. if (IsMapFieldInApi(field)) {
  476. reinterpret_cast<DynamicMapField*>(field_ptr)->~DynamicMapField();
  477. } else {
  478. reinterpret_cast<RepeatedPtrField<Message>*>(field_ptr)
  479. ->~RepeatedPtrField<Message>();
  480. }
  481. break;
  482. }
  483. } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
  484. switch (field->options().ctype()) {
  485. default: // TODO(kenton): Support other string reps.
  486. case FieldOptions::STRING: {
  487. const std::string* default_value =
  488. &(reinterpret_cast<const ArenaStringPtr*>(
  489. type_info_->prototype->OffsetToPointer(
  490. type_info_->offsets[i]))
  491. ->Get());
  492. reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy(default_value,
  493. NULL);
  494. break;
  495. }
  496. }
  497. } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
  498. if (!is_prototype()) {
  499. Message* message = *reinterpret_cast<Message**>(field_ptr);
  500. if (message != NULL) {
  501. delete message;
  502. }
  503. }
  504. }
  505. }
  506. }
  507. void DynamicMessage::CrossLinkPrototypes() {
  508. // This should only be called on the prototype message.
  509. GOOGLE_CHECK(is_prototype());
  510. DynamicMessageFactory* factory = type_info_->factory;
  511. const Descriptor* descriptor = type_info_->type;
  512. // Cross-link default messages.
  513. for (int i = 0; i < descriptor->field_count(); i++) {
  514. const FieldDescriptor* field = descriptor->field(i);
  515. void* field_ptr = OffsetToPointer(type_info_->offsets[i]);
  516. if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
  517. !field->is_repeated()) {
  518. // For fields with message types, we need to cross-link with the
  519. // prototype for the field's type.
  520. // For singular fields, the field is just a pointer which should
  521. // point to the prototype.
  522. *reinterpret_cast<const Message**>(field_ptr) =
  523. factory->GetPrototypeNoLock(field->message_type());
  524. }
  525. }
  526. }
  527. Message* DynamicMessage::New() const { return New(NULL); }
  528. Message* DynamicMessage::New(Arena* arena) const {
  529. if (arena != NULL) {
  530. void* new_base = Arena::CreateArray<char>(arena, type_info_->size);
  531. memset(new_base, 0, type_info_->size);
  532. return new (new_base) DynamicMessage(type_info_, arena);
  533. } else {
  534. void* new_base = operator new(type_info_->size);
  535. memset(new_base, 0, type_info_->size);
  536. return new (new_base) DynamicMessage(type_info_);
  537. }
  538. }
  539. int DynamicMessage::GetCachedSize() const {
  540. return cached_byte_size_.load(std::memory_order_relaxed);
  541. }
  542. void DynamicMessage::SetCachedSize(int size) const {
  543. cached_byte_size_.store(size, std::memory_order_relaxed);
  544. }
  545. Metadata DynamicMessage::GetMetadata() const {
  546. Metadata metadata;
  547. metadata.descriptor = type_info_->type;
  548. metadata.reflection = type_info_->reflection.get();
  549. return metadata;
  550. }
  551. // ===================================================================
  552. struct DynamicMessageFactory::PrototypeMap {
  553. typedef std::unordered_map<const Descriptor*, const DynamicMessage::TypeInfo*>
  554. Map;
  555. Map map_;
  556. };
  557. DynamicMessageFactory::DynamicMessageFactory()
  558. : pool_(NULL),
  559. delegate_to_generated_factory_(false),
  560. prototypes_(new PrototypeMap) {}
  561. DynamicMessageFactory::DynamicMessageFactory(const DescriptorPool* pool)
  562. : pool_(pool),
  563. delegate_to_generated_factory_(false),
  564. prototypes_(new PrototypeMap) {}
  565. DynamicMessageFactory::~DynamicMessageFactory() {
  566. for (PrototypeMap::Map::iterator iter = prototypes_->map_.begin();
  567. iter != prototypes_->map_.end(); ++iter) {
  568. DeleteDefaultOneofInstance(iter->second->type, iter->second->offsets.get(),
  569. iter->second->prototype);
  570. delete iter->second;
  571. }
  572. }
  573. const Message* DynamicMessageFactory::GetPrototype(const Descriptor* type) {
  574. MutexLock lock(&prototypes_mutex_);
  575. return GetPrototypeNoLock(type);
  576. }
  577. const Message* DynamicMessageFactory::GetPrototypeNoLock(
  578. const Descriptor* type) {
  579. if (delegate_to_generated_factory_ &&
  580. type->file()->pool() == DescriptorPool::generated_pool()) {
  581. return MessageFactory::generated_factory()->GetPrototype(type);
  582. }
  583. const DynamicMessage::TypeInfo** target = &prototypes_->map_[type];
  584. if (*target != NULL) {
  585. // Already exists.
  586. return (*target)->prototype;
  587. }
  588. DynamicMessage::TypeInfo* type_info = new DynamicMessage::TypeInfo;
  589. *target = type_info;
  590. type_info->type = type;
  591. type_info->pool = (pool_ == NULL) ? type->file()->pool() : pool_;
  592. type_info->factory = this;
  593. // We need to construct all the structures passed to Reflection's constructor.
  594. // This includes:
  595. // - A block of memory that contains space for all the message's fields.
  596. // - An array of integers indicating the byte offset of each field within
  597. // this block.
  598. // - A big bitfield containing a bit for each field indicating whether
  599. // or not that field is set.
  600. // Compute size and offsets.
  601. uint32* offsets = new uint32[type->field_count() + type->oneof_decl_count()];
  602. type_info->offsets.reset(offsets);
  603. // Decide all field offsets by packing in order.
  604. // We place the DynamicMessage object itself at the beginning of the allocated
  605. // space.
  606. int size = sizeof(DynamicMessage);
  607. size = AlignOffset(size);
  608. // Next the has_bits, which is an array of uint32s.
  609. if (type->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) {
  610. type_info->has_bits_offset = -1;
  611. } else {
  612. type_info->has_bits_offset = size;
  613. int has_bits_array_size =
  614. DivideRoundingUp(type->field_count(), bitsizeof(uint32));
  615. size += has_bits_array_size * sizeof(uint32);
  616. size = AlignOffset(size);
  617. uint32* has_bits_indices = new uint32[type->field_count()];
  618. for (int i = 0; i < type->field_count(); i++) {
  619. has_bits_indices[i] = i;
  620. }
  621. type_info->has_bits_indices.reset(has_bits_indices);
  622. }
  623. // The oneof_case, if any. It is an array of uint32s.
  624. if (type->oneof_decl_count() > 0) {
  625. type_info->oneof_case_offset = size;
  626. size += type->oneof_decl_count() * sizeof(uint32);
  627. size = AlignOffset(size);
  628. }
  629. // The ExtensionSet, if any.
  630. if (type->extension_range_count() > 0) {
  631. type_info->extensions_offset = size;
  632. size += sizeof(ExtensionSet);
  633. size = AlignOffset(size);
  634. } else {
  635. // No extensions.
  636. type_info->extensions_offset = -1;
  637. }
  638. // All the fields.
  639. //
  640. // TODO(b/31226269): Optimize the order of fields to minimize padding.
  641. int num_weak_fields = 0;
  642. for (int i = 0; i < type->field_count(); i++) {
  643. // Make sure field is aligned to avoid bus errors.
  644. // Oneof fields do not use any space.
  645. if (!type->field(i)->containing_oneof()) {
  646. int field_size = FieldSpaceUsed(type->field(i));
  647. size = AlignTo(size, std::min(kSafeAlignment, field_size));
  648. offsets[i] = size;
  649. size += field_size;
  650. }
  651. }
  652. // The oneofs.
  653. for (int i = 0; i < type->oneof_decl_count(); i++) {
  654. size = AlignTo(size, kSafeAlignment);
  655. offsets[type->field_count() + i] = size;
  656. size += kMaxOneofUnionSize;
  657. }
  658. // Add the InternalMetadataWithArena to the end.
  659. size = AlignOffset(size);
  660. type_info->internal_metadata_offset = size;
  661. size += sizeof(InternalMetadataWithArena);
  662. type_info->weak_field_map_offset = -1;
  663. // Align the final size to make sure no clever allocators think that
  664. // alignment is not necessary.
  665. type_info->size = size;
  666. // Construct the reflection object.
  667. if (type->oneof_decl_count() > 0) {
  668. // Compute the size of default oneof instance and offsets of default
  669. // oneof fields.
  670. for (int i = 0; i < type->oneof_decl_count(); i++) {
  671. for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) {
  672. const FieldDescriptor* field = type->oneof_decl(i)->field(j);
  673. int field_size = OneofFieldSpaceUsed(field);
  674. size = AlignTo(size, std::min(kSafeAlignment, field_size));
  675. offsets[field->index()] = size;
  676. size += field_size;
  677. }
  678. }
  679. }
  680. size = AlignOffset(size);
  681. // Allocate the prototype + oneof fields.
  682. void* base = operator new(size);
  683. memset(base, 0, size);
  684. // We have already locked the factory so we should not lock in the constructor
  685. // of dynamic message to avoid dead lock.
  686. DynamicMessage* prototype = new (base) DynamicMessage(type_info, false);
  687. if (type->oneof_decl_count() > 0 || num_weak_fields > 0) {
  688. // Construct default oneof instance.
  689. ConstructDefaultOneofInstance(type_info->type, type_info->offsets.get(),
  690. prototype);
  691. }
  692. internal::ReflectionSchema schema = {type_info->prototype,
  693. type_info->offsets.get(),
  694. type_info->has_bits_indices.get(),
  695. type_info->has_bits_offset,
  696. type_info->internal_metadata_offset,
  697. type_info->extensions_offset,
  698. type_info->oneof_case_offset,
  699. type_info->size,
  700. type_info->weak_field_map_offset};
  701. type_info->reflection.reset(
  702. new Reflection(type_info->type, schema, type_info->pool, this));
  703. // Cross link prototypes.
  704. prototype->CrossLinkPrototypes();
  705. return prototype;
  706. }
  707. void DynamicMessageFactory::ConstructDefaultOneofInstance(
  708. const Descriptor* type, const uint32 offsets[],
  709. void* default_oneof_or_weak_instance) {
  710. for (int i = 0; i < type->oneof_decl_count(); i++) {
  711. for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) {
  712. const FieldDescriptor* field = type->oneof_decl(i)->field(j);
  713. void* field_ptr =
  714. reinterpret_cast<uint8*>(default_oneof_or_weak_instance) +
  715. offsets[field->index()];
  716. switch (field->cpp_type()) {
  717. #define HANDLE_TYPE(CPPTYPE, TYPE) \
  718. case FieldDescriptor::CPPTYPE_##CPPTYPE: \
  719. new (field_ptr) TYPE(field->default_value_##TYPE()); \
  720. break;
  721. HANDLE_TYPE(INT32, int32);
  722. HANDLE_TYPE(INT64, int64);
  723. HANDLE_TYPE(UINT32, uint32);
  724. HANDLE_TYPE(UINT64, uint64);
  725. HANDLE_TYPE(DOUBLE, double);
  726. HANDLE_TYPE(FLOAT, float);
  727. HANDLE_TYPE(BOOL, bool);
  728. #undef HANDLE_TYPE
  729. case FieldDescriptor::CPPTYPE_ENUM:
  730. new (field_ptr) int(field->default_value_enum()->number());
  731. break;
  732. case FieldDescriptor::CPPTYPE_STRING:
  733. switch (field->options().ctype()) {
  734. default:
  735. case FieldOptions::STRING:
  736. ArenaStringPtr* asp = new (field_ptr) ArenaStringPtr();
  737. asp->UnsafeSetDefault(&field->default_value_string());
  738. break;
  739. }
  740. break;
  741. case FieldDescriptor::CPPTYPE_MESSAGE: {
  742. new (field_ptr) Message*(NULL);
  743. break;
  744. }
  745. }
  746. }
  747. }
  748. }
  749. void DynamicMessageFactory::DeleteDefaultOneofInstance(
  750. const Descriptor* type, const uint32 offsets[],
  751. const void* default_oneof_instance) {
  752. for (int i = 0; i < type->oneof_decl_count(); i++) {
  753. for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) {
  754. const FieldDescriptor* field = type->oneof_decl(i)->field(j);
  755. if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
  756. switch (field->options().ctype()) {
  757. default:
  758. case FieldOptions::STRING:
  759. break;
  760. }
  761. }
  762. }
  763. }
  764. }
  765. } // namespace protobuf
  766. } // namespace google