webkit  2cdf99a9e3038c7e01b3c37e8ad903ecbe5eecf1
https://github.com/WebKit/webkit
map_field.h
Go to the documentation of this file.
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 
38 #include <google/protobuf/arena.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.
61  public:
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 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;
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 
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.
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;
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:
188  explicit TypeDefinedMapFieldBase(Arena* arena) : MapFieldBase(arena) {}
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 accesss 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.
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:
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 
328  public:
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  }
336  MapIterator(const MapIterator& other) {
337  map_ = other.map_;
338  map_->InitializeIterator(this);
339  map_->CopyIterator(this, other);
340  }
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  }
351  map_->IncreaseIterator(this);
352  return *this;
353  }
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  }
361  const MapKey& GetKey() {
362  return key_;
363  }
365  return value_;
366  }
368  map_->SetMapDirty();
369  return &value_;
370  }
371 
372  private:
373  template <typename Key, typename T>
376  template <typename Key, typename T,
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.
390  MapKey key_;
391  MapValueRef value_;
392 };
393 
394 } // namespace protobuf
395 
396 } // namespace google
397 #endif // GOOGLE_PROTOBUF_MAP_FIELD_H__
Mutex mutex_
Definition: map_field.h:148
friend bool operator==(const MapIterator &a, const MapIterator &b)
Definition: map_field.h:344
TypeDefinedMapFieldBase(Arena *arena)
Definition: map_field.h:188
FieldType
Definition: wire_format_lite.h:96
#define size
Definition: float-mm.c:27
Definition: mutex.h:48
Definition: message.h:179
Definition: reflection_internal.h:205
const FieldDescriptor * field
Definition: parser_unittest.cc:2279
Definition: map_field.h:60
Definition: message.h:401
virtual bool EqualIterator(const MapIterator &a, const MapIterator &b) const =0
~TypeDefinedMapFieldBase()
Definition: map_field.h:189
MapIterator & operator++()
Definition: map_field.h:350
AVCFAssetRef CFArrayRef AVCFAssetLoadValuesCompletionCallback callback
Definition: AVFoundationCFSoftLinking.h:99
const Descriptor * descriptor
Definition: descriptor.cc:271
~MapIterator()
Definition: map_field.h:341
Definition: map.h:57
MapFieldBase()
Definition: map_field.h:62
Definition: command_line_interface.h:56
Definition: descriptor.h:172
volatile Atomic32 state_
Definition: map_field.h:150
virtual const Reflection * GetReflection() const
Definition: message.h:331
State
Definition: map_field.h:130
MapIterator(const MapIterator &other)
Definition: map_field.h:336
Definition: descriptor.h:439
void
Definition: AVFoundationCFSoftLinking.h:81
std::unique_ptr< TrackMediaInfoMap > map_
Definition: trackmediainfomap_unittest.cc:171
Definition: generated_message_reflection.h:100
TypeDefinedMapFieldBase()
Definition: map_field.h:187
Definition: map_type_handler.h:45
Definition: map.h:97
GOOGLE_ATTRIBUTE_NOINLINE void OwnDestructor(T *object)
Definition: arena.h:479
MapFieldBase(Arena *arena)
Definition: map_field.h:68
Definition: map.h:297
Definition: __init__.py:1
Definition: map_type_handler.h:138
GLboolean GLboolean GLboolean GLboolean a
Definition: gl2ext.h:306
MapIterator operator++(int)
Definition: map_field.h:354
Definition: arena.h:218
Definition: document.h:393
#define EntryType
Definition: map_field_lite.h:220
Definition: repeated_field.h:369
const MapValueRef & GetValueRef()
Definition: map_field.h:364
const FieldDescriptor * FindFieldByName(const string &name) const
Definition: descriptor.cc:1357
#define NULL
Definition: common_types.h:41
Key
Definition: keyboard.h:10
RepeatedPtrField< Message > * repeated_field_
Definition: map_field.h:139
#define LIBPROTOBUF_EXPORT
Definition: port.h:97
MapValueRef * MutableValueRef()
Definition: map_field.h:367
GLboolean GLboolean GLboolean b
Definition: gl2ext.h:306
Arena * arena_
Definition: map_field.h:138
Definition: gflags_completions.h:115
MapIterator(Message *message, const FieldDescriptor *field)
Definition: map_field.h:329
friend bool operator!=(const MapIterator &a, const MapIterator &b)
Definition: map_field.h:347
int32 Atomic32
Definition: atomicops.h:75
Definition: map_entry.h:112
const MapKey & GetKey()
Definition: map_field.h:361
GLuint GLsizei const GLchar * message
Definition: gl2ext.h:137
Definition: map_field.h:327
const Descriptor * message_type() const
GLuint GLsizei GLsizei GLfloat * val
Definition: gl2ext.h:3301
const Descriptor ** entry_descriptor_
Definition: map_field.h:145
MergeFrom
Definition: python_message.py:1259
#define T(a)
Definition: row_common.cc:1964
virtual void SyncMapWithRepeatedFieldNoLock() const
Definition: map_field.h:116
Definition: map_entry_lite.h:63