map_entry_lite.h 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671
  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. #ifndef GOOGLE_PROTOBUF_MAP_ENTRY_LITE_H__
  31. #define GOOGLE_PROTOBUF_MAP_ENTRY_LITE_H__
  32. #include <assert.h>
  33. #include <google/protobuf/stubs/casts.h>
  34. #include <google/protobuf/arena.h>
  35. #include <google/protobuf/arenastring.h>
  36. #include <google/protobuf/map.h>
  37. #include <google/protobuf/map_type_handler.h>
  38. #include <google/protobuf/stubs/port.h>
  39. #include <google/protobuf/wire_format_lite_inl.h>
  40. namespace google {
  41. namespace protobuf {
  42. namespace internal {
  43. template <typename Derived, typename Key, typename Value,
  44. WireFormatLite::FieldType kKeyFieldType,
  45. WireFormatLite::FieldType kValueFieldType, int default_enum_value>
  46. class MapEntry;
  47. template <typename Derived, typename Key, typename Value,
  48. WireFormatLite::FieldType kKeyFieldType,
  49. WireFormatLite::FieldType kValueFieldType, int default_enum_value>
  50. class MapFieldLite;
  51. } // namespace internal
  52. } // namespace protobuf
  53. namespace protobuf {
  54. namespace internal {
  55. // MoveHelper::Move is used to set *dest. It copies *src, or moves it (in
  56. // the C++11 sense), or swaps it. *src is left in a sane state for
  57. // subsequent destruction, but shouldn't be used for anything.
  58. template <bool is_enum, bool is_message, bool is_stringlike, typename T>
  59. struct MoveHelper { // primitives
  60. static void Move(T* src, T* dest) { *dest = *src; }
  61. };
  62. template <bool is_message, bool is_stringlike, typename T>
  63. struct MoveHelper<true, is_message, is_stringlike, T> { // enums
  64. static void Move(T* src, T* dest) { *dest = *src; }
  65. // T is an enum here, so allow conversions to and from int.
  66. static void Move(T* src, int* dest) { *dest = static_cast<int>(*src); }
  67. static void Move(int* src, T* dest) { *dest = static_cast<T>(*src); }
  68. };
  69. template <bool is_stringlike, typename T>
  70. struct MoveHelper<false, true, is_stringlike, T> { // messages
  71. static void Move(T* src, T* dest) { dest->Swap(src); }
  72. };
  73. template <typename T>
  74. struct MoveHelper<false, false, true, T> { // strings and similar
  75. static void Move(T* src, T* dest) {
  76. #if __cplusplus >= 201103L
  77. *dest = std::move(*src);
  78. #else
  79. dest->swap(*src);
  80. #endif
  81. }
  82. };
  83. // MapEntryImpl is used to implement parsing and serialization of map entries.
  84. // It uses Curious Recursive Template Pattern (CRTP) to provide the type of
  85. // the eventual code to the template code.
  86. template <typename Derived, typename Base, typename Key, typename Value,
  87. WireFormatLite::FieldType kKeyFieldType,
  88. WireFormatLite::FieldType kValueFieldType, int default_enum_value>
  89. class MapEntryImpl : public Base {
  90. protected:
  91. // Provide utilities to parse/serialize key/value. Provide utilities to
  92. // manipulate internal stored type.
  93. typedef MapTypeHandler<kKeyFieldType, Key> KeyTypeHandler;
  94. typedef MapTypeHandler<kValueFieldType, Value> ValueTypeHandler;
  95. // Define internal memory layout. Strings and messages are stored as
  96. // pointers, while other types are stored as values.
  97. typedef typename KeyTypeHandler::TypeOnMemory KeyOnMemory;
  98. typedef typename ValueTypeHandler::TypeOnMemory ValueOnMemory;
  99. // Enum type cannot be used for MapTypeHandler::Read. Define a type
  100. // which will replace Enum with int.
  101. typedef typename KeyTypeHandler::MapEntryAccessorType KeyMapEntryAccessorType;
  102. typedef typename ValueTypeHandler::MapEntryAccessorType
  103. ValueMapEntryAccessorType;
  104. // Constants for field number.
  105. static const int kKeyFieldNumber = 1;
  106. static const int kValueFieldNumber = 2;
  107. // Constants for field tag.
  108. static const uint8 kKeyTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(
  109. kKeyFieldNumber, KeyTypeHandler::kWireType);
  110. static const uint8 kValueTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(
  111. kValueFieldNumber, ValueTypeHandler::kWireType);
  112. static const size_t kTagSize = 1;
  113. public:
  114. // Work-around for a compiler bug (see repeated_field.h).
  115. typedef void MapEntryHasMergeTypeTrait;
  116. typedef Derived EntryType;
  117. typedef Key EntryKeyType;
  118. typedef Value EntryValueType;
  119. static const WireFormatLite::FieldType kEntryKeyFieldType = kKeyFieldType;
  120. static const WireFormatLite::FieldType kEntryValueFieldType = kValueFieldType;
  121. static const int kEntryDefaultEnumValue = default_enum_value;
  122. MapEntryImpl() : arena_(NULL) {
  123. KeyTypeHandler::Initialize(&key_, NULL);
  124. ValueTypeHandler::InitializeMaybeByDefaultEnum(&value_, default_enum_value,
  125. NULL);
  126. _has_bits_[0] = 0;
  127. }
  128. explicit MapEntryImpl(Arena* arena) : arena_(arena) {
  129. KeyTypeHandler::Initialize(&key_, arena);
  130. ValueTypeHandler::InitializeMaybeByDefaultEnum(&value_, default_enum_value,
  131. arena);
  132. _has_bits_[0] = 0;
  133. }
  134. ~MapEntryImpl() {
  135. if (GetArenaNoVirtual() != NULL) return;
  136. KeyTypeHandler::DeleteNoArena(key_);
  137. ValueTypeHandler::DeleteNoArena(value_);
  138. }
  139. // accessors ======================================================
  140. virtual inline const KeyMapEntryAccessorType& key() const {
  141. return KeyTypeHandler::GetExternalReference(key_);
  142. }
  143. virtual inline const ValueMapEntryAccessorType& value() const {
  144. return ValueTypeHandler::DefaultIfNotInitialized(
  145. value_, Derived::internal_default_instance()->value_);
  146. }
  147. inline KeyMapEntryAccessorType* mutable_key() {
  148. set_has_key();
  149. return KeyTypeHandler::EnsureMutable(&key_, GetArenaNoVirtual());
  150. }
  151. inline ValueMapEntryAccessorType* mutable_value() {
  152. set_has_value();
  153. return ValueTypeHandler::EnsureMutable(&value_, GetArenaNoVirtual());
  154. }
  155. // implements MessageLite =========================================
  156. // MapEntryImpl is for implementation only and this function isn't called
  157. // anywhere. Just provide a fake implementation here for MessageLite.
  158. string GetTypeName() const { return ""; }
  159. void CheckTypeAndMergeFrom(const MessageLite& other) {
  160. MergeFromInternal(*::google::protobuf::down_cast<const Derived*>(&other));
  161. }
  162. bool MergePartialFromCodedStream(::google::protobuf::io::CodedInputStream* input) {
  163. uint32 tag;
  164. for (;;) {
  165. // 1) corrupted data: return false;
  166. // 2) unknown field: skip without putting into unknown field set;
  167. // 3) unknown enum value: keep it in parsing. In proto2, caller should
  168. // check the value and put this entry into containing message's unknown
  169. // field set if the value is an unknown enum. In proto3, caller doesn't
  170. // need to care whether the value is unknown enum;
  171. // 4) missing key/value: missed key/value will have default value. caller
  172. // should take this entry as if key/value is set to default value.
  173. tag = input->ReadTagNoLastTag();
  174. switch (tag) {
  175. case kKeyTag:
  176. if (!KeyTypeHandler::Read(input, mutable_key())) {
  177. return false;
  178. }
  179. set_has_key();
  180. break;
  181. case kValueTag:
  182. if (!ValueTypeHandler::Read(input, mutable_value())) {
  183. return false;
  184. }
  185. set_has_value();
  186. if (input->ExpectAtEnd()) return true;
  187. break;
  188. default:
  189. if (tag == 0 ||
  190. WireFormatLite::GetTagWireType(tag) ==
  191. WireFormatLite::WIRETYPE_END_GROUP) {
  192. return true;
  193. }
  194. if (!WireFormatLite::SkipField(input, tag)) return false;
  195. break;
  196. }
  197. }
  198. }
  199. size_t ByteSizeLong() const {
  200. size_t size = 0;
  201. size += has_key() ?
  202. kTagSize + static_cast<size_t>(KeyTypeHandler::ByteSize(key())) : 0;
  203. size += has_value() ?
  204. kTagSize + static_cast<size_t>(ValueTypeHandler::ByteSize(value())) : 0;
  205. return size;
  206. }
  207. void SerializeWithCachedSizes(::google::protobuf::io::CodedOutputStream* output) const {
  208. KeyTypeHandler::Write(kKeyFieldNumber, key(), output);
  209. ValueTypeHandler::Write(kValueFieldNumber, value(), output);
  210. }
  211. ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(bool deterministic,
  212. ::google::protobuf::uint8* output) const {
  213. output = KeyTypeHandler::InternalWriteToArray(kKeyFieldNumber, key(),
  214. deterministic, output);
  215. output = ValueTypeHandler::InternalWriteToArray(kValueFieldNumber, value(),
  216. deterministic, output);
  217. return output;
  218. }
  219. // Don't override SerializeWithCachedSizesToArray. Use MessageLite's.
  220. int GetCachedSize() const {
  221. int size = 0;
  222. size += has_key()
  223. ? static_cast<int>(kTagSize) + KeyTypeHandler::GetCachedSize(key())
  224. : 0;
  225. size += has_value()
  226. ? static_cast<int>(kTagSize) + ValueTypeHandler::GetCachedSize(value())
  227. : 0;
  228. return size;
  229. }
  230. bool IsInitialized() const { return ValueTypeHandler::IsInitialized(value_); }
  231. Base* New() const {
  232. Derived* entry = new Derived;
  233. return entry;
  234. }
  235. Base* New(Arena* arena) const {
  236. Derived* entry = Arena::CreateMessage<Derived>(arena);
  237. return entry;
  238. }
  239. size_t SpaceUsedLong() const {
  240. size_t size = sizeof(Derived);
  241. size += KeyTypeHandler::SpaceUsedInMapEntryLong(key_);
  242. size += ValueTypeHandler::SpaceUsedInMapEntryLong(value_);
  243. return size;
  244. }
  245. protected:
  246. // We can't declare this function directly here as it would hide the other
  247. // overload (const Message&).
  248. void MergeFromInternal(const MapEntryImpl& from) {
  249. if (from._has_bits_[0]) {
  250. if (from.has_key()) {
  251. KeyTypeHandler::EnsureMutable(&key_, GetArenaNoVirtual());
  252. KeyTypeHandler::Merge(from.key(), &key_, GetArenaNoVirtual());
  253. set_has_key();
  254. }
  255. if (from.has_value()) {
  256. ValueTypeHandler::EnsureMutable(&value_, GetArenaNoVirtual());
  257. ValueTypeHandler::Merge(from.value(), &value_, GetArenaNoVirtual());
  258. set_has_value();
  259. }
  260. }
  261. }
  262. public:
  263. void Clear() {
  264. KeyTypeHandler::Clear(&key_, GetArenaNoVirtual());
  265. ValueTypeHandler::ClearMaybeByDefaultEnum(
  266. &value_, GetArenaNoVirtual(), default_enum_value);
  267. clear_has_key();
  268. clear_has_value();
  269. }
  270. static void InitAsDefaultInstance() {
  271. Derived* d = const_cast<Derived*>(Derived::internal_default_instance());
  272. KeyTypeHandler::AssignDefaultValue(&d->key_);
  273. ValueTypeHandler::AssignDefaultValue(&d->value_);
  274. }
  275. Arena* GetArena() const {
  276. return GetArenaNoVirtual();
  277. }
  278. // Create a MapEntryImpl for given key and value from google::protobuf::Map in
  279. // serialization. This function is only called when value is enum. Enum is
  280. // treated differently because its type in MapEntry is int and its type in
  281. // google::protobuf::Map is enum. We cannot create a reference to int from an enum.
  282. static Derived* EnumWrap(const Key& key, const Value value, Arena* arena) {
  283. return Arena::CreateMessage<MapEnumEntryWrapper>(arena, key, value);
  284. }
  285. // Like above, but for all the other types. This avoids value copy to create
  286. // MapEntryImpl from google::protobuf::Map in serialization.
  287. static Derived* Wrap(const Key& key, const Value& value, Arena* arena) {
  288. return Arena::CreateMessage<MapEntryWrapper>(arena, key, value);
  289. }
  290. // Parsing using MergePartialFromCodedStream, above, is not as
  291. // efficient as it could be. This helper class provides a speedier way.
  292. template <typename MapField, typename Map>
  293. class Parser {
  294. public:
  295. explicit Parser(MapField* mf) : mf_(mf), map_(mf->MutableMap()) {}
  296. // This does what the typical MergePartialFromCodedStream() is expected to
  297. // do, with the additional side-effect that if successful (i.e., if true is
  298. // going to be its return value) it inserts the key-value pair into map_.
  299. bool MergePartialFromCodedStream(::google::protobuf::io::CodedInputStream* input) {
  300. // Look for the expected thing: a key and then a value. If it fails,
  301. // invoke the enclosing class's MergePartialFromCodedStream, or return
  302. // false if that would be pointless.
  303. if (input->ExpectTag(kKeyTag)) {
  304. if (!KeyTypeHandler::Read(input, &key_)) {
  305. return false;
  306. }
  307. // Peek at the next byte to see if it is kValueTag. If not, bail out.
  308. const void* data;
  309. int size;
  310. input->GetDirectBufferPointerInline(&data, &size);
  311. // We could use memcmp here, but we don't bother. The tag is one byte.
  312. GOOGLE_COMPILE_ASSERT(kTagSize == 1, tag_size_error);
  313. if (size > 0 && *reinterpret_cast<const char*>(data) == kValueTag) {
  314. typename Map::size_type map_size = map_->size();
  315. value_ptr_ = &(*map_)[key_];
  316. if (GOOGLE_PREDICT_TRUE(map_size != map_->size())) {
  317. // We created a new key-value pair. Fill in the value.
  318. typedef
  319. typename MapIf<ValueTypeHandler::kIsEnum, int*, Value*>::type T;
  320. input->Skip(kTagSize); // Skip kValueTag.
  321. if (!ValueTypeHandler::Read(input,
  322. reinterpret_cast<T>(value_ptr_))) {
  323. map_->erase(key_); // Failure! Undo insertion.
  324. return false;
  325. }
  326. if (input->ExpectAtEnd()) return true;
  327. return ReadBeyondKeyValuePair(input);
  328. }
  329. }
  330. } else {
  331. key_ = Key();
  332. }
  333. entry_.reset(mf_->NewEntry());
  334. *entry_->mutable_key() = key_;
  335. const bool result = entry_->MergePartialFromCodedStream(input);
  336. if (result) UseKeyAndValueFromEntry();
  337. if (entry_->GetArena() != NULL) entry_.release();
  338. return result;
  339. }
  340. const Key& key() const { return key_; }
  341. const Value& value() const { return *value_ptr_; }
  342. private:
  343. void UseKeyAndValueFromEntry() GOOGLE_PROTOBUF_ATTRIBUTE_COLD {
  344. // Update key_ in case we need it later (because key() is called).
  345. // This is potentially inefficient, especially if the key is
  346. // expensive to copy (e.g., a long string), but this is a cold
  347. // path, so it's not a big deal.
  348. key_ = entry_->key();
  349. value_ptr_ = &(*map_)[key_];
  350. MoveHelper<ValueTypeHandler::kIsEnum,
  351. ValueTypeHandler::kIsMessage,
  352. ValueTypeHandler::kWireType ==
  353. WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
  354. Value>::Move(entry_->mutable_value(), value_ptr_);
  355. }
  356. // After reading a key and value successfully, and inserting that data
  357. // into map_, we are not at the end of the input. This is unusual, but
  358. // allowed by the spec.
  359. bool ReadBeyondKeyValuePair(::google::protobuf::io::CodedInputStream* input)
  360. GOOGLE_PROTOBUF_ATTRIBUTE_COLD {
  361. typedef MoveHelper<KeyTypeHandler::kIsEnum,
  362. KeyTypeHandler::kIsMessage,
  363. KeyTypeHandler::kWireType ==
  364. WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
  365. Key> KeyMover;
  366. typedef MoveHelper<ValueTypeHandler::kIsEnum,
  367. ValueTypeHandler::kIsMessage,
  368. ValueTypeHandler::kWireType ==
  369. WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
  370. Value> ValueMover;
  371. entry_.reset(mf_->NewEntry());
  372. ValueMover::Move(value_ptr_, entry_->mutable_value());
  373. map_->erase(key_);
  374. KeyMover::Move(&key_, entry_->mutable_key());
  375. const bool result = entry_->MergePartialFromCodedStream(input);
  376. if (result) UseKeyAndValueFromEntry();
  377. if (entry_->GetArena() != NULL) entry_.release();
  378. return result;
  379. }
  380. MapField* const mf_;
  381. Map* const map_;
  382. Key key_;
  383. Value* value_ptr_;
  384. // On the fast path entry_ is not used. And, when entry_ is used, it's set
  385. // to mf_->NewEntry(), so in the arena case we must call entry_.release.
  386. std::unique_ptr<MapEntryImpl> entry_;
  387. };
  388. protected:
  389. void set_has_key() { _has_bits_[0] |= 0x00000001u; }
  390. bool has_key() const { return (_has_bits_[0] & 0x00000001u) != 0; }
  391. void clear_has_key() { _has_bits_[0] &= ~0x00000001u; }
  392. void set_has_value() { _has_bits_[0] |= 0x00000002u; }
  393. bool has_value() const { return (_has_bits_[0] & 0x00000002u) != 0; }
  394. void clear_has_value() { _has_bits_[0] &= ~0x00000002u; }
  395. private:
  396. // Serializing a generated message containing map field involves serializing
  397. // key-value pairs from google::protobuf::Map. The wire format of each key-value pair
  398. // after serialization should be the same as that of a MapEntry message
  399. // containing the same key and value inside it. However, google::protobuf::Map doesn't
  400. // store key and value as MapEntry message, which disables us to use existing
  401. // code to serialize message. In order to use existing code to serialize
  402. // message, we need to construct a MapEntry from key-value pair. But it
  403. // involves copy of key and value to construct a MapEntry. In order to avoid
  404. // this copy in constructing a MapEntry, we need the following class which
  405. // only takes references of given key and value.
  406. class MapEntryWrapper : public Derived {
  407. typedef Derived BaseClass;
  408. typedef typename BaseClass::KeyMapEntryAccessorType KeyMapEntryAccessorType;
  409. typedef
  410. typename BaseClass::ValueMapEntryAccessorType ValueMapEntryAccessorType;
  411. public:
  412. MapEntryWrapper(Arena* arena, const Key& key, const Value& value)
  413. : Derived(arena), key_(key), value_(value) {
  414. BaseClass::set_has_key();
  415. BaseClass::set_has_value();
  416. }
  417. inline const KeyMapEntryAccessorType& key() const { return key_; }
  418. inline const ValueMapEntryAccessorType& value() const { return value_; }
  419. private:
  420. const Key& key_;
  421. const Value& value_;
  422. friend class ::google::protobuf::Arena;
  423. typedef void InternalArenaConstructable_;
  424. typedef void DestructorSkippable_;
  425. };
  426. // Like above, but for enum value only, which stores value instead of
  427. // reference of value field inside. This is needed because the type of value
  428. // field in constructor is an enum, while we need to store it as an int. If we
  429. // initialize a reference to int with a reference to enum, compiler will
  430. // generate a temporary int from enum and initialize the reference to int with
  431. // the temporary.
  432. class MapEnumEntryWrapper : public Derived {
  433. typedef Derived BaseClass;
  434. typedef typename BaseClass::KeyMapEntryAccessorType KeyMapEntryAccessorType;
  435. typedef
  436. typename BaseClass::ValueMapEntryAccessorType ValueMapEntryAccessorType;
  437. public:
  438. MapEnumEntryWrapper(Arena* arena, const Key& key, const Value& value)
  439. : Derived(arena), key_(key), value_(value) {
  440. BaseClass::set_has_key();
  441. BaseClass::set_has_value();
  442. }
  443. inline const KeyMapEntryAccessorType& key() const { return key_; }
  444. inline const ValueMapEntryAccessorType& value() const { return value_; }
  445. private:
  446. const KeyMapEntryAccessorType& key_;
  447. const ValueMapEntryAccessorType value_;
  448. friend class google::protobuf::Arena;
  449. typedef void DestructorSkippable_;
  450. };
  451. inline Arena* GetArenaNoVirtual() const {
  452. return arena_;
  453. }
  454. public: // Needed for constructing tables
  455. KeyOnMemory key_;
  456. ValueOnMemory value_;
  457. Arena* arena_;
  458. uint32 _has_bits_[1];
  459. private:
  460. friend class ::google::protobuf::Arena;
  461. typedef void InternalArenaConstructable_;
  462. typedef void DestructorSkippable_;
  463. template <typename C, typename K, typename V, WireFormatLite::FieldType,
  464. WireFormatLite::FieldType, int>
  465. friend class internal::MapEntry;
  466. template <typename C, typename K, typename V, WireFormatLite::FieldType,
  467. WireFormatLite::FieldType, int>
  468. friend class internal::MapFieldLite;
  469. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntryImpl);
  470. };
  471. template <typename T, typename Key, typename Value,
  472. WireFormatLite::FieldType kKeyFieldType,
  473. WireFormatLite::FieldType kValueFieldType, int default_enum_value>
  474. class MapEntryLite
  475. : public MapEntryImpl<T, MessageLite, Key, Value, kKeyFieldType,
  476. kValueFieldType, default_enum_value> {
  477. public:
  478. typedef MapEntryImpl<T, MessageLite, Key, Value, kKeyFieldType,
  479. kValueFieldType, default_enum_value>
  480. SuperType;
  481. MapEntryLite() {}
  482. explicit MapEntryLite(Arena* arena) : SuperType(arena) {}
  483. void MergeFrom(const MapEntryLite& other) { MergeFromInternal(other); }
  484. private:
  485. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntryLite);
  486. };
  487. // The completely unprincipled and unwieldy use of template parameters in
  488. // the map code necessitates wrappers to make the code a little bit more
  489. // manageable.
  490. template <typename Derived>
  491. struct DeconstructMapEntry;
  492. template <typename T, typename K, typename V, WireFormatLite::FieldType key,
  493. WireFormatLite::FieldType value, int default_enum>
  494. struct DeconstructMapEntry<MapEntryLite<T, K, V, key, value, default_enum> > {
  495. typedef K Key;
  496. typedef V Value;
  497. static const WireFormatLite::FieldType kKeyFieldType = key;
  498. static const WireFormatLite::FieldType kValueFieldType = value;
  499. static const int default_enum_value = default_enum;
  500. };
  501. // Helpers for deterministic serialization =============================
  502. // This struct can be used with any generic sorting algorithm. If the Key
  503. // type is relatively small and easy to copy then copying Keys into an
  504. // array of SortItems can be beneficial. Then all the data the sorting
  505. // algorithm needs to touch is in that one array.
  506. template <typename Key, typename PtrToKeyValuePair> struct SortItem {
  507. SortItem() {}
  508. explicit SortItem(PtrToKeyValuePair p) : first(p->first), second(p) {}
  509. Key first;
  510. PtrToKeyValuePair second;
  511. };
  512. template <typename T> struct CompareByFirstField {
  513. bool operator()(const T& a, const T& b) const {
  514. return a.first < b.first;
  515. }
  516. };
  517. template <typename T> struct CompareByDerefFirst {
  518. bool operator()(const T& a, const T& b) const {
  519. return a->first < b->first;
  520. }
  521. };
  522. // Helper for table driven serialization
  523. template <WireFormatLite::FieldType FieldType>
  524. struct FromHelper {
  525. template <typename T>
  526. static const T& From(const T& x) {
  527. return x;
  528. }
  529. };
  530. template <>
  531. struct FromHelper<WireFormatLite::TYPE_STRING> {
  532. static ArenaStringPtr From(const string& x) {
  533. ArenaStringPtr res;
  534. TaggedPtr<::std::string> ptr;
  535. ptr.Set(const_cast<string*>(&x));
  536. res.UnsafeSetTaggedPointer(ptr);
  537. return res;
  538. }
  539. };
  540. template <>
  541. struct FromHelper<WireFormatLite::TYPE_BYTES> {
  542. static ArenaStringPtr From(const string& x) {
  543. ArenaStringPtr res;
  544. TaggedPtr<::std::string> ptr;
  545. ptr.Set(const_cast<string*>(&x));
  546. res.UnsafeSetTaggedPointer(ptr);
  547. return res;
  548. }
  549. };
  550. template <>
  551. struct FromHelper<WireFormatLite::TYPE_MESSAGE> {
  552. template <typename T>
  553. static T* From(const T& x) {
  554. return const_cast<T*>(&x);
  555. }
  556. };
  557. template <typename MapEntryType>
  558. struct MapEntryHelper;
  559. template <typename T, typename Key, typename Value,
  560. WireFormatLite::FieldType kKeyFieldType,
  561. WireFormatLite::FieldType kValueFieldType, int default_enum_value>
  562. struct MapEntryHelper<MapEntryLite<T, Key, Value, kKeyFieldType,
  563. kValueFieldType, default_enum_value> > {
  564. // Provide utilities to parse/serialize key/value. Provide utilities to
  565. // manipulate internal stored type.
  566. typedef MapTypeHandler<kKeyFieldType, Key> KeyTypeHandler;
  567. typedef MapTypeHandler<kValueFieldType, Value> ValueTypeHandler;
  568. // Define internal memory layout. Strings and messages are stored as
  569. // pointers, while other types are stored as values.
  570. typedef typename KeyTypeHandler::TypeOnMemory KeyOnMemory;
  571. typedef typename ValueTypeHandler::TypeOnMemory ValueOnMemory;
  572. explicit MapEntryHelper(const MapPair<Key, Value>& map_pair)
  573. : _has_bits_(3),
  574. _cached_size_(2 + KeyTypeHandler::GetCachedSize(map_pair.first) +
  575. ValueTypeHandler::GetCachedSize(map_pair.second)),
  576. key_(FromHelper<kKeyFieldType>::From(map_pair.first)),
  577. value_(FromHelper<kValueFieldType>::From(map_pair.second)) {}
  578. // Purposely not folowing the style guide naming. These are the names
  579. // the proto compiler would generate given the map entry descriptor.
  580. // The proto compiler generates the offsets in this struct as if this was
  581. // a regular message. This way the table driven code barely notices it's
  582. // dealing with a map field.
  583. uint32 _has_bits_; // NOLINT
  584. uint32 _cached_size_; // NOLINT
  585. KeyOnMemory key_; // NOLINT
  586. ValueOnMemory value_; // NOLINT
  587. };
  588. } // namespace internal
  589. } // namespace protobuf
  590. } // namespace google
  591. #endif // GOOGLE_PROTOBUF_MAP_ENTRY_LITE_H__