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