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 189void 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 198namespace { 199 200enum 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 \ 216LOWERCASE 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 \ 227void 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 \ 242LOWERCASE 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 \ 249void 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 \ 257void 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 274PRIMITIVE_ACCESSORS( INT32, int32, Int32) 275PRIMITIVE_ACCESSORS( INT64, int64, Int64) 276PRIMITIVE_ACCESSORS(UINT32, uint32, UInt32) 277PRIMITIVE_ACCESSORS(UINT64, uint64, UInt64) 278PRIMITIVE_ACCESSORS( FLOAT, float, Float) 279PRIMITIVE_ACCESSORS(DOUBLE, double, Double) 280PRIMITIVE_ACCESSORS( BOOL, bool, Bool) 281 282#undef PRIMITIVE_ACCESSORS 283 284// ------------------------------------------------------------------- 285// Enums 286 287int 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 298void 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 312int 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 319void 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 326void 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 346const 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 358string* 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 373const 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 380string* 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 387string* 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 405const 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 422MessageLite* 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 443const 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 451MessageLite* 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 458MessageLite* 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 490void 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 531void 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 574void ExtensionSet::Clear() { 575 for (map<int, Extension>::iterator iter = extensions_.begin(); 576 iter != extensions_.end(); ++iter) { 577 iter->second.Clear(); 578 } 579} 580 581void 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 678void ExtensionSet::Swap(ExtensionSet* x) { 679 extensions_.swap(x->extensions_); 680} 681 682bool 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 706bool 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 875bool 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 887bool 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 909bool 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 921bool 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 1001void 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 1012void 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 1020int 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 1031int 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 1045bool 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 1058void 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 1099void 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 1203void 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 1231int 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 1366int 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 1389int 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 1413void 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