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