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