You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

map_field.h 35 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946
  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_FIELD_H__
  31. #define GOOGLE_PROTOBUF_MAP_FIELD_H__
  32. #include <atomic>
  33. #include <functional>
  34. #include <google/protobuf/arena.h>
  35. #include <google/protobuf/stubs/mutex.h>
  36. #include <google/protobuf/port.h>
  37. #include <google/protobuf/descriptor.h>
  38. #include <google/protobuf/generated_message_reflection.h>
  39. #include <google/protobuf/generated_message_util.h>
  40. #include <google/protobuf/map_entry.h>
  41. #include <google/protobuf/map_field_lite.h>
  42. #include <google/protobuf/map_type_handler.h>
  43. #include <google/protobuf/message.h>
  44. #include <google/protobuf/repeated_field.h>
  45. #include <google/protobuf/unknown_field_set.h>
  46. // Must be included last.
  47. #include <google/protobuf/port_def.inc>
  48. #ifdef SWIG
  49. #error "You cannot SWIG proto headers"
  50. #endif
  51. namespace google {
  52. namespace protobuf {
  53. class DynamicMessage;
  54. class MapIterator;
  55. // Microsoft compiler complains about non-virtual destructor,
  56. // even when the destructor is private.
  57. #ifdef _MSC_VER
  58. #pragma warning(push)
  59. #pragma warning(disable : 4265)
  60. #endif // _MSC_VER
  61. #define TYPE_CHECK(EXPECTEDTYPE, METHOD) \
  62. if (type() != EXPECTEDTYPE) { \
  63. GOOGLE_LOG(FATAL) << "Protocol Buffer map usage error:\n" \
  64. << METHOD << " type does not match\n" \
  65. << " Expected : " \
  66. << FieldDescriptor::CppTypeName(EXPECTEDTYPE) << "\n" \
  67. << " Actual : " << FieldDescriptor::CppTypeName(type()); \
  68. }
  69. // MapKey is an union type for representing any possible
  70. // map key.
  71. class PROTOBUF_EXPORT MapKey {
  72. public:
  73. MapKey() : type_() {}
  74. MapKey(const MapKey& other) : type_() { CopyFrom(other); }
  75. MapKey& operator=(const MapKey& other) {
  76. CopyFrom(other);
  77. return *this;
  78. }
  79. ~MapKey() {
  80. if (type_ == FieldDescriptor::CPPTYPE_STRING) {
  81. val_.string_value_.Destruct();
  82. }
  83. }
  84. FieldDescriptor::CppType type() const {
  85. if (type_ == FieldDescriptor::CppType()) {
  86. GOOGLE_LOG(FATAL) << "Protocol Buffer map usage error:\n"
  87. << "MapKey::type MapKey is not initialized. "
  88. << "Call set methods to initialize MapKey.";
  89. }
  90. return type_;
  91. }
  92. void SetInt64Value(int64_t value) {
  93. SetType(FieldDescriptor::CPPTYPE_INT64);
  94. val_.int64_value_ = value;
  95. }
  96. void SetUInt64Value(uint64_t value) {
  97. SetType(FieldDescriptor::CPPTYPE_UINT64);
  98. val_.uint64_value_ = value;
  99. }
  100. void SetInt32Value(int32_t value) {
  101. SetType(FieldDescriptor::CPPTYPE_INT32);
  102. val_.int32_value_ = value;
  103. }
  104. void SetUInt32Value(uint32_t value) {
  105. SetType(FieldDescriptor::CPPTYPE_UINT32);
  106. val_.uint32_value_ = value;
  107. }
  108. void SetBoolValue(bool value) {
  109. SetType(FieldDescriptor::CPPTYPE_BOOL);
  110. val_.bool_value_ = value;
  111. }
  112. void SetStringValue(std::string val) {
  113. SetType(FieldDescriptor::CPPTYPE_STRING);
  114. *val_.string_value_.get_mutable() = std::move(val);
  115. }
  116. int64_t GetInt64Value() const {
  117. TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, "MapKey::GetInt64Value");
  118. return val_.int64_value_;
  119. }
  120. uint64_t GetUInt64Value() const {
  121. TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, "MapKey::GetUInt64Value");
  122. return val_.uint64_value_;
  123. }
  124. int32_t GetInt32Value() const {
  125. TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, "MapKey::GetInt32Value");
  126. return val_.int32_value_;
  127. }
  128. uint32_t GetUInt32Value() const {
  129. TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, "MapKey::GetUInt32Value");
  130. return val_.uint32_value_;
  131. }
  132. bool GetBoolValue() const {
  133. TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, "MapKey::GetBoolValue");
  134. return val_.bool_value_;
  135. }
  136. const std::string& GetStringValue() const {
  137. TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING, "MapKey::GetStringValue");
  138. return val_.string_value_.get();
  139. }
  140. bool operator<(const MapKey& other) const {
  141. if (type_ != other.type_) {
  142. // We could define a total order that handles this case, but
  143. // there currently no need. So, for now, fail.
  144. GOOGLE_LOG(FATAL) << "Unsupported: type mismatch";
  145. }
  146. switch (type()) {
  147. case FieldDescriptor::CPPTYPE_DOUBLE:
  148. case FieldDescriptor::CPPTYPE_FLOAT:
  149. case FieldDescriptor::CPPTYPE_ENUM:
  150. case FieldDescriptor::CPPTYPE_MESSAGE:
  151. GOOGLE_LOG(FATAL) << "Unsupported";
  152. return false;
  153. case FieldDescriptor::CPPTYPE_STRING:
  154. return val_.string_value_.get() < other.val_.string_value_.get();
  155. case FieldDescriptor::CPPTYPE_INT64:
  156. return val_.int64_value_ < other.val_.int64_value_;
  157. case FieldDescriptor::CPPTYPE_INT32:
  158. return val_.int32_value_ < other.val_.int32_value_;
  159. case FieldDescriptor::CPPTYPE_UINT64:
  160. return val_.uint64_value_ < other.val_.uint64_value_;
  161. case FieldDescriptor::CPPTYPE_UINT32:
  162. return val_.uint32_value_ < other.val_.uint32_value_;
  163. case FieldDescriptor::CPPTYPE_BOOL:
  164. return val_.bool_value_ < other.val_.bool_value_;
  165. }
  166. return false;
  167. }
  168. bool operator==(const MapKey& other) const {
  169. if (type_ != other.type_) {
  170. // To be consistent with operator<, we don't allow this either.
  171. GOOGLE_LOG(FATAL) << "Unsupported: type mismatch";
  172. }
  173. switch (type()) {
  174. case FieldDescriptor::CPPTYPE_DOUBLE:
  175. case FieldDescriptor::CPPTYPE_FLOAT:
  176. case FieldDescriptor::CPPTYPE_ENUM:
  177. case FieldDescriptor::CPPTYPE_MESSAGE:
  178. GOOGLE_LOG(FATAL) << "Unsupported";
  179. break;
  180. case FieldDescriptor::CPPTYPE_STRING:
  181. return val_.string_value_.get() == other.val_.string_value_.get();
  182. case FieldDescriptor::CPPTYPE_INT64:
  183. return val_.int64_value_ == other.val_.int64_value_;
  184. case FieldDescriptor::CPPTYPE_INT32:
  185. return val_.int32_value_ == other.val_.int32_value_;
  186. case FieldDescriptor::CPPTYPE_UINT64:
  187. return val_.uint64_value_ == other.val_.uint64_value_;
  188. case FieldDescriptor::CPPTYPE_UINT32:
  189. return val_.uint32_value_ == other.val_.uint32_value_;
  190. case FieldDescriptor::CPPTYPE_BOOL:
  191. return val_.bool_value_ == other.val_.bool_value_;
  192. }
  193. GOOGLE_LOG(FATAL) << "Can't get here.";
  194. return false;
  195. }
  196. void CopyFrom(const MapKey& other) {
  197. SetType(other.type());
  198. switch (type_) {
  199. case FieldDescriptor::CPPTYPE_DOUBLE:
  200. case FieldDescriptor::CPPTYPE_FLOAT:
  201. case FieldDescriptor::CPPTYPE_ENUM:
  202. case FieldDescriptor::CPPTYPE_MESSAGE:
  203. GOOGLE_LOG(FATAL) << "Unsupported";
  204. break;
  205. case FieldDescriptor::CPPTYPE_STRING:
  206. *val_.string_value_.get_mutable() = other.val_.string_value_.get();
  207. break;
  208. case FieldDescriptor::CPPTYPE_INT64:
  209. val_.int64_value_ = other.val_.int64_value_;
  210. break;
  211. case FieldDescriptor::CPPTYPE_INT32:
  212. val_.int32_value_ = other.val_.int32_value_;
  213. break;
  214. case FieldDescriptor::CPPTYPE_UINT64:
  215. val_.uint64_value_ = other.val_.uint64_value_;
  216. break;
  217. case FieldDescriptor::CPPTYPE_UINT32:
  218. val_.uint32_value_ = other.val_.uint32_value_;
  219. break;
  220. case FieldDescriptor::CPPTYPE_BOOL:
  221. val_.bool_value_ = other.val_.bool_value_;
  222. break;
  223. }
  224. }
  225. private:
  226. template <typename K, typename V>
  227. friend class internal::TypeDefinedMapFieldBase;
  228. friend class ::PROTOBUF_NAMESPACE_ID::MapIterator;
  229. friend class internal::DynamicMapField;
  230. union KeyValue {
  231. KeyValue() {}
  232. internal::ExplicitlyConstructed<std::string> string_value_;
  233. int64_t int64_value_;
  234. int32_t int32_value_;
  235. uint64_t uint64_value_;
  236. uint32_t uint32_value_;
  237. bool bool_value_;
  238. } val_;
  239. void SetType(FieldDescriptor::CppType type) {
  240. if (type_ == type) return;
  241. if (type_ == FieldDescriptor::CPPTYPE_STRING) {
  242. val_.string_value_.Destruct();
  243. }
  244. type_ = type;
  245. if (type_ == FieldDescriptor::CPPTYPE_STRING) {
  246. val_.string_value_.DefaultConstruct();
  247. }
  248. }
  249. // type_ is 0 or a valid FieldDescriptor::CppType.
  250. // Use "CppType()" to indicate zero.
  251. FieldDescriptor::CppType type_;
  252. };
  253. } // namespace protobuf
  254. } // namespace google
  255. namespace std {
  256. template <>
  257. struct hash<::PROTOBUF_NAMESPACE_ID::MapKey> {
  258. size_t operator()(const ::PROTOBUF_NAMESPACE_ID::MapKey& map_key) const {
  259. switch (map_key.type()) {
  260. case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_DOUBLE:
  261. case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_FLOAT:
  262. case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_ENUM:
  263. case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_MESSAGE:
  264. GOOGLE_LOG(FATAL) << "Unsupported";
  265. break;
  266. case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_STRING:
  267. return hash<std::string>()(map_key.GetStringValue());
  268. case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_INT64: {
  269. auto value = map_key.GetInt64Value();
  270. return hash<decltype(value)>()(value);
  271. }
  272. case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_INT32: {
  273. auto value = map_key.GetInt32Value();
  274. return hash<decltype(value)>()(map_key.GetInt32Value());
  275. }
  276. case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_UINT64: {
  277. auto value = map_key.GetUInt64Value();
  278. return hash<decltype(value)>()(map_key.GetUInt64Value());
  279. }
  280. case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_UINT32: {
  281. auto value = map_key.GetUInt32Value();
  282. return hash<decltype(value)>()(map_key.GetUInt32Value());
  283. }
  284. case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_BOOL: {
  285. return hash<bool>()(map_key.GetBoolValue());
  286. }
  287. }
  288. GOOGLE_LOG(FATAL) << "Can't get here.";
  289. return 0;
  290. }
  291. bool operator()(const ::PROTOBUF_NAMESPACE_ID::MapKey& map_key1,
  292. const ::PROTOBUF_NAMESPACE_ID::MapKey& map_key2) const {
  293. return map_key1 < map_key2;
  294. }
  295. };
  296. } // namespace std
  297. namespace google {
  298. namespace protobuf {
  299. namespace internal {
  300. class ContendedMapCleanTest;
  301. class GeneratedMessageReflection;
  302. class MapFieldAccessor;
  303. // This class provides access to map field using reflection, which is the same
  304. // as those provided for RepeatedPtrField<Message>. It is used for internal
  305. // reflection implementation only. Users should never use this directly.
  306. class PROTOBUF_EXPORT MapFieldBase {
  307. public:
  308. MapFieldBase()
  309. : arena_(nullptr), repeated_field_(nullptr), state_(STATE_MODIFIED_MAP) {}
  310. // This constructor is for constant initialized global instances.
  311. // It uses a linker initialized mutex, so it is not compatible with regular
  312. // runtime instances.
  313. // Except in MSVC, where we can't have a constinit mutex.
  314. // NOLINTNEXTLINE(google-explicit-constructor)
  315. constexpr MapFieldBase(ConstantInitialized)
  316. : arena_(nullptr),
  317. repeated_field_(nullptr),
  318. mutex_(GOOGLE_PROTOBUF_LINKER_INITIALIZED),
  319. state_(STATE_MODIFIED_MAP) {}
  320. explicit MapFieldBase(Arena* arena)
  321. : arena_(arena), repeated_field_(nullptr), state_(STATE_MODIFIED_MAP) {}
  322. protected:
  323. ~MapFieldBase() { // "protected" stops users from deleting a `MapFieldBase *`
  324. GOOGLE_DCHECK(repeated_field_ == nullptr);
  325. }
  326. void Destruct();
  327. public:
  328. // Returns reference to internal repeated field. Data written using
  329. // Map's api prior to calling this function is guarantted to be
  330. // included in repeated field.
  331. const RepeatedPtrFieldBase& GetRepeatedField() const;
  332. // Like above. Returns mutable pointer to the internal repeated field.
  333. RepeatedPtrFieldBase* MutableRepeatedField();
  334. // Pure virtual map APIs for Map Reflection.
  335. virtual bool ContainsMapKey(const MapKey& map_key) const = 0;
  336. virtual bool InsertOrLookupMapValue(const MapKey& map_key,
  337. MapValueRef* val) = 0;
  338. virtual bool LookupMapValue(const MapKey& map_key,
  339. MapValueConstRef* val) const = 0;
  340. bool LookupMapValue(const MapKey&, MapValueRef*) const = delete;
  341. // Returns whether changes to the map are reflected in the repeated field.
  342. bool IsRepeatedFieldValid() const;
  343. // Insures operations after won't get executed before calling this.
  344. bool IsMapValid() const;
  345. virtual bool DeleteMapValue(const MapKey& map_key) = 0;
  346. virtual bool EqualIterator(const MapIterator& a,
  347. const MapIterator& b) const = 0;
  348. virtual void MapBegin(MapIterator* map_iter) const = 0;
  349. virtual void MapEnd(MapIterator* map_iter) const = 0;
  350. virtual void MergeFrom(const MapFieldBase& other) = 0;
  351. virtual void Swap(MapFieldBase* other);
  352. virtual void UnsafeShallowSwap(MapFieldBase* other);
  353. // Sync Map with repeated field and returns the size of map.
  354. virtual int size() const = 0;
  355. virtual void Clear() = 0;
  356. // Returns the number of bytes used by the repeated field, excluding
  357. // sizeof(*this)
  358. size_t SpaceUsedExcludingSelfLong() const;
  359. int SpaceUsedExcludingSelf() const {
  360. return internal::ToIntSize(SpaceUsedExcludingSelfLong());
  361. }
  362. protected:
  363. // Gets the size of space used by map field.
  364. virtual size_t SpaceUsedExcludingSelfNoLock() const;
  365. // Synchronizes the content in Map to RepeatedPtrField if there is any change
  366. // to Map after last synchronization.
  367. void SyncRepeatedFieldWithMap() const;
  368. virtual void SyncRepeatedFieldWithMapNoLock() const;
  369. // Synchronizes the content in RepeatedPtrField to Map if there is any change
  370. // to RepeatedPtrField after last synchronization.
  371. void SyncMapWithRepeatedField() const;
  372. virtual void SyncMapWithRepeatedFieldNoLock() const {}
  373. // Tells MapFieldBase that there is new change to Map.
  374. void SetMapDirty();
  375. // Tells MapFieldBase that there is new change to RepeatedPtrField.
  376. void SetRepeatedDirty();
  377. // Provides derived class the access to repeated field.
  378. void* MutableRepeatedPtrField() const;
  379. void InternalSwap(MapFieldBase* other);
  380. // Support thread sanitizer (tsan) by making const / mutable races
  381. // more apparent. If one thread calls MutableAccess() while another
  382. // thread calls either ConstAccess() or MutableAccess(), on the same
  383. // MapFieldBase-derived object, and there is no synchronization going
  384. // on between them, tsan will alert.
  385. #if defined(__SANITIZE_THREAD__) || defined(THREAD_SANITIZER)
  386. void ConstAccess() const { GOOGLE_CHECK_EQ(seq1_, seq2_); }
  387. void MutableAccess() {
  388. if (seq1_ & 1) {
  389. seq2_ = ++seq1_;
  390. } else {
  391. seq1_ = ++seq2_;
  392. }
  393. }
  394. unsigned int seq1_ = 0, seq2_ = 0;
  395. #else
  396. void ConstAccess() const {}
  397. void MutableAccess() {}
  398. #endif
  399. enum State {
  400. STATE_MODIFIED_MAP = 0, // map has newly added data that has not been
  401. // synchronized to repeated field
  402. STATE_MODIFIED_REPEATED = 1, // repeated field has newly added data that
  403. // has not been synchronized to map
  404. CLEAN = 2, // data in map and repeated field are same
  405. };
  406. Arena* arena_;
  407. mutable RepeatedPtrField<Message>* repeated_field_;
  408. mutable internal::WrappedMutex
  409. mutex_; // The thread to synchronize map and repeated field
  410. // needs to get lock first;
  411. mutable std::atomic<State> state_;
  412. private:
  413. friend class ContendedMapCleanTest;
  414. friend class GeneratedMessageReflection;
  415. friend class MapFieldAccessor;
  416. friend class ::PROTOBUF_NAMESPACE_ID::Reflection;
  417. friend class ::PROTOBUF_NAMESPACE_ID::DynamicMessage;
  418. // Virtual helper methods for MapIterator. MapIterator doesn't have the
  419. // type helper for key and value. Call these help methods to deal with
  420. // different types. Real helper methods are implemented in
  421. // TypeDefinedMapFieldBase.
  422. friend class ::PROTOBUF_NAMESPACE_ID::MapIterator;
  423. // Allocate map<...>::iterator for MapIterator.
  424. virtual void InitializeIterator(MapIterator* map_iter) const = 0;
  425. // DeleteIterator() is called by the destructor of MapIterator only.
  426. // It deletes map<...>::iterator for MapIterator.
  427. virtual void DeleteIterator(MapIterator* map_iter) const = 0;
  428. // Copy the map<...>::iterator from other_iterator to
  429. // this_iterator.
  430. virtual void CopyIterator(MapIterator* this_iterator,
  431. const MapIterator& other_iterator) const = 0;
  432. // IncreaseIterator() is called by operator++() of MapIterator only.
  433. // It implements the ++ operator of MapIterator.
  434. virtual void IncreaseIterator(MapIterator* map_iter) const = 0;
  435. // Swaps state_ with another MapFieldBase
  436. void SwapState(MapFieldBase* other);
  437. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapFieldBase);
  438. };
  439. // This class provides common Map Reflection implementations for generated
  440. // message and dynamic message.
  441. template <typename Key, typename T>
  442. class TypeDefinedMapFieldBase : public MapFieldBase {
  443. public:
  444. TypeDefinedMapFieldBase() {}
  445. // This constructor is for constant initialized global instances.
  446. // It uses a linker initialized mutex, so it is not compatible with regular
  447. // runtime instances.
  448. // NOLINTNEXTLINE(google-explicit-constructor)
  449. constexpr TypeDefinedMapFieldBase(ConstantInitialized tag)
  450. : MapFieldBase(tag) {}
  451. explicit TypeDefinedMapFieldBase(Arena* arena) : MapFieldBase(arena) {}
  452. TypeDefinedMapFieldBase(ArenaInitialized, Arena* arena)
  453. : TypeDefinedMapFieldBase(arena) {}
  454. protected:
  455. ~TypeDefinedMapFieldBase() {}
  456. using MapFieldBase::Destruct;
  457. public:
  458. void MapBegin(MapIterator* map_iter) const override;
  459. void MapEnd(MapIterator* map_iter) const override;
  460. bool EqualIterator(const MapIterator& a, const MapIterator& b) const override;
  461. virtual const Map<Key, T>& GetMap() const = 0;
  462. virtual Map<Key, T>* MutableMap() = 0;
  463. protected:
  464. typename Map<Key, T>::const_iterator& InternalGetIterator(
  465. const MapIterator* map_iter) const;
  466. private:
  467. void InitializeIterator(MapIterator* map_iter) const override;
  468. void DeleteIterator(MapIterator* map_iter) const override;
  469. void CopyIterator(MapIterator* this_iteratorm,
  470. const MapIterator& that_iterator) const override;
  471. void IncreaseIterator(MapIterator* map_iter) const override;
  472. virtual void SetMapIteratorValue(MapIterator* map_iter) const = 0;
  473. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeDefinedMapFieldBase);
  474. };
  475. // This class provides access to map field using generated api. It is used for
  476. // internal generated message implementation only. Users should never use this
  477. // directly.
  478. template <typename Derived, typename Key, typename T,
  479. WireFormatLite::FieldType kKeyFieldType,
  480. WireFormatLite::FieldType kValueFieldType>
  481. class MapField : public TypeDefinedMapFieldBase<Key, T> {
  482. // Provide utilities to parse/serialize key/value. Provide utilities to
  483. // manipulate internal stored type.
  484. typedef MapTypeHandler<kKeyFieldType, Key> KeyTypeHandler;
  485. typedef MapTypeHandler<kValueFieldType, T> ValueTypeHandler;
  486. // Define message type for internal repeated field.
  487. typedef Derived EntryType;
  488. // Define abbreviation for parent MapFieldLite
  489. typedef MapFieldLite<Derived, Key, T, kKeyFieldType, kValueFieldType>
  490. MapFieldLiteType;
  491. // Enum needs to be handled differently from other types because it has
  492. // different exposed type in Map's api and repeated field's api. For
  493. // details see the comment in the implementation of
  494. // SyncMapWithRepeatedFieldNoLock.
  495. static constexpr bool kIsValueEnum = ValueTypeHandler::kIsEnum;
  496. typedef typename MapIf<kIsValueEnum, T, const T&>::type CastValueType;
  497. public:
  498. typedef Map<Key, T> MapType;
  499. MapField() : impl_() {}
  500. virtual ~MapField() {} // Destruct() must already have been called!
  501. void Destruct() {
  502. impl_.Destruct();
  503. TypeDefinedMapFieldBase<Key, T>::Destruct();
  504. }
  505. // This constructor is for constant initialized global instances.
  506. // It uses a linker initialized mutex, so it is not compatible with regular
  507. // runtime instances.
  508. // NOLINTNEXTLINE(google-explicit-constructor)
  509. constexpr MapField(ConstantInitialized tag)
  510. : TypeDefinedMapFieldBase<Key, T>(tag), impl_() {}
  511. explicit MapField(Arena* arena)
  512. : TypeDefinedMapFieldBase<Key, T>(arena), impl_(arena) {}
  513. MapField(ArenaInitialized, Arena* arena) : MapField(arena) {}
  514. // Implement MapFieldBase
  515. bool ContainsMapKey(const MapKey& map_key) const override;
  516. bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val) override;
  517. bool LookupMapValue(const MapKey& map_key,
  518. MapValueConstRef* val) const override;
  519. bool LookupMapValue(const MapKey&, MapValueRef*) const = delete;
  520. bool DeleteMapValue(const MapKey& map_key) override;
  521. const Map<Key, T>& GetMap() const override {
  522. MapFieldBase::SyncMapWithRepeatedField();
  523. return impl_.GetMap();
  524. }
  525. Map<Key, T>* MutableMap() override {
  526. MapFieldBase::SyncMapWithRepeatedField();
  527. Map<Key, T>* result = impl_.MutableMap();
  528. MapFieldBase::SetMapDirty();
  529. return result;
  530. }
  531. int size() const override;
  532. void Clear() override;
  533. void MergeFrom(const MapFieldBase& other) override;
  534. void Swap(MapFieldBase* other) override;
  535. void UnsafeShallowSwap(MapFieldBase* other) override;
  536. void InternalSwap(MapField* other);
  537. // Used in the implementation of parsing. Caller should take the ownership iff
  538. // arena_ is nullptr.
  539. EntryType* NewEntry() const { return impl_.NewEntry(); }
  540. const char* _InternalParse(const char* ptr, ParseContext* ctx) {
  541. return impl_._InternalParse(ptr, ctx);
  542. }
  543. template <typename UnknownType>
  544. const char* ParseWithEnumValidation(const char* ptr, ParseContext* ctx,
  545. bool (*is_valid)(int), uint32_t field_num,
  546. InternalMetadata* metadata) {
  547. return impl_.template ParseWithEnumValidation<UnknownType>(
  548. ptr, ctx, is_valid, field_num, metadata);
  549. }
  550. private:
  551. MapFieldLiteType impl_;
  552. typedef void InternalArenaConstructable_;
  553. typedef void DestructorSkippable_;
  554. // Implements MapFieldBase
  555. void SyncRepeatedFieldWithMapNoLock() const override;
  556. void SyncMapWithRepeatedFieldNoLock() const override;
  557. size_t SpaceUsedExcludingSelfNoLock() const override;
  558. void SetMapIteratorValue(MapIterator* map_iter) const override;
  559. friend class ::PROTOBUF_NAMESPACE_ID::Arena;
  560. friend class MapFieldStateTest; // For testing, it needs raw access to impl_
  561. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapField);
  562. };
  563. template <typename Derived, typename Key, typename T,
  564. WireFormatLite::FieldType key_wire_type,
  565. WireFormatLite::FieldType value_wire_type>
  566. bool AllAreInitialized(
  567. const MapField<Derived, Key, T, key_wire_type, value_wire_type>& field) {
  568. const auto& t = field.GetMap();
  569. for (typename Map<Key, T>::const_iterator it = t.begin(); it != t.end();
  570. ++it) {
  571. if (!it->second.IsInitialized()) return false;
  572. }
  573. return true;
  574. }
  575. template <typename T, typename Key, typename Value,
  576. WireFormatLite::FieldType kKeyFieldType,
  577. WireFormatLite::FieldType kValueFieldType>
  578. struct MapEntryToMapField<
  579. MapEntry<T, Key, Value, kKeyFieldType, kValueFieldType>> {
  580. typedef MapField<T, Key, Value, kKeyFieldType, kValueFieldType> MapFieldType;
  581. };
  582. class PROTOBUF_EXPORT DynamicMapField
  583. : public TypeDefinedMapFieldBase<MapKey, MapValueRef> {
  584. public:
  585. explicit DynamicMapField(const Message* default_entry);
  586. DynamicMapField(const Message* default_entry, Arena* arena);
  587. virtual ~DynamicMapField();
  588. // Implement MapFieldBase
  589. bool ContainsMapKey(const MapKey& map_key) const override;
  590. bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val) override;
  591. bool LookupMapValue(const MapKey& map_key,
  592. MapValueConstRef* val) const override;
  593. bool LookupMapValue(const MapKey&, MapValueRef*) const = delete;
  594. bool DeleteMapValue(const MapKey& map_key) override;
  595. void MergeFrom(const MapFieldBase& other) override;
  596. void Swap(MapFieldBase* other) override;
  597. void UnsafeShallowSwap(MapFieldBase* other) override { Swap(other); }
  598. const Map<MapKey, MapValueRef>& GetMap() const override;
  599. Map<MapKey, MapValueRef>* MutableMap() override;
  600. int size() const override;
  601. void Clear() override;
  602. private:
  603. Map<MapKey, MapValueRef> map_;
  604. const Message* default_entry_;
  605. void AllocateMapValue(MapValueRef* map_val);
  606. // Implements MapFieldBase
  607. void SyncRepeatedFieldWithMapNoLock() const override;
  608. void SyncMapWithRepeatedFieldNoLock() const override;
  609. size_t SpaceUsedExcludingSelfNoLock() const override;
  610. void SetMapIteratorValue(MapIterator* map_iter) const override;
  611. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMapField);
  612. };
  613. } // namespace internal
  614. // MapValueConstRef points to a map value. Users can NOT modify
  615. // the map value.
  616. class PROTOBUF_EXPORT MapValueConstRef {
  617. public:
  618. MapValueConstRef() : data_(nullptr), type_() {}
  619. int64_t GetInt64Value() const {
  620. TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64,
  621. "MapValueConstRef::GetInt64Value");
  622. return *reinterpret_cast<int64_t*>(data_);
  623. }
  624. uint64_t GetUInt64Value() const {
  625. TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64,
  626. "MapValueConstRef::GetUInt64Value");
  627. return *reinterpret_cast<uint64_t*>(data_);
  628. }
  629. int32_t GetInt32Value() const {
  630. TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32,
  631. "MapValueConstRef::GetInt32Value");
  632. return *reinterpret_cast<int32_t*>(data_);
  633. }
  634. uint32_t GetUInt32Value() const {
  635. TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32,
  636. "MapValueConstRef::GetUInt32Value");
  637. return *reinterpret_cast<uint32_t*>(data_);
  638. }
  639. bool GetBoolValue() const {
  640. TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, "MapValueConstRef::GetBoolValue");
  641. return *reinterpret_cast<bool*>(data_);
  642. }
  643. int GetEnumValue() const {
  644. TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM, "MapValueConstRef::GetEnumValue");
  645. return *reinterpret_cast<int*>(data_);
  646. }
  647. const std::string& GetStringValue() const {
  648. TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING,
  649. "MapValueConstRef::GetStringValue");
  650. return *reinterpret_cast<std::string*>(data_);
  651. }
  652. float GetFloatValue() const {
  653. TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT,
  654. "MapValueConstRef::GetFloatValue");
  655. return *reinterpret_cast<float*>(data_);
  656. }
  657. double GetDoubleValue() const {
  658. TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE,
  659. "MapValueConstRef::GetDoubleValue");
  660. return *reinterpret_cast<double*>(data_);
  661. }
  662. const Message& GetMessageValue() const {
  663. TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE,
  664. "MapValueConstRef::GetMessageValue");
  665. return *reinterpret_cast<Message*>(data_);
  666. }
  667. protected:
  668. // data_ point to a map value. MapValueConstRef does not
  669. // own this value.
  670. void* data_;
  671. // type_ is 0 or a valid FieldDescriptor::CppType.
  672. // Use "CppType()" to indicate zero.
  673. FieldDescriptor::CppType type_;
  674. FieldDescriptor::CppType type() const {
  675. if (type_ == FieldDescriptor::CppType() || data_ == nullptr) {
  676. GOOGLE_LOG(FATAL)
  677. << "Protocol Buffer map usage error:\n"
  678. << "MapValueConstRef::type MapValueConstRef is not initialized.";
  679. }
  680. return type_;
  681. }
  682. private:
  683. template <typename Derived, typename K, typename V,
  684. internal::WireFormatLite::FieldType key_wire_type,
  685. internal::WireFormatLite::FieldType value_wire_type>
  686. friend class internal::MapField;
  687. template <typename K, typename V>
  688. friend class internal::TypeDefinedMapFieldBase;
  689. friend class ::PROTOBUF_NAMESPACE_ID::MapIterator;
  690. friend class Reflection;
  691. friend class internal::DynamicMapField;
  692. void SetType(FieldDescriptor::CppType type) { type_ = type; }
  693. void SetValue(const void* val) { data_ = const_cast<void*>(val); }
  694. void CopyFrom(const MapValueConstRef& other) {
  695. type_ = other.type_;
  696. data_ = other.data_;
  697. }
  698. };
  699. // MapValueRef points to a map value. Users are able to modify
  700. // the map value.
  701. class PROTOBUF_EXPORT MapValueRef final : public MapValueConstRef {
  702. public:
  703. MapValueRef() {}
  704. void SetInt64Value(int64_t value) {
  705. TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, "MapValueRef::SetInt64Value");
  706. *reinterpret_cast<int64_t*>(data_) = value;
  707. }
  708. void SetUInt64Value(uint64_t value) {
  709. TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, "MapValueRef::SetUInt64Value");
  710. *reinterpret_cast<uint64_t*>(data_) = value;
  711. }
  712. void SetInt32Value(int32_t value) {
  713. TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, "MapValueRef::SetInt32Value");
  714. *reinterpret_cast<int32_t*>(data_) = value;
  715. }
  716. void SetUInt32Value(uint32_t value) {
  717. TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, "MapValueRef::SetUInt32Value");
  718. *reinterpret_cast<uint32_t*>(data_) = value;
  719. }
  720. void SetBoolValue(bool value) {
  721. TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, "MapValueRef::SetBoolValue");
  722. *reinterpret_cast<bool*>(data_) = value;
  723. }
  724. // TODO(jieluo) - Checks that enum is member.
  725. void SetEnumValue(int value) {
  726. TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM, "MapValueRef::SetEnumValue");
  727. *reinterpret_cast<int*>(data_) = value;
  728. }
  729. void SetStringValue(const std::string& value) {
  730. TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING, "MapValueRef::SetStringValue");
  731. *reinterpret_cast<std::string*>(data_) = value;
  732. }
  733. void SetFloatValue(float value) {
  734. TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT, "MapValueRef::SetFloatValue");
  735. *reinterpret_cast<float*>(data_) = value;
  736. }
  737. void SetDoubleValue(double value) {
  738. TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE, "MapValueRef::SetDoubleValue");
  739. *reinterpret_cast<double*>(data_) = value;
  740. }
  741. Message* MutableMessageValue() {
  742. TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE,
  743. "MapValueRef::MutableMessageValue");
  744. return reinterpret_cast<Message*>(data_);
  745. }
  746. private:
  747. friend class internal::DynamicMapField;
  748. // Only used in DynamicMapField
  749. void DeleteData() {
  750. switch (type_) {
  751. #define HANDLE_TYPE(CPPTYPE, TYPE) \
  752. case FieldDescriptor::CPPTYPE_##CPPTYPE: { \
  753. delete reinterpret_cast<TYPE*>(data_); \
  754. break; \
  755. }
  756. HANDLE_TYPE(INT32, int32_t);
  757. HANDLE_TYPE(INT64, int64_t);
  758. HANDLE_TYPE(UINT32, uint32_t);
  759. HANDLE_TYPE(UINT64, uint64_t);
  760. HANDLE_TYPE(DOUBLE, double);
  761. HANDLE_TYPE(FLOAT, float);
  762. HANDLE_TYPE(BOOL, bool);
  763. HANDLE_TYPE(STRING, std::string);
  764. HANDLE_TYPE(ENUM, int32_t);
  765. HANDLE_TYPE(MESSAGE, Message);
  766. #undef HANDLE_TYPE
  767. }
  768. }
  769. };
  770. #undef TYPE_CHECK
  771. class PROTOBUF_EXPORT MapIterator {
  772. public:
  773. MapIterator(Message* message, const FieldDescriptor* field) {
  774. const Reflection* reflection = message->GetReflection();
  775. map_ = reflection->MutableMapData(message, field);
  776. key_.SetType(field->message_type()->map_key()->cpp_type());
  777. value_.SetType(field->message_type()->map_value()->cpp_type());
  778. map_->InitializeIterator(this);
  779. }
  780. MapIterator(const MapIterator& other) {
  781. map_ = other.map_;
  782. map_->InitializeIterator(this);
  783. map_->CopyIterator(this, other);
  784. }
  785. ~MapIterator() { map_->DeleteIterator(this); }
  786. MapIterator& operator=(const MapIterator& other) {
  787. map_ = other.map_;
  788. map_->CopyIterator(this, other);
  789. return *this;
  790. }
  791. friend bool operator==(const MapIterator& a, const MapIterator& b) {
  792. return a.map_->EqualIterator(a, b);
  793. }
  794. friend bool operator!=(const MapIterator& a, const MapIterator& b) {
  795. return !a.map_->EqualIterator(a, b);
  796. }
  797. MapIterator& operator++() {
  798. map_->IncreaseIterator(this);
  799. return *this;
  800. }
  801. MapIterator operator++(int) {
  802. // iter_ is copied from Map<...>::iterator, no need to
  803. // copy from its self again. Use the same implementation
  804. // with operator++()
  805. map_->IncreaseIterator(this);
  806. return *this;
  807. }
  808. const MapKey& GetKey() { return key_; }
  809. const MapValueRef& GetValueRef() { return value_; }
  810. MapValueRef* MutableValueRef() {
  811. map_->SetMapDirty();
  812. return &value_;
  813. }
  814. private:
  815. template <typename Key, typename T>
  816. friend class internal::TypeDefinedMapFieldBase;
  817. friend class internal::DynamicMapField;
  818. template <typename Derived, typename Key, typename T,
  819. internal::WireFormatLite::FieldType kKeyFieldType,
  820. internal::WireFormatLite::FieldType kValueFieldType>
  821. friend class internal::MapField;
  822. // reinterpret_cast from heap-allocated Map<...>::iterator*. MapIterator owns
  823. // the iterator. It is allocated by MapField<...>::InitializeIterator() called
  824. // in constructor and deleted by MapField<...>::DeleteIterator() called in
  825. // destructor.
  826. void* iter_;
  827. // Point to a MapField to call helper methods implemented in MapField.
  828. // MapIterator does not own this object.
  829. internal::MapFieldBase* map_;
  830. MapKey key_;
  831. MapValueRef value_;
  832. };
  833. } // namespace protobuf
  834. } // namespace google
  835. #ifdef _MSC_VER
  836. #pragma warning(pop) // restore warning C4265
  837. #endif // _MSC_VER
  838. #include <google/protobuf/port_undef.inc>
  839. #endif // GOOGLE_PROTOBUF_MAP_FIELD_H__