• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
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 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.
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