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