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