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