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