Line data Source code
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:
66 0 : ::google::protobuf::Metadata GetMetadata() const {
67 : ::google::protobuf::Metadata metadata;
68 0 : metadata.descriptor = descriptor_;
69 0 : metadata.reflection = reflection_;
70 0 : return metadata;
71 : }
72 :
73 : protected:
74 : MapEntryBase() : descriptor_(NULL), reflection_(NULL) { }
75 0 : 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 : // implmentation, 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:
134 : ~MapEntry() {
135 : if (this == default_instance_) {
136 : delete reflection_;
137 : }
138 : }
139 :
140 : // accessors ======================================================
141 :
142 : virtual inline const KeyMapEntryAccessorType& key() const {
143 : return entry_lite_.key();
144 : }
145 : inline KeyMapEntryAccessorType* mutable_key() {
146 : return entry_lite_.mutable_key();
147 : }
148 : virtual inline const ValueMapEntryAccessorType& value() const {
149 : return entry_lite_.value();
150 : }
151 : inline ValueMapEntryAccessorType* mutable_value() {
152 : return entry_lite_.mutable_value();
153 : }
154 :
155 : // implements Message =============================================
156 :
157 : bool MergePartialFromCodedStream(::google::protobuf::io::CodedInputStream* input) {
158 : return entry_lite_.MergePartialFromCodedStream(input);
159 : }
160 :
161 : int ByteSize() const {
162 : return entry_lite_.ByteSize();
163 : }
164 :
165 : void SerializeWithCachedSizes(::google::protobuf::io::CodedOutputStream* output) const {
166 : entry_lite_.SerializeWithCachedSizes(output);
167 : }
168 :
169 : ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
170 : return entry_lite_.SerializeWithCachedSizesToArray(output);
171 : }
172 :
173 : int GetCachedSize() const {
174 : return entry_lite_.GetCachedSize();
175 : }
176 :
177 : bool IsInitialized() const {
178 : return entry_lite_.IsInitialized();
179 : }
180 :
181 : Message* New() const {
182 : MapEntry* entry = new MapEntry;
183 : entry->descriptor_ = descriptor_;
184 : entry->reflection_ = reflection_;
185 : entry->set_default_instance(default_instance_);
186 : return entry;
187 : }
188 :
189 : Message* New(Arena* arena) const {
190 : MapEntry* entry = Arena::CreateMessage<MapEntry>(arena);
191 : entry->descriptor_ = descriptor_;
192 : entry->reflection_ = reflection_;
193 : entry->set_default_instance(default_instance_);
194 : return entry;
195 : }
196 :
197 : int SpaceUsed() const {
198 : int size = sizeof(MapEntry);
199 : size += entry_lite_.SpaceUsed();
200 : return size;
201 : }
202 :
203 : void CopyFrom(const ::google::protobuf::Message& from) {
204 : Clear();
205 : MergeFrom(from);
206 : }
207 :
208 : void MergeFrom(const ::google::protobuf::Message& from) {
209 : GOOGLE_CHECK_NE(&from, this);
210 : const MapEntry* source = dynamic_cast_if_available<const MapEntry*>(&from);
211 : if (source == NULL) {
212 : ReflectionOps::Merge(from, this);
213 : } else {
214 : MergeFrom(*source);
215 : }
216 : }
217 :
218 : void CopyFrom(const MapEntry& from) {
219 : Clear();
220 : MergeFrom(from);
221 : }
222 :
223 : void MergeFrom(const MapEntry& from) {
224 : entry_lite_.MergeFrom(from.entry_lite_);
225 : }
226 :
227 : void Clear() {
228 : entry_lite_.Clear();
229 : }
230 :
231 : void InitAsDefaultInstance() {
232 : entry_lite_.InitAsDefaultInstance();
233 : }
234 :
235 : Arena* GetArena() const {
236 : return entry_lite_.GetArena();
237 : }
238 :
239 : // Create default MapEntry instance for given descriptor. Descriptor has to be
240 : // given when creating default MapEntry instance because different map field
241 : // may have the same type and MapEntry class. The given descriptor is needed
242 : // to distinguish instances of the same MapEntry class.
243 : static MapEntry* CreateDefaultInstance(const Descriptor* descriptor) {
244 : MapEntry* entry = new MapEntry;
245 : const Reflection* reflection = new GeneratedMessageReflection(
246 : descriptor, entry, offsets_,
247 : GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, entry_lite_._has_bits_),
248 : GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, _unknown_fields_), -1,
249 : DescriptorPool::generated_pool(),
250 : ::google::protobuf::MessageFactory::generated_factory(),
251 : sizeof(MapEntry),
252 : GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, _internal_metadata_));
253 : entry->descriptor_ = descriptor;
254 : entry->reflection_ = reflection;
255 : entry->set_default_instance(entry);
256 : entry->InitAsDefaultInstance();
257 : RegisterMapEntryDefaultInstance(entry);
258 : return entry;
259 : }
260 :
261 : private:
262 : MapEntry()
263 : : _internal_metadata_(NULL), default_instance_(NULL), entry_lite_() {}
264 :
265 : explicit MapEntry(Arena* arena)
266 : : _internal_metadata_(arena),
267 : default_instance_(NULL),
268 : entry_lite_(arena) {}
269 :
270 : inline Arena* GetArenaNoVirtual() const {
271 : return entry_lite_.GetArenaNoVirtual();
272 : }
273 :
274 : void set_default_instance(MapEntry* default_instance) {
275 : default_instance_ = default_instance;
276 : entry_lite_.set_default_instance(&default_instance->entry_lite_);
277 : }
278 :
279 : static int offsets_[2];
280 : UnknownFieldSet _unknown_fields_;
281 : InternalMetadataWithArena _internal_metadata_;
282 : MapEntry* default_instance_;
283 : EntryLiteType entry_lite_;
284 :
285 : friend class ::google::protobuf::Arena;
286 : typedef void InternalArenaConstructable_;
287 : typedef void DestructorSkippable_;
288 : template <typename K, typename V, WireFormatLite::FieldType k_wire_type,
289 : WireFormatLite::FieldType, int default_enum>
290 : friend class internal::MapField;
291 : friend class internal::GeneratedMessageReflection;
292 :
293 : GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntry);
294 : };
295 :
296 : template <typename Key, typename Value, WireFormatLite::FieldType kKeyFieldType,
297 : WireFormatLite::FieldType kValueFieldType, int default_enum_value>
298 : int MapEntry<Key, Value, kKeyFieldType, kValueFieldType,
299 : default_enum_value>::offsets_[2] = {
300 : GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, entry_lite_.key_),
301 : GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, entry_lite_.value_),
302 : };
303 :
304 : } // namespace internal
305 : } // namespace protobuf
306 :
307 : } // namespace google
308 : #endif // GOOGLE_PROTOBUF_MAP_ENTRY_H__
|