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_TYPE_HANDLER_H__
32#define GOOGLE_PROTOBUF_TYPE_HANDLER_H__
33
34#include <google/protobuf/parse_context.h>
35#include <google/protobuf/io/coded_stream.h>
36#include <google/protobuf/arena.h>
37#include <google/protobuf/wire_format_lite.h>
38
39#ifdef SWIG
40#error "You cannot SWIG proto headers"
41#endif
42
43namespace google {
44namespace protobuf {
45namespace internal {
46
47// Used for compile time type selection. MapIf::type will be TrueType if Flag is
48// true and FalseType otherwise.
49template <bool Flag, typename TrueType, typename FalseType>
50struct MapIf;
51
52template <typename TrueType, typename FalseType>
53struct MapIf<true, TrueType, FalseType> {
54 typedef TrueType type;
55};
56
57template <typename TrueType, typename FalseType>
58struct MapIf<false, TrueType, FalseType> {
59 typedef FalseType type;
60};
61
62// In proto2 Map, enum needs to be initialized to given default value, while
63// other types' default value can be inferred from the type.
64template <bool IsEnum, typename Type>
65class MapValueInitializer {
66 public:
67 static inline void Initialize(Type& type, int default_enum_value);
68};
69
70template <typename Type>
71class MapValueInitializer<true, Type> {
72 public:
73 static inline void Initialize(Type& value, int default_enum_value) {
74 value = static_cast<Type>(default_enum_value);
75 }
76};
77
78template <typename Type>
79class MapValueInitializer<false, Type> {
80 public:
81 static inline void Initialize(Type& /* value */,
82 int /* default_enum_value */) {}
83};
84
85template <typename Type, bool is_arena_constructable>
86class MapArenaMessageCreator {
87 public:
88 // Use arena to create message if Type is arena constructable. Otherwise,
89 // create the message on heap.
90 static inline Type* CreateMessage(Arena* arena);
91};
92template <typename Type>
93class MapArenaMessageCreator<Type, true> {
94 public:
95 static inline Type* CreateMessage(Arena* arena) {
96 return Arena::CreateMessage<Type>(arena);
97 }
98};
99template <typename Type>
100class MapArenaMessageCreator<Type, false> {
101 public:
102 static inline Type* CreateMessage(Arena* arena) {
103 return Arena::Create<Type>(arena);
104 }
105};
106
107// Define constants for given wire field type
108template <WireFormatLite::FieldType field_type, typename Type>
109class MapWireFieldTypeTraits {};
110
111#define TYPE_TRAITS(FieldType, CType, WireFormatType, IsMessage, IsEnum) \
112 template <typename Type> \
113 class MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType, Type> { \
114 public: \
115 static const bool kIsMessage = IsMessage; \
116 static const bool kIsEnum = IsEnum; \
117 typedef typename MapIf<kIsMessage, Type*, CType>::type TypeOnMemory; \
118 typedef typename MapIf<kIsEnum, int, Type>::type MapEntryAccessorType; \
119 static const WireFormatLite::WireType kWireType = \
120 WireFormatLite::WIRETYPE_##WireFormatType; \
121 };
122
123TYPE_TRAITS(MESSAGE, Type, LENGTH_DELIMITED, true, false)
124TYPE_TRAITS(STRING, ArenaStringPtr, LENGTH_DELIMITED, false, false)
125TYPE_TRAITS(BYTES, ArenaStringPtr, LENGTH_DELIMITED, false, false)
126TYPE_TRAITS(INT64, int64, VARINT, false, false)
127TYPE_TRAITS(UINT64, uint64, VARINT, false, false)
128TYPE_TRAITS(INT32, int32, VARINT, false, false)
129TYPE_TRAITS(UINT32, uint32, VARINT, false, false)
130TYPE_TRAITS(SINT64, int64, VARINT, false, false)
131TYPE_TRAITS(SINT32, int32, VARINT, false, false)
132TYPE_TRAITS(ENUM, int, VARINT, false, true)
133TYPE_TRAITS(DOUBLE, double, FIXED64, false, false)
134TYPE_TRAITS(FLOAT, float, FIXED32, false, false)
135TYPE_TRAITS(FIXED64, uint64, FIXED64, false, false)
136TYPE_TRAITS(FIXED32, uint32, FIXED32, false, false)
137TYPE_TRAITS(SFIXED64, int64, FIXED64, false, false)
138TYPE_TRAITS(SFIXED32, int32, FIXED32, false, false)
139TYPE_TRAITS(BOOL, bool, VARINT, false, false)
140
141#undef TYPE_TRAITS
142
143template <WireFormatLite::FieldType field_type, typename Type>
144class MapTypeHandler {};
145
146template <typename Type>
147class MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type> {
148 public:
149 // Enum type cannot be used for MapTypeHandler::Read. Define a type which will
150 // replace Enum with int.
151 typedef typename MapWireFieldTypeTraits<WireFormatLite::TYPE_MESSAGE,
152 Type>::MapEntryAccessorType
153 MapEntryAccessorType;
154 // Internal stored type in MapEntryLite for given wire field type.
155 typedef typename MapWireFieldTypeTraits<WireFormatLite::TYPE_MESSAGE,
156 Type>::TypeOnMemory TypeOnMemory;
157 // Corresponding wire type for field type.
158 static constexpr WireFormatLite::WireType kWireType =
159 MapWireFieldTypeTraits<WireFormatLite::TYPE_MESSAGE, Type>::kWireType;
160 // Whether wire type is for message.
161 static constexpr bool kIsMessage =
162 MapWireFieldTypeTraits<WireFormatLite::TYPE_MESSAGE, Type>::kIsMessage;
163 // Whether wire type is for enum.
164 static constexpr bool kIsEnum =
165 MapWireFieldTypeTraits<WireFormatLite::TYPE_MESSAGE, Type>::kIsEnum;
166
167 // Functions used in parsing and serialization. ===================
168 static inline size_t ByteSize(const MapEntryAccessorType& value);
169 static inline int GetCachedSize(const MapEntryAccessorType& value);
170 static inline bool Read(io::CodedInputStream* input,
171 MapEntryAccessorType* value);
172 static inline const char* Read(const char* ptr, ParseContext* ctx,
173 MapEntryAccessorType* value);
174
175 static inline uint8* Write(int field, const MapEntryAccessorType& value,
176 uint8* ptr, io::EpsCopyOutputStream* stream);
177
178 // Functions to manipulate data on memory. ========================
179 static inline const Type& GetExternalReference(const Type* value);
180 static inline void DeleteNoArena(const Type* x);
181 static inline void Merge(const Type& from, Type** to, Arena* arena);
182 static inline void Clear(Type** value, Arena* arena);
183 static inline void ClearMaybeByDefaultEnum(Type** value, Arena* arena,
184 int default_enum_value);
185 static inline void Initialize(Type** x, Arena* arena);
186
187 static inline void InitializeMaybeByDefaultEnum(Type** x,
188 int default_enum_value,
189 Arena* arena);
190 static inline Type* EnsureMutable(Type** value, Arena* arena);
191 // SpaceUsedInMapEntry: Return bytes used by value in MapEntry, excluding
192 // those already calculate in sizeof(MapField).
193 static inline size_t SpaceUsedInMapEntryLong(const Type* value);
194 // Return bytes used by value in Map.
195 static inline size_t SpaceUsedInMapLong(const Type& value);
196 // Assign default value to given instance.
197 static inline void AssignDefaultValue(Type** value);
198 // Return default instance if value is not initialized when calling const
199 // reference accessor.
200 static inline const Type& DefaultIfNotInitialized(const Type* value,
201 const Type* default_value);
202 // Check if all required fields have values set.
203 static inline bool IsInitialized(Type* value);
204};
205
206#define MAP_HANDLER(FieldType) \
207 template <typename Type> \
208 class MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type> { \
209 public: \
210 typedef typename MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType, \
211 Type>::MapEntryAccessorType \
212 MapEntryAccessorType; \
213 typedef typename MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType, \
214 Type>::TypeOnMemory TypeOnMemory; \
215 static const WireFormatLite::WireType kWireType = \
216 MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType, \
217 Type>::kWireType; \
218 static const bool kIsMessage = \
219 MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType, \
220 Type>::kIsMessage; \
221 static const bool kIsEnum = \
222 MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType, \
223 Type>::kIsEnum; \
224 static inline int ByteSize(const MapEntryAccessorType& value); \
225 static inline int GetCachedSize(const MapEntryAccessorType& value); \
226 static inline bool Read(io::CodedInputStream* input, \
227 MapEntryAccessorType* value); \
228 static inline const char* Read(const char* begin, ParseContext* ctx, \
229 MapEntryAccessorType* value); \
230 static inline uint8* Write(int field, const MapEntryAccessorType& value, \
231 uint8* ptr, io::EpsCopyOutputStream* stream); \
232 static inline const MapEntryAccessorType& GetExternalReference( \
233 const TypeOnMemory& value); \
234 static inline void DeleteNoArena(const TypeOnMemory& x); \
235 static inline void Merge(const MapEntryAccessorType& from, \
236 TypeOnMemory* to, Arena* arena); \
237 static inline void Clear(TypeOnMemory* value, Arena* arena); \
238 static inline void ClearMaybeByDefaultEnum(TypeOnMemory* value, \
239 Arena* arena, \
240 int default_enum); \
241 static inline size_t SpaceUsedInMapEntryLong(const TypeOnMemory& value); \
242 static inline size_t SpaceUsedInMapLong(const TypeOnMemory& value); \
243 static inline size_t SpaceUsedInMapLong(const std::string& value); \
244 static inline void AssignDefaultValue(TypeOnMemory* value); \
245 static inline const MapEntryAccessorType& DefaultIfNotInitialized( \
246 const TypeOnMemory& value, const TypeOnMemory& default_value); \
247 static inline bool IsInitialized(const TypeOnMemory& value); \
248 static void DeleteNoArena(TypeOnMemory& value); \
249 static inline void Initialize(TypeOnMemory* value, Arena* arena); \
250 static inline void InitializeMaybeByDefaultEnum(TypeOnMemory* value, \
251 int default_enum_value, \
252 Arena* arena); \
253 static inline MapEntryAccessorType* EnsureMutable(TypeOnMemory* value, \
254 Arena* arena); \
255 };
256MAP_HANDLER(STRING)
257MAP_HANDLER(BYTES)
258MAP_HANDLER(INT64)
259MAP_HANDLER(UINT64)
260MAP_HANDLER(INT32)
261MAP_HANDLER(UINT32)
262MAP_HANDLER(SINT64)
263MAP_HANDLER(SINT32)
264MAP_HANDLER(ENUM)
265MAP_HANDLER(DOUBLE)
266MAP_HANDLER(FLOAT)
267MAP_HANDLER(FIXED64)
268MAP_HANDLER(FIXED32)
269MAP_HANDLER(SFIXED64)
270MAP_HANDLER(SFIXED32)
271MAP_HANDLER(BOOL)
272#undef MAP_HANDLER
273
274template <typename Type>
275inline size_t MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::ByteSize(
276 const MapEntryAccessorType& value) {
277 return WireFormatLite::MessageSizeNoVirtual(value);
278}
279
280#define GOOGLE_PROTOBUF_BYTE_SIZE(FieldType, DeclaredType) \
281 template <typename Type> \
282 inline int MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::ByteSize( \
283 const MapEntryAccessorType& value) { \
284 return static_cast<int>(WireFormatLite::DeclaredType##Size(value)); \
285 }
286
287GOOGLE_PROTOBUF_BYTE_SIZE(STRING, String)
288GOOGLE_PROTOBUF_BYTE_SIZE(BYTES, Bytes)
289GOOGLE_PROTOBUF_BYTE_SIZE(INT64, Int64)
290GOOGLE_PROTOBUF_BYTE_SIZE(UINT64, UInt64)
291GOOGLE_PROTOBUF_BYTE_SIZE(INT32, Int32)
292GOOGLE_PROTOBUF_BYTE_SIZE(UINT32, UInt32)
293GOOGLE_PROTOBUF_BYTE_SIZE(SINT64, SInt64)
294GOOGLE_PROTOBUF_BYTE_SIZE(SINT32, SInt32)
295GOOGLE_PROTOBUF_BYTE_SIZE(ENUM, Enum)
296
297#undef GOOGLE_PROTOBUF_BYTE_SIZE
298
299#define FIXED_BYTE_SIZE(FieldType, DeclaredType) \
300 template <typename Type> \
301 inline int MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::ByteSize( \
302 const MapEntryAccessorType& /* value */) { \
303 return WireFormatLite::k##DeclaredType##Size; \
304 }
305
306FIXED_BYTE_SIZE(DOUBLE, Double)
307FIXED_BYTE_SIZE(FLOAT, Float)
308FIXED_BYTE_SIZE(FIXED64, Fixed64)
309FIXED_BYTE_SIZE(FIXED32, Fixed32)
310FIXED_BYTE_SIZE(SFIXED64, SFixed64)
311FIXED_BYTE_SIZE(SFIXED32, SFixed32)
312FIXED_BYTE_SIZE(BOOL, Bool)
313
314#undef FIXED_BYTE_SIZE
315
316template <typename Type>
317inline int MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::GetCachedSize(
318 const MapEntryAccessorType& value) {
319 return static_cast<int>(WireFormatLite::LengthDelimitedSize(
320 length: static_cast<size_t>(value.GetCachedSize())));
321}
322
323#define GET_CACHED_SIZE(FieldType, DeclaredType) \
324 template <typename Type> \
325 inline int \
326 MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::GetCachedSize( \
327 const MapEntryAccessorType& value) { \
328 return static_cast<int>(WireFormatLite::DeclaredType##Size(value)); \
329 }
330
331GET_CACHED_SIZE(STRING, String)
332GET_CACHED_SIZE(BYTES, Bytes)
333GET_CACHED_SIZE(INT64, Int64)
334GET_CACHED_SIZE(UINT64, UInt64)
335GET_CACHED_SIZE(INT32, Int32)
336GET_CACHED_SIZE(UINT32, UInt32)
337GET_CACHED_SIZE(SINT64, SInt64)
338GET_CACHED_SIZE(SINT32, SInt32)
339GET_CACHED_SIZE(ENUM, Enum)
340
341#undef GET_CACHED_SIZE
342
343#define GET_FIXED_CACHED_SIZE(FieldType, DeclaredType) \
344 template <typename Type> \
345 inline int \
346 MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::GetCachedSize( \
347 const MapEntryAccessorType& /* value */) { \
348 return WireFormatLite::k##DeclaredType##Size; \
349 }
350
351GET_FIXED_CACHED_SIZE(DOUBLE, Double)
352GET_FIXED_CACHED_SIZE(FLOAT, Float)
353GET_FIXED_CACHED_SIZE(FIXED64, Fixed64)
354GET_FIXED_CACHED_SIZE(FIXED32, Fixed32)
355GET_FIXED_CACHED_SIZE(SFIXED64, SFixed64)
356GET_FIXED_CACHED_SIZE(SFIXED32, SFixed32)
357GET_FIXED_CACHED_SIZE(BOOL, Bool)
358
359#undef GET_FIXED_CACHED_SIZE
360
361template <typename Type>
362inline uint8* MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::Write(
363 int field, const MapEntryAccessorType& value, uint8* ptr,
364 io::EpsCopyOutputStream* stream) {
365 ptr = stream->EnsureSpace(ptr);
366 return WireFormatLite::InternalWriteMessage(field, value, ptr, stream);
367}
368
369#define WRITE_METHOD(FieldType, DeclaredType) \
370 template <typename Type> \
371 inline uint8* MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Write( \
372 int field, const MapEntryAccessorType& value, uint8* ptr, \
373 io::EpsCopyOutputStream* stream) { \
374 ptr = stream->EnsureSpace(ptr); \
375 return stream->Write##DeclaredType(field, value, ptr); \
376 }
377
378WRITE_METHOD(STRING, String)
379WRITE_METHOD(BYTES, Bytes)
380
381#undef WRITE_METHOD
382#define WRITE_METHOD(FieldType, DeclaredType) \
383 template <typename Type> \
384 inline uint8* MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Write( \
385 int field, const MapEntryAccessorType& value, uint8* ptr, \
386 io::EpsCopyOutputStream* stream) { \
387 ptr = stream->EnsureSpace(ptr); \
388 return WireFormatLite::Write##DeclaredType##ToArray(field, value, ptr); \
389 }
390
391WRITE_METHOD(INT64, Int64)
392WRITE_METHOD(UINT64, UInt64)
393WRITE_METHOD(INT32, Int32)
394WRITE_METHOD(UINT32, UInt32)
395WRITE_METHOD(SINT64, SInt64)
396WRITE_METHOD(SINT32, SInt32)
397WRITE_METHOD(ENUM, Enum)
398WRITE_METHOD(DOUBLE, Double)
399WRITE_METHOD(FLOAT, Float)
400WRITE_METHOD(FIXED64, Fixed64)
401WRITE_METHOD(FIXED32, Fixed32)
402WRITE_METHOD(SFIXED64, SFixed64)
403WRITE_METHOD(SFIXED32, SFixed32)
404WRITE_METHOD(BOOL, Bool)
405
406#undef WRITE_METHOD
407
408template <typename Type>
409inline bool MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::Read(
410 io::CodedInputStream* input, MapEntryAccessorType* value) {
411 return WireFormatLite::ReadMessageNoVirtual(input, value);
412}
413
414template <typename Type>
415inline bool MapTypeHandler<WireFormatLite::TYPE_STRING, Type>::Read(
416 io::CodedInputStream* input, MapEntryAccessorType* value) {
417 return WireFormatLite::ReadString(input, value);
418}
419
420template <typename Type>
421inline bool MapTypeHandler<WireFormatLite::TYPE_BYTES, Type>::Read(
422 io::CodedInputStream* input, MapEntryAccessorType* value) {
423 return WireFormatLite::ReadBytes(input, value);
424}
425
426template <typename Type>
427const char* MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::Read(
428 const char* ptr, ParseContext* ctx, MapEntryAccessorType* value) {
429 return ctx->ParseMessage(value, ptr);
430}
431
432template <typename Type>
433const char* MapTypeHandler<WireFormatLite::TYPE_STRING, Type>::Read(
434 const char* ptr, ParseContext* ctx, MapEntryAccessorType* value) {
435 int size = ReadSize(pp: &ptr);
436 GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
437 return ctx->ReadString(ptr, size, s: value);
438}
439
440template <typename Type>
441const char* MapTypeHandler<WireFormatLite::TYPE_BYTES, Type>::Read(
442 const char* ptr, ParseContext* ctx, MapEntryAccessorType* value) {
443 int size = ReadSize(pp: &ptr);
444 GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
445 return ctx->ReadString(ptr, size, s: value);
446}
447
448inline const char* ReadINT64(const char* ptr, int64* value) {
449 return VarintParse(p: ptr, out: reinterpret_cast<uint64*>(value));
450}
451inline const char* ReadUINT64(const char* ptr, uint64* value) {
452 return VarintParse(p: ptr, out: value);
453}
454inline const char* ReadINT32(const char* ptr, int32* value) {
455 return VarintParse(p: ptr, out: reinterpret_cast<uint32*>(value));
456}
457inline const char* ReadUINT32(const char* ptr, uint32* value) {
458 return VarintParse(p: ptr, out: value);
459}
460inline const char* ReadSINT64(const char* ptr, int64* value) {
461 *value = ReadVarintZigZag64(p: &ptr);
462 return ptr;
463}
464inline const char* ReadSINT32(const char* ptr, int32* value) {
465 *value = ReadVarintZigZag32(p: &ptr);
466 return ptr;
467}
468template <typename E>
469inline const char* ReadENUM(const char* ptr, E* value) {
470 *value = static_cast<E>(ReadVarint32(p: &ptr));
471 return ptr;
472}
473inline const char* ReadBOOL(const char* ptr, bool* value) {
474 *value = static_cast<bool>(ReadVarint32(p: &ptr));
475 return ptr;
476}
477
478template <typename F>
479inline const char* ReadUnaligned(const char* ptr, F* value) {
480 *value = UnalignedLoad<F>(ptr);
481 return ptr + sizeof(F);
482}
483inline const char* ReadFLOAT(const char* ptr, float* value) {
484 return ReadUnaligned(ptr, value);
485}
486inline const char* ReadDOUBLE(const char* ptr, double* value) {
487 return ReadUnaligned(ptr, value);
488}
489inline const char* ReadFIXED64(const char* ptr, uint64* value) {
490 return ReadUnaligned(ptr, value);
491}
492inline const char* ReadFIXED32(const char* ptr, uint32* value) {
493 return ReadUnaligned(ptr, value);
494}
495inline const char* ReadSFIXED64(const char* ptr, int64* value) {
496 return ReadUnaligned(ptr, value);
497}
498inline const char* ReadSFIXED32(const char* ptr, int32* value) {
499 return ReadUnaligned(ptr, value);
500}
501
502#define READ_METHOD(FieldType) \
503 template <typename Type> \
504 inline bool MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Read( \
505 io::CodedInputStream* input, MapEntryAccessorType* value) { \
506 return WireFormatLite::ReadPrimitive<TypeOnMemory, \
507 WireFormatLite::TYPE_##FieldType>( \
508 input, value); \
509 } \
510 template <typename Type> \
511 const char* MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Read( \
512 const char* begin, ParseContext* ctx, MapEntryAccessorType* value) { \
513 (void)ctx; \
514 return Read##FieldType(begin, value); \
515 }
516
517READ_METHOD(INT64)
518READ_METHOD(UINT64)
519READ_METHOD(INT32)
520READ_METHOD(UINT32)
521READ_METHOD(SINT64)
522READ_METHOD(SINT32)
523READ_METHOD(ENUM)
524READ_METHOD(DOUBLE)
525READ_METHOD(FLOAT)
526READ_METHOD(FIXED64)
527READ_METHOD(FIXED32)
528READ_METHOD(SFIXED64)
529READ_METHOD(SFIXED32)
530READ_METHOD(BOOL)
531
532#undef READ_METHOD
533
534// Definition for message handler
535
536template <typename Type>
537inline const Type&
538MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::GetExternalReference(
539 const Type* value) {
540 return *value;
541}
542
543template <typename Type>
544inline size_t MapTypeHandler<WireFormatLite::TYPE_MESSAGE,
545 Type>::SpaceUsedInMapEntryLong(const Type* value) {
546 return value->SpaceUsedLong();
547}
548
549template <typename Type>
550size_t MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::SpaceUsedInMapLong(
551 const Type& value) {
552 return value.SpaceUsedLong();
553}
554
555template <typename Type>
556inline void MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::Clear(
557 Type** value, Arena* /* arena */) {
558 if (*value != NULL) (*value)->Clear();
559}
560template <typename Type>
561inline void
562MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::ClearMaybeByDefaultEnum(
563 Type** value, Arena* /* arena */, int /* default_enum_value */) {
564 if (*value != NULL) (*value)->Clear();
565}
566template <typename Type>
567inline void MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::Merge(
568 const Type& from, Type** to, Arena* /* arena */) {
569 (*to)->MergeFrom(from);
570}
571
572template <typename Type>
573void MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::DeleteNoArena(
574 const Type* ptr) {
575 delete ptr;
576}
577
578template <typename Type>
579inline void MapTypeHandler<WireFormatLite::TYPE_MESSAGE,
580 Type>::AssignDefaultValue(Type** value) {
581 *value = const_cast<Type*>(Type::internal_default_instance());
582}
583
584template <typename Type>
585inline void MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::Initialize(
586 Type** x, Arena* /* arena */) {
587 *x = NULL;
588}
589
590template <typename Type>
591inline void MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::
592 InitializeMaybeByDefaultEnum(Type** x, int /* default_enum_value */,
593 Arena* /* arena */) {
594 *x = NULL;
595}
596
597template <typename Type>
598inline Type* MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::EnsureMutable(
599 Type** value, Arena* arena) {
600 if (*value == NULL) {
601 *value = MapArenaMessageCreator<
602 Type,
603 Arena::is_arena_constructable<Type>::type::value>::CreateMessage(arena);
604 }
605 return *value;
606}
607
608template <typename Type>
609inline const Type&
610MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::DefaultIfNotInitialized(
611 const Type* value, const Type* default_value) {
612 return value != NULL ? *value : *default_value;
613}
614
615template <typename Type>
616inline bool MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::IsInitialized(
617 Type* value) {
618 return value ? value->IsInitialized() : false;
619}
620
621// Definition for string/bytes handler
622
623#define STRING_OR_BYTES_HANDLER_FUNCTIONS(FieldType) \
624 template <typename Type> \
625 inline const typename MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
626 Type>::MapEntryAccessorType& \
627 MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
628 Type>::GetExternalReference(const TypeOnMemory& value) { \
629 return value.Get(); \
630 } \
631 template <typename Type> \
632 inline size_t \
633 MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
634 Type>::SpaceUsedInMapEntryLong(const TypeOnMemory& value) { \
635 return sizeof(value); \
636 } \
637 template <typename Type> \
638 inline size_t \
639 MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::SpaceUsedInMapLong( \
640 const TypeOnMemory& value) { \
641 return sizeof(value); \
642 } \
643 template <typename Type> \
644 inline size_t \
645 MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::SpaceUsedInMapLong( \
646 const std::string& value) { \
647 return sizeof(value); \
648 } \
649 template <typename Type> \
650 inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Clear( \
651 TypeOnMemory* value, Arena* arena) { \
652 value->ClearToEmpty(&internal::GetEmptyStringAlreadyInited(), arena); \
653 } \
654 template <typename Type> \
655 inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>:: \
656 ClearMaybeByDefaultEnum(TypeOnMemory* value, Arena* arena, \
657 int /* default_enum */) { \
658 Clear(value, arena); \
659 } \
660 template <typename Type> \
661 inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Merge( \
662 const MapEntryAccessorType& from, TypeOnMemory* to, Arena* arena) { \
663 to->Set(&internal::GetEmptyStringAlreadyInited(), from, arena); \
664 } \
665 template <typename Type> \
666 void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::DeleteNoArena( \
667 TypeOnMemory& value) { \
668 value.DestroyNoArena(&internal::GetEmptyStringAlreadyInited()); \
669 } \
670 template <typename Type> \
671 inline void \
672 MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::AssignDefaultValue( \
673 TypeOnMemory* /* value */) {} \
674 template <typename Type> \
675 inline void \
676 MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Initialize( \
677 TypeOnMemory* value, Arena* /* arena */) { \
678 value->UnsafeSetDefault(&internal::GetEmptyStringAlreadyInited()); \
679 } \
680 template <typename Type> \
681 inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>:: \
682 InitializeMaybeByDefaultEnum( \
683 TypeOnMemory* value, int /* default_enum_value */, Arena* arena) { \
684 Initialize(value, arena); \
685 } \
686 template <typename Type> \
687 inline typename MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
688 Type>::MapEntryAccessorType* \
689 MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::EnsureMutable( \
690 TypeOnMemory* value, Arena* arena) { \
691 return value->Mutable(&internal::GetEmptyStringAlreadyInited(), arena); \
692 } \
693 template <typename Type> \
694 inline const typename MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
695 Type>::MapEntryAccessorType& \
696 MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>:: \
697 DefaultIfNotInitialized(const TypeOnMemory& value, \
698 const TypeOnMemory& /* default_value */) { \
699 return value.Get(); \
700 } \
701 template <typename Type> \
702 inline bool \
703 MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::IsInitialized( \
704 const TypeOnMemory& /* value */) { \
705 return true; \
706 }
707STRING_OR_BYTES_HANDLER_FUNCTIONS(STRING)
708STRING_OR_BYTES_HANDLER_FUNCTIONS(BYTES)
709#undef STRING_OR_BYTES_HANDLER_FUNCTIONS
710
711#define PRIMITIVE_HANDLER_FUNCTIONS(FieldType) \
712 template <typename Type> \
713 inline const typename MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
714 Type>::MapEntryAccessorType& \
715 MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
716 Type>::GetExternalReference(const TypeOnMemory& value) { \
717 return value; \
718 } \
719 template <typename Type> \
720 inline size_t MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>:: \
721 SpaceUsedInMapEntryLong(const TypeOnMemory& /* value */) { \
722 return 0; \
723 } \
724 template <typename Type> \
725 inline size_t \
726 MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::SpaceUsedInMapLong( \
727 const TypeOnMemory& /* value */) { \
728 return sizeof(Type); \
729 } \
730 template <typename Type> \
731 inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Clear( \
732 TypeOnMemory* value, Arena* /* arena */) { \
733 *value = 0; \
734 } \
735 template <typename Type> \
736 inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>:: \
737 ClearMaybeByDefaultEnum(TypeOnMemory* value, Arena* /* arena */, \
738 int default_enum_value) { \
739 *value = static_cast<TypeOnMemory>(default_enum_value); \
740 } \
741 template <typename Type> \
742 inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Merge( \
743 const MapEntryAccessorType& from, TypeOnMemory* to, \
744 Arena* /* arena */) { \
745 *to = from; \
746 } \
747 template <typename Type> \
748 inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
749 Type>::DeleteNoArena(TypeOnMemory& /* x */) {} \
750 template <typename Type> \
751 inline void \
752 MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::AssignDefaultValue( \
753 TypeOnMemory* /* value */) {} \
754 template <typename Type> \
755 inline void \
756 MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Initialize( \
757 TypeOnMemory* value, Arena* /* arena */) { \
758 *value = 0; \
759 } \
760 template <typename Type> \
761 inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>:: \
762 InitializeMaybeByDefaultEnum( \
763 TypeOnMemory* value, int default_enum_value, Arena* /* arena */) { \
764 *value = static_cast<TypeOnMemory>(default_enum_value); \
765 } \
766 template <typename Type> \
767 inline typename MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
768 Type>::MapEntryAccessorType* \
769 MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::EnsureMutable( \
770 TypeOnMemory* value, Arena* /* arena */) { \
771 return value; \
772 } \
773 template <typename Type> \
774 inline const typename MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
775 Type>::MapEntryAccessorType& \
776 MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>:: \
777 DefaultIfNotInitialized(const TypeOnMemory& value, \
778 const TypeOnMemory& /* default_value */) { \
779 return value; \
780 } \
781 template <typename Type> \
782 inline bool \
783 MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::IsInitialized( \
784 const TypeOnMemory& /* value */) { \
785 return true; \
786 }
787PRIMITIVE_HANDLER_FUNCTIONS(INT64)
788PRIMITIVE_HANDLER_FUNCTIONS(UINT64)
789PRIMITIVE_HANDLER_FUNCTIONS(INT32)
790PRIMITIVE_HANDLER_FUNCTIONS(UINT32)
791PRIMITIVE_HANDLER_FUNCTIONS(SINT64)
792PRIMITIVE_HANDLER_FUNCTIONS(SINT32)
793PRIMITIVE_HANDLER_FUNCTIONS(ENUM)
794PRIMITIVE_HANDLER_FUNCTIONS(DOUBLE)
795PRIMITIVE_HANDLER_FUNCTIONS(FLOAT)
796PRIMITIVE_HANDLER_FUNCTIONS(FIXED64)
797PRIMITIVE_HANDLER_FUNCTIONS(FIXED32)
798PRIMITIVE_HANDLER_FUNCTIONS(SFIXED64)
799PRIMITIVE_HANDLER_FUNCTIONS(SFIXED32)
800PRIMITIVE_HANDLER_FUNCTIONS(BOOL)
801#undef PRIMITIVE_HANDLER_FUNCTIONS
802
803} // namespace internal
804} // namespace protobuf
805} // namespace google
806
807#endif // GOOGLE_PROTOBUF_TYPE_HANDLER_H__
808

source code of include/google/protobuf/map_type_handler.h