dynamic_message.cc 32 KB

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