1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // http://code.google.com/p/protobuf/ 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/io/zero_copy_stream_impl.h> 42 #include <google/protobuf/wire_format_lite_inl.h> 43 #include <google/protobuf/repeated_field.h> 44 #include <google/protobuf/stubs/map-util.h> 45 46 namespace google { 47 namespace protobuf { 48 namespace internal { 49 50 namespace { 51 52 inline WireFormatLite::FieldType real_type(FieldType type) { 53 GOOGLE_DCHECK(type > 0 && type <= WireFormatLite::MAX_FIELD_TYPE); 54 return static_cast<WireFormatLite::FieldType>(type); 55 } 56 57 inline WireFormatLite::CppType cpp_type(FieldType type) { 58 return WireFormatLite::FieldTypeToCppType(real_type(type)); 59 } 60 61 // Registry stuff. 62 typedef hash_map<pair<const MessageLite*, int>, 63 ExtensionInfo> ExtensionRegistry; 64 ExtensionRegistry* registry_ = NULL; 65 GOOGLE_PROTOBUF_DECLARE_ONCE(registry_init_); 66 67 void DeleteRegistry() { 68 delete registry_; 69 registry_ = NULL; 70 } 71 72 void InitRegistry() { 73 registry_ = new ExtensionRegistry; 74 OnShutdown(&DeleteRegistry); 75 } 76 77 // This function is only called at startup, so there is no need for thread- 78 // safety. 79 void Register(const MessageLite* containing_type, 80 int number, ExtensionInfo info) { 81 ::google::protobuf::GoogleOnceInit(®istry_init_, &InitRegistry); 82 83 if (!InsertIfNotPresent(registry_, make_pair(containing_type, number), 84 info)) { 85 GOOGLE_LOG(FATAL) << "Multiple extension registrations for type \"" 86 << containing_type->GetTypeName() 87 << "\", field number " << number << "."; 88 } 89 } 90 91 const ExtensionInfo* FindRegisteredExtension( 92 const MessageLite* containing_type, int number) { 93 return (registry_ == NULL) ? NULL : 94 FindOrNull(*registry_, make_pair(containing_type, number)); 95 } 96 97 } // namespace 98 99 ExtensionFinder::~ExtensionFinder() {} 100 101 bool GeneratedExtensionFinder::Find(int number, ExtensionInfo* output) { 102 const ExtensionInfo* extension = 103 FindRegisteredExtension(containing_type_, number); 104 if (extension == NULL) { 105 return false; 106 } else { 107 *output = *extension; 108 return true; 109 } 110 } 111 112 void ExtensionSet::RegisterExtension(const MessageLite* containing_type, 113 int number, FieldType type, 114 bool is_repeated, bool is_packed) { 115 GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_ENUM); 116 GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_MESSAGE); 117 GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_GROUP); 118 ExtensionInfo info(type, is_repeated, is_packed); 119 Register(containing_type, number, info); 120 } 121 122 static bool CallNoArgValidityFunc(const void* arg, int number) { 123 // Note: Must use C-style cast here rather than reinterpret_cast because 124 // the C++ standard at one point did not allow casts between function and 125 // data pointers and some compilers enforce this for C++-style casts. No 126 // compiler enforces it for C-style casts since lots of C-style code has 127 // relied on these kinds of casts for a long time, despite being 128 // technically undefined. See: 129 // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#195 130 // Also note: Some compilers do not allow function pointers to be "const". 131 // Which makes sense, I suppose, because it's meaningless. 132 return ((EnumValidityFunc*)arg)(number); 133 } 134 135 void ExtensionSet::RegisterEnumExtension(const MessageLite* containing_type, 136 int number, FieldType type, 137 bool is_repeated, bool is_packed, 138 EnumValidityFunc* is_valid) { 139 GOOGLE_CHECK_EQ(type, WireFormatLite::TYPE_ENUM); 140 ExtensionInfo info(type, is_repeated, is_packed); 141 info.enum_validity_check.func = CallNoArgValidityFunc; 142 // See comment in CallNoArgValidityFunc() about why we use a c-style cast. 143 info.enum_validity_check.arg = (void*)is_valid; 144 Register(containing_type, number, info); 145 } 146 147 void ExtensionSet::RegisterMessageExtension(const MessageLite* containing_type, 148 int number, FieldType type, 149 bool is_repeated, bool is_packed, 150 const MessageLite* prototype) { 151 GOOGLE_CHECK(type == WireFormatLite::TYPE_MESSAGE || 152 type == WireFormatLite::TYPE_GROUP); 153 ExtensionInfo info(type, is_repeated, is_packed); 154 info.message_prototype = prototype; 155 Register(containing_type, number, info); 156 } 157 158 159 // =================================================================== 160 // Constructors and basic methods. 161 162 ExtensionSet::ExtensionSet() {} 163 164 ExtensionSet::~ExtensionSet() { 165 for (map<int, Extension>::iterator iter = extensions_.begin(); 166 iter != extensions_.end(); ++iter) { 167 iter->second.Free(); 168 } 169 } 170 171 // Defined in extension_set_heavy.cc. 172 // void ExtensionSet::AppendToList(const Descriptor* containing_type, 173 // const DescriptorPool* pool, 174 // vector<const FieldDescriptor*>* output) const 175 176 bool ExtensionSet::Has(int number) const { 177 map<int, Extension>::const_iterator iter = extensions_.find(number); 178 if (iter == extensions_.end()) return false; 179 GOOGLE_DCHECK(!iter->second.is_repeated); 180 return !iter->second.is_cleared; 181 } 182 183 int ExtensionSet::NumExtensions() const { 184 int result = 0; 185 for (map<int, Extension>::const_iterator iter = extensions_.begin(); 186 iter != extensions_.end(); ++iter) { 187 if (!iter->second.is_cleared) { 188 ++result; 189 } 190 } 191 return result; 192 } 193 194 int ExtensionSet::ExtensionSize(int number) const { 195 map<int, Extension>::const_iterator iter = extensions_.find(number); 196 if (iter == extensions_.end()) return false; 197 return iter->second.GetSize(); 198 } 199 200 FieldType ExtensionSet::ExtensionType(int number) const { 201 map<int, Extension>::const_iterator iter = extensions_.find(number); 202 if (iter == extensions_.end()) { 203 GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (1). "; 204 return 0; 205 } 206 if (iter->second.is_cleared) { 207 GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (2). "; 208 } 209 return iter->second.type; 210 } 211 212 void ExtensionSet::ClearExtension(int number) { 213 map<int, Extension>::iterator iter = extensions_.find(number); 214 if (iter == extensions_.end()) return; 215 iter->second.Clear(); 216 } 217 218 // =================================================================== 219 // Field accessors 220 221 namespace { 222 223 enum Cardinality { 224 REPEATED, 225 OPTIONAL 226 }; 227 228 } // namespace 229 230 #define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE) \ 231 GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? REPEATED : OPTIONAL, LABEL); \ 232 GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), WireFormatLite::CPPTYPE_##CPPTYPE) 233 234 // ------------------------------------------------------------------- 235 // Primitives 236 237 #define PRIMITIVE_ACCESSORS(UPPERCASE, LOWERCASE, CAMELCASE) \ 238 \ 239 LOWERCASE ExtensionSet::Get##CAMELCASE(int number, \ 240 LOWERCASE default_value) const { \ 241 map<int, Extension>::const_iterator iter = extensions_.find(number); \ 242 if (iter == extensions_.end() || iter->second.is_cleared) { \ 243 return default_value; \ 244 } else { \ 245 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, UPPERCASE); \ 246 return iter->second.LOWERCASE##_value; \ 247 } \ 248 } \ 249 \ 250 void ExtensionSet::Set##CAMELCASE(int number, FieldType type, \ 251 LOWERCASE value, \ 252 const FieldDescriptor* descriptor) { \ 253 Extension* extension; \ 254 if (MaybeNewExtension(number, descriptor, &extension)) { \ 255 extension->type = type; \ 256 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \ 257 extension->is_repeated = false; \ 258 } else { \ 259 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, UPPERCASE); \ 260 } \ 261 extension->is_cleared = false; \ 262 extension->LOWERCASE##_value = value; \ 263 } \ 264 \ 265 LOWERCASE ExtensionSet::GetRepeated##CAMELCASE(int number, int index) const { \ 266 map<int, Extension>::const_iterator iter = extensions_.find(number); \ 267 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \ 268 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE); \ 269 return iter->second.repeated_##LOWERCASE##_value->Get(index); \ 270 } \ 271 \ 272 void ExtensionSet::SetRepeated##CAMELCASE( \ 273 int number, int index, LOWERCASE value) { \ 274 map<int, Extension>::iterator iter = extensions_.find(number); \ 275 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \ 276 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE); \ 277 iter->second.repeated_##LOWERCASE##_value->Set(index, value); \ 278 } \ 279 \ 280 void ExtensionSet::Add##CAMELCASE(int number, FieldType type, \ 281 bool packed, LOWERCASE value, \ 282 const FieldDescriptor* descriptor) { \ 283 Extension* extension; \ 284 if (MaybeNewExtension(number, descriptor, &extension)) { \ 285 extension->type = type; \ 286 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \ 287 extension->is_repeated = true; \ 288 extension->is_packed = packed; \ 289 extension->repeated_##LOWERCASE##_value = new RepeatedField<LOWERCASE>(); \ 290 } else { \ 291 GOOGLE_DCHECK_TYPE(*extension, REPEATED, UPPERCASE); \ 292 GOOGLE_DCHECK_EQ(extension->is_packed, packed); \ 293 } \ 294 extension->repeated_##LOWERCASE##_value->Add(value); \ 295 } 296 297 PRIMITIVE_ACCESSORS( INT32, int32, Int32) 298 PRIMITIVE_ACCESSORS( INT64, int64, Int64) 299 PRIMITIVE_ACCESSORS(UINT32, uint32, UInt32) 300 PRIMITIVE_ACCESSORS(UINT64, uint64, UInt64) 301 PRIMITIVE_ACCESSORS( FLOAT, float, Float) 302 PRIMITIVE_ACCESSORS(DOUBLE, double, Double) 303 PRIMITIVE_ACCESSORS( BOOL, bool, Bool) 304 305 #undef PRIMITIVE_ACCESSORS 306 307 void* ExtensionSet::MutableRawRepeatedField(int number) { 308 // We assume that all the RepeatedField<>* pointers have the same 309 // size and alignment within the anonymous union in Extension. 310 map<int, Extension>::const_iterator iter = extensions_.find(number); 311 GOOGLE_CHECK(iter != extensions_.end()) << "no extension numbered " << number; 312 return iter->second.repeated_int32_value; 313 } 314 315 // ------------------------------------------------------------------- 316 // Enums 317 318 int ExtensionSet::GetEnum(int number, int default_value) const { 319 map<int, Extension>::const_iterator iter = extensions_.find(number); 320 if (iter == extensions_.end() || iter->second.is_cleared) { 321 // Not present. Return the default value. 322 return default_value; 323 } else { 324 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, ENUM); 325 return iter->second.enum_value; 326 } 327 } 328 329 void ExtensionSet::SetEnum(int number, FieldType type, int value, 330 const FieldDescriptor* descriptor) { 331 Extension* extension; 332 if (MaybeNewExtension(number, descriptor, &extension)) { 333 extension->type = type; 334 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM); 335 extension->is_repeated = false; 336 } else { 337 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, ENUM); 338 } 339 extension->is_cleared = false; 340 extension->enum_value = value; 341 } 342 343 int ExtensionSet::GetRepeatedEnum(int number, int index) const { 344 map<int, Extension>::const_iterator iter = extensions_.find(number); 345 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; 346 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM); 347 return iter->second.repeated_enum_value->Get(index); 348 } 349 350 void ExtensionSet::SetRepeatedEnum(int number, int index, int value) { 351 map<int, Extension>::iterator iter = extensions_.find(number); 352 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; 353 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM); 354 iter->second.repeated_enum_value->Set(index, value); 355 } 356 357 void ExtensionSet::AddEnum(int number, FieldType type, 358 bool packed, int value, 359 const FieldDescriptor* descriptor) { 360 Extension* extension; 361 if (MaybeNewExtension(number, descriptor, &extension)) { 362 extension->type = type; 363 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM); 364 extension->is_repeated = true; 365 extension->is_packed = packed; 366 extension->repeated_enum_value = new RepeatedField<int>(); 367 } else { 368 GOOGLE_DCHECK_TYPE(*extension, REPEATED, ENUM); 369 GOOGLE_DCHECK_EQ(extension->is_packed, packed); 370 } 371 extension->repeated_enum_value->Add(value); 372 } 373 374 // ------------------------------------------------------------------- 375 // Strings 376 377 const string& ExtensionSet::GetString(int number, 378 const string& default_value) const { 379 map<int, Extension>::const_iterator iter = extensions_.find(number); 380 if (iter == extensions_.end() || iter->second.is_cleared) { 381 // Not present. Return the default value. 382 return default_value; 383 } else { 384 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, STRING); 385 return *iter->second.string_value; 386 } 387 } 388 389 string* ExtensionSet::MutableString(int number, FieldType type, 390 const FieldDescriptor* descriptor) { 391 Extension* extension; 392 if (MaybeNewExtension(number, descriptor, &extension)) { 393 extension->type = type; 394 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING); 395 extension->is_repeated = false; 396 extension->string_value = new string; 397 } else { 398 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, STRING); 399 } 400 extension->is_cleared = false; 401 return extension->string_value; 402 } 403 404 const string& ExtensionSet::GetRepeatedString(int number, int index) const { 405 map<int, Extension>::const_iterator iter = extensions_.find(number); 406 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; 407 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING); 408 return iter->second.repeated_string_value->Get(index); 409 } 410 411 string* ExtensionSet::MutableRepeatedString(int number, int index) { 412 map<int, Extension>::iterator iter = extensions_.find(number); 413 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; 414 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING); 415 return iter->second.repeated_string_value->Mutable(index); 416 } 417 418 string* ExtensionSet::AddString(int number, FieldType type, 419 const FieldDescriptor* descriptor) { 420 Extension* extension; 421 if (MaybeNewExtension(number, descriptor, &extension)) { 422 extension->type = type; 423 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING); 424 extension->is_repeated = true; 425 extension->is_packed = false; 426 extension->repeated_string_value = new RepeatedPtrField<string>(); 427 } else { 428 GOOGLE_DCHECK_TYPE(*extension, REPEATED, STRING); 429 } 430 return extension->repeated_string_value->Add(); 431 } 432 433 // ------------------------------------------------------------------- 434 // Messages 435 436 const MessageLite& ExtensionSet::GetMessage( 437 int number, const MessageLite& default_value) const { 438 map<int, Extension>::const_iterator iter = extensions_.find(number); 439 if (iter == extensions_.end()) { 440 // Not present. Return the default value. 441 return default_value; 442 } else { 443 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE); 444 if (iter->second.is_lazy) { 445 return iter->second.lazymessage_value->GetMessage(default_value); 446 } else { 447 return *iter->second.message_value; 448 } 449 } 450 } 451 452 // Defined in extension_set_heavy.cc. 453 // const MessageLite& ExtensionSet::GetMessage(int number, 454 // const Descriptor* message_type, 455 // MessageFactory* factory) const 456 457 MessageLite* ExtensionSet::MutableMessage(int number, FieldType type, 458 const MessageLite& prototype, 459 const FieldDescriptor* descriptor) { 460 Extension* extension; 461 if (MaybeNewExtension(number, descriptor, &extension)) { 462 extension->type = type; 463 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE); 464 extension->is_repeated = false; 465 extension->is_lazy = false; 466 extension->message_value = prototype.New(); 467 extension->is_cleared = false; 468 return extension->message_value; 469 } else { 470 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE); 471 extension->is_cleared = false; 472 if (extension->is_lazy) { 473 return extension->lazymessage_value->MutableMessage(prototype); 474 } else { 475 return extension->message_value; 476 } 477 } 478 } 479 480 // Defined in extension_set_heavy.cc. 481 // MessageLite* ExtensionSet::MutableMessage(int number, FieldType type, 482 // const Descriptor* message_type, 483 // MessageFactory* factory) 484 485 void ExtensionSet::SetAllocatedMessage(int number, FieldType type, 486 const FieldDescriptor* descriptor, 487 MessageLite* message) { 488 if (message == NULL) { 489 ClearExtension(number); 490 return; 491 } 492 Extension* extension; 493 if (MaybeNewExtension(number, descriptor, &extension)) { 494 extension->type = type; 495 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE); 496 extension->is_repeated = false; 497 extension->is_lazy = false; 498 extension->message_value = message; 499 } else { 500 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE); 501 if (extension->is_lazy) { 502 extension->lazymessage_value->SetAllocatedMessage(message); 503 } else { 504 delete extension->message_value; 505 extension->message_value = message; 506 } 507 } 508 extension->is_cleared = false; 509 } 510 511 MessageLite* ExtensionSet::ReleaseMessage(int number, 512 const MessageLite& prototype) { 513 map<int, Extension>::iterator iter = extensions_.find(number); 514 if (iter == extensions_.end()) { 515 // Not present. Return NULL. 516 return NULL; 517 } else { 518 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE); 519 MessageLite* ret = NULL; 520 if (iter->second.is_lazy) { 521 ret = iter->second.lazymessage_value->ReleaseMessage(prototype); 522 delete iter->second.lazymessage_value; 523 } else { 524 ret = iter->second.message_value; 525 } 526 extensions_.erase(number); 527 return ret; 528 } 529 } 530 531 // Defined in extension_set_heavy.cc. 532 // MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor, 533 // MessageFactory* factory); 534 535 const MessageLite& ExtensionSet::GetRepeatedMessage( 536 int number, int index) const { 537 map<int, Extension>::const_iterator iter = extensions_.find(number); 538 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; 539 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE); 540 return iter->second.repeated_message_value->Get(index); 541 } 542 543 MessageLite* ExtensionSet::MutableRepeatedMessage(int number, int index) { 544 map<int, Extension>::iterator iter = extensions_.find(number); 545 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; 546 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE); 547 return iter->second.repeated_message_value->Mutable(index); 548 } 549 550 MessageLite* ExtensionSet::AddMessage(int number, FieldType type, 551 const MessageLite& prototype, 552 const FieldDescriptor* descriptor) { 553 Extension* extension; 554 if (MaybeNewExtension(number, descriptor, &extension)) { 555 extension->type = type; 556 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE); 557 extension->is_repeated = true; 558 extension->repeated_message_value = 559 new RepeatedPtrField<MessageLite>(); 560 } else { 561 GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE); 562 } 563 564 // RepeatedPtrField<MessageLite> does not know how to Add() since it cannot 565 // allocate an abstract object, so we have to be tricky. 566 MessageLite* result = extension->repeated_message_value 567 ->AddFromCleared<GenericTypeHandler<MessageLite> >(); 568 if (result == NULL) { 569 result = prototype.New(); 570 extension->repeated_message_value->AddAllocated(result); 571 } 572 return result; 573 } 574 575 // Defined in extension_set_heavy.cc. 576 // MessageLite* ExtensionSet::AddMessage(int number, FieldType type, 577 // const Descriptor* message_type, 578 // MessageFactory* factory) 579 580 #undef GOOGLE_DCHECK_TYPE 581 582 void ExtensionSet::RemoveLast(int number) { 583 map<int, Extension>::iterator iter = extensions_.find(number); 584 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; 585 586 Extension* extension = &iter->second; 587 GOOGLE_DCHECK(extension->is_repeated); 588 589 switch(cpp_type(extension->type)) { 590 case WireFormatLite::CPPTYPE_INT32: 591 extension->repeated_int32_value->RemoveLast(); 592 break; 593 case WireFormatLite::CPPTYPE_INT64: 594 extension->repeated_int64_value->RemoveLast(); 595 break; 596 case WireFormatLite::CPPTYPE_UINT32: 597 extension->repeated_uint32_value->RemoveLast(); 598 break; 599 case WireFormatLite::CPPTYPE_UINT64: 600 extension->repeated_uint64_value->RemoveLast(); 601 break; 602 case WireFormatLite::CPPTYPE_FLOAT: 603 extension->repeated_float_value->RemoveLast(); 604 break; 605 case WireFormatLite::CPPTYPE_DOUBLE: 606 extension->repeated_double_value->RemoveLast(); 607 break; 608 case WireFormatLite::CPPTYPE_BOOL: 609 extension->repeated_bool_value->RemoveLast(); 610 break; 611 case WireFormatLite::CPPTYPE_ENUM: 612 extension->repeated_enum_value->RemoveLast(); 613 break; 614 case WireFormatLite::CPPTYPE_STRING: 615 extension->repeated_string_value->RemoveLast(); 616 break; 617 case WireFormatLite::CPPTYPE_MESSAGE: 618 extension->repeated_message_value->RemoveLast(); 619 break; 620 } 621 } 622 623 MessageLite* ExtensionSet::ReleaseLast(int number) { 624 map<int, Extension>::iterator iter = extensions_.find(number); 625 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; 626 627 Extension* extension = &iter->second; 628 GOOGLE_DCHECK(extension->is_repeated); 629 GOOGLE_DCHECK(cpp_type(extension->type) == WireFormatLite::CPPTYPE_MESSAGE); 630 return extension->repeated_message_value->ReleaseLast(); 631 } 632 633 void ExtensionSet::SwapElements(int number, int index1, int index2) { 634 map<int, Extension>::iterator iter = extensions_.find(number); 635 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; 636 637 Extension* extension = &iter->second; 638 GOOGLE_DCHECK(extension->is_repeated); 639 640 switch(cpp_type(extension->type)) { 641 case WireFormatLite::CPPTYPE_INT32: 642 extension->repeated_int32_value->SwapElements(index1, index2); 643 break; 644 case WireFormatLite::CPPTYPE_INT64: 645 extension->repeated_int64_value->SwapElements(index1, index2); 646 break; 647 case WireFormatLite::CPPTYPE_UINT32: 648 extension->repeated_uint32_value->SwapElements(index1, index2); 649 break; 650 case WireFormatLite::CPPTYPE_UINT64: 651 extension->repeated_uint64_value->SwapElements(index1, index2); 652 break; 653 case WireFormatLite::CPPTYPE_FLOAT: 654 extension->repeated_float_value->SwapElements(index1, index2); 655 break; 656 case WireFormatLite::CPPTYPE_DOUBLE: 657 extension->repeated_double_value->SwapElements(index1, index2); 658 break; 659 case WireFormatLite::CPPTYPE_BOOL: 660 extension->repeated_bool_value->SwapElements(index1, index2); 661 break; 662 case WireFormatLite::CPPTYPE_ENUM: 663 extension->repeated_enum_value->SwapElements(index1, index2); 664 break; 665 case WireFormatLite::CPPTYPE_STRING: 666 extension->repeated_string_value->SwapElements(index1, index2); 667 break; 668 case WireFormatLite::CPPTYPE_MESSAGE: 669 extension->repeated_message_value->SwapElements(index1, index2); 670 break; 671 } 672 } 673 674 // =================================================================== 675 676 void ExtensionSet::Clear() { 677 for (map<int, Extension>::iterator iter = extensions_.begin(); 678 iter != extensions_.end(); ++iter) { 679 iter->second.Clear(); 680 } 681 } 682 683 void ExtensionSet::MergeFrom(const ExtensionSet& other) { 684 for (map<int, Extension>::const_iterator iter = other.extensions_.begin(); 685 iter != other.extensions_.end(); ++iter) { 686 const Extension& other_extension = iter->second; 687 688 if (other_extension.is_repeated) { 689 Extension* extension; 690 bool is_new = MaybeNewExtension(iter->first, other_extension.descriptor, 691 &extension); 692 if (is_new) { 693 // Extension did not already exist in set. 694 extension->type = other_extension.type; 695 extension->is_packed = other_extension.is_packed; 696 extension->is_repeated = true; 697 } else { 698 GOOGLE_DCHECK_EQ(extension->type, other_extension.type); 699 GOOGLE_DCHECK_EQ(extension->is_packed, other_extension.is_packed); 700 GOOGLE_DCHECK(extension->is_repeated); 701 } 702 703 switch (cpp_type(other_extension.type)) { 704 #define HANDLE_TYPE(UPPERCASE, LOWERCASE, REPEATED_TYPE) \ 705 case WireFormatLite::CPPTYPE_##UPPERCASE: \ 706 if (is_new) { \ 707 extension->repeated_##LOWERCASE##_value = \ 708 new REPEATED_TYPE; \ 709 } \ 710 extension->repeated_##LOWERCASE##_value->MergeFrom( \ 711 *other_extension.repeated_##LOWERCASE##_value); \ 712 break; 713 714 HANDLE_TYPE( INT32, int32, RepeatedField < int32>); 715 HANDLE_TYPE( INT64, int64, RepeatedField < int64>); 716 HANDLE_TYPE( UINT32, uint32, RepeatedField < uint32>); 717 HANDLE_TYPE( UINT64, uint64, RepeatedField < uint64>); 718 HANDLE_TYPE( FLOAT, float, RepeatedField < float>); 719 HANDLE_TYPE( DOUBLE, double, RepeatedField < double>); 720 HANDLE_TYPE( BOOL, bool, RepeatedField < bool>); 721 HANDLE_TYPE( ENUM, enum, RepeatedField < int>); 722 HANDLE_TYPE( STRING, string, RepeatedPtrField< string>); 723 #undef HANDLE_TYPE 724 725 case WireFormatLite::CPPTYPE_MESSAGE: 726 if (is_new) { 727 extension->repeated_message_value = 728 new RepeatedPtrField<MessageLite>(); 729 } 730 // We can't call RepeatedPtrField<MessageLite>::MergeFrom() because 731 // it would attempt to allocate new objects. 732 RepeatedPtrField<MessageLite>* other_repeated_message = 733 other_extension.repeated_message_value; 734 for (int i = 0; i < other_repeated_message->size(); i++) { 735 const MessageLite& other_message = other_repeated_message->Get(i); 736 MessageLite* target = extension->repeated_message_value 737 ->AddFromCleared<GenericTypeHandler<MessageLite> >(); 738 if (target == NULL) { 739 target = other_message.New(); 740 extension->repeated_message_value->AddAllocated(target); 741 } 742 target->CheckTypeAndMergeFrom(other_message); 743 } 744 break; 745 } 746 } else { 747 if (!other_extension.is_cleared) { 748 switch (cpp_type(other_extension.type)) { 749 #define HANDLE_TYPE(UPPERCASE, LOWERCASE, CAMELCASE) \ 750 case WireFormatLite::CPPTYPE_##UPPERCASE: \ 751 Set##CAMELCASE(iter->first, other_extension.type, \ 752 other_extension.LOWERCASE##_value, \ 753 other_extension.descriptor); \ 754 break; 755 756 HANDLE_TYPE( INT32, int32, Int32); 757 HANDLE_TYPE( INT64, int64, Int64); 758 HANDLE_TYPE(UINT32, uint32, UInt32); 759 HANDLE_TYPE(UINT64, uint64, UInt64); 760 HANDLE_TYPE( FLOAT, float, Float); 761 HANDLE_TYPE(DOUBLE, double, Double); 762 HANDLE_TYPE( BOOL, bool, Bool); 763 HANDLE_TYPE( ENUM, enum, Enum); 764 #undef HANDLE_TYPE 765 case WireFormatLite::CPPTYPE_STRING: 766 SetString(iter->first, other_extension.type, 767 *other_extension.string_value, 768 other_extension.descriptor); 769 break; 770 case WireFormatLite::CPPTYPE_MESSAGE: { 771 Extension* extension; 772 bool is_new = MaybeNewExtension(iter->first, 773 other_extension.descriptor, 774 &extension); 775 if (is_new) { 776 extension->type = other_extension.type; 777 extension->is_packed = other_extension.is_packed; 778 extension->is_repeated = false; 779 if (other_extension.is_lazy) { 780 extension->is_lazy = true; 781 extension->lazymessage_value = 782 other_extension.lazymessage_value->New(); 783 extension->lazymessage_value->MergeFrom( 784 *other_extension.lazymessage_value); 785 } else { 786 extension->is_lazy = false; 787 extension->message_value = 788 other_extension.message_value->New(); 789 extension->message_value->CheckTypeAndMergeFrom( 790 *other_extension.message_value); 791 } 792 } else { 793 GOOGLE_DCHECK_EQ(extension->type, other_extension.type); 794 GOOGLE_DCHECK_EQ(extension->is_packed,other_extension.is_packed); 795 GOOGLE_DCHECK(!extension->is_repeated); 796 if (other_extension.is_lazy) { 797 if (extension->is_lazy) { 798 extension->lazymessage_value->MergeFrom( 799 *other_extension.lazymessage_value); 800 } else { 801 extension->message_value->CheckTypeAndMergeFrom( 802 other_extension.lazymessage_value->GetMessage( 803 *extension->message_value)); 804 } 805 } else { 806 if (extension->is_lazy) { 807 extension->lazymessage_value->MutableMessage( 808 *other_extension.message_value)->CheckTypeAndMergeFrom( 809 *other_extension.message_value); 810 } else { 811 extension->message_value->CheckTypeAndMergeFrom( 812 *other_extension.message_value); 813 } 814 } 815 } 816 extension->is_cleared = false; 817 break; 818 } 819 } 820 } 821 } 822 } 823 } 824 825 void ExtensionSet::Swap(ExtensionSet* x) { 826 extensions_.swap(x->extensions_); 827 } 828 829 bool ExtensionSet::IsInitialized() const { 830 // Extensions are never required. However, we need to check that all 831 // embedded messages are initialized. 832 for (map<int, Extension>::const_iterator iter = extensions_.begin(); 833 iter != extensions_.end(); ++iter) { 834 const Extension& extension = iter->second; 835 if (cpp_type(extension.type) == WireFormatLite::CPPTYPE_MESSAGE) { 836 if (extension.is_repeated) { 837 for (int i = 0; i < extension.repeated_message_value->size(); i++) { 838 if (!extension.repeated_message_value->Get(i).IsInitialized()) { 839 return false; 840 } 841 } 842 } else { 843 if (!extension.is_cleared) { 844 if (extension.is_lazy) { 845 if (!extension.lazymessage_value->IsInitialized()) return false; 846 } else { 847 if (!extension.message_value->IsInitialized()) return false; 848 } 849 } 850 } 851 } 852 } 853 854 return true; 855 } 856 857 bool ExtensionSet::FindExtensionInfoFromTag( 858 uint32 tag, ExtensionFinder* extension_finder, 859 int* field_number, ExtensionInfo* extension) { 860 *field_number = WireFormatLite::GetTagFieldNumber(tag); 861 WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag); 862 863 bool is_unknown; 864 if (!extension_finder->Find(*field_number, extension)) { 865 is_unknown = true; 866 } else if (extension->is_packed) { 867 is_unknown = (wire_type != WireFormatLite::WIRETYPE_LENGTH_DELIMITED); 868 } else { 869 WireFormatLite::WireType expected_wire_type = 870 WireFormatLite::WireTypeForFieldType(real_type(extension->type)); 871 is_unknown = (wire_type != expected_wire_type); 872 } 873 return !is_unknown; 874 } 875 876 bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, 877 ExtensionFinder* extension_finder, 878 FieldSkipper* field_skipper) { 879 int number; 880 ExtensionInfo extension; 881 if (!FindExtensionInfoFromTag(tag, extension_finder, &number, &extension)) { 882 return field_skipper->SkipField(input, tag); 883 } else { 884 return ParseFieldWithExtensionInfo(number, extension, input, field_skipper); 885 } 886 } 887 888 bool ExtensionSet::ParseFieldWithExtensionInfo( 889 int number, const ExtensionInfo& extension, 890 io::CodedInputStream* input, 891 FieldSkipper* field_skipper) { 892 if (extension.is_packed) { 893 uint32 size; 894 if (!input->ReadVarint32(&size)) return false; 895 io::CodedInputStream::Limit limit = input->PushLimit(size); 896 897 switch (extension.type) { 898 #define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE) \ 899 case WireFormatLite::TYPE_##UPPERCASE: \ 900 while (input->BytesUntilLimit() > 0) { \ 901 CPP_LOWERCASE value; \ 902 if (!WireFormatLite::ReadPrimitive< \ 903 CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>( \ 904 input, &value)) return false; \ 905 Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \ 906 true, value, extension.descriptor); \ 907 } \ 908 break 909 910 HANDLE_TYPE( INT32, Int32, int32); 911 HANDLE_TYPE( INT64, Int64, int64); 912 HANDLE_TYPE( UINT32, UInt32, uint32); 913 HANDLE_TYPE( UINT64, UInt64, uint64); 914 HANDLE_TYPE( SINT32, Int32, int32); 915 HANDLE_TYPE( SINT64, Int64, int64); 916 HANDLE_TYPE( FIXED32, UInt32, uint32); 917 HANDLE_TYPE( FIXED64, UInt64, uint64); 918 HANDLE_TYPE(SFIXED32, Int32, int32); 919 HANDLE_TYPE(SFIXED64, Int64, int64); 920 HANDLE_TYPE( FLOAT, Float, float); 921 HANDLE_TYPE( DOUBLE, Double, double); 922 HANDLE_TYPE( BOOL, Bool, bool); 923 #undef HANDLE_TYPE 924 925 case WireFormatLite::TYPE_ENUM: 926 while (input->BytesUntilLimit() > 0) { 927 int value; 928 if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>( 929 input, &value)) return false; 930 if (extension.enum_validity_check.func( 931 extension.enum_validity_check.arg, value)) { 932 AddEnum(number, WireFormatLite::TYPE_ENUM, true, value, 933 extension.descriptor); 934 } 935 } 936 break; 937 938 case WireFormatLite::TYPE_STRING: 939 case WireFormatLite::TYPE_BYTES: 940 case WireFormatLite::TYPE_GROUP: 941 case WireFormatLite::TYPE_MESSAGE: 942 GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed."; 943 break; 944 } 945 946 input->PopLimit(limit); 947 } else { 948 switch (extension.type) { 949 #define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE) \ 950 case WireFormatLite::TYPE_##UPPERCASE: { \ 951 CPP_LOWERCASE value; \ 952 if (!WireFormatLite::ReadPrimitive< \ 953 CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>( \ 954 input, &value)) return false; \ 955 if (extension.is_repeated) { \ 956 Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \ 957 false, value, extension.descriptor); \ 958 } else { \ 959 Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value, \ 960 extension.descriptor); \ 961 } \ 962 } break 963 964 HANDLE_TYPE( INT32, Int32, int32); 965 HANDLE_TYPE( INT64, Int64, int64); 966 HANDLE_TYPE( UINT32, UInt32, uint32); 967 HANDLE_TYPE( UINT64, UInt64, uint64); 968 HANDLE_TYPE( SINT32, Int32, int32); 969 HANDLE_TYPE( SINT64, Int64, int64); 970 HANDLE_TYPE( FIXED32, UInt32, uint32); 971 HANDLE_TYPE( FIXED64, UInt64, uint64); 972 HANDLE_TYPE(SFIXED32, Int32, int32); 973 HANDLE_TYPE(SFIXED64, Int64, int64); 974 HANDLE_TYPE( FLOAT, Float, float); 975 HANDLE_TYPE( DOUBLE, Double, double); 976 HANDLE_TYPE( BOOL, Bool, bool); 977 #undef HANDLE_TYPE 978 979 case WireFormatLite::TYPE_ENUM: { 980 int value; 981 if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>( 982 input, &value)) return false; 983 984 if (!extension.enum_validity_check.func( 985 extension.enum_validity_check.arg, value)) { 986 // Invalid value. Treat as unknown. 987 field_skipper->SkipUnknownEnum(number, value); 988 } else if (extension.is_repeated) { 989 AddEnum(number, WireFormatLite::TYPE_ENUM, false, value, 990 extension.descriptor); 991 } else { 992 SetEnum(number, WireFormatLite::TYPE_ENUM, value, 993 extension.descriptor); 994 } 995 break; 996 } 997 998 case WireFormatLite::TYPE_STRING: { 999 string* value = extension.is_repeated ? 1000 AddString(number, WireFormatLite::TYPE_STRING, extension.descriptor) : 1001 MutableString(number, WireFormatLite::TYPE_STRING, 1002 extension.descriptor); 1003 if (!WireFormatLite::ReadString(input, value)) return false; 1004 break; 1005 } 1006 1007 case WireFormatLite::TYPE_BYTES: { 1008 string* value = extension.is_repeated ? 1009 AddString(number, WireFormatLite::TYPE_BYTES, extension.descriptor) : 1010 MutableString(number, WireFormatLite::TYPE_BYTES, 1011 extension.descriptor); 1012 if (!WireFormatLite::ReadBytes(input, value)) return false; 1013 break; 1014 } 1015 1016 case WireFormatLite::TYPE_GROUP: { 1017 MessageLite* value = extension.is_repeated ? 1018 AddMessage(number, WireFormatLite::TYPE_GROUP, 1019 *extension.message_prototype, extension.descriptor) : 1020 MutableMessage(number, WireFormatLite::TYPE_GROUP, 1021 *extension.message_prototype, extension.descriptor); 1022 if (!WireFormatLite::ReadGroup(number, input, value)) return false; 1023 break; 1024 } 1025 1026 case WireFormatLite::TYPE_MESSAGE: { 1027 MessageLite* value = extension.is_repeated ? 1028 AddMessage(number, WireFormatLite::TYPE_MESSAGE, 1029 *extension.message_prototype, extension.descriptor) : 1030 MutableMessage(number, WireFormatLite::TYPE_MESSAGE, 1031 *extension.message_prototype, extension.descriptor); 1032 if (!WireFormatLite::ReadMessage(input, value)) return false; 1033 break; 1034 } 1035 } 1036 } 1037 1038 return true; 1039 } 1040 1041 bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, 1042 const MessageLite* containing_type, 1043 UnknownFieldSet* unknown_fields) { 1044 FieldSkipper skipper(unknown_fields); 1045 GeneratedExtensionFinder finder(containing_type); 1046 return ParseField(tag, input, &finder, &skipper); 1047 } 1048 1049 // Defined in extension_set_heavy.cc. 1050 // bool ExtensionSet::ParseFieldHeavy(uint32 tag, io::CodedInputStream* input, 1051 // const Message* containing_type, 1052 // UnknownFieldSet* unknown_fields) 1053 1054 // Defined in extension_set_heavy.cc. 1055 // bool ExtensionSet::ParseMessageSetHeavy(io::CodedInputStream* input, 1056 // const Message* containing_type, 1057 // UnknownFieldSet* unknown_fields); 1058 1059 void ExtensionSet::SerializeWithCachedSizes( 1060 int start_field_number, int end_field_number, 1061 io::CodedOutputStream* output) const { 1062 map<int, Extension>::const_iterator iter; 1063 for (iter = extensions_.lower_bound(start_field_number); 1064 iter != extensions_.end() && iter->first < end_field_number; 1065 ++iter) { 1066 iter->second.SerializeFieldWithCachedSizes(iter->first, output); 1067 } 1068 } 1069 1070 int ExtensionSet::ByteSize() const { 1071 int total_size = 0; 1072 1073 for (map<int, Extension>::const_iterator iter = extensions_.begin(); 1074 iter != extensions_.end(); ++iter) { 1075 total_size += iter->second.ByteSize(iter->first); 1076 } 1077 1078 return total_size; 1079 } 1080 1081 // Defined in extension_set_heavy.cc. 1082 // int ExtensionSet::SpaceUsedExcludingSelf() const 1083 1084 bool ExtensionSet::MaybeNewExtension(int number, 1085 const FieldDescriptor* descriptor, 1086 Extension** result) { 1087 pair<map<int, Extension>::iterator, bool> insert_result = 1088 extensions_.insert(make_pair(number, Extension())); 1089 *result = &insert_result.first->second; 1090 (*result)->descriptor = descriptor; 1091 return insert_result.second; 1092 } 1093 1094 // =================================================================== 1095 // Methods of ExtensionSet::Extension 1096 1097 void ExtensionSet::Extension::Clear() { 1098 if (is_repeated) { 1099 switch (cpp_type(type)) { 1100 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ 1101 case WireFormatLite::CPPTYPE_##UPPERCASE: \ 1102 repeated_##LOWERCASE##_value->Clear(); \ 1103 break 1104 1105 HANDLE_TYPE( INT32, int32); 1106 HANDLE_TYPE( INT64, int64); 1107 HANDLE_TYPE( UINT32, uint32); 1108 HANDLE_TYPE( UINT64, uint64); 1109 HANDLE_TYPE( FLOAT, float); 1110 HANDLE_TYPE( DOUBLE, double); 1111 HANDLE_TYPE( BOOL, bool); 1112 HANDLE_TYPE( ENUM, enum); 1113 HANDLE_TYPE( STRING, string); 1114 HANDLE_TYPE(MESSAGE, message); 1115 #undef HANDLE_TYPE 1116 } 1117 } else { 1118 if (!is_cleared) { 1119 switch (cpp_type(type)) { 1120 case WireFormatLite::CPPTYPE_STRING: 1121 string_value->clear(); 1122 break; 1123 case WireFormatLite::CPPTYPE_MESSAGE: 1124 if (is_lazy) { 1125 lazymessage_value->Clear(); 1126 } else { 1127 message_value->Clear(); 1128 } 1129 break; 1130 default: 1131 // No need to do anything. Get*() will return the default value 1132 // as long as is_cleared is true and Set*() will overwrite the 1133 // previous value. 1134 break; 1135 } 1136 1137 is_cleared = true; 1138 } 1139 } 1140 } 1141 1142 void ExtensionSet::Extension::SerializeFieldWithCachedSizes( 1143 int number, 1144 io::CodedOutputStream* output) const { 1145 if (is_repeated) { 1146 if (is_packed) { 1147 if (cached_size == 0) return; 1148 1149 WireFormatLite::WriteTag(number, 1150 WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output); 1151 output->WriteVarint32(cached_size); 1152 1153 switch (real_type(type)) { 1154 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ 1155 case WireFormatLite::TYPE_##UPPERCASE: \ 1156 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ 1157 WireFormatLite::Write##CAMELCASE##NoTag( \ 1158 repeated_##LOWERCASE##_value->Get(i), output); \ 1159 } \ 1160 break 1161 1162 HANDLE_TYPE( INT32, Int32, int32); 1163 HANDLE_TYPE( INT64, Int64, int64); 1164 HANDLE_TYPE( UINT32, UInt32, uint32); 1165 HANDLE_TYPE( UINT64, UInt64, uint64); 1166 HANDLE_TYPE( SINT32, SInt32, int32); 1167 HANDLE_TYPE( SINT64, SInt64, int64); 1168 HANDLE_TYPE( FIXED32, Fixed32, uint32); 1169 HANDLE_TYPE( FIXED64, Fixed64, uint64); 1170 HANDLE_TYPE(SFIXED32, SFixed32, int32); 1171 HANDLE_TYPE(SFIXED64, SFixed64, int64); 1172 HANDLE_TYPE( FLOAT, Float, float); 1173 HANDLE_TYPE( DOUBLE, Double, double); 1174 HANDLE_TYPE( BOOL, Bool, bool); 1175 HANDLE_TYPE( ENUM, Enum, enum); 1176 #undef HANDLE_TYPE 1177 1178 case WireFormatLite::TYPE_STRING: 1179 case WireFormatLite::TYPE_BYTES: 1180 case WireFormatLite::TYPE_GROUP: 1181 case WireFormatLite::TYPE_MESSAGE: 1182 GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed."; 1183 break; 1184 } 1185 } else { 1186 switch (real_type(type)) { 1187 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ 1188 case WireFormatLite::TYPE_##UPPERCASE: \ 1189 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ 1190 WireFormatLite::Write##CAMELCASE(number, \ 1191 repeated_##LOWERCASE##_value->Get(i), output); \ 1192 } \ 1193 break 1194 1195 HANDLE_TYPE( INT32, Int32, int32); 1196 HANDLE_TYPE( INT64, Int64, int64); 1197 HANDLE_TYPE( UINT32, UInt32, uint32); 1198 HANDLE_TYPE( UINT64, UInt64, uint64); 1199 HANDLE_TYPE( SINT32, SInt32, int32); 1200 HANDLE_TYPE( SINT64, SInt64, int64); 1201 HANDLE_TYPE( FIXED32, Fixed32, uint32); 1202 HANDLE_TYPE( FIXED64, Fixed64, uint64); 1203 HANDLE_TYPE(SFIXED32, SFixed32, int32); 1204 HANDLE_TYPE(SFIXED64, SFixed64, int64); 1205 HANDLE_TYPE( FLOAT, Float, float); 1206 HANDLE_TYPE( DOUBLE, Double, double); 1207 HANDLE_TYPE( BOOL, Bool, bool); 1208 HANDLE_TYPE( STRING, String, string); 1209 HANDLE_TYPE( BYTES, Bytes, string); 1210 HANDLE_TYPE( ENUM, Enum, enum); 1211 HANDLE_TYPE( GROUP, Group, message); 1212 HANDLE_TYPE( MESSAGE, Message, message); 1213 #undef HANDLE_TYPE 1214 } 1215 } 1216 } else if (!is_cleared) { 1217 switch (real_type(type)) { 1218 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE) \ 1219 case WireFormatLite::TYPE_##UPPERCASE: \ 1220 WireFormatLite::Write##CAMELCASE(number, VALUE, output); \ 1221 break 1222 1223 HANDLE_TYPE( INT32, Int32, int32_value); 1224 HANDLE_TYPE( INT64, Int64, int64_value); 1225 HANDLE_TYPE( UINT32, UInt32, uint32_value); 1226 HANDLE_TYPE( UINT64, UInt64, uint64_value); 1227 HANDLE_TYPE( SINT32, SInt32, int32_value); 1228 HANDLE_TYPE( SINT64, SInt64, int64_value); 1229 HANDLE_TYPE( FIXED32, Fixed32, uint32_value); 1230 HANDLE_TYPE( FIXED64, Fixed64, uint64_value); 1231 HANDLE_TYPE(SFIXED32, SFixed32, int32_value); 1232 HANDLE_TYPE(SFIXED64, SFixed64, int64_value); 1233 HANDLE_TYPE( FLOAT, Float, float_value); 1234 HANDLE_TYPE( DOUBLE, Double, double_value); 1235 HANDLE_TYPE( BOOL, Bool, bool_value); 1236 HANDLE_TYPE( STRING, String, *string_value); 1237 HANDLE_TYPE( BYTES, Bytes, *string_value); 1238 HANDLE_TYPE( ENUM, Enum, enum_value); 1239 HANDLE_TYPE( GROUP, Group, *message_value); 1240 #undef HANDLE_TYPE 1241 case WireFormatLite::TYPE_MESSAGE: 1242 if (is_lazy) { 1243 lazymessage_value->WriteMessage(number, output); 1244 } else { 1245 WireFormatLite::WriteMessage(number, *message_value, output); 1246 } 1247 break; 1248 } 1249 } 1250 } 1251 1252 int ExtensionSet::Extension::ByteSize(int number) const { 1253 int result = 0; 1254 1255 if (is_repeated) { 1256 if (is_packed) { 1257 switch (real_type(type)) { 1258 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ 1259 case WireFormatLite::TYPE_##UPPERCASE: \ 1260 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ 1261 result += WireFormatLite::CAMELCASE##Size( \ 1262 repeated_##LOWERCASE##_value->Get(i)); \ 1263 } \ 1264 break 1265 1266 HANDLE_TYPE( INT32, Int32, int32); 1267 HANDLE_TYPE( INT64, Int64, int64); 1268 HANDLE_TYPE( UINT32, UInt32, uint32); 1269 HANDLE_TYPE( UINT64, UInt64, uint64); 1270 HANDLE_TYPE( SINT32, SInt32, int32); 1271 HANDLE_TYPE( SINT64, SInt64, int64); 1272 HANDLE_TYPE( ENUM, Enum, enum); 1273 #undef HANDLE_TYPE 1274 1275 // Stuff with fixed size. 1276 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ 1277 case WireFormatLite::TYPE_##UPPERCASE: \ 1278 result += WireFormatLite::k##CAMELCASE##Size * \ 1279 repeated_##LOWERCASE##_value->size(); \ 1280 break 1281 HANDLE_TYPE( FIXED32, Fixed32, uint32); 1282 HANDLE_TYPE( FIXED64, Fixed64, uint64); 1283 HANDLE_TYPE(SFIXED32, SFixed32, int32); 1284 HANDLE_TYPE(SFIXED64, SFixed64, int64); 1285 HANDLE_TYPE( FLOAT, Float, float); 1286 HANDLE_TYPE( DOUBLE, Double, double); 1287 HANDLE_TYPE( BOOL, Bool, bool); 1288 #undef HANDLE_TYPE 1289 1290 case WireFormatLite::TYPE_STRING: 1291 case WireFormatLite::TYPE_BYTES: 1292 case WireFormatLite::TYPE_GROUP: 1293 case WireFormatLite::TYPE_MESSAGE: 1294 GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed."; 1295 break; 1296 } 1297 1298 cached_size = result; 1299 if (result > 0) { 1300 result += io::CodedOutputStream::VarintSize32(result); 1301 result += io::CodedOutputStream::VarintSize32( 1302 WireFormatLite::MakeTag(number, 1303 WireFormatLite::WIRETYPE_LENGTH_DELIMITED)); 1304 } 1305 } else { 1306 int tag_size = WireFormatLite::TagSize(number, real_type(type)); 1307 1308 switch (real_type(type)) { 1309 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ 1310 case WireFormatLite::TYPE_##UPPERCASE: \ 1311 result += tag_size * repeated_##LOWERCASE##_value->size(); \ 1312 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ 1313 result += WireFormatLite::CAMELCASE##Size( \ 1314 repeated_##LOWERCASE##_value->Get(i)); \ 1315 } \ 1316 break 1317 1318 HANDLE_TYPE( INT32, Int32, int32); 1319 HANDLE_TYPE( INT64, Int64, int64); 1320 HANDLE_TYPE( UINT32, UInt32, uint32); 1321 HANDLE_TYPE( UINT64, UInt64, uint64); 1322 HANDLE_TYPE( SINT32, SInt32, int32); 1323 HANDLE_TYPE( SINT64, SInt64, int64); 1324 HANDLE_TYPE( STRING, String, string); 1325 HANDLE_TYPE( BYTES, Bytes, string); 1326 HANDLE_TYPE( ENUM, Enum, enum); 1327 HANDLE_TYPE( GROUP, Group, message); 1328 HANDLE_TYPE( MESSAGE, Message, message); 1329 #undef HANDLE_TYPE 1330 1331 // Stuff with fixed size. 1332 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ 1333 case WireFormatLite::TYPE_##UPPERCASE: \ 1334 result += (tag_size + WireFormatLite::k##CAMELCASE##Size) * \ 1335 repeated_##LOWERCASE##_value->size(); \ 1336 break 1337 HANDLE_TYPE( FIXED32, Fixed32, uint32); 1338 HANDLE_TYPE( FIXED64, Fixed64, uint64); 1339 HANDLE_TYPE(SFIXED32, SFixed32, int32); 1340 HANDLE_TYPE(SFIXED64, SFixed64, int64); 1341 HANDLE_TYPE( FLOAT, Float, float); 1342 HANDLE_TYPE( DOUBLE, Double, double); 1343 HANDLE_TYPE( BOOL, Bool, bool); 1344 #undef HANDLE_TYPE 1345 } 1346 } 1347 } else if (!is_cleared) { 1348 result += WireFormatLite::TagSize(number, real_type(type)); 1349 switch (real_type(type)) { 1350 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ 1351 case WireFormatLite::TYPE_##UPPERCASE: \ 1352 result += WireFormatLite::CAMELCASE##Size(LOWERCASE); \ 1353 break 1354 1355 HANDLE_TYPE( INT32, Int32, int32_value); 1356 HANDLE_TYPE( INT64, Int64, int64_value); 1357 HANDLE_TYPE( UINT32, UInt32, uint32_value); 1358 HANDLE_TYPE( UINT64, UInt64, uint64_value); 1359 HANDLE_TYPE( SINT32, SInt32, int32_value); 1360 HANDLE_TYPE( SINT64, SInt64, int64_value); 1361 HANDLE_TYPE( STRING, String, *string_value); 1362 HANDLE_TYPE( BYTES, Bytes, *string_value); 1363 HANDLE_TYPE( ENUM, Enum, enum_value); 1364 HANDLE_TYPE( GROUP, Group, *message_value); 1365 #undef HANDLE_TYPE 1366 case WireFormatLite::TYPE_MESSAGE: { 1367 if (is_lazy) { 1368 int size = lazymessage_value->ByteSize(); 1369 result += io::CodedOutputStream::VarintSize32(size) + size; 1370 } else { 1371 result += WireFormatLite::MessageSize(*message_value); 1372 } 1373 break; 1374 } 1375 1376 // Stuff with fixed size. 1377 #define HANDLE_TYPE(UPPERCASE, CAMELCASE) \ 1378 case WireFormatLite::TYPE_##UPPERCASE: \ 1379 result += WireFormatLite::k##CAMELCASE##Size; \ 1380 break 1381 HANDLE_TYPE( FIXED32, Fixed32); 1382 HANDLE_TYPE( FIXED64, Fixed64); 1383 HANDLE_TYPE(SFIXED32, SFixed32); 1384 HANDLE_TYPE(SFIXED64, SFixed64); 1385 HANDLE_TYPE( FLOAT, Float); 1386 HANDLE_TYPE( DOUBLE, Double); 1387 HANDLE_TYPE( BOOL, Bool); 1388 #undef HANDLE_TYPE 1389 } 1390 } 1391 1392 return result; 1393 } 1394 1395 int ExtensionSet::Extension::GetSize() const { 1396 GOOGLE_DCHECK(is_repeated); 1397 switch (cpp_type(type)) { 1398 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ 1399 case WireFormatLite::CPPTYPE_##UPPERCASE: \ 1400 return repeated_##LOWERCASE##_value->size() 1401 1402 HANDLE_TYPE( INT32, int32); 1403 HANDLE_TYPE( INT64, int64); 1404 HANDLE_TYPE( UINT32, uint32); 1405 HANDLE_TYPE( UINT64, uint64); 1406 HANDLE_TYPE( FLOAT, float); 1407 HANDLE_TYPE( DOUBLE, double); 1408 HANDLE_TYPE( BOOL, bool); 1409 HANDLE_TYPE( ENUM, enum); 1410 HANDLE_TYPE( STRING, string); 1411 HANDLE_TYPE(MESSAGE, message); 1412 #undef HANDLE_TYPE 1413 } 1414 1415 GOOGLE_LOG(FATAL) << "Can't get here."; 1416 return 0; 1417 } 1418 1419 void ExtensionSet::Extension::Free() { 1420 if (is_repeated) { 1421 switch (cpp_type(type)) { 1422 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ 1423 case WireFormatLite::CPPTYPE_##UPPERCASE: \ 1424 delete repeated_##LOWERCASE##_value; \ 1425 break 1426 1427 HANDLE_TYPE( INT32, int32); 1428 HANDLE_TYPE( INT64, int64); 1429 HANDLE_TYPE( UINT32, uint32); 1430 HANDLE_TYPE( UINT64, uint64); 1431 HANDLE_TYPE( FLOAT, float); 1432 HANDLE_TYPE( DOUBLE, double); 1433 HANDLE_TYPE( BOOL, bool); 1434 HANDLE_TYPE( ENUM, enum); 1435 HANDLE_TYPE( STRING, string); 1436 HANDLE_TYPE(MESSAGE, message); 1437 #undef HANDLE_TYPE 1438 } 1439 } else { 1440 switch (cpp_type(type)) { 1441 case WireFormatLite::CPPTYPE_STRING: 1442 delete string_value; 1443 break; 1444 case WireFormatLite::CPPTYPE_MESSAGE: 1445 if (is_lazy) { 1446 delete lazymessage_value; 1447 } else { 1448 delete message_value; 1449 } 1450 break; 1451 default: 1452 break; 1453 } 1454 } 1455 } 1456 1457 // Defined in extension_set_heavy.cc. 1458 // int ExtensionSet::Extension::SpaceUsedExcludingSelf() const 1459 1460 } // namespace internal 1461 } // namespace protobuf 1462 } // namespace google 1463