map_field.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  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 <google/protobuf/stubs/atomicops.h>
  33. #include <google/protobuf/stubs/mutex.h>
  34. #include <google/protobuf/stubs/common.h>
  35. #include <google/protobuf/generated_message_reflection.h>
  36. #include <google/protobuf/arena.h>
  37. #include <google/protobuf/map_entry.h>
  38. #include <google/protobuf/map_field_lite.h>
  39. #include <google/protobuf/map_type_handler.h>
  40. #include <google/protobuf/message.h>
  41. #include <google/protobuf/repeated_field.h>
  42. #include <google/protobuf/unknown_field_set.h>
  43. namespace google {
  44. namespace protobuf {
  45. class DynamicMessage;
  46. class MapKey;
  47. namespace internal {
  48. class ContendedMapCleanTest;
  49. class GeneratedMessageReflection;
  50. class MapFieldAccessor;
  51. // This class provides accesss to map field using reflection, which is the same
  52. // as those provided for RepeatedPtrField<Message>. It is used for internal
  53. // reflection implentation only. Users should never use this directly.
  54. class LIBPROTOBUF_EXPORT MapFieldBase {
  55. public:
  56. MapFieldBase()
  57. : arena_(NULL),
  58. repeated_field_(NULL),
  59. entry_descriptor_(NULL),
  60. assign_descriptor_callback_(NULL),
  61. state_(STATE_MODIFIED_MAP) {}
  62. explicit MapFieldBase(Arena* arena)
  63. : arena_(arena),
  64. repeated_field_(NULL),
  65. entry_descriptor_(NULL),
  66. assign_descriptor_callback_(NULL),
  67. state_(STATE_MODIFIED_MAP) {
  68. // Mutex's destructor needs to be called explicitly to release resources
  69. // acquired in its constructor.
  70. arena->OwnDestructor(&mutex_);
  71. }
  72. virtual ~MapFieldBase();
  73. // Returns reference to internal repeated field. Data written using
  74. // google::protobuf::Map's api prior to calling this function is guarantted to be
  75. // included in repeated field.
  76. const RepeatedPtrFieldBase& GetRepeatedField() const;
  77. // Like above. Returns mutable pointer to the internal repeated field.
  78. RepeatedPtrFieldBase* MutableRepeatedField();
  79. // Pure virtual map APIs for Map Reflection.
  80. virtual bool ContainsMapKey(const MapKey& map_key) const = 0;
  81. virtual bool InsertMapValue(const MapKey& map_key, MapValueRef* val) = 0;
  82. virtual bool DeleteMapValue(const MapKey& map_key) = 0;
  83. virtual bool EqualIterator(const MapIterator& a,
  84. const MapIterator& b) const = 0;
  85. virtual void MapBegin(MapIterator* map_iter) const = 0;
  86. virtual void MapEnd(MapIterator* map_iter) const = 0;
  87. // Sync Map with repeated field and returns the size of map.
  88. virtual int size() const = 0;
  89. // Returns the number of bytes used by the repeated field, excluding
  90. // sizeof(*this)
  91. int SpaceUsedExcludingSelf() const;
  92. protected:
  93. // Gets the size of space used by map field.
  94. virtual int SpaceUsedExcludingSelfNoLock() const;
  95. // Synchronizes the content in Map to RepeatedPtrField if there is any change
  96. // to Map after last synchronization.
  97. void SyncRepeatedFieldWithMap() const;
  98. virtual void SyncRepeatedFieldWithMapNoLock() const;
  99. // Synchronizes the content in RepeatedPtrField to Map if there is any change
  100. // to RepeatedPtrField after last synchronization.
  101. void SyncMapWithRepeatedField() const;
  102. virtual void SyncMapWithRepeatedFieldNoLock() const {}
  103. // Tells MapFieldBase that there is new change to Map.
  104. void SetMapDirty();
  105. // Tells MapFieldBase that there is new change to RepeatedPTrField.
  106. void SetRepeatedDirty();
  107. // Provides derived class the access to repeated field.
  108. void* MutableRepeatedPtrField() const;
  109. // Creates descriptor for only one time.
  110. void InitMetadataOnce() const;
  111. enum State {
  112. STATE_MODIFIED_MAP = 0, // map has newly added data that has not been
  113. // synchronized to repeated field
  114. STATE_MODIFIED_REPEATED = 1, // repeated field has newly added data that
  115. // has not been synchronized to map
  116. CLEAN = 2, // data in map and repeated field are same
  117. };
  118. Arena* arena_;
  119. mutable RepeatedPtrField<Message>* repeated_field_;
  120. // MapEntry can only be created from MapField. To create MapEntry, MapField
  121. // needs to know its descriptor, because MapEntry is not generated class which
  122. // cannot initialize its own descriptor by calling generated
  123. // descriptor-assign-function. Thus, we need to register a callback to
  124. // initialize MapEntry's descriptor.
  125. const Descriptor** entry_descriptor_;
  126. void (*assign_descriptor_callback_)();
  127. mutable Mutex mutex_; // The thread to synchronize map and repeated field
  128. // needs to get lock first;
  129. mutable volatile Atomic32 state_; // 0: STATE_MODIFIED_MAP
  130. // 1: STATE_MODIFIED_REPEATED
  131. // 2: CLEAN
  132. private:
  133. friend class ContendedMapCleanTest;
  134. friend class GeneratedMessageReflection;
  135. friend class MapFieldAccessor;
  136. friend class ::google::protobuf::DynamicMessage;
  137. // Virtual helper methods for MapIterator. MapIterator doesn't have the
  138. // type helper for key and value. Call these help methods to deal with
  139. // different types. Real helper methods are implemented in
  140. // TypeDefinedMapFieldBase.
  141. friend class ::google::protobuf::MapIterator;
  142. // Allocate map<...>::iterator for MapIterator.
  143. virtual void InitializeIterator(MapIterator* map_iter) const = 0;
  144. // DeleteIterator() is called by the destructor of MapIterator only.
  145. // It deletes map<...>::iterator for MapIterator.
  146. virtual void DeleteIterator(MapIterator* map_iter) const = 0;
  147. // Copy the map<...>::iterator from other_iterator to
  148. // this_iterator.
  149. virtual void CopyIterator(MapIterator* this_iterator,
  150. const MapIterator& other_iterator) const = 0;
  151. // IncreaseIterator() is called by operator++() of MapIterator only.
  152. // It implements the ++ operator of MapIterator.
  153. virtual void IncreaseIterator(MapIterator* map_iter) const = 0;
  154. };
  155. // This class provides common Map Reflection implementations for generated
  156. // message and dynamic message.
  157. template<typename Key, typename T>
  158. class TypeDefinedMapFieldBase : public MapFieldBase {
  159. public:
  160. TypeDefinedMapFieldBase() {}
  161. explicit TypeDefinedMapFieldBase(Arena* arena) : MapFieldBase(arena) {}
  162. ~TypeDefinedMapFieldBase() {}
  163. void MapBegin(MapIterator* map_iter) const;
  164. void MapEnd(MapIterator* map_iter) const;
  165. bool EqualIterator(const MapIterator& a, const MapIterator& b) const;
  166. virtual const Map<Key, T>& GetMap() const = 0;
  167. virtual Map<Key, T>* MutableMap() = 0;
  168. protected:
  169. typename Map<Key, T>::const_iterator& InternalGetIterator(
  170. const MapIterator* map_iter) const;
  171. private:
  172. void InitializeIterator(MapIterator* map_iter) const;
  173. void DeleteIterator(MapIterator* map_iter) const;
  174. void CopyIterator(MapIterator* this_iteratorm,
  175. const MapIterator& that_iterator) const;
  176. void IncreaseIterator(MapIterator* map_iter) const;
  177. virtual void SetMapIteratorValue(MapIterator* map_iter) const = 0;
  178. };
  179. // This class provides accesss to map field using generated api. It is used for
  180. // internal generated message implentation only. Users should never use this
  181. // directly.
  182. template <typename Key, typename T,
  183. WireFormatLite::FieldType kKeyFieldType,
  184. WireFormatLite::FieldType kValueFieldType,
  185. int default_enum_value = 0>
  186. class MapField : public TypeDefinedMapFieldBase<Key, T>,
  187. public MapFieldLite<Key, T, kKeyFieldType, kValueFieldType,
  188. default_enum_value> {
  189. // Provide utilities to parse/serialize key/value. Provide utilities to
  190. // manipulate internal stored type.
  191. typedef MapTypeHandler<kKeyFieldType, Key> KeyTypeHandler;
  192. typedef MapTypeHandler<kValueFieldType, T> ValueTypeHandler;
  193. // Define message type for internal repeated field.
  194. typedef MapEntry<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>
  195. EntryType;
  196. typedef MapEntryLite<Key, T, kKeyFieldType, kValueFieldType,
  197. default_enum_value> EntryLiteType;
  198. // Define abbreviation for parent MapFieldLite
  199. typedef MapFieldLite<Key, T, kKeyFieldType, kValueFieldType,
  200. default_enum_value> MapFieldLiteType;
  201. // Enum needs to be handled differently from other types because it has
  202. // different exposed type in google::protobuf::Map's api and repeated field's api. For
  203. // details see the comment in the implementation of
  204. // SyncMapWithRepeatedFieldNoLock.
  205. static const bool kIsValueEnum = ValueTypeHandler::kIsEnum;
  206. typedef typename MapIf<kIsValueEnum, T, const T&>::type CastValueType;
  207. public:
  208. MapField();
  209. explicit MapField(Arena* arena);
  210. // MapField doesn't own the default_entry, which means default_entry must
  211. // outlive the lifetime of MapField.
  212. MapField(const Message* default_entry);
  213. // For tests only.
  214. MapField(Arena* arena, const Message* default_entry);
  215. ~MapField();
  216. // Implement MapFieldBase
  217. bool ContainsMapKey(const MapKey& map_key) const;
  218. bool InsertMapValue(const MapKey& map_key, MapValueRef* val);
  219. bool DeleteMapValue(const MapKey& map_key);
  220. // Accessors
  221. const Map<Key, T>& GetMap() const;
  222. Map<Key, T>* MutableMap();
  223. // Convenient methods for generated message implementation.
  224. int size() const;
  225. void Clear();
  226. void MergeFrom(const MapFieldLiteType& other);
  227. void Swap(MapFieldLiteType* other);
  228. // Allocates metadata only if this MapField is part of a generated message.
  229. void SetEntryDescriptor(const Descriptor** descriptor);
  230. void SetAssignDescriptorCallback(void (*callback)());
  231. private:
  232. typedef void InternalArenaConstructable_;
  233. typedef void DestructorSkippable_;
  234. // MapField needs MapEntry's default instance to create new MapEntry.
  235. void InitDefaultEntryOnce() const;
  236. // Manually set default entry instance. For test only.
  237. void SetDefaultEntryOnce(const EntryType* default_entry) const;
  238. // Convenient methods to get internal google::protobuf::Map
  239. const Map<Key, T>& GetInternalMap() const;
  240. Map<Key, T>* MutableInternalMap();
  241. // Implements MapFieldBase
  242. void SyncRepeatedFieldWithMapNoLock() const;
  243. void SyncMapWithRepeatedFieldNoLock() const;
  244. int SpaceUsedExcludingSelfNoLock() const;
  245. void SetMapIteratorValue(MapIterator* map_iter) const;
  246. mutable const EntryType* default_entry_;
  247. friend class ::google::protobuf::Arena;
  248. };
  249. class LIBPROTOBUF_EXPORT DynamicMapField: public TypeDefinedMapFieldBase<MapKey, MapValueRef> {
  250. public:
  251. explicit DynamicMapField(const Message* default_entry);
  252. DynamicMapField(const Message* default_entry, Arena* arena);
  253. ~DynamicMapField();
  254. // Implement MapFieldBase
  255. bool ContainsMapKey(const MapKey& map_key) const;
  256. bool InsertMapValue(const MapKey& map_key, MapValueRef* val);
  257. bool DeleteMapValue(const MapKey& map_key);
  258. const Map<MapKey, MapValueRef>& GetMap() const;
  259. Map<MapKey, MapValueRef>* MutableMap();
  260. int size() const;
  261. private:
  262. Map<MapKey, MapValueRef> map_;
  263. const Message* default_entry_;
  264. // Implements MapFieldBase
  265. void SyncRepeatedFieldWithMapNoLock() const;
  266. void SyncMapWithRepeatedFieldNoLock() const;
  267. int SpaceUsedExcludingSelfNoLock() const;
  268. void SetMapIteratorValue(MapIterator* map_iter) const;
  269. };
  270. } // namespace internal
  271. class LIBPROTOBUF_EXPORT MapIterator {
  272. public:
  273. MapIterator(Message* message, const FieldDescriptor* field) {
  274. const Reflection* reflection = message->GetReflection();
  275. map_ = reflection->MapData(message, field);
  276. key_.SetType(field->message_type()->FindFieldByName("key")->cpp_type());
  277. value_.SetType(field->message_type()->FindFieldByName("value")->cpp_type());
  278. map_->InitializeIterator(this);
  279. }
  280. MapIterator(const MapIterator& other) {
  281. map_ = other.map_;
  282. map_->InitializeIterator(this);
  283. map_->CopyIterator(this, other);
  284. }
  285. ~MapIterator() {
  286. map_->DeleteIterator(this);
  287. }
  288. friend bool operator==(const MapIterator& a, const MapIterator& b) {
  289. return a.map_->EqualIterator(a, b);
  290. }
  291. friend bool operator!=(const MapIterator& a, const MapIterator& b) {
  292. return !a.map_->EqualIterator(a, b);
  293. }
  294. MapIterator& operator++() {
  295. map_->IncreaseIterator(this);
  296. return *this;
  297. }
  298. MapIterator operator++(int) {
  299. // iter_ is copied from Map<...>::iterator, no need to
  300. // copy from its self again. Use the same implementation
  301. // with operator++()
  302. map_->IncreaseIterator(this);
  303. return *this;
  304. }
  305. const MapKey& GetKey() {
  306. return key_;
  307. }
  308. const MapValueRef& GetValueRef() {
  309. return value_;
  310. }
  311. MapValueRef* MutableValueRef() {
  312. map_->SetMapDirty();
  313. return &value_;
  314. }
  315. private:
  316. template <typename Key, typename T>
  317. friend class internal::TypeDefinedMapFieldBase;
  318. friend class internal::DynamicMapField;
  319. template <typename Key, typename T,
  320. internal::WireFormatLite::FieldType kKeyFieldType,
  321. internal::WireFormatLite::FieldType kValueFieldType,
  322. int default_enum_value>
  323. friend class internal::MapField;
  324. // reinterpret_cast from heap-allocated Map<...>::iterator*. MapIterator owns
  325. // the iterator. It is allocated by MapField<...>::InitializeIterator() called
  326. // in constructor and deleted by MapField<...>::DeleteIterator() called in
  327. // destructor.
  328. void* iter_;
  329. // Point to a MapField to call helper methods implemented in MapField.
  330. // MapIterator does not own this object.
  331. internal::MapFieldBase* map_;
  332. MapKey key_;
  333. MapValueRef value_;
  334. };
  335. } // namespace protobuf
  336. } // namespace google
  337. #endif // GOOGLE_PROTOBUF_MAP_FIELD_H__