• 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_ENTRY_H__
32 #define GOOGLE_PROTOBUF_MAP_ENTRY_H__
33 
34 #include <google/protobuf/generated_message_reflection.h>
35 #include <google/protobuf/map_entry_lite.h>
36 #include <google/protobuf/map_type_handler.h>
37 #include <google/protobuf/metadata.h>
38 #include <google/protobuf/reflection_ops.h>
39 #include <google/protobuf/unknown_field_set.h>
40 #include <google/protobuf/wire_format_lite_inl.h>
41 
42 namespace google {
43 namespace protobuf {
44 class Arena;
45 namespace internal {
46 template <typename Key, typename Value,
47           WireFormatLite::FieldType kKeyFieldType,
48           WireFormatLite::FieldType kValueFieldType,
49           int default_enum_value>
50 class MapField;
51 }
52 }
53 
54 namespace protobuf {
55 namespace internal {
56 
57 // Register all MapEntry default instances so we can delete them in
58 // ShutdownProtobufLibrary().
59 void LIBPROTOBUF_EXPORT RegisterMapEntryDefaultInstance(
60     MessageLite* default_instance);
61 
62 // This is the common base class for MapEntry. It is used by MapFieldBase in
63 // reflection api, in which the static type of key and value is unknown.
64 class LIBPROTOBUF_EXPORT MapEntryBase : public Message {
65  public:
GetMetadata()66   ::google::protobuf::Metadata GetMetadata() const {
67     ::google::protobuf::Metadata metadata;
68     metadata.descriptor = descriptor_;
69     metadata.reflection = reflection_;
70     return metadata;
71   }
72 
73  protected:
MapEntryBase()74   MapEntryBase() : descriptor_(NULL), reflection_(NULL) {  }
~MapEntryBase()75   virtual ~MapEntryBase() {}
76 
77   const Descriptor* descriptor_;
78   const Reflection* reflection_;
79 };
80 
81 // MapEntry is the returned google::protobuf::Message when calling AddMessage of
82 // google::protobuf::Reflection. In order to let it work with generated message
83 // reflection, its in-memory type is the same as generated message with the same
84 // fields. However, in order to decide the in-memory type of key/value, we need
85 // to know both their cpp type in generated api and proto type. In
86 // implementation, all in-memory types have related wire format functions to
87 // support except ArenaStringPtr. Therefore, we need to define another type with
88 // supporting wire format functions. Since this type is only used as return type
89 // of MapEntry accessors, it's named MapEntry accessor type.
90 //
91 // cpp type:               the type visible to users in public API.
92 // proto type:             WireFormatLite::FieldType of the field.
93 // in-memory type:         type of the data member used to stored this field.
94 // MapEntry accessor type: type used in MapEntry getters/mutators to access the
95 //                         field.
96 //
97 // cpp type | proto type  | in-memory type | MapEntry accessor type
98 // int32      TYPE_INT32    int32            int32
99 // int32      TYPE_FIXED32  int32            int32
100 // string     TYPE_STRING   ArenaStringPtr   string
101 // FooEnum    TYPE_ENUM     int              int
102 // FooMessage TYPE_MESSAGE  FooMessage*      FooMessage
103 //
104 // The in-memory types of primitive types can be inferred from its proto type,
105 // while we need to explicitly specify the cpp type if proto type is
106 // TYPE_MESSAGE to infer the in-memory type.  Moreover, default_enum_value is
107 // used to initialize enum field in proto2.
108 template <typename Key, typename Value,
109           WireFormatLite::FieldType kKeyFieldType,
110           WireFormatLite::FieldType kValueFieldType,
111           int default_enum_value>
112 class MapEntry : public MapEntryBase {
113   // Provide utilities to parse/serialize key/value.  Provide utilities to
114   // manipulate internal stored type.
115   typedef MapTypeHandler<kKeyFieldType, Key> KeyTypeHandler;
116   typedef MapTypeHandler<kValueFieldType, Value> ValueTypeHandler;
117 
118   // Enum type cannot be used for MapTypeHandler::Read. Define a type
119   // which will replace Enum with int.
120   typedef typename KeyTypeHandler::MapEntryAccessorType KeyMapEntryAccessorType;
121   typedef typename ValueTypeHandler::MapEntryAccessorType
122       ValueMapEntryAccessorType;
123 
124   // Abbreviation for MapEntry
125   typedef typename google::protobuf::internal::MapEntry<
126       Key, Value, kKeyFieldType, kValueFieldType, default_enum_value> EntryType;
127 
128   // Abbreviation for MapEntryLite
129   typedef typename google::protobuf::internal::MapEntryLite<
130       Key, Value, kKeyFieldType, kValueFieldType, default_enum_value>
131       EntryLiteType;
132 
133  public:
~MapEntry()134   ~MapEntry() {
135     if (this == default_instance_) {
136       delete reflection_;
137     }
138   }
139 
140   // accessors ======================================================
141 
key()142   virtual inline const KeyMapEntryAccessorType& key() const {
143     return entry_lite_.key();
144   }
mutable_key()145   inline KeyMapEntryAccessorType* mutable_key() {
146     return entry_lite_.mutable_key();
147   }
value()148   virtual inline const ValueMapEntryAccessorType& value() const {
149     return entry_lite_.value();
150   }
mutable_value()151   inline ValueMapEntryAccessorType* mutable_value() {
152     return entry_lite_.mutable_value();
153   }
154 
155   // implements Message =============================================
156 
MergePartialFromCodedStream(::google::protobuf::io::CodedInputStream * input)157   bool MergePartialFromCodedStream(::google::protobuf::io::CodedInputStream* input) {
158     return entry_lite_.MergePartialFromCodedStream(input);
159   }
160 
ByteSize()161   int ByteSize() const {
162     return entry_lite_.ByteSize();
163   }
164 
SerializeWithCachedSizes(::google::protobuf::io::CodedOutputStream * output)165   void SerializeWithCachedSizes(::google::protobuf::io::CodedOutputStream* output) const {
166     entry_lite_.SerializeWithCachedSizes(output);
167   }
168 
InternalSerializeWithCachedSizesToArray(bool deterministic,::google::protobuf::uint8 * output)169   ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(bool deterministic,
170                                                    ::google::protobuf::uint8* output) const {
171     return entry_lite_.InternalSerializeWithCachedSizesToArray(deterministic,
172                                                                output);
173   }
174 
GetCachedSize()175   int GetCachedSize() const {
176     return entry_lite_.GetCachedSize();
177   }
178 
IsInitialized()179   bool IsInitialized() const {
180     return entry_lite_.IsInitialized();
181   }
182 
New()183   Message* New() const {
184     MapEntry* entry = new MapEntry;
185     entry->descriptor_ = descriptor_;
186     entry->reflection_ = reflection_;
187     entry->set_default_instance(default_instance_);
188     return entry;
189   }
190 
New(Arena * arena)191   Message* New(Arena* arena) const {
192     MapEntry* entry = Arena::CreateMessage<MapEntry>(arena);
193     entry->descriptor_ = descriptor_;
194     entry->reflection_ = reflection_;
195     entry->set_default_instance(default_instance_);
196     return entry;
197   }
198 
SpaceUsed()199   int SpaceUsed() const {
200     int size = sizeof(MapEntry);
201     size += entry_lite_.SpaceUsed();
202     return size;
203   }
204 
CopyFrom(const::google::protobuf::Message & from)205   void CopyFrom(const ::google::protobuf::Message& from) {
206     Clear();
207     MergeFrom(from);
208   }
209 
MergeFrom(const::google::protobuf::Message & from)210   void MergeFrom(const ::google::protobuf::Message& from) {
211     GOOGLE_CHECK_NE(&from, this);
212     const MapEntry* source = dynamic_cast_if_available<const MapEntry*>(&from);
213     if (source == NULL) {
214       ReflectionOps::Merge(from, this);
215     } else {
216       MergeFrom(*source);
217     }
218   }
219 
CopyFrom(const MapEntry & from)220   void CopyFrom(const MapEntry& from) {
221     Clear();
222     MergeFrom(from);
223   }
224 
MergeFrom(const MapEntry & from)225   void MergeFrom(const MapEntry& from) {
226     entry_lite_.MergeFrom(from.entry_lite_);
227   }
228 
Clear()229   void Clear() {
230     entry_lite_.Clear();
231   }
232 
InitAsDefaultInstance()233   void InitAsDefaultInstance() {
234     entry_lite_.InitAsDefaultInstance();
235   }
236 
GetArena()237   Arena* GetArena() const {
238     return entry_lite_.GetArena();
239   }
240 
241   // Create default MapEntry instance for given descriptor. Descriptor has to be
242   // given when creating default MapEntry instance because different map field
243   // may have the same type and MapEntry class. The given descriptor is needed
244   // to distinguish instances of the same MapEntry class.
CreateDefaultInstance(const Descriptor * descriptor)245   static MapEntry* CreateDefaultInstance(const Descriptor* descriptor) {
246     MapEntry* entry = new MapEntry;
247     const Reflection* reflection = new GeneratedMessageReflection(
248         descriptor, entry, offsets_,
249         GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, entry_lite_._has_bits_),
250         GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, _unknown_fields_), -1,
251         DescriptorPool::generated_pool(),
252         ::google::protobuf::MessageFactory::generated_factory(),
253         sizeof(MapEntry),
254         GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, _internal_metadata_));
255     entry->descriptor_ = descriptor;
256     entry->reflection_ = reflection;
257     entry->set_default_instance(entry);
258     entry->InitAsDefaultInstance();
259     RegisterMapEntryDefaultInstance(entry);
260     return entry;
261   }
262 
263  private:
MapEntry()264   MapEntry()
265       : _internal_metadata_(NULL), default_instance_(NULL), entry_lite_() {}
266 
MapEntry(Arena * arena)267   explicit MapEntry(Arena* arena)
268       : _internal_metadata_(arena),
269         default_instance_(NULL),
270         entry_lite_(arena) {}
271 
GetArenaNoVirtual()272   inline Arena* GetArenaNoVirtual() const {
273     return entry_lite_.GetArenaNoVirtual();
274   }
275 
set_default_instance(MapEntry * default_instance)276   void set_default_instance(MapEntry* default_instance) {
277     default_instance_ = default_instance;
278     entry_lite_.set_default_instance(&default_instance->entry_lite_);
279   }
280 
281   static int offsets_[2];
282   UnknownFieldSet _unknown_fields_;
283   InternalMetadataWithArena _internal_metadata_;
284   MapEntry* default_instance_;
285   EntryLiteType entry_lite_;
286 
287   friend class ::google::protobuf::Arena;
288   typedef void InternalArenaConstructable_;
289   typedef void DestructorSkippable_;
290   template <typename K, typename V, WireFormatLite::FieldType k_wire_type,
291             WireFormatLite::FieldType, int default_enum>
292   friend class internal::MapField;
293   friend class internal::GeneratedMessageReflection;
294 
295   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntry);
296 };
297 
298 template <typename Key, typename Value, WireFormatLite::FieldType kKeyFieldType,
299           WireFormatLite::FieldType kValueFieldType, int default_enum_value>
300 int MapEntry<Key, Value, kKeyFieldType, kValueFieldType,
301              default_enum_value>::offsets_[2] = {
302     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, entry_lite_.key_),
303     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, entry_lite_.value_),
304 };
305 
306 }  // namespace internal
307 }  // namespace protobuf
308 
309 }  // namespace google
310 #endif  // GOOGLE_PROTOBUF_MAP_ENTRY_H__
311