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 // Author: kenton (at) google.com (Kenton Varda) 32 // Based on original Protocol Buffers design by 33 // Sanjay Ghemawat, Jeff Dean, and others. 34 35 #include <google/protobuf/stubs/hash.h> 36 #include <google/protobuf/stubs/common.h> 37 #include <google/protobuf/stubs/once.h> 38 #include <google/protobuf/extension_set.h> 39 #include <google/protobuf/message_lite.h> 40 #include <google/protobuf/io/coded_stream.h> 41 #include <google/protobuf/wire_format_lite_inl.h> 42 #include <google/protobuf/repeated_field.h> 43 #include <google/protobuf/stubs/map_util.h> 44 45 namespace google { 46 namespace protobuf { 47 namespace internal { 48 49 namespace { 50 51 inline WireFormatLite::FieldType real_type(FieldType type) { 52 GOOGLE_DCHECK(type > 0 && type <= WireFormatLite::MAX_FIELD_TYPE); 53 return static_cast<WireFormatLite::FieldType>(type); 54 } 55 56 inline WireFormatLite::CppType cpp_type(FieldType type) { 57 return WireFormatLite::FieldTypeToCppType(real_type(type)); 58 } 59 60 inline bool is_packable(WireFormatLite::WireType type) { 61 switch (type) { 62 case WireFormatLite::WIRETYPE_VARINT: 63 case WireFormatLite::WIRETYPE_FIXED64: 64 case WireFormatLite::WIRETYPE_FIXED32: 65 return true; 66 case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: 67 case WireFormatLite::WIRETYPE_START_GROUP: 68 case WireFormatLite::WIRETYPE_END_GROUP: 69 return false; 70 71 // Do not add a default statement. Let the compiler complain when someone 72 // adds a new wire type. 73 } 74 GOOGLE_LOG(FATAL) << "can't reach here."; 75 return false; 76 } 77 78 // Registry stuff. 79 typedef hash_map<pair<const MessageLite*, int>, 80 ExtensionInfo> ExtensionRegistry; 81 ExtensionRegistry* registry_ = NULL; 82 GOOGLE_PROTOBUF_DECLARE_ONCE(registry_init_); 83 84 void DeleteRegistry() { 85 delete registry_; 86 registry_ = NULL; 87 } 88 89 void InitRegistry() { 90 registry_ = new ExtensionRegistry; 91 OnShutdown(&DeleteRegistry); 92 } 93 94 // This function is only called at startup, so there is no need for thread- 95 // safety. 96 void Register(const MessageLite* containing_type, 97 int number, ExtensionInfo info) { 98 ::google::protobuf::GoogleOnceInit(®istry_init_, &InitRegistry); 99 100 if (!InsertIfNotPresent(registry_, std::make_pair(containing_type, number), 101 info)) { 102 GOOGLE_LOG(FATAL) << "Multiple extension registrations for type \"" 103 << containing_type->GetTypeName() 104 << "\", field number " << number << "."; 105 } 106 } 107 108 const ExtensionInfo* FindRegisteredExtension( 109 const MessageLite* containing_type, int number) { 110 return (registry_ == NULL) 111 ? NULL 112 : FindOrNull(*registry_, std::make_pair(containing_type, number)); 113 } 114 115 } // namespace 116 117 ExtensionFinder::~ExtensionFinder() {} 118 119 bool GeneratedExtensionFinder::Find(int number, ExtensionInfo* output) { 120 const ExtensionInfo* extension = 121 FindRegisteredExtension(containing_type_, number); 122 if (extension == NULL) { 123 return false; 124 } else { 125 *output = *extension; 126 return true; 127 } 128 } 129 130 void ExtensionSet::RegisterExtension(const MessageLite* containing_type, 131 int number, FieldType type, 132 bool is_repeated, bool is_packed) { 133 GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_ENUM); 134 GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_MESSAGE); 135 GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_GROUP); 136 ExtensionInfo info(type, is_repeated, is_packed); 137 Register(containing_type, number, info); 138 } 139 140 static bool CallNoArgValidityFunc(const void* arg, int number) { 141 // Note: Must use C-style cast here rather than reinterpret_cast because 142 // the C++ standard at one point did not allow casts between function and 143 // data pointers and some compilers enforce this for C++-style casts. No 144 // compiler enforces it for C-style casts since lots of C-style code has 145 // relied on these kinds of casts for a long time, despite being 146 // technically undefined. See: 147 // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#195 148 // Also note: Some compilers do not allow function pointers to be "const". 149 // Which makes sense, I suppose, because it's meaningless. 150 return ((EnumValidityFunc*)arg)(number); 151 } 152 153 void ExtensionSet::RegisterEnumExtension(const MessageLite* containing_type, 154 int number, FieldType type, 155 bool is_repeated, bool is_packed, 156 EnumValidityFunc* is_valid) { 157 GOOGLE_CHECK_EQ(type, WireFormatLite::TYPE_ENUM); 158 ExtensionInfo info(type, is_repeated, is_packed); 159 info.enum_validity_check.func = CallNoArgValidityFunc; 160 // See comment in CallNoArgValidityFunc() about why we use a c-style cast. 161 info.enum_validity_check.arg = (void*)is_valid; 162 Register(containing_type, number, info); 163 } 164 165 void ExtensionSet::RegisterMessageExtension(const MessageLite* containing_type, 166 int number, FieldType type, 167 bool is_repeated, bool is_packed, 168 const MessageLite* prototype) { 169 GOOGLE_CHECK(type == WireFormatLite::TYPE_MESSAGE || 170 type == WireFormatLite::TYPE_GROUP); 171 ExtensionInfo info(type, is_repeated, is_packed); 172 info.message_prototype = prototype; 173 Register(containing_type, number, info); 174 } 175 176 177 // =================================================================== 178 // Constructors and basic methods. 179 180 ExtensionSet::ExtensionSet(::google::protobuf::Arena* arena) : arena_(arena) { 181 if (arena_ != NULL) { 182 arena_->OwnDestructor(&extensions_); 183 } 184 } 185 186 ExtensionSet::ExtensionSet() : arena_(NULL) {} 187 188 ExtensionSet::~ExtensionSet() { 189 // Deletes all allocated extensions. 190 if (arena_ == NULL) { 191 for (map<int, Extension>::iterator iter = extensions_.begin(); 192 iter != extensions_.end(); ++iter) { 193 iter->second.Free(); 194 } 195 } 196 } 197 198 // Defined in extension_set_heavy.cc. 199 // void ExtensionSet::AppendToList(const Descriptor* containing_type, 200 // const DescriptorPool* pool, 201 // vector<const FieldDescriptor*>* output) const 202 203 bool ExtensionSet::Has(int number) const { 204 map<int, Extension>::const_iterator iter = extensions_.find(number); 205 if (iter == extensions_.end()) return false; 206 GOOGLE_DCHECK(!iter->second.is_repeated); 207 return !iter->second.is_cleared; 208 } 209 210 int ExtensionSet::NumExtensions() const { 211 int result = 0; 212 for (map<int, Extension>::const_iterator iter = extensions_.begin(); 213 iter != extensions_.end(); ++iter) { 214 if (!iter->second.is_cleared) { 215 ++result; 216 } 217 } 218 return result; 219 } 220 221 int ExtensionSet::ExtensionSize(int number) const { 222 map<int, Extension>::const_iterator iter = extensions_.find(number); 223 if (iter == extensions_.end()) return false; 224 return iter->second.GetSize(); 225 } 226 227 FieldType ExtensionSet::ExtensionType(int number) const { 228 map<int, Extension>::const_iterator iter = extensions_.find(number); 229 if (iter == extensions_.end()) { 230 GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (1). "; 231 return 0; 232 } 233 if (iter->second.is_cleared) { 234 GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (2). "; 235 } 236 return iter->second.type; 237 } 238 239 void ExtensionSet::ClearExtension(int number) { 240 map<int, Extension>::iterator iter = extensions_.find(number); 241 if (iter == extensions_.end()) return; 242 iter->second.Clear(); 243 } 244 245 // =================================================================== 246 // Field accessors 247 248 namespace { 249 250 enum Cardinality { 251 REPEATED, 252 OPTIONAL 253 }; 254 255 } // namespace 256 257 #define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE) \ 258 GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? REPEATED : OPTIONAL, LABEL); \ 259 GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), WireFormatLite::CPPTYPE_##CPPTYPE) 260 261 // ------------------------------------------------------------------- 262 // Primitives 263 264 #define PRIMITIVE_ACCESSORS(UPPERCASE, LOWERCASE, CAMELCASE) \ 265 \ 266 LOWERCASE ExtensionSet::Get##CAMELCASE(int number, \ 267 LOWERCASE default_value) const { \ 268 map<int, Extension>::const_iterator iter = extensions_.find(number); \ 269 if (iter == extensions_.end() || iter->second.is_cleared) { \ 270 return default_value; \ 271 } else { \ 272 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, UPPERCASE); \ 273 return iter->second.LOWERCASE##_value; \ 274 } \ 275 } \ 276 \ 277 void ExtensionSet::Set##CAMELCASE(int number, FieldType type, \ 278 LOWERCASE value, \ 279 const FieldDescriptor* descriptor) { \ 280 Extension* extension; \ 281 if (MaybeNewExtension(number, descriptor, &extension)) { \ 282 extension->type = type; \ 283 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \ 284 extension->is_repeated = false; \ 285 } else { \ 286 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, UPPERCASE); \ 287 } \ 288 extension->is_cleared = false; \ 289 extension->LOWERCASE##_value = value; \ 290 } \ 291 \ 292 LOWERCASE ExtensionSet::GetRepeated##CAMELCASE(int number, int index) const { \ 293 map<int, Extension>::const_iterator iter = extensions_.find(number); \ 294 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \ 295 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE); \ 296 return iter->second.repeated_##LOWERCASE##_value->Get(index); \ 297 } \ 298 \ 299 void ExtensionSet::SetRepeated##CAMELCASE( \ 300 int number, int index, LOWERCASE value) { \ 301 map<int, Extension>::iterator iter = extensions_.find(number); \ 302 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \ 303 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE); \ 304 iter->second.repeated_##LOWERCASE##_value->Set(index, value); \ 305 } \ 306 \ 307 void ExtensionSet::Add##CAMELCASE(int number, FieldType type, \ 308 bool packed, LOWERCASE value, \ 309 const FieldDescriptor* descriptor) { \ 310 Extension* extension; \ 311 if (MaybeNewExtension(number, descriptor, &extension)) { \ 312 extension->type = type; \ 313 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \ 314 extension->is_repeated = true; \ 315 extension->is_packed = packed; \ 316 extension->repeated_##LOWERCASE##_value = \ 317 Arena::CreateMessage<RepeatedField<LOWERCASE> >(arena_); \ 318 } else { \ 319 GOOGLE_DCHECK_TYPE(*extension, REPEATED, UPPERCASE); \ 320 GOOGLE_DCHECK_EQ(extension->is_packed, packed); \ 321 } \ 322 extension->repeated_##LOWERCASE##_value->Add(value); \ 323 } 324 325 PRIMITIVE_ACCESSORS( INT32, int32, Int32) 326 PRIMITIVE_ACCESSORS( INT64, int64, Int64) 327 PRIMITIVE_ACCESSORS(UINT32, uint32, UInt32) 328 PRIMITIVE_ACCESSORS(UINT64, uint64, UInt64) 329 PRIMITIVE_ACCESSORS( FLOAT, float, Float) 330 PRIMITIVE_ACCESSORS(DOUBLE, double, Double) 331 PRIMITIVE_ACCESSORS( BOOL, bool, Bool) 332 333 #undef PRIMITIVE_ACCESSORS 334 335 const void* ExtensionSet::GetRawRepeatedField(int number, 336 const void* default_value) const { 337 map<int, Extension>::const_iterator iter = extensions_.find(number); 338 if (iter == extensions_.end()) { 339 return default_value; 340 } 341 // We assume that all the RepeatedField<>* pointers have the same 342 // size and alignment within the anonymous union in Extension. 343 return iter->second.repeated_int32_value; 344 } 345 346 void* ExtensionSet::MutableRawRepeatedField(int number, FieldType field_type, 347 bool packed, 348 const FieldDescriptor* desc) { 349 Extension* extension; 350 351 // We instantiate an empty Repeated{,Ptr}Field if one doesn't exist for this 352 // extension. 353 if (MaybeNewExtension(number, desc, &extension)) { 354 extension->is_repeated = true; 355 extension->type = field_type; 356 extension->is_packed = packed; 357 358 switch (WireFormatLite::FieldTypeToCppType( 359 static_cast<WireFormatLite::FieldType>(field_type))) { 360 case WireFormatLite::CPPTYPE_INT32: 361 extension->repeated_int32_value = 362 Arena::CreateMessage<RepeatedField<int32> >(arena_); 363 break; 364 case WireFormatLite::CPPTYPE_INT64: 365 extension->repeated_int64_value = 366 Arena::CreateMessage<RepeatedField<int64> >(arena_); 367 break; 368 case WireFormatLite::CPPTYPE_UINT32: 369 extension->repeated_uint32_value = 370 Arena::CreateMessage<RepeatedField<uint32> >(arena_); 371 break; 372 case WireFormatLite::CPPTYPE_UINT64: 373 extension->repeated_uint64_value = 374 Arena::CreateMessage<RepeatedField<uint64> >(arena_); 375 break; 376 case WireFormatLite::CPPTYPE_DOUBLE: 377 extension->repeated_double_value = 378 Arena::CreateMessage<RepeatedField<double> >(arena_); 379 break; 380 case WireFormatLite::CPPTYPE_FLOAT: 381 extension->repeated_float_value = 382 Arena::CreateMessage<RepeatedField<float> >(arena_); 383 break; 384 case WireFormatLite::CPPTYPE_BOOL: 385 extension->repeated_bool_value = 386 Arena::CreateMessage<RepeatedField<bool> >(arena_); 387 break; 388 case WireFormatLite::CPPTYPE_ENUM: 389 extension->repeated_enum_value = 390 Arena::CreateMessage<RepeatedField<int> >(arena_); 391 break; 392 case WireFormatLite::CPPTYPE_STRING: 393 extension->repeated_string_value = 394 Arena::CreateMessage<RepeatedPtrField< ::std::string> >(arena_); 395 break; 396 case WireFormatLite::CPPTYPE_MESSAGE: 397 extension->repeated_message_value = 398 Arena::CreateMessage<RepeatedPtrField<MessageLite> >(arena_); 399 break; 400 } 401 } 402 403 // We assume that all the RepeatedField<>* pointers have the same 404 // size and alignment within the anonymous union in Extension. 405 return extension->repeated_int32_value; 406 } 407 408 // Compatible version using old call signature. Does not create extensions when 409 // the don't already exist; instead, just GOOGLE_CHECK-fails. 410 void* ExtensionSet::MutableRawRepeatedField(int number) { 411 map<int, Extension>::iterator iter = extensions_.find(number); 412 GOOGLE_CHECK(iter == extensions_.end()) << "Extension not found."; 413 // We assume that all the RepeatedField<>* pointers have the same 414 // size and alignment within the anonymous union in Extension. 415 return iter->second.repeated_int32_value; 416 } 417 418 419 // ------------------------------------------------------------------- 420 // Enums 421 422 int ExtensionSet::GetEnum(int number, int default_value) const { 423 map<int, Extension>::const_iterator iter = extensions_.find(number); 424 if (iter == extensions_.end() || iter->second.is_cleared) { 425 // Not present. Return the default value. 426 return default_value; 427 } else { 428 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, ENUM); 429 return iter->second.enum_value; 430 } 431 } 432 433 void ExtensionSet::SetEnum(int number, FieldType type, int value, 434 const FieldDescriptor* descriptor) { 435 Extension* extension; 436 if (MaybeNewExtension(number, descriptor, &extension)) { 437 extension->type = type; 438 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM); 439 extension->is_repeated = false; 440 } else { 441 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, ENUM); 442 } 443 extension->is_cleared = false; 444 extension->enum_value = value; 445 } 446 447 int ExtensionSet::GetRepeatedEnum(int number, int index) const { 448 map<int, Extension>::const_iterator iter = extensions_.find(number); 449 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; 450 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM); 451 return iter->second.repeated_enum_value->Get(index); 452 } 453 454 void ExtensionSet::SetRepeatedEnum(int number, int index, int value) { 455 map<int, Extension>::iterator iter = extensions_.find(number); 456 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; 457 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM); 458 iter->second.repeated_enum_value->Set(index, value); 459 } 460 461 void ExtensionSet::AddEnum(int number, FieldType type, 462 bool packed, int value, 463 const FieldDescriptor* descriptor) { 464 Extension* extension; 465 if (MaybeNewExtension(number, descriptor, &extension)) { 466 extension->type = type; 467 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM); 468 extension->is_repeated = true; 469 extension->is_packed = packed; 470 extension->repeated_enum_value = 471 Arena::CreateMessage<RepeatedField<int> >(arena_); 472 } else { 473 GOOGLE_DCHECK_TYPE(*extension, REPEATED, ENUM); 474 GOOGLE_DCHECK_EQ(extension->is_packed, packed); 475 } 476 extension->repeated_enum_value->Add(value); 477 } 478 479 // ------------------------------------------------------------------- 480 // Strings 481 482 const string& ExtensionSet::GetString(int number, 483 const string& default_value) const { 484 map<int, Extension>::const_iterator iter = extensions_.find(number); 485 if (iter == extensions_.end() || iter->second.is_cleared) { 486 // Not present. Return the default value. 487 return default_value; 488 } else { 489 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, STRING); 490 return *iter->second.string_value; 491 } 492 } 493 494 string* ExtensionSet::MutableString(int number, FieldType type, 495 const FieldDescriptor* descriptor) { 496 Extension* extension; 497 if (MaybeNewExtension(number, descriptor, &extension)) { 498 extension->type = type; 499 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING); 500 extension->is_repeated = false; 501 extension->string_value = Arena::Create<string>(arena_); 502 } else { 503 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, STRING); 504 } 505 extension->is_cleared = false; 506 return extension->string_value; 507 } 508 509 const string& ExtensionSet::GetRepeatedString(int number, int index) const { 510 map<int, Extension>::const_iterator iter = extensions_.find(number); 511 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; 512 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING); 513 return iter->second.repeated_string_value->Get(index); 514 } 515 516 string* ExtensionSet::MutableRepeatedString(int number, int index) { 517 map<int, Extension>::iterator iter = extensions_.find(number); 518 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; 519 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING); 520 return iter->second.repeated_string_value->Mutable(index); 521 } 522 523 string* ExtensionSet::AddString(int number, FieldType type, 524 const FieldDescriptor* descriptor) { 525 Extension* extension; 526 if (MaybeNewExtension(number, descriptor, &extension)) { 527 extension->type = type; 528 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING); 529 extension->is_repeated = true; 530 extension->is_packed = false; 531 extension->repeated_string_value = 532 Arena::CreateMessage<RepeatedPtrField<string> >(arena_); 533 } else { 534 GOOGLE_DCHECK_TYPE(*extension, REPEATED, STRING); 535 } 536 return extension->repeated_string_value->Add(); 537 } 538 539 // ------------------------------------------------------------------- 540 // Messages 541 542 const MessageLite& ExtensionSet::GetMessage( 543 int number, const MessageLite& default_value) const { 544 map<int, Extension>::const_iterator iter = extensions_.find(number); 545 if (iter == extensions_.end()) { 546 // Not present. Return the default value. 547 return default_value; 548 } else { 549 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE); 550 if (iter->second.is_lazy) { 551 return iter->second.lazymessage_value->GetMessage(default_value); 552 } else { 553 return *iter->second.message_value; 554 } 555 } 556 } 557 558 // Defined in extension_set_heavy.cc. 559 // const MessageLite& ExtensionSet::GetMessage(int number, 560 // const Descriptor* message_type, 561 // MessageFactory* factory) const 562 563 MessageLite* ExtensionSet::MutableMessage(int number, FieldType type, 564 const MessageLite& prototype, 565 const FieldDescriptor* descriptor) { 566 Extension* extension; 567 if (MaybeNewExtension(number, descriptor, &extension)) { 568 extension->type = type; 569 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE); 570 extension->is_repeated = false; 571 extension->is_lazy = false; 572 extension->message_value = prototype.New(arena_); 573 extension->is_cleared = false; 574 return extension->message_value; 575 } else { 576 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE); 577 extension->is_cleared = false; 578 if (extension->is_lazy) { 579 return extension->lazymessage_value->MutableMessage(prototype); 580 } else { 581 return extension->message_value; 582 } 583 } 584 } 585 586 // Defined in extension_set_heavy.cc. 587 // MessageLite* ExtensionSet::MutableMessage(int number, FieldType type, 588 // const Descriptor* message_type, 589 // MessageFactory* factory) 590 591 void ExtensionSet::SetAllocatedMessage(int number, FieldType type, 592 const FieldDescriptor* descriptor, 593 MessageLite* message) { 594 if (message == NULL) { 595 ClearExtension(number); 596 return; 597 } 598 ::google::protobuf::Arena* message_arena = message->GetArena(); 599 Extension* extension; 600 if (MaybeNewExtension(number, descriptor, &extension)) { 601 extension->type = type; 602 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE); 603 extension->is_repeated = false; 604 extension->is_lazy = false; 605 if (message_arena == arena_) { 606 extension->message_value = message; 607 } else if (message_arena == NULL) { 608 extension->message_value = message; 609 arena_->Own(message); // not NULL because not equal to message_arena 610 } else { 611 extension->message_value = message->New(arena_); 612 extension->message_value->CheckTypeAndMergeFrom(*message); 613 } 614 } else { 615 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE); 616 if (extension->is_lazy) { 617 extension->lazymessage_value->SetAllocatedMessage(message); 618 } else { 619 if (arena_ == NULL) { 620 delete extension->message_value; 621 } 622 if (message_arena == arena_) { 623 extension->message_value = message; 624 } else if (message_arena == NULL) { 625 extension->message_value = message; 626 arena_->Own(message); // not NULL because not equal to message_arena 627 } else { 628 extension->message_value = message->New(arena_); 629 extension->message_value->CheckTypeAndMergeFrom(*message); 630 } 631 } 632 } 633 extension->is_cleared = false; 634 } 635 636 void ExtensionSet::UnsafeArenaSetAllocatedMessage( 637 int number, FieldType type, const FieldDescriptor* descriptor, 638 MessageLite* message) { 639 if (message == NULL) { 640 ClearExtension(number); 641 return; 642 } 643 Extension* extension; 644 if (MaybeNewExtension(number, descriptor, &extension)) { 645 extension->type = type; 646 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE); 647 extension->is_repeated = false; 648 extension->is_lazy = false; 649 extension->message_value = message; 650 } else { 651 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE); 652 if (extension->is_lazy) { 653 extension->lazymessage_value->UnsafeArenaSetAllocatedMessage(message); 654 } else { 655 if (arena_ == NULL) { 656 delete extension->message_value; 657 } 658 extension->message_value = message; 659 } 660 } 661 extension->is_cleared = false; 662 } 663 664 665 MessageLite* ExtensionSet::ReleaseMessage(int number, 666 const MessageLite& prototype) { 667 map<int, Extension>::iterator iter = extensions_.find(number); 668 if (iter == extensions_.end()) { 669 // Not present. Return NULL. 670 return NULL; 671 } else { 672 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE); 673 MessageLite* ret = NULL; 674 if (iter->second.is_lazy) { 675 ret = iter->second.lazymessage_value->ReleaseMessage(prototype); 676 if (arena_ == NULL) { 677 delete iter->second.lazymessage_value; 678 } 679 } else { 680 if (arena_ == NULL) { 681 ret = iter->second.message_value; 682 } else { 683 // ReleaseMessage() always returns a heap-allocated message, and we are 684 // on an arena, so we need to make a copy of this message to return. 685 ret = (iter->second.message_value)->New(); 686 ret->CheckTypeAndMergeFrom(*iter->second.message_value); 687 } 688 } 689 extensions_.erase(number); 690 return ret; 691 } 692 } 693 694 MessageLite* ExtensionSet::UnsafeArenaReleaseMessage( 695 int number, const MessageLite& prototype) { 696 map<int, Extension>::iterator iter = extensions_.find(number); 697 if (iter == extensions_.end()) { 698 // Not present. Return NULL. 699 return NULL; 700 } else { 701 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE); 702 MessageLite* ret = NULL; 703 if (iter->second.is_lazy) { 704 ret = 705 iter->second.lazymessage_value->UnsafeArenaReleaseMessage(prototype); 706 if (arena_ == NULL) { 707 delete iter->second.lazymessage_value; 708 } 709 } else { 710 ret = iter->second.message_value; 711 } 712 extensions_.erase(number); 713 return ret; 714 } 715 } 716 717 // Defined in extension_set_heavy.cc. 718 // MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor, 719 // MessageFactory* factory); 720 721 const MessageLite& ExtensionSet::GetRepeatedMessage( 722 int number, int index) const { 723 map<int, Extension>::const_iterator iter = extensions_.find(number); 724 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; 725 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE); 726 return iter->second.repeated_message_value->Get(index); 727 } 728 729 MessageLite* ExtensionSet::MutableRepeatedMessage(int number, int index) { 730 map<int, Extension>::iterator iter = extensions_.find(number); 731 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; 732 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE); 733 return iter->second.repeated_message_value->Mutable(index); 734 } 735 736 MessageLite* ExtensionSet::AddMessage(int number, FieldType type, 737 const MessageLite& prototype, 738 const FieldDescriptor* descriptor) { 739 Extension* extension; 740 if (MaybeNewExtension(number, descriptor, &extension)) { 741 extension->type = type; 742 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE); 743 extension->is_repeated = true; 744 extension->repeated_message_value = 745 Arena::CreateMessage<RepeatedPtrField<MessageLite> >(arena_); 746 } else { 747 GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE); 748 } 749 750 // RepeatedPtrField<MessageLite> does not know how to Add() since it cannot 751 // allocate an abstract object, so we have to be tricky. 752 MessageLite* result = extension->repeated_message_value 753 ->AddFromCleared<GenericTypeHandler<MessageLite> >(); 754 if (result == NULL) { 755 result = prototype.New(arena_); 756 extension->repeated_message_value->AddAllocated(result); 757 } 758 return result; 759 } 760 761 // Defined in extension_set_heavy.cc. 762 // MessageLite* ExtensionSet::AddMessage(int number, FieldType type, 763 // const Descriptor* message_type, 764 // MessageFactory* factory) 765 766 #undef GOOGLE_DCHECK_TYPE 767 768 void ExtensionSet::RemoveLast(int number) { 769 map<int, Extension>::iterator iter = extensions_.find(number); 770 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; 771 772 Extension* extension = &iter->second; 773 GOOGLE_DCHECK(extension->is_repeated); 774 775 switch(cpp_type(extension->type)) { 776 case WireFormatLite::CPPTYPE_INT32: 777 extension->repeated_int32_value->RemoveLast(); 778 break; 779 case WireFormatLite::CPPTYPE_INT64: 780 extension->repeated_int64_value->RemoveLast(); 781 break; 782 case WireFormatLite::CPPTYPE_UINT32: 783 extension->repeated_uint32_value->RemoveLast(); 784 break; 785 case WireFormatLite::CPPTYPE_UINT64: 786 extension->repeated_uint64_value->RemoveLast(); 787 break; 788 case WireFormatLite::CPPTYPE_FLOAT: 789 extension->repeated_float_value->RemoveLast(); 790 break; 791 case WireFormatLite::CPPTYPE_DOUBLE: 792 extension->repeated_double_value->RemoveLast(); 793 break; 794 case WireFormatLite::CPPTYPE_BOOL: 795 extension->repeated_bool_value->RemoveLast(); 796 break; 797 case WireFormatLite::CPPTYPE_ENUM: 798 extension->repeated_enum_value->RemoveLast(); 799 break; 800 case WireFormatLite::CPPTYPE_STRING: 801 extension->repeated_string_value->RemoveLast(); 802 break; 803 case WireFormatLite::CPPTYPE_MESSAGE: 804 extension->repeated_message_value->RemoveLast(); 805 break; 806 } 807 } 808 809 MessageLite* ExtensionSet::ReleaseLast(int number) { 810 map<int, Extension>::iterator iter = extensions_.find(number); 811 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; 812 813 Extension* extension = &iter->second; 814 GOOGLE_DCHECK(extension->is_repeated); 815 GOOGLE_DCHECK(cpp_type(extension->type) == WireFormatLite::CPPTYPE_MESSAGE); 816 return extension->repeated_message_value->ReleaseLast(); 817 } 818 819 void ExtensionSet::SwapElements(int number, int index1, int index2) { 820 map<int, Extension>::iterator iter = extensions_.find(number); 821 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; 822 823 Extension* extension = &iter->second; 824 GOOGLE_DCHECK(extension->is_repeated); 825 826 switch(cpp_type(extension->type)) { 827 case WireFormatLite::CPPTYPE_INT32: 828 extension->repeated_int32_value->SwapElements(index1, index2); 829 break; 830 case WireFormatLite::CPPTYPE_INT64: 831 extension->repeated_int64_value->SwapElements(index1, index2); 832 break; 833 case WireFormatLite::CPPTYPE_UINT32: 834 extension->repeated_uint32_value->SwapElements(index1, index2); 835 break; 836 case WireFormatLite::CPPTYPE_UINT64: 837 extension->repeated_uint64_value->SwapElements(index1, index2); 838 break; 839 case WireFormatLite::CPPTYPE_FLOAT: 840 extension->repeated_float_value->SwapElements(index1, index2); 841 break; 842 case WireFormatLite::CPPTYPE_DOUBLE: 843 extension->repeated_double_value->SwapElements(index1, index2); 844 break; 845 case WireFormatLite::CPPTYPE_BOOL: 846 extension->repeated_bool_value->SwapElements(index1, index2); 847 break; 848 case WireFormatLite::CPPTYPE_ENUM: 849 extension->repeated_enum_value->SwapElements(index1, index2); 850 break; 851 case WireFormatLite::CPPTYPE_STRING: 852 extension->repeated_string_value->SwapElements(index1, index2); 853 break; 854 case WireFormatLite::CPPTYPE_MESSAGE: 855 extension->repeated_message_value->SwapElements(index1, index2); 856 break; 857 } 858 } 859 860 // =================================================================== 861 862 void ExtensionSet::Clear() { 863 for (map<int, Extension>::iterator iter = extensions_.begin(); 864 iter != extensions_.end(); ++iter) { 865 iter->second.Clear(); 866 } 867 } 868 869 void ExtensionSet::MergeFrom(const ExtensionSet& other) { 870 for (map<int, Extension>::const_iterator iter = other.extensions_.begin(); 871 iter != other.extensions_.end(); ++iter) { 872 const Extension& other_extension = iter->second; 873 InternalExtensionMergeFrom(iter->first, other_extension); 874 } 875 } 876 877 void ExtensionSet::InternalExtensionMergeFrom( 878 int number, const Extension& other_extension) { 879 if (other_extension.is_repeated) { 880 Extension* extension; 881 bool is_new = MaybeNewExtension(number, other_extension.descriptor, 882 &extension); 883 if (is_new) { 884 // Extension did not already exist in set. 885 extension->type = other_extension.type; 886 extension->is_packed = other_extension.is_packed; 887 extension->is_repeated = true; 888 } else { 889 GOOGLE_DCHECK_EQ(extension->type, other_extension.type); 890 GOOGLE_DCHECK_EQ(extension->is_packed, other_extension.is_packed); 891 GOOGLE_DCHECK(extension->is_repeated); 892 } 893 894 switch (cpp_type(other_extension.type)) { 895 #define HANDLE_TYPE(UPPERCASE, LOWERCASE, REPEATED_TYPE) \ 896 case WireFormatLite::CPPTYPE_##UPPERCASE: \ 897 if (is_new) { \ 898 extension->repeated_##LOWERCASE##_value = \ 899 Arena::CreateMessage<REPEATED_TYPE >(arena_); \ 900 } \ 901 extension->repeated_##LOWERCASE##_value->MergeFrom( \ 902 *other_extension.repeated_##LOWERCASE##_value); \ 903 break; 904 905 HANDLE_TYPE( INT32, int32, RepeatedField < int32>); 906 HANDLE_TYPE( INT64, int64, RepeatedField < int64>); 907 HANDLE_TYPE( UINT32, uint32, RepeatedField < uint32>); 908 HANDLE_TYPE( UINT64, uint64, RepeatedField < uint64>); 909 HANDLE_TYPE( FLOAT, float, RepeatedField < float>); 910 HANDLE_TYPE( DOUBLE, double, RepeatedField < double>); 911 HANDLE_TYPE( BOOL, bool, RepeatedField < bool>); 912 HANDLE_TYPE( ENUM, enum, RepeatedField < int>); 913 HANDLE_TYPE( STRING, string, RepeatedPtrField< string>); 914 #undef HANDLE_TYPE 915 916 case WireFormatLite::CPPTYPE_MESSAGE: 917 if (is_new) { 918 extension->repeated_message_value = 919 Arena::CreateMessage<RepeatedPtrField<MessageLite> >(arena_); 920 } 921 // We can't call RepeatedPtrField<MessageLite>::MergeFrom() because 922 // it would attempt to allocate new objects. 923 RepeatedPtrField<MessageLite>* other_repeated_message = 924 other_extension.repeated_message_value; 925 for (int i = 0; i < other_repeated_message->size(); i++) { 926 const MessageLite& other_message = other_repeated_message->Get(i); 927 MessageLite* target = extension->repeated_message_value 928 ->AddFromCleared<GenericTypeHandler<MessageLite> >(); 929 if (target == NULL) { 930 target = other_message.New(arena_); 931 extension->repeated_message_value->AddAllocated(target); 932 } 933 target->CheckTypeAndMergeFrom(other_message); 934 } 935 break; 936 } 937 } else { 938 if (!other_extension.is_cleared) { 939 switch (cpp_type(other_extension.type)) { 940 #define HANDLE_TYPE(UPPERCASE, LOWERCASE, CAMELCASE) \ 941 case WireFormatLite::CPPTYPE_##UPPERCASE: \ 942 Set##CAMELCASE(number, other_extension.type, \ 943 other_extension.LOWERCASE##_value, \ 944 other_extension.descriptor); \ 945 break; 946 947 HANDLE_TYPE( INT32, int32, Int32); 948 HANDLE_TYPE( INT64, int64, Int64); 949 HANDLE_TYPE(UINT32, uint32, UInt32); 950 HANDLE_TYPE(UINT64, uint64, UInt64); 951 HANDLE_TYPE( FLOAT, float, Float); 952 HANDLE_TYPE(DOUBLE, double, Double); 953 HANDLE_TYPE( BOOL, bool, Bool); 954 HANDLE_TYPE( ENUM, enum, Enum); 955 #undef HANDLE_TYPE 956 case WireFormatLite::CPPTYPE_STRING: 957 SetString(number, other_extension.type, 958 *other_extension.string_value, 959 other_extension.descriptor); 960 break; 961 case WireFormatLite::CPPTYPE_MESSAGE: { 962 Extension* extension; 963 bool is_new = MaybeNewExtension(number, 964 other_extension.descriptor, 965 &extension); 966 if (is_new) { 967 extension->type = other_extension.type; 968 extension->is_packed = other_extension.is_packed; 969 extension->is_repeated = false; 970 if (other_extension.is_lazy) { 971 extension->is_lazy = true; 972 extension->lazymessage_value = 973 other_extension.lazymessage_value->New(arena_); 974 extension->lazymessage_value->MergeFrom( 975 *other_extension.lazymessage_value); 976 } else { 977 extension->is_lazy = false; 978 extension->message_value = 979 other_extension.message_value->New(arena_); 980 extension->message_value->CheckTypeAndMergeFrom( 981 *other_extension.message_value); 982 } 983 } else { 984 GOOGLE_DCHECK_EQ(extension->type, other_extension.type); 985 GOOGLE_DCHECK_EQ(extension->is_packed,other_extension.is_packed); 986 GOOGLE_DCHECK(!extension->is_repeated); 987 if (other_extension.is_lazy) { 988 if (extension->is_lazy) { 989 extension->lazymessage_value->MergeFrom( 990 *other_extension.lazymessage_value); 991 } else { 992 extension->message_value->CheckTypeAndMergeFrom( 993 other_extension.lazymessage_value->GetMessage( 994 *extension->message_value)); 995 } 996 } else { 997 if (extension->is_lazy) { 998 extension->lazymessage_value->MutableMessage( 999 *other_extension.message_value)->CheckTypeAndMergeFrom( 1000 *other_extension.message_value); 1001 } else { 1002 extension->message_value->CheckTypeAndMergeFrom( 1003 *other_extension.message_value); 1004 } 1005 } 1006 } 1007 extension->is_cleared = false; 1008 break; 1009 } 1010 } 1011 } 1012 } 1013 } 1014 1015 void ExtensionSet::Swap(ExtensionSet* x) { 1016 if (GetArenaNoVirtual() == x->GetArenaNoVirtual()) { 1017 extensions_.swap(x->extensions_); 1018 } else { 1019 // TODO(cfallin, rohananil): We maybe able to optimize a case where we are 1020 // swapping from heap to arena-allocated extension set, by just Own()'ing 1021 // the extensions. 1022 ExtensionSet extension_set; 1023 extension_set.MergeFrom(*x); 1024 x->Clear(); 1025 x->MergeFrom(*this); 1026 Clear(); 1027 MergeFrom(extension_set); 1028 } 1029 } 1030 1031 void ExtensionSet::SwapExtension(ExtensionSet* other, 1032 int number) { 1033 if (this == other) return; 1034 map<int, Extension>::iterator this_iter = extensions_.find(number); 1035 map<int, Extension>::iterator other_iter = other->extensions_.find(number); 1036 1037 if (this_iter == extensions_.end() && 1038 other_iter == other->extensions_.end()) { 1039 return; 1040 } 1041 1042 if (this_iter != extensions_.end() && 1043 other_iter != other->extensions_.end()) { 1044 if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { 1045 using std::swap; 1046 swap(this_iter->second, other_iter->second); 1047 } else { 1048 // TODO(cfallin, rohananil): We could further optimize these cases, 1049 // especially avoid creation of ExtensionSet, and move MergeFrom logic 1050 // into Extensions itself (which takes arena as an argument). 1051 // We do it this way to reuse the copy-across-arenas logic already 1052 // implemented in ExtensionSet's MergeFrom. 1053 ExtensionSet temp; 1054 temp.InternalExtensionMergeFrom(number, other_iter->second); 1055 map<int, Extension>::iterator temp_iter = temp.extensions_.find(number); 1056 other_iter->second.Clear(); 1057 other->InternalExtensionMergeFrom(number, this_iter->second); 1058 this_iter->second.Clear(); 1059 InternalExtensionMergeFrom(number, temp_iter->second); 1060 } 1061 return; 1062 } 1063 1064 if (this_iter == extensions_.end()) { 1065 if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { 1066 extensions_.insert(std::make_pair(number, other_iter->second)); 1067 } else { 1068 InternalExtensionMergeFrom(number, other_iter->second); 1069 } 1070 other->extensions_.erase(number); 1071 return; 1072 } 1073 1074 if (other_iter == other->extensions_.end()) { 1075 if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { 1076 other->extensions_.insert(std::make_pair(number, this_iter->second)); 1077 } else { 1078 other->InternalExtensionMergeFrom(number, this_iter->second); 1079 } 1080 extensions_.erase(number); 1081 return; 1082 } 1083 } 1084 1085 bool ExtensionSet::IsInitialized() const { 1086 // Extensions are never required. However, we need to check that all 1087 // embedded messages are initialized. 1088 for (map<int, Extension>::const_iterator iter = extensions_.begin(); 1089 iter != extensions_.end(); ++iter) { 1090 const Extension& extension = iter->second; 1091 if (cpp_type(extension.type) == WireFormatLite::CPPTYPE_MESSAGE) { 1092 if (extension.is_repeated) { 1093 for (int i = 0; i < extension.repeated_message_value->size(); i++) { 1094 if (!extension.repeated_message_value->Get(i).IsInitialized()) { 1095 return false; 1096 } 1097 } 1098 } else { 1099 if (!extension.is_cleared) { 1100 if (extension.is_lazy) { 1101 if (!extension.lazymessage_value->IsInitialized()) return false; 1102 } else { 1103 if (!extension.message_value->IsInitialized()) return false; 1104 } 1105 } 1106 } 1107 } 1108 } 1109 1110 return true; 1111 } 1112 1113 bool ExtensionSet::FindExtensionInfoFromTag( 1114 uint32 tag, ExtensionFinder* extension_finder, int* field_number, 1115 ExtensionInfo* extension, bool* was_packed_on_wire) { 1116 *field_number = WireFormatLite::GetTagFieldNumber(tag); 1117 WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag); 1118 return FindExtensionInfoFromFieldNumber(wire_type, *field_number, 1119 extension_finder, extension, 1120 was_packed_on_wire); 1121 } 1122 1123 bool ExtensionSet::FindExtensionInfoFromFieldNumber( 1124 int wire_type, int field_number, ExtensionFinder* extension_finder, 1125 ExtensionInfo* extension, bool* was_packed_on_wire) { 1126 if (!extension_finder->Find(field_number, extension)) { 1127 return false; 1128 } 1129 1130 WireFormatLite::WireType expected_wire_type = 1131 WireFormatLite::WireTypeForFieldType(real_type(extension->type)); 1132 1133 // Check if this is a packed field. 1134 *was_packed_on_wire = false; 1135 if (extension->is_repeated && 1136 wire_type == WireFormatLite::WIRETYPE_LENGTH_DELIMITED && 1137 is_packable(expected_wire_type)) { 1138 *was_packed_on_wire = true; 1139 return true; 1140 } 1141 // Otherwise the wire type must match. 1142 return expected_wire_type == wire_type; 1143 } 1144 1145 bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, 1146 ExtensionFinder* extension_finder, 1147 FieldSkipper* field_skipper) { 1148 int number; 1149 bool was_packed_on_wire; 1150 ExtensionInfo extension; 1151 if (!FindExtensionInfoFromTag( 1152 tag, extension_finder, &number, &extension, &was_packed_on_wire)) { 1153 return field_skipper->SkipField(input, tag); 1154 } else { 1155 return ParseFieldWithExtensionInfo( 1156 number, was_packed_on_wire, extension, input, field_skipper); 1157 } 1158 } 1159 1160 bool ExtensionSet::ParseFieldWithExtensionInfo( 1161 int number, bool was_packed_on_wire, const ExtensionInfo& extension, 1162 io::CodedInputStream* input, 1163 FieldSkipper* field_skipper) { 1164 // Explicitly not read extension.is_packed, instead check whether the field 1165 // was encoded in packed form on the wire. 1166 if (was_packed_on_wire) { 1167 uint32 size; 1168 if (!input->ReadVarint32(&size)) return false; 1169 io::CodedInputStream::Limit limit = input->PushLimit(size); 1170 1171 switch (extension.type) { 1172 #define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE) \ 1173 case WireFormatLite::TYPE_##UPPERCASE: \ 1174 while (input->BytesUntilLimit() > 0) { \ 1175 CPP_LOWERCASE value; \ 1176 if (!WireFormatLite::ReadPrimitive< \ 1177 CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>( \ 1178 input, &value)) return false; \ 1179 Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \ 1180 extension.is_packed, value, \ 1181 extension.descriptor); \ 1182 } \ 1183 break 1184 1185 HANDLE_TYPE( INT32, Int32, int32); 1186 HANDLE_TYPE( INT64, Int64, int64); 1187 HANDLE_TYPE( UINT32, UInt32, uint32); 1188 HANDLE_TYPE( UINT64, UInt64, uint64); 1189 HANDLE_TYPE( SINT32, Int32, int32); 1190 HANDLE_TYPE( SINT64, Int64, int64); 1191 HANDLE_TYPE( FIXED32, UInt32, uint32); 1192 HANDLE_TYPE( FIXED64, UInt64, uint64); 1193 HANDLE_TYPE(SFIXED32, Int32, int32); 1194 HANDLE_TYPE(SFIXED64, Int64, int64); 1195 HANDLE_TYPE( FLOAT, Float, float); 1196 HANDLE_TYPE( DOUBLE, Double, double); 1197 HANDLE_TYPE( BOOL, Bool, bool); 1198 #undef HANDLE_TYPE 1199 1200 case WireFormatLite::TYPE_ENUM: 1201 while (input->BytesUntilLimit() > 0) { 1202 int value; 1203 if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>( 1204 input, &value)) return false; 1205 if (extension.enum_validity_check.func( 1206 extension.enum_validity_check.arg, value)) { 1207 AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed, 1208 value, extension.descriptor); 1209 } else { 1210 // Invalid value. Treat as unknown. 1211 field_skipper->SkipUnknownEnum(number, value); 1212 } 1213 } 1214 break; 1215 1216 case WireFormatLite::TYPE_STRING: 1217 case WireFormatLite::TYPE_BYTES: 1218 case WireFormatLite::TYPE_GROUP: 1219 case WireFormatLite::TYPE_MESSAGE: 1220 GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed."; 1221 break; 1222 } 1223 1224 input->PopLimit(limit); 1225 } else { 1226 switch (extension.type) { 1227 #define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE) \ 1228 case WireFormatLite::TYPE_##UPPERCASE: { \ 1229 CPP_LOWERCASE value; \ 1230 if (!WireFormatLite::ReadPrimitive< \ 1231 CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>( \ 1232 input, &value)) return false; \ 1233 if (extension.is_repeated) { \ 1234 Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \ 1235 extension.is_packed, value, \ 1236 extension.descriptor); \ 1237 } else { \ 1238 Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value, \ 1239 extension.descriptor); \ 1240 } \ 1241 } break 1242 1243 HANDLE_TYPE( INT32, Int32, int32); 1244 HANDLE_TYPE( INT64, Int64, int64); 1245 HANDLE_TYPE( UINT32, UInt32, uint32); 1246 HANDLE_TYPE( UINT64, UInt64, uint64); 1247 HANDLE_TYPE( SINT32, Int32, int32); 1248 HANDLE_TYPE( SINT64, Int64, int64); 1249 HANDLE_TYPE( FIXED32, UInt32, uint32); 1250 HANDLE_TYPE( FIXED64, UInt64, uint64); 1251 HANDLE_TYPE(SFIXED32, Int32, int32); 1252 HANDLE_TYPE(SFIXED64, Int64, int64); 1253 HANDLE_TYPE( FLOAT, Float, float); 1254 HANDLE_TYPE( DOUBLE, Double, double); 1255 HANDLE_TYPE( BOOL, Bool, bool); 1256 #undef HANDLE_TYPE 1257 1258 case WireFormatLite::TYPE_ENUM: { 1259 int value; 1260 if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>( 1261 input, &value)) return false; 1262 1263 if (!extension.enum_validity_check.func( 1264 extension.enum_validity_check.arg, value)) { 1265 // Invalid value. Treat as unknown. 1266 field_skipper->SkipUnknownEnum(number, value); 1267 } else if (extension.is_repeated) { 1268 AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed, value, 1269 extension.descriptor); 1270 } else { 1271 SetEnum(number, WireFormatLite::TYPE_ENUM, value, 1272 extension.descriptor); 1273 } 1274 break; 1275 } 1276 1277 case WireFormatLite::TYPE_STRING: { 1278 string* value = extension.is_repeated ? 1279 AddString(number, WireFormatLite::TYPE_STRING, extension.descriptor) : 1280 MutableString(number, WireFormatLite::TYPE_STRING, 1281 extension.descriptor); 1282 if (!WireFormatLite::ReadString(input, value)) return false; 1283 break; 1284 } 1285 1286 case WireFormatLite::TYPE_BYTES: { 1287 string* value = extension.is_repeated ? 1288 AddString(number, WireFormatLite::TYPE_BYTES, extension.descriptor) : 1289 MutableString(number, WireFormatLite::TYPE_BYTES, 1290 extension.descriptor); 1291 if (!WireFormatLite::ReadBytes(input, value)) return false; 1292 break; 1293 } 1294 1295 case WireFormatLite::TYPE_GROUP: { 1296 MessageLite* value = extension.is_repeated ? 1297 AddMessage(number, WireFormatLite::TYPE_GROUP, 1298 *extension.message_prototype, extension.descriptor) : 1299 MutableMessage(number, WireFormatLite::TYPE_GROUP, 1300 *extension.message_prototype, extension.descriptor); 1301 if (!WireFormatLite::ReadGroup(number, input, value)) return false; 1302 break; 1303 } 1304 1305 case WireFormatLite::TYPE_MESSAGE: { 1306 MessageLite* value = extension.is_repeated ? 1307 AddMessage(number, WireFormatLite::TYPE_MESSAGE, 1308 *extension.message_prototype, extension.descriptor) : 1309 MutableMessage(number, WireFormatLite::TYPE_MESSAGE, 1310 *extension.message_prototype, extension.descriptor); 1311 if (!WireFormatLite::ReadMessage(input, value)) return false; 1312 break; 1313 } 1314 } 1315 } 1316 1317 return true; 1318 } 1319 1320 bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, 1321 const MessageLite* containing_type) { 1322 FieldSkipper skipper; 1323 GeneratedExtensionFinder finder(containing_type); 1324 return ParseField(tag, input, &finder, &skipper); 1325 } 1326 1327 bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, 1328 const MessageLite* containing_type, 1329 io::CodedOutputStream* unknown_fields) { 1330 CodedOutputStreamFieldSkipper skipper(unknown_fields); 1331 GeneratedExtensionFinder finder(containing_type); 1332 return ParseField(tag, input, &finder, &skipper); 1333 } 1334 1335 // Defined in extension_set_heavy.cc. 1336 // bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, 1337 // const MessageLite* containing_type, 1338 // UnknownFieldSet* unknown_fields) 1339 1340 // Defined in extension_set_heavy.cc. 1341 // bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, 1342 // const MessageLite* containing_type, 1343 // UnknownFieldSet* unknown_fields); 1344 1345 void ExtensionSet::SerializeWithCachedSizes( 1346 int start_field_number, int end_field_number, 1347 io::CodedOutputStream* output) const { 1348 map<int, Extension>::const_iterator iter; 1349 for (iter = extensions_.lower_bound(start_field_number); 1350 iter != extensions_.end() && iter->first < end_field_number; 1351 ++iter) { 1352 iter->second.SerializeFieldWithCachedSizes(iter->first, output); 1353 } 1354 } 1355 1356 int ExtensionSet::ByteSize() const { 1357 int total_size = 0; 1358 1359 for (map<int, Extension>::const_iterator iter = extensions_.begin(); 1360 iter != extensions_.end(); ++iter) { 1361 total_size += iter->second.ByteSize(iter->first); 1362 } 1363 1364 return total_size; 1365 } 1366 1367 // Defined in extension_set_heavy.cc. 1368 // int ExtensionSet::SpaceUsedExcludingSelf() const 1369 1370 bool ExtensionSet::MaybeNewExtension(int number, 1371 const FieldDescriptor* descriptor, 1372 Extension** result) { 1373 pair<map<int, Extension>::iterator, bool> insert_result = 1374 extensions_.insert(std::make_pair(number, Extension())); 1375 *result = &insert_result.first->second; 1376 (*result)->descriptor = descriptor; 1377 return insert_result.second; 1378 } 1379 1380 // =================================================================== 1381 // Methods of ExtensionSet::Extension 1382 1383 void ExtensionSet::Extension::Clear() { 1384 if (is_repeated) { 1385 switch (cpp_type(type)) { 1386 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ 1387 case WireFormatLite::CPPTYPE_##UPPERCASE: \ 1388 repeated_##LOWERCASE##_value->Clear(); \ 1389 break 1390 1391 HANDLE_TYPE( INT32, int32); 1392 HANDLE_TYPE( INT64, int64); 1393 HANDLE_TYPE( UINT32, uint32); 1394 HANDLE_TYPE( UINT64, uint64); 1395 HANDLE_TYPE( FLOAT, float); 1396 HANDLE_TYPE( DOUBLE, double); 1397 HANDLE_TYPE( BOOL, bool); 1398 HANDLE_TYPE( ENUM, enum); 1399 HANDLE_TYPE( STRING, string); 1400 HANDLE_TYPE(MESSAGE, message); 1401 #undef HANDLE_TYPE 1402 } 1403 } else { 1404 if (!is_cleared) { 1405 switch (cpp_type(type)) { 1406 case WireFormatLite::CPPTYPE_STRING: 1407 string_value->clear(); 1408 break; 1409 case WireFormatLite::CPPTYPE_MESSAGE: 1410 if (is_lazy) { 1411 lazymessage_value->Clear(); 1412 } else { 1413 message_value->Clear(); 1414 } 1415 break; 1416 default: 1417 // No need to do anything. Get*() will return the default value 1418 // as long as is_cleared is true and Set*() will overwrite the 1419 // previous value. 1420 break; 1421 } 1422 1423 is_cleared = true; 1424 } 1425 } 1426 } 1427 1428 void ExtensionSet::Extension::SerializeFieldWithCachedSizes( 1429 int number, 1430 io::CodedOutputStream* output) const { 1431 if (is_repeated) { 1432 if (is_packed) { 1433 if (cached_size == 0) return; 1434 1435 WireFormatLite::WriteTag(number, 1436 WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output); 1437 output->WriteVarint32(cached_size); 1438 1439 switch (real_type(type)) { 1440 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ 1441 case WireFormatLite::TYPE_##UPPERCASE: \ 1442 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ 1443 WireFormatLite::Write##CAMELCASE##NoTag( \ 1444 repeated_##LOWERCASE##_value->Get(i), output); \ 1445 } \ 1446 break 1447 1448 HANDLE_TYPE( INT32, Int32, int32); 1449 HANDLE_TYPE( INT64, Int64, int64); 1450 HANDLE_TYPE( UINT32, UInt32, uint32); 1451 HANDLE_TYPE( UINT64, UInt64, uint64); 1452 HANDLE_TYPE( SINT32, SInt32, int32); 1453 HANDLE_TYPE( SINT64, SInt64, int64); 1454 HANDLE_TYPE( FIXED32, Fixed32, uint32); 1455 HANDLE_TYPE( FIXED64, Fixed64, uint64); 1456 HANDLE_TYPE(SFIXED32, SFixed32, int32); 1457 HANDLE_TYPE(SFIXED64, SFixed64, int64); 1458 HANDLE_TYPE( FLOAT, Float, float); 1459 HANDLE_TYPE( DOUBLE, Double, double); 1460 HANDLE_TYPE( BOOL, Bool, bool); 1461 HANDLE_TYPE( ENUM, Enum, enum); 1462 #undef HANDLE_TYPE 1463 1464 case WireFormatLite::TYPE_STRING: 1465 case WireFormatLite::TYPE_BYTES: 1466 case WireFormatLite::TYPE_GROUP: 1467 case WireFormatLite::TYPE_MESSAGE: 1468 GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed."; 1469 break; 1470 } 1471 } else { 1472 switch (real_type(type)) { 1473 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ 1474 case WireFormatLite::TYPE_##UPPERCASE: \ 1475 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ 1476 WireFormatLite::Write##CAMELCASE(number, \ 1477 repeated_##LOWERCASE##_value->Get(i), output); \ 1478 } \ 1479 break 1480 1481 HANDLE_TYPE( INT32, Int32, int32); 1482 HANDLE_TYPE( INT64, Int64, int64); 1483 HANDLE_TYPE( UINT32, UInt32, uint32); 1484 HANDLE_TYPE( UINT64, UInt64, uint64); 1485 HANDLE_TYPE( SINT32, SInt32, int32); 1486 HANDLE_TYPE( SINT64, SInt64, int64); 1487 HANDLE_TYPE( FIXED32, Fixed32, uint32); 1488 HANDLE_TYPE( FIXED64, Fixed64, uint64); 1489 HANDLE_TYPE(SFIXED32, SFixed32, int32); 1490 HANDLE_TYPE(SFIXED64, SFixed64, int64); 1491 HANDLE_TYPE( FLOAT, Float, float); 1492 HANDLE_TYPE( DOUBLE, Double, double); 1493 HANDLE_TYPE( BOOL, Bool, bool); 1494 HANDLE_TYPE( STRING, String, string); 1495 HANDLE_TYPE( BYTES, Bytes, string); 1496 HANDLE_TYPE( ENUM, Enum, enum); 1497 HANDLE_TYPE( GROUP, Group, message); 1498 HANDLE_TYPE( MESSAGE, Message, message); 1499 #undef HANDLE_TYPE 1500 } 1501 } 1502 } else if (!is_cleared) { 1503 switch (real_type(type)) { 1504 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE) \ 1505 case WireFormatLite::TYPE_##UPPERCASE: \ 1506 WireFormatLite::Write##CAMELCASE(number, VALUE, output); \ 1507 break 1508 1509 HANDLE_TYPE( INT32, Int32, int32_value); 1510 HANDLE_TYPE( INT64, Int64, int64_value); 1511 HANDLE_TYPE( UINT32, UInt32, uint32_value); 1512 HANDLE_TYPE( UINT64, UInt64, uint64_value); 1513 HANDLE_TYPE( SINT32, SInt32, int32_value); 1514 HANDLE_TYPE( SINT64, SInt64, int64_value); 1515 HANDLE_TYPE( FIXED32, Fixed32, uint32_value); 1516 HANDLE_TYPE( FIXED64, Fixed64, uint64_value); 1517 HANDLE_TYPE(SFIXED32, SFixed32, int32_value); 1518 HANDLE_TYPE(SFIXED64, SFixed64, int64_value); 1519 HANDLE_TYPE( FLOAT, Float, float_value); 1520 HANDLE_TYPE( DOUBLE, Double, double_value); 1521 HANDLE_TYPE( BOOL, Bool, bool_value); 1522 HANDLE_TYPE( STRING, String, *string_value); 1523 HANDLE_TYPE( BYTES, Bytes, *string_value); 1524 HANDLE_TYPE( ENUM, Enum, enum_value); 1525 HANDLE_TYPE( GROUP, Group, *message_value); 1526 #undef HANDLE_TYPE 1527 case WireFormatLite::TYPE_MESSAGE: 1528 if (is_lazy) { 1529 lazymessage_value->WriteMessage(number, output); 1530 } else { 1531 WireFormatLite::WriteMessage(number, *message_value, output); 1532 } 1533 break; 1534 } 1535 } 1536 } 1537 1538 int ExtensionSet::Extension::ByteSize(int number) const { 1539 int result = 0; 1540 1541 if (is_repeated) { 1542 if (is_packed) { 1543 switch (real_type(type)) { 1544 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ 1545 case WireFormatLite::TYPE_##UPPERCASE: \ 1546 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ 1547 result += WireFormatLite::CAMELCASE##Size( \ 1548 repeated_##LOWERCASE##_value->Get(i)); \ 1549 } \ 1550 break 1551 1552 HANDLE_TYPE( INT32, Int32, int32); 1553 HANDLE_TYPE( INT64, Int64, int64); 1554 HANDLE_TYPE( UINT32, UInt32, uint32); 1555 HANDLE_TYPE( UINT64, UInt64, uint64); 1556 HANDLE_TYPE( SINT32, SInt32, int32); 1557 HANDLE_TYPE( SINT64, SInt64, int64); 1558 HANDLE_TYPE( ENUM, Enum, enum); 1559 #undef HANDLE_TYPE 1560 1561 // Stuff with fixed size. 1562 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ 1563 case WireFormatLite::TYPE_##UPPERCASE: \ 1564 result += WireFormatLite::k##CAMELCASE##Size * \ 1565 repeated_##LOWERCASE##_value->size(); \ 1566 break 1567 HANDLE_TYPE( FIXED32, Fixed32, uint32); 1568 HANDLE_TYPE( FIXED64, Fixed64, uint64); 1569 HANDLE_TYPE(SFIXED32, SFixed32, int32); 1570 HANDLE_TYPE(SFIXED64, SFixed64, int64); 1571 HANDLE_TYPE( FLOAT, Float, float); 1572 HANDLE_TYPE( DOUBLE, Double, double); 1573 HANDLE_TYPE( BOOL, Bool, bool); 1574 #undef HANDLE_TYPE 1575 1576 case WireFormatLite::TYPE_STRING: 1577 case WireFormatLite::TYPE_BYTES: 1578 case WireFormatLite::TYPE_GROUP: 1579 case WireFormatLite::TYPE_MESSAGE: 1580 GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed."; 1581 break; 1582 } 1583 1584 cached_size = result; 1585 if (result > 0) { 1586 result += io::CodedOutputStream::VarintSize32(result); 1587 result += io::CodedOutputStream::VarintSize32( 1588 WireFormatLite::MakeTag(number, 1589 WireFormatLite::WIRETYPE_LENGTH_DELIMITED)); 1590 } 1591 } else { 1592 int tag_size = WireFormatLite::TagSize(number, real_type(type)); 1593 1594 switch (real_type(type)) { 1595 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ 1596 case WireFormatLite::TYPE_##UPPERCASE: \ 1597 result += tag_size * repeated_##LOWERCASE##_value->size(); \ 1598 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ 1599 result += WireFormatLite::CAMELCASE##Size( \ 1600 repeated_##LOWERCASE##_value->Get(i)); \ 1601 } \ 1602 break 1603 1604 HANDLE_TYPE( INT32, Int32, int32); 1605 HANDLE_TYPE( INT64, Int64, int64); 1606 HANDLE_TYPE( UINT32, UInt32, uint32); 1607 HANDLE_TYPE( UINT64, UInt64, uint64); 1608 HANDLE_TYPE( SINT32, SInt32, int32); 1609 HANDLE_TYPE( SINT64, SInt64, int64); 1610 HANDLE_TYPE( STRING, String, string); 1611 HANDLE_TYPE( BYTES, Bytes, string); 1612 HANDLE_TYPE( ENUM, Enum, enum); 1613 HANDLE_TYPE( GROUP, Group, message); 1614 HANDLE_TYPE( MESSAGE, Message, message); 1615 #undef HANDLE_TYPE 1616 1617 // Stuff with fixed size. 1618 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ 1619 case WireFormatLite::TYPE_##UPPERCASE: \ 1620 result += (tag_size + WireFormatLite::k##CAMELCASE##Size) * \ 1621 repeated_##LOWERCASE##_value->size(); \ 1622 break 1623 HANDLE_TYPE( FIXED32, Fixed32, uint32); 1624 HANDLE_TYPE( FIXED64, Fixed64, uint64); 1625 HANDLE_TYPE(SFIXED32, SFixed32, int32); 1626 HANDLE_TYPE(SFIXED64, SFixed64, int64); 1627 HANDLE_TYPE( FLOAT, Float, float); 1628 HANDLE_TYPE( DOUBLE, Double, double); 1629 HANDLE_TYPE( BOOL, Bool, bool); 1630 #undef HANDLE_TYPE 1631 } 1632 } 1633 } else if (!is_cleared) { 1634 result += WireFormatLite::TagSize(number, real_type(type)); 1635 switch (real_type(type)) { 1636 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ 1637 case WireFormatLite::TYPE_##UPPERCASE: \ 1638 result += WireFormatLite::CAMELCASE##Size(LOWERCASE); \ 1639 break 1640 1641 HANDLE_TYPE( INT32, Int32, int32_value); 1642 HANDLE_TYPE( INT64, Int64, int64_value); 1643 HANDLE_TYPE( UINT32, UInt32, uint32_value); 1644 HANDLE_TYPE( UINT64, UInt64, uint64_value); 1645 HANDLE_TYPE( SINT32, SInt32, int32_value); 1646 HANDLE_TYPE( SINT64, SInt64, int64_value); 1647 HANDLE_TYPE( STRING, String, *string_value); 1648 HANDLE_TYPE( BYTES, Bytes, *string_value); 1649 HANDLE_TYPE( ENUM, Enum, enum_value); 1650 HANDLE_TYPE( GROUP, Group, *message_value); 1651 #undef HANDLE_TYPE 1652 case WireFormatLite::TYPE_MESSAGE: { 1653 if (is_lazy) { 1654 int size = lazymessage_value->ByteSize(); 1655 result += io::CodedOutputStream::VarintSize32(size) + size; 1656 } else { 1657 result += WireFormatLite::MessageSize(*message_value); 1658 } 1659 break; 1660 } 1661 1662 // Stuff with fixed size. 1663 #define HANDLE_TYPE(UPPERCASE, CAMELCASE) \ 1664 case WireFormatLite::TYPE_##UPPERCASE: \ 1665 result += WireFormatLite::k##CAMELCASE##Size; \ 1666 break 1667 HANDLE_TYPE( FIXED32, Fixed32); 1668 HANDLE_TYPE( FIXED64, Fixed64); 1669 HANDLE_TYPE(SFIXED32, SFixed32); 1670 HANDLE_TYPE(SFIXED64, SFixed64); 1671 HANDLE_TYPE( FLOAT, Float); 1672 HANDLE_TYPE( DOUBLE, Double); 1673 HANDLE_TYPE( BOOL, Bool); 1674 #undef HANDLE_TYPE 1675 } 1676 } 1677 1678 return result; 1679 } 1680 1681 int ExtensionSet::Extension::GetSize() const { 1682 GOOGLE_DCHECK(is_repeated); 1683 switch (cpp_type(type)) { 1684 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ 1685 case WireFormatLite::CPPTYPE_##UPPERCASE: \ 1686 return repeated_##LOWERCASE##_value->size() 1687 1688 HANDLE_TYPE( INT32, int32); 1689 HANDLE_TYPE( INT64, int64); 1690 HANDLE_TYPE( UINT32, uint32); 1691 HANDLE_TYPE( UINT64, uint64); 1692 HANDLE_TYPE( FLOAT, float); 1693 HANDLE_TYPE( DOUBLE, double); 1694 HANDLE_TYPE( BOOL, bool); 1695 HANDLE_TYPE( ENUM, enum); 1696 HANDLE_TYPE( STRING, string); 1697 HANDLE_TYPE(MESSAGE, message); 1698 #undef HANDLE_TYPE 1699 } 1700 1701 GOOGLE_LOG(FATAL) << "Can't get here."; 1702 return 0; 1703 } 1704 1705 // This function deletes all allocated objects. This function should be only 1706 // called if the Extension was created with an arena. 1707 void ExtensionSet::Extension::Free() { 1708 if (is_repeated) { 1709 switch (cpp_type(type)) { 1710 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ 1711 case WireFormatLite::CPPTYPE_##UPPERCASE: \ 1712 delete repeated_##LOWERCASE##_value; \ 1713 break 1714 1715 HANDLE_TYPE( INT32, int32); 1716 HANDLE_TYPE( INT64, int64); 1717 HANDLE_TYPE( UINT32, uint32); 1718 HANDLE_TYPE( UINT64, uint64); 1719 HANDLE_TYPE( FLOAT, float); 1720 HANDLE_TYPE( DOUBLE, double); 1721 HANDLE_TYPE( BOOL, bool); 1722 HANDLE_TYPE( ENUM, enum); 1723 HANDLE_TYPE( STRING, string); 1724 HANDLE_TYPE(MESSAGE, message); 1725 #undef HANDLE_TYPE 1726 } 1727 } else { 1728 switch (cpp_type(type)) { 1729 case WireFormatLite::CPPTYPE_STRING: 1730 delete string_value; 1731 break; 1732 case WireFormatLite::CPPTYPE_MESSAGE: 1733 if (is_lazy) { 1734 delete lazymessage_value; 1735 } else { 1736 delete message_value; 1737 } 1738 break; 1739 default: 1740 break; 1741 } 1742 } 1743 } 1744 1745 // Defined in extension_set_heavy.cc. 1746 // int ExtensionSet::Extension::SpaceUsedExcludingSelf() const 1747 1748 // ================================================================== 1749 // Default repeated field instances for iterator-compatible accessors 1750 1751 GOOGLE_PROTOBUF_DECLARE_ONCE(repeated_primitive_generic_type_traits_once_init_); 1752 GOOGLE_PROTOBUF_DECLARE_ONCE(repeated_string_type_traits_once_init_); 1753 GOOGLE_PROTOBUF_DECLARE_ONCE(repeated_message_generic_type_traits_once_init_); 1754 1755 void RepeatedPrimitiveGenericTypeTraits::InitializeDefaultRepeatedFields() { 1756 default_repeated_field_int32_ = new RepeatedField<int32>; 1757 default_repeated_field_int64_ = new RepeatedField<int64>; 1758 default_repeated_field_uint32_ = new RepeatedField<uint32>; 1759 default_repeated_field_uint64_ = new RepeatedField<uint64>; 1760 default_repeated_field_double_ = new RepeatedField<double>; 1761 default_repeated_field_float_ = new RepeatedField<float>; 1762 default_repeated_field_bool_ = new RepeatedField<bool>; 1763 OnShutdown(&DestroyDefaultRepeatedFields); 1764 } 1765 1766 void RepeatedPrimitiveGenericTypeTraits::DestroyDefaultRepeatedFields() { 1767 delete default_repeated_field_int32_; 1768 delete default_repeated_field_int64_; 1769 delete default_repeated_field_uint32_; 1770 delete default_repeated_field_uint64_; 1771 delete default_repeated_field_double_; 1772 delete default_repeated_field_float_; 1773 delete default_repeated_field_bool_; 1774 } 1775 1776 void RepeatedStringTypeTraits::InitializeDefaultRepeatedFields() { 1777 default_repeated_field_ = new RepeatedFieldType; 1778 OnShutdown(&DestroyDefaultRepeatedFields); 1779 } 1780 1781 void RepeatedStringTypeTraits::DestroyDefaultRepeatedFields() { 1782 delete default_repeated_field_; 1783 } 1784 1785 void RepeatedMessageGenericTypeTraits::InitializeDefaultRepeatedFields() { 1786 default_repeated_field_ = new RepeatedFieldType; 1787 OnShutdown(&DestroyDefaultRepeatedFields); 1788 } 1789 1790 void RepeatedMessageGenericTypeTraits::DestroyDefaultRepeatedFields() { 1791 delete default_repeated_field_; 1792 } 1793 1794 const RepeatedField<int32>* 1795 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int32_ = NULL; 1796 const RepeatedField<int64>* 1797 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int64_ = NULL; 1798 const RepeatedField<uint32>* 1799 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint32_ = NULL; 1800 const RepeatedField<uint64>* 1801 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint64_ = NULL; 1802 const RepeatedField<double>* 1803 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_double_ = NULL; 1804 const RepeatedField<float>* 1805 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_float_ = NULL; 1806 const RepeatedField<bool>* 1807 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_bool_ = NULL; 1808 const RepeatedStringTypeTraits::RepeatedFieldType* 1809 RepeatedStringTypeTraits::default_repeated_field_ = NULL; 1810 const RepeatedMessageGenericTypeTraits::RepeatedFieldType* 1811 RepeatedMessageGenericTypeTraits::default_repeated_field_ = NULL; 1812 1813 } // namespace internal 1814 } // namespace protobuf 1815 } // namespace google 1816