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