map_entry_lite.h 25 KB

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