1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // http://code.google.com/p/protobuf/ 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions are 7 // met: 8 // 9 // * Redistributions of source code must retain the above copyright 10 // notice, this list of conditions and the following disclaimer. 11 // * Redistributions in binary form must reproduce the above 12 // copyright notice, this list of conditions and the following disclaimer 13 // in the documentation and/or other materials provided with the 14 // distribution. 15 // * Neither the name of Google Inc. nor the names of its 16 // contributors may be used to endorse or promote products derived from 17 // this software without specific prior written permission. 18 // 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31 // Author: kenton (at) google.com (Kenton Varda) 32 // Based on original Protocol Buffers design by 33 // Sanjay Ghemawat, Jeff Dean, and others. 34 35 #include <algorithm> 36 #include <google/protobuf/generated_message_reflection.h> 37 #include <google/protobuf/descriptor.h> 38 #include <google/protobuf/descriptor.pb.h> 39 #include <google/protobuf/repeated_field.h> 40 #include <google/protobuf/extension_set.h> 41 #include <google/protobuf/generated_message_util.h> 42 #include <google/protobuf/stubs/common.h> 43 44 namespace google { 45 namespace protobuf { 46 namespace internal { 47 48 namespace { const string kEmptyString; } 49 50 int StringSpaceUsedExcludingSelf(const string& str) { 51 const void* start = &str; 52 const void* end = &str + 1; 53 54 if (start <= str.data() && str.data() <= end) { 55 // The string's data is stored inside the string object itself. 56 return 0; 57 } else { 58 return str.capacity(); 59 } 60 } 61 62 bool ParseNamedEnum(const EnumDescriptor* descriptor, 63 const string& name, 64 int* value) { 65 const EnumValueDescriptor* d = descriptor->FindValueByName(name); 66 if (d == NULL) return false; 67 *value = d->number(); 68 return true; 69 } 70 71 const string& NameOfEnum(const EnumDescriptor* descriptor, int value) { 72 static string kEmptyString; 73 const EnumValueDescriptor* d = descriptor->FindValueByNumber(value); 74 return (d == NULL ? kEmptyString : d->name()); 75 } 76 77 // =================================================================== 78 // Helpers for reporting usage errors (e.g. trying to use GetInt32() on 79 // a string field). 80 81 namespace { 82 83 void ReportReflectionUsageError( 84 const Descriptor* descriptor, const FieldDescriptor* field, 85 const char* method, const char* description) { 86 GOOGLE_LOG(FATAL) 87 << "Protocol Buffer reflection usage error:\n" 88 " Method : google::protobuf::Reflection::" << method << "\n" 89 " Message type: " << descriptor->full_name() << "\n" 90 " Field : " << field->full_name() << "\n" 91 " Problem : " << description; 92 } 93 94 const char* cpptype_names_[FieldDescriptor::MAX_CPPTYPE + 1] = { 95 "INVALID_CPPTYPE", 96 "CPPTYPE_INT32", 97 "CPPTYPE_INT64", 98 "CPPTYPE_UINT32", 99 "CPPTYPE_UINT64", 100 "CPPTYPE_DOUBLE", 101 "CPPTYPE_FLOAT", 102 "CPPTYPE_BOOL", 103 "CPPTYPE_ENUM", 104 "CPPTYPE_STRING", 105 "CPPTYPE_MESSAGE" 106 }; 107 108 static void ReportReflectionUsageTypeError( 109 const Descriptor* descriptor, const FieldDescriptor* field, 110 const char* method, 111 FieldDescriptor::CppType expected_type) { 112 GOOGLE_LOG(FATAL) 113 << "Protocol Buffer reflection usage error:\n" 114 " Method : google::protobuf::Reflection::" << method << "\n" 115 " Message type: " << descriptor->full_name() << "\n" 116 " Field : " << field->full_name() << "\n" 117 " Problem : Field is not the right type for this message:\n" 118 " Expected : " << cpptype_names_[expected_type] << "\n" 119 " Field type: " << cpptype_names_[field->cpp_type()]; 120 } 121 122 static void ReportReflectionUsageEnumTypeError( 123 const Descriptor* descriptor, const FieldDescriptor* field, 124 const char* method, const EnumValueDescriptor* value) { 125 GOOGLE_LOG(FATAL) 126 << "Protocol Buffer reflection usage error:\n" 127 " Method : google::protobuf::Reflection::" << method << "\n" 128 " Message type: " << descriptor->full_name() << "\n" 129 " Field : " << field->full_name() << "\n" 130 " Problem : Enum value did not match field type:\n" 131 " Expected : " << field->enum_type()->full_name() << "\n" 132 " Actual : " << value->full_name(); 133 } 134 135 #define USAGE_CHECK(CONDITION, METHOD, ERROR_DESCRIPTION) \ 136 if (!(CONDITION)) \ 137 ReportReflectionUsageError(descriptor_, field, #METHOD, ERROR_DESCRIPTION) 138 #define USAGE_CHECK_EQ(A, B, METHOD, ERROR_DESCRIPTION) \ 139 USAGE_CHECK((A) == (B), METHOD, ERROR_DESCRIPTION) 140 #define USAGE_CHECK_NE(A, B, METHOD, ERROR_DESCRIPTION) \ 141 USAGE_CHECK((A) != (B), METHOD, ERROR_DESCRIPTION) 142 143 #define USAGE_CHECK_TYPE(METHOD, CPPTYPE) \ 144 if (field->cpp_type() != FieldDescriptor::CPPTYPE_##CPPTYPE) \ 145 ReportReflectionUsageTypeError(descriptor_, field, #METHOD, \ 146 FieldDescriptor::CPPTYPE_##CPPTYPE) 147 148 #define USAGE_CHECK_ENUM_VALUE(METHOD) \ 149 if (value->type() != field->enum_type()) \ 150 ReportReflectionUsageEnumTypeError(descriptor_, field, #METHOD, value) 151 152 #define USAGE_CHECK_MESSAGE_TYPE(METHOD) \ 153 USAGE_CHECK_EQ(field->containing_type(), descriptor_, \ 154 METHOD, "Field does not match message type."); 155 #define USAGE_CHECK_SINGULAR(METHOD) \ 156 USAGE_CHECK_NE(field->label(), FieldDescriptor::LABEL_REPEATED, METHOD, \ 157 "Field is repeated; the method requires a singular field.") 158 #define USAGE_CHECK_REPEATED(METHOD) \ 159 USAGE_CHECK_EQ(field->label(), FieldDescriptor::LABEL_REPEATED, METHOD, \ 160 "Field is singular; the method requires a repeated field.") 161 162 #define USAGE_CHECK_ALL(METHOD, LABEL, CPPTYPE) \ 163 USAGE_CHECK_MESSAGE_TYPE(METHOD); \ 164 USAGE_CHECK_##LABEL(METHOD); \ 165 USAGE_CHECK_TYPE(METHOD, CPPTYPE) 166 167 } // namespace 168 169 // =================================================================== 170 171 GeneratedMessageReflection::GeneratedMessageReflection( 172 const Descriptor* descriptor, 173 const Message* default_instance, 174 const int offsets[], 175 int has_bits_offset, 176 int unknown_fields_offset, 177 int extensions_offset, 178 const DescriptorPool* descriptor_pool, 179 MessageFactory* factory, 180 int object_size) 181 : descriptor_ (descriptor), 182 default_instance_ (default_instance), 183 offsets_ (offsets), 184 has_bits_offset_ (has_bits_offset), 185 unknown_fields_offset_(unknown_fields_offset), 186 extensions_offset_(extensions_offset), 187 object_size_ (object_size), 188 descriptor_pool_ ((descriptor_pool == NULL) ? 189 DescriptorPool::generated_pool() : 190 descriptor_pool), 191 message_factory_ (factory) { 192 } 193 194 GeneratedMessageReflection::~GeneratedMessageReflection() {} 195 196 const UnknownFieldSet& GeneratedMessageReflection::GetUnknownFields( 197 const Message& message) const { 198 const void* ptr = reinterpret_cast<const uint8*>(&message) + 199 unknown_fields_offset_; 200 return *reinterpret_cast<const UnknownFieldSet*>(ptr); 201 } 202 UnknownFieldSet* GeneratedMessageReflection::MutableUnknownFields( 203 Message* message) const { 204 void* ptr = reinterpret_cast<uint8*>(message) + unknown_fields_offset_; 205 return reinterpret_cast<UnknownFieldSet*>(ptr); 206 } 207 208 int GeneratedMessageReflection::SpaceUsed(const Message& message) const { 209 // object_size_ already includes the in-memory representation of each field 210 // in the message, so we only need to account for additional memory used by 211 // the fields. 212 int total_size = object_size_; 213 214 total_size += GetUnknownFields(message).SpaceUsedExcludingSelf(); 215 216 if (extensions_offset_ != -1) { 217 total_size += GetExtensionSet(message).SpaceUsedExcludingSelf(); 218 } 219 220 for (int i = 0; i < descriptor_->field_count(); i++) { 221 const FieldDescriptor* field = descriptor_->field(i); 222 223 if (field->is_repeated()) { 224 switch (field->cpp_type()) { 225 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ 226 case FieldDescriptor::CPPTYPE_##UPPERCASE : \ 227 total_size += GetRaw<RepeatedField<LOWERCASE> >(message, field) \ 228 .SpaceUsedExcludingSelf(); \ 229 break 230 231 HANDLE_TYPE( INT32, int32); 232 HANDLE_TYPE( INT64, int64); 233 HANDLE_TYPE(UINT32, uint32); 234 HANDLE_TYPE(UINT64, uint64); 235 HANDLE_TYPE(DOUBLE, double); 236 HANDLE_TYPE( FLOAT, float); 237 HANDLE_TYPE( BOOL, bool); 238 HANDLE_TYPE( ENUM, int); 239 #undef HANDLE_TYPE 240 241 case FieldDescriptor::CPPTYPE_STRING: 242 switch (field->options().ctype()) { 243 default: // TODO(kenton): Support other string reps. 244 case FieldOptions::STRING: 245 total_size += GetRaw<RepeatedPtrField<string> >(message, field) 246 .SpaceUsedExcludingSelf(); 247 break; 248 } 249 break; 250 251 case FieldDescriptor::CPPTYPE_MESSAGE: 252 // We don't know which subclass of RepeatedPtrFieldBase the type is, 253 // so we use RepeatedPtrFieldBase directly. 254 total_size += 255 GetRaw<RepeatedPtrFieldBase>(message, field) 256 .SpaceUsedExcludingSelf<GenericTypeHandler<Message> >(); 257 break; 258 } 259 } else { 260 switch (field->cpp_type()) { 261 case FieldDescriptor::CPPTYPE_INT32 : 262 case FieldDescriptor::CPPTYPE_INT64 : 263 case FieldDescriptor::CPPTYPE_UINT32: 264 case FieldDescriptor::CPPTYPE_UINT64: 265 case FieldDescriptor::CPPTYPE_DOUBLE: 266 case FieldDescriptor::CPPTYPE_FLOAT : 267 case FieldDescriptor::CPPTYPE_BOOL : 268 case FieldDescriptor::CPPTYPE_ENUM : 269 // Field is inline, so we've already counted it. 270 break; 271 272 case FieldDescriptor::CPPTYPE_STRING: { 273 switch (field->options().ctype()) { 274 default: // TODO(kenton): Support other string reps. 275 case FieldOptions::STRING: { 276 const string* ptr = GetField<const string*>(message, field); 277 278 // Initially, the string points to the default value stored in 279 // the prototype. Only count the string if it has been changed 280 // from the default value. 281 const string* default_ptr = DefaultRaw<const string*>(field); 282 283 if (ptr != default_ptr) { 284 // string fields are represented by just a pointer, so also 285 // include sizeof(string) as well. 286 total_size += sizeof(*ptr) + StringSpaceUsedExcludingSelf(*ptr); 287 } 288 break; 289 } 290 } 291 break; 292 } 293 294 case FieldDescriptor::CPPTYPE_MESSAGE: 295 if (&message == default_instance_) { 296 // For singular fields, the prototype just stores a pointer to the 297 // external type's prototype, so there is no extra memory usage. 298 } else { 299 const Message* sub_message = GetRaw<const Message*>(message, field); 300 if (sub_message != NULL) { 301 total_size += sub_message->SpaceUsed(); 302 } 303 } 304 break; 305 } 306 } 307 } 308 309 return total_size; 310 } 311 312 void GeneratedMessageReflection::Swap( 313 Message* message1, 314 Message* message2) const { 315 if (message1 == message2) return; 316 317 // TODO(kenton): Other Reflection methods should probably check this too. 318 GOOGLE_CHECK_EQ(message1->GetReflection(), this) 319 << "First argument to Swap() (of type \"" 320 << message1->GetDescriptor()->full_name() 321 << "\") is not compatible with this reflection object (which is for type \"" 322 << descriptor_->full_name() 323 << "\"). Note that the exact same class is required; not just the same " 324 "descriptor."; 325 GOOGLE_CHECK_EQ(message2->GetReflection(), this) 326 << "Second argument to Swap() (of type \"" 327 << message1->GetDescriptor()->full_name() 328 << "\") is not compatible with this reflection object (which is for type \"" 329 << descriptor_->full_name() 330 << "\"). Note that the exact same class is required; not just the same " 331 "descriptor."; 332 333 uint32* has_bits1 = MutableHasBits(message1); 334 uint32* has_bits2 = MutableHasBits(message2); 335 int has_bits_size = (descriptor_->field_count() + 31) / 32; 336 337 for (int i = 0; i < has_bits_size; i++) { 338 std::swap(has_bits1[i], has_bits2[i]); 339 } 340 341 for (int i = 0; i < descriptor_->field_count(); i++) { 342 const FieldDescriptor* field = descriptor_->field(i); 343 if (field->is_repeated()) { 344 switch (field->cpp_type()) { 345 #define SWAP_ARRAYS(CPPTYPE, TYPE) \ 346 case FieldDescriptor::CPPTYPE_##CPPTYPE: \ 347 MutableRaw<RepeatedField<TYPE> >(message1, field)->Swap( \ 348 MutableRaw<RepeatedField<TYPE> >(message2, field)); \ 349 break; 350 351 SWAP_ARRAYS(INT32 , int32 ); 352 SWAP_ARRAYS(INT64 , int64 ); 353 SWAP_ARRAYS(UINT32, uint32); 354 SWAP_ARRAYS(UINT64, uint64); 355 SWAP_ARRAYS(FLOAT , float ); 356 SWAP_ARRAYS(DOUBLE, double); 357 SWAP_ARRAYS(BOOL , bool ); 358 SWAP_ARRAYS(ENUM , int ); 359 #undef SWAP_ARRAYS 360 361 case FieldDescriptor::CPPTYPE_STRING: 362 case FieldDescriptor::CPPTYPE_MESSAGE: 363 MutableRaw<RepeatedPtrFieldBase>(message1, field)->Swap( 364 MutableRaw<RepeatedPtrFieldBase>(message2, field)); 365 break; 366 367 default: 368 GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type(); 369 } 370 } else { 371 switch (field->cpp_type()) { 372 #define SWAP_VALUES(CPPTYPE, TYPE) \ 373 case FieldDescriptor::CPPTYPE_##CPPTYPE: \ 374 std::swap(*MutableRaw<TYPE>(message1, field), \ 375 *MutableRaw<TYPE>(message2, field)); \ 376 break; 377 378 SWAP_VALUES(INT32 , int32 ); 379 SWAP_VALUES(INT64 , int64 ); 380 SWAP_VALUES(UINT32, uint32); 381 SWAP_VALUES(UINT64, uint64); 382 SWAP_VALUES(FLOAT , float ); 383 SWAP_VALUES(DOUBLE, double); 384 SWAP_VALUES(BOOL , bool ); 385 SWAP_VALUES(ENUM , int ); 386 SWAP_VALUES(MESSAGE, Message*); 387 #undef SWAP_VALUES 388 389 case FieldDescriptor::CPPTYPE_STRING: 390 switch (field->options().ctype()) { 391 default: // TODO(kenton): Support other string reps. 392 case FieldOptions::STRING: 393 std::swap(*MutableRaw<string*>(message1, field), 394 *MutableRaw<string*>(message2, field)); 395 break; 396 } 397 break; 398 399 default: 400 GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type(); 401 } 402 } 403 } 404 405 if (extensions_offset_ != -1) { 406 MutableExtensionSet(message1)->Swap(MutableExtensionSet(message2)); 407 } 408 409 MutableUnknownFields(message1)->Swap(MutableUnknownFields(message2)); 410 } 411 412 // ------------------------------------------------------------------- 413 414 bool GeneratedMessageReflection::HasField(const Message& message, 415 const FieldDescriptor* field) const { 416 USAGE_CHECK_MESSAGE_TYPE(HasField); 417 USAGE_CHECK_SINGULAR(HasField); 418 419 if (field->is_extension()) { 420 return GetExtensionSet(message).Has(field->number()); 421 } else { 422 return HasBit(message, field); 423 } 424 } 425 426 int GeneratedMessageReflection::FieldSize(const Message& message, 427 const FieldDescriptor* field) const { 428 USAGE_CHECK_MESSAGE_TYPE(FieldSize); 429 USAGE_CHECK_REPEATED(FieldSize); 430 431 if (field->is_extension()) { 432 return GetExtensionSet(message).ExtensionSize(field->number()); 433 } else { 434 switch (field->cpp_type()) { 435 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ 436 case FieldDescriptor::CPPTYPE_##UPPERCASE : \ 437 return GetRaw<RepeatedField<LOWERCASE> >(message, field).size() 438 439 HANDLE_TYPE( INT32, int32); 440 HANDLE_TYPE( INT64, int64); 441 HANDLE_TYPE(UINT32, uint32); 442 HANDLE_TYPE(UINT64, uint64); 443 HANDLE_TYPE(DOUBLE, double); 444 HANDLE_TYPE( FLOAT, float); 445 HANDLE_TYPE( BOOL, bool); 446 HANDLE_TYPE( ENUM, int); 447 #undef HANDLE_TYPE 448 449 case FieldDescriptor::CPPTYPE_STRING: 450 case FieldDescriptor::CPPTYPE_MESSAGE: 451 return GetRaw<RepeatedPtrFieldBase>(message, field).size(); 452 } 453 454 GOOGLE_LOG(FATAL) << "Can't get here."; 455 return 0; 456 } 457 } 458 459 void GeneratedMessageReflection::ClearField( 460 Message* message, const FieldDescriptor* field) const { 461 USAGE_CHECK_MESSAGE_TYPE(ClearField); 462 463 if (field->is_extension()) { 464 MutableExtensionSet(message)->ClearExtension(field->number()); 465 } else if (!field->is_repeated()) { 466 if (HasBit(*message, field)) { 467 ClearBit(message, field); 468 469 // We need to set the field back to its default value. 470 switch (field->cpp_type()) { 471 #define CLEAR_TYPE(CPPTYPE, TYPE) \ 472 case FieldDescriptor::CPPTYPE_##CPPTYPE: \ 473 *MutableRaw<TYPE>(message, field) = \ 474 field->default_value_##TYPE(); \ 475 break; 476 477 CLEAR_TYPE(INT32 , int32 ); 478 CLEAR_TYPE(INT64 , int64 ); 479 CLEAR_TYPE(UINT32, uint32); 480 CLEAR_TYPE(UINT64, uint64); 481 CLEAR_TYPE(FLOAT , float ); 482 CLEAR_TYPE(DOUBLE, double); 483 CLEAR_TYPE(BOOL , bool ); 484 #undef CLEAR_TYPE 485 486 case FieldDescriptor::CPPTYPE_ENUM: 487 *MutableRaw<int>(message, field) = 488 field->default_value_enum()->number(); 489 break; 490 491 case FieldDescriptor::CPPTYPE_STRING: { 492 switch (field->options().ctype()) { 493 default: // TODO(kenton): Support other string reps. 494 case FieldOptions::STRING: 495 const string* default_ptr = DefaultRaw<const string*>(field); 496 string** value = MutableRaw<string*>(message, field); 497 if (*value != default_ptr) { 498 if (field->has_default_value()) { 499 (*value)->assign(field->default_value_string()); 500 } else { 501 (*value)->clear(); 502 } 503 } 504 break; 505 } 506 break; 507 } 508 509 case FieldDescriptor::CPPTYPE_MESSAGE: 510 (*MutableRaw<Message*>(message, field))->Clear(); 511 break; 512 } 513 } 514 } else { 515 switch (field->cpp_type()) { 516 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ 517 case FieldDescriptor::CPPTYPE_##UPPERCASE : \ 518 MutableRaw<RepeatedField<LOWERCASE> >(message, field)->Clear(); \ 519 break 520 521 HANDLE_TYPE( INT32, int32); 522 HANDLE_TYPE( INT64, int64); 523 HANDLE_TYPE(UINT32, uint32); 524 HANDLE_TYPE(UINT64, uint64); 525 HANDLE_TYPE(DOUBLE, double); 526 HANDLE_TYPE( FLOAT, float); 527 HANDLE_TYPE( BOOL, bool); 528 HANDLE_TYPE( ENUM, int); 529 #undef HANDLE_TYPE 530 531 case FieldDescriptor::CPPTYPE_STRING: { 532 switch (field->options().ctype()) { 533 default: // TODO(kenton): Support other string reps. 534 case FieldOptions::STRING: 535 MutableRaw<RepeatedPtrField<string> >(message, field)->Clear(); 536 break; 537 } 538 break; 539 } 540 541 case FieldDescriptor::CPPTYPE_MESSAGE: { 542 // We don't know which subclass of RepeatedPtrFieldBase the type is, 543 // so we use RepeatedPtrFieldBase directly. 544 MutableRaw<RepeatedPtrFieldBase>(message, field) 545 ->Clear<GenericTypeHandler<Message> >(); 546 break; 547 } 548 } 549 } 550 } 551 552 void GeneratedMessageReflection::RemoveLast( 553 Message* message, 554 const FieldDescriptor* field) const { 555 USAGE_CHECK_MESSAGE_TYPE(RemoveLast); 556 USAGE_CHECK_REPEATED(RemoveLast); 557 558 if (field->is_extension()) { 559 MutableExtensionSet(message)->RemoveLast(field->number()); 560 } else { 561 switch (field->cpp_type()) { 562 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ 563 case FieldDescriptor::CPPTYPE_##UPPERCASE : \ 564 MutableRaw<RepeatedField<LOWERCASE> >(message, field)->RemoveLast(); \ 565 break 566 567 HANDLE_TYPE( INT32, int32); 568 HANDLE_TYPE( INT64, int64); 569 HANDLE_TYPE(UINT32, uint32); 570 HANDLE_TYPE(UINT64, uint64); 571 HANDLE_TYPE(DOUBLE, double); 572 HANDLE_TYPE( FLOAT, float); 573 HANDLE_TYPE( BOOL, bool); 574 HANDLE_TYPE( ENUM, int); 575 #undef HANDLE_TYPE 576 577 case FieldDescriptor::CPPTYPE_STRING: 578 switch (field->options().ctype()) { 579 default: // TODO(kenton): Support other string reps. 580 case FieldOptions::STRING: 581 MutableRaw<RepeatedPtrField<string> >(message, field)->RemoveLast(); 582 break; 583 } 584 break; 585 586 case FieldDescriptor::CPPTYPE_MESSAGE: 587 MutableRaw<RepeatedPtrFieldBase>(message, field) 588 ->RemoveLast<GenericTypeHandler<Message> >(); 589 break; 590 } 591 } 592 } 593 594 void GeneratedMessageReflection::SwapElements( 595 Message* message, 596 const FieldDescriptor* field, 597 int index1, 598 int index2) const { 599 USAGE_CHECK_MESSAGE_TYPE(Swap); 600 USAGE_CHECK_REPEATED(Swap); 601 602 if (field->is_extension()) { 603 MutableExtensionSet(message)->SwapElements(field->number(), index1, index2); 604 } else { 605 switch (field->cpp_type()) { 606 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ 607 case FieldDescriptor::CPPTYPE_##UPPERCASE : \ 608 MutableRaw<RepeatedField<LOWERCASE> >(message, field) \ 609 ->SwapElements(index1, index2); \ 610 break 611 612 HANDLE_TYPE( INT32, int32); 613 HANDLE_TYPE( INT64, int64); 614 HANDLE_TYPE(UINT32, uint32); 615 HANDLE_TYPE(UINT64, uint64); 616 HANDLE_TYPE(DOUBLE, double); 617 HANDLE_TYPE( FLOAT, float); 618 HANDLE_TYPE( BOOL, bool); 619 HANDLE_TYPE( ENUM, int); 620 #undef HANDLE_TYPE 621 622 case FieldDescriptor::CPPTYPE_STRING: 623 case FieldDescriptor::CPPTYPE_MESSAGE: 624 MutableRaw<RepeatedPtrFieldBase>(message, field) 625 ->SwapElements(index1, index2); 626 break; 627 } 628 } 629 } 630 631 namespace { 632 // Comparison functor for sorting FieldDescriptors by field number. 633 struct FieldNumberSorter { 634 bool operator()(const FieldDescriptor* left, 635 const FieldDescriptor* right) const { 636 return left->number() < right->number(); 637 } 638 }; 639 } // namespace 640 641 void GeneratedMessageReflection::ListFields( 642 const Message& message, 643 vector<const FieldDescriptor*>* output) const { 644 output->clear(); 645 646 // Optimization: The default instance never has any fields set. 647 if (&message == default_instance_) return; 648 649 for (int i = 0; i < descriptor_->field_count(); i++) { 650 const FieldDescriptor* field = descriptor_->field(i); 651 if (field->is_repeated()) { 652 if (FieldSize(message, field) > 0) { 653 output->push_back(field); 654 } 655 } else { 656 if (HasBit(message, field)) { 657 output->push_back(field); 658 } 659 } 660 } 661 662 if (extensions_offset_ != -1) { 663 GetExtensionSet(message).AppendToList(descriptor_, descriptor_pool_, 664 output); 665 } 666 667 // ListFields() must sort output by field number. 668 sort(output->begin(), output->end(), FieldNumberSorter()); 669 } 670 671 // ------------------------------------------------------------------- 672 673 #undef DEFINE_PRIMITIVE_ACCESSORS 674 #define DEFINE_PRIMITIVE_ACCESSORS(TYPENAME, TYPE, PASSTYPE, CPPTYPE) \ 675 PASSTYPE GeneratedMessageReflection::Get##TYPENAME( \ 676 const Message& message, const FieldDescriptor* field) const { \ 677 USAGE_CHECK_ALL(Get##TYPENAME, SINGULAR, CPPTYPE); \ 678 if (field->is_extension()) { \ 679 return GetExtensionSet(message).Get##TYPENAME( \ 680 field->number(), field->default_value_##PASSTYPE()); \ 681 } else { \ 682 return GetField<TYPE>(message, field); \ 683 } \ 684 } \ 685 \ 686 void GeneratedMessageReflection::Set##TYPENAME( \ 687 Message* message, const FieldDescriptor* field, \ 688 PASSTYPE value) const { \ 689 USAGE_CHECK_ALL(Set##TYPENAME, SINGULAR, CPPTYPE); \ 690 if (field->is_extension()) { \ 691 return MutableExtensionSet(message)->Set##TYPENAME( \ 692 field->number(), field->type(), value, field); \ 693 } else { \ 694 SetField<TYPE>(message, field, value); \ 695 } \ 696 } \ 697 \ 698 PASSTYPE GeneratedMessageReflection::GetRepeated##TYPENAME( \ 699 const Message& message, \ 700 const FieldDescriptor* field, int index) const { \ 701 USAGE_CHECK_ALL(GetRepeated##TYPENAME, REPEATED, CPPTYPE); \ 702 if (field->is_extension()) { \ 703 return GetExtensionSet(message).GetRepeated##TYPENAME( \ 704 field->number(), index); \ 705 } else { \ 706 return GetRepeatedField<TYPE>(message, field, index); \ 707 } \ 708 } \ 709 \ 710 void GeneratedMessageReflection::SetRepeated##TYPENAME( \ 711 Message* message, const FieldDescriptor* field, \ 712 int index, PASSTYPE value) const { \ 713 USAGE_CHECK_ALL(SetRepeated##TYPENAME, REPEATED, CPPTYPE); \ 714 if (field->is_extension()) { \ 715 MutableExtensionSet(message)->SetRepeated##TYPENAME( \ 716 field->number(), index, value); \ 717 } else { \ 718 SetRepeatedField<TYPE>(message, field, index, value); \ 719 } \ 720 } \ 721 \ 722 void GeneratedMessageReflection::Add##TYPENAME( \ 723 Message* message, const FieldDescriptor* field, \ 724 PASSTYPE value) const { \ 725 USAGE_CHECK_ALL(Add##TYPENAME, REPEATED, CPPTYPE); \ 726 if (field->is_extension()) { \ 727 MutableExtensionSet(message)->Add##TYPENAME( \ 728 field->number(), field->type(), field->options().packed(), value, \ 729 field); \ 730 } else { \ 731 AddField<TYPE>(message, field, value); \ 732 } \ 733 } 734 735 DEFINE_PRIMITIVE_ACCESSORS(Int32 , int32 , int32 , INT32 ) 736 DEFINE_PRIMITIVE_ACCESSORS(Int64 , int64 , int64 , INT64 ) 737 DEFINE_PRIMITIVE_ACCESSORS(UInt32, uint32, uint32, UINT32) 738 DEFINE_PRIMITIVE_ACCESSORS(UInt64, uint64, uint64, UINT64) 739 DEFINE_PRIMITIVE_ACCESSORS(Float , float , float , FLOAT ) 740 DEFINE_PRIMITIVE_ACCESSORS(Double, double, double, DOUBLE) 741 DEFINE_PRIMITIVE_ACCESSORS(Bool , bool , bool , BOOL ) 742 #undef DEFINE_PRIMITIVE_ACCESSORS 743 744 // ------------------------------------------------------------------- 745 746 string GeneratedMessageReflection::GetString( 747 const Message& message, const FieldDescriptor* field) const { 748 USAGE_CHECK_ALL(GetString, SINGULAR, STRING); 749 if (field->is_extension()) { 750 return GetExtensionSet(message).GetString(field->number(), 751 field->default_value_string()); 752 } else { 753 switch (field->options().ctype()) { 754 default: // TODO(kenton): Support other string reps. 755 case FieldOptions::STRING: 756 return *GetField<const string*>(message, field); 757 } 758 759 GOOGLE_LOG(FATAL) << "Can't get here."; 760 return kEmptyString; // Make compiler happy. 761 } 762 } 763 764 const string& GeneratedMessageReflection::GetStringReference( 765 const Message& message, 766 const FieldDescriptor* field, string* scratch) const { 767 USAGE_CHECK_ALL(GetStringReference, SINGULAR, STRING); 768 if (field->is_extension()) { 769 return GetExtensionSet(message).GetString(field->number(), 770 field->default_value_string()); 771 } else { 772 switch (field->options().ctype()) { 773 default: // TODO(kenton): Support other string reps. 774 case FieldOptions::STRING: 775 return *GetField<const string*>(message, field); 776 } 777 778 GOOGLE_LOG(FATAL) << "Can't get here."; 779 return kEmptyString; // Make compiler happy. 780 } 781 } 782 783 784 void GeneratedMessageReflection::SetString( 785 Message* message, const FieldDescriptor* field, 786 const string& value) const { 787 USAGE_CHECK_ALL(SetString, SINGULAR, STRING); 788 if (field->is_extension()) { 789 return MutableExtensionSet(message)->SetString(field->number(), 790 field->type(), value, field); 791 } else { 792 switch (field->options().ctype()) { 793 default: // TODO(kenton): Support other string reps. 794 case FieldOptions::STRING: { 795 string** ptr = MutableField<string*>(message, field); 796 if (*ptr == DefaultRaw<const string*>(field)) { 797 *ptr = new string(value); 798 } else { 799 (*ptr)->assign(value); 800 } 801 break; 802 } 803 } 804 } 805 } 806 807 808 string GeneratedMessageReflection::GetRepeatedString( 809 const Message& message, const FieldDescriptor* field, int index) const { 810 USAGE_CHECK_ALL(GetRepeatedString, REPEATED, STRING); 811 if (field->is_extension()) { 812 return GetExtensionSet(message).GetRepeatedString(field->number(), index); 813 } else { 814 switch (field->options().ctype()) { 815 default: // TODO(kenton): Support other string reps. 816 case FieldOptions::STRING: 817 return GetRepeatedPtrField<string>(message, field, index); 818 } 819 820 GOOGLE_LOG(FATAL) << "Can't get here."; 821 return kEmptyString; // Make compiler happy. 822 } 823 } 824 825 const string& GeneratedMessageReflection::GetRepeatedStringReference( 826 const Message& message, const FieldDescriptor* field, 827 int index, string* scratch) const { 828 USAGE_CHECK_ALL(GetRepeatedStringReference, REPEATED, STRING); 829 if (field->is_extension()) { 830 return GetExtensionSet(message).GetRepeatedString(field->number(), index); 831 } else { 832 switch (field->options().ctype()) { 833 default: // TODO(kenton): Support other string reps. 834 case FieldOptions::STRING: 835 return GetRepeatedPtrField<string>(message, field, index); 836 } 837 838 GOOGLE_LOG(FATAL) << "Can't get here."; 839 return kEmptyString; // Make compiler happy. 840 } 841 } 842 843 844 void GeneratedMessageReflection::SetRepeatedString( 845 Message* message, const FieldDescriptor* field, 846 int index, const string& value) const { 847 USAGE_CHECK_ALL(SetRepeatedString, REPEATED, STRING); 848 if (field->is_extension()) { 849 MutableExtensionSet(message)->SetRepeatedString( 850 field->number(), index, value); 851 } else { 852 switch (field->options().ctype()) { 853 default: // TODO(kenton): Support other string reps. 854 case FieldOptions::STRING: 855 *MutableRepeatedField<string>(message, field, index) = value; 856 break; 857 } 858 } 859 } 860 861 862 void GeneratedMessageReflection::AddString( 863 Message* message, const FieldDescriptor* field, 864 const string& value) const { 865 USAGE_CHECK_ALL(AddString, REPEATED, STRING); 866 if (field->is_extension()) { 867 MutableExtensionSet(message)->AddString(field->number(), 868 field->type(), value, field); 869 } else { 870 switch (field->options().ctype()) { 871 default: // TODO(kenton): Support other string reps. 872 case FieldOptions::STRING: 873 *AddField<string>(message, field) = value; 874 break; 875 } 876 } 877 } 878 879 880 // ------------------------------------------------------------------- 881 882 const EnumValueDescriptor* GeneratedMessageReflection::GetEnum( 883 const Message& message, const FieldDescriptor* field) const { 884 USAGE_CHECK_ALL(GetEnum, SINGULAR, ENUM); 885 886 int value; 887 if (field->is_extension()) { 888 value = GetExtensionSet(message).GetEnum( 889 field->number(), field->default_value_enum()->number()); 890 } else { 891 value = GetField<int>(message, field); 892 } 893 const EnumValueDescriptor* result = 894 field->enum_type()->FindValueByNumber(value); 895 GOOGLE_CHECK(result != NULL); 896 return result; 897 } 898 899 void GeneratedMessageReflection::SetEnum( 900 Message* message, const FieldDescriptor* field, 901 const EnumValueDescriptor* value) const { 902 USAGE_CHECK_ALL(SetEnum, SINGULAR, ENUM); 903 USAGE_CHECK_ENUM_VALUE(SetEnum); 904 905 if (field->is_extension()) { 906 MutableExtensionSet(message)->SetEnum(field->number(), field->type(), 907 value->number(), field); 908 } else { 909 SetField<int>(message, field, value->number()); 910 } 911 } 912 913 const EnumValueDescriptor* GeneratedMessageReflection::GetRepeatedEnum( 914 const Message& message, const FieldDescriptor* field, int index) const { 915 USAGE_CHECK_ALL(GetRepeatedEnum, REPEATED, ENUM); 916 917 int value; 918 if (field->is_extension()) { 919 value = GetExtensionSet(message).GetRepeatedEnum(field->number(), index); 920 } else { 921 value = GetRepeatedField<int>(message, field, index); 922 } 923 const EnumValueDescriptor* result = 924 field->enum_type()->FindValueByNumber(value); 925 GOOGLE_CHECK(result != NULL); 926 return result; 927 } 928 929 void GeneratedMessageReflection::SetRepeatedEnum( 930 Message* message, 931 const FieldDescriptor* field, int index, 932 const EnumValueDescriptor* value) const { 933 USAGE_CHECK_ALL(SetRepeatedEnum, REPEATED, ENUM); 934 USAGE_CHECK_ENUM_VALUE(SetRepeatedEnum); 935 936 if (field->is_extension()) { 937 MutableExtensionSet(message)->SetRepeatedEnum( 938 field->number(), index, value->number()); 939 } else { 940 SetRepeatedField<int>(message, field, index, value->number()); 941 } 942 } 943 944 void GeneratedMessageReflection::AddEnum( 945 Message* message, const FieldDescriptor* field, 946 const EnumValueDescriptor* value) const { 947 USAGE_CHECK_ALL(AddEnum, REPEATED, ENUM); 948 USAGE_CHECK_ENUM_VALUE(AddEnum); 949 950 if (field->is_extension()) { 951 MutableExtensionSet(message)->AddEnum(field->number(), field->type(), 952 field->options().packed(), 953 value->number(), field); 954 } else { 955 AddField<int>(message, field, value->number()); 956 } 957 } 958 959 // ------------------------------------------------------------------- 960 961 const Message& GeneratedMessageReflection::GetMessage( 962 const Message& message, const FieldDescriptor* field, 963 MessageFactory* factory) const { 964 USAGE_CHECK_ALL(GetMessage, SINGULAR, MESSAGE); 965 966 if (field->is_extension()) { 967 return static_cast<const Message&>( 968 GetExtensionSet(message).GetMessage( 969 field->number(), field->message_type(), 970 factory == NULL ? message_factory_ : factory)); 971 } else { 972 const Message* result = GetRaw<const Message*>(message, field); 973 if (result == NULL) { 974 result = DefaultRaw<const Message*>(field); 975 } 976 return *result; 977 } 978 } 979 980 Message* GeneratedMessageReflection::MutableMessage( 981 Message* message, const FieldDescriptor* field, 982 MessageFactory* factory) const { 983 USAGE_CHECK_ALL(MutableMessage, SINGULAR, MESSAGE); 984 985 if (field->is_extension()) { 986 return static_cast<Message*>( 987 MutableExtensionSet(message)->MutableMessage(field, 988 factory == NULL ? message_factory_ : factory)); 989 } else { 990 Message** result = MutableField<Message*>(message, field); 991 if (*result == NULL) { 992 const Message* default_message = DefaultRaw<const Message*>(field); 993 *result = default_message->New(); 994 } 995 return *result; 996 } 997 } 998 999 const Message& GeneratedMessageReflection::GetRepeatedMessage( 1000 const Message& message, const FieldDescriptor* field, int index) const { 1001 USAGE_CHECK_ALL(GetRepeatedMessage, REPEATED, MESSAGE); 1002 1003 if (field->is_extension()) { 1004 return static_cast<const Message&>( 1005 GetExtensionSet(message).GetRepeatedMessage(field->number(), index)); 1006 } else { 1007 return GetRaw<RepeatedPtrFieldBase>(message, field) 1008 .Get<GenericTypeHandler<Message> >(index); 1009 } 1010 } 1011 1012 Message* GeneratedMessageReflection::MutableRepeatedMessage( 1013 Message* message, const FieldDescriptor* field, int index) const { 1014 USAGE_CHECK_ALL(MutableRepeatedMessage, REPEATED, MESSAGE); 1015 1016 if (field->is_extension()) { 1017 return static_cast<Message*>( 1018 MutableExtensionSet(message)->MutableRepeatedMessage( 1019 field->number(), index)); 1020 } else { 1021 return MutableRaw<RepeatedPtrFieldBase>(message, field) 1022 ->Mutable<GenericTypeHandler<Message> >(index); 1023 } 1024 } 1025 1026 Message* GeneratedMessageReflection::AddMessage( 1027 Message* message, const FieldDescriptor* field, 1028 MessageFactory* factory) const { 1029 USAGE_CHECK_ALL(AddMessage, REPEATED, MESSAGE); 1030 1031 if (factory == NULL) factory = message_factory_; 1032 1033 if (field->is_extension()) { 1034 return static_cast<Message*>( 1035 MutableExtensionSet(message)->AddMessage(field, factory)); 1036 } else { 1037 // We can't use AddField<Message>() because RepeatedPtrFieldBase doesn't 1038 // know how to allocate one. 1039 RepeatedPtrFieldBase* repeated = 1040 MutableRaw<RepeatedPtrFieldBase>(message, field); 1041 Message* result = repeated->AddFromCleared<GenericTypeHandler<Message> >(); 1042 if (result == NULL) { 1043 // We must allocate a new object. 1044 const Message* prototype; 1045 if (repeated->size() == 0) { 1046 prototype = factory->GetPrototype(field->message_type()); 1047 } else { 1048 prototype = &repeated->Get<GenericTypeHandler<Message> >(0); 1049 } 1050 result = prototype->New(); 1051 repeated->AddAllocated<GenericTypeHandler<Message> >(result); 1052 } 1053 return result; 1054 } 1055 } 1056 1057 // ------------------------------------------------------------------- 1058 1059 const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByName( 1060 const string& name) const { 1061 if (extensions_offset_ == -1) return NULL; 1062 1063 const FieldDescriptor* result = descriptor_pool_->FindExtensionByName(name); 1064 if (result != NULL && result->containing_type() == descriptor_) { 1065 return result; 1066 } 1067 1068 if (descriptor_->options().message_set_wire_format()) { 1069 // MessageSet extensions may be identified by type name. 1070 const Descriptor* type = descriptor_pool_->FindMessageTypeByName(name); 1071 if (type != NULL) { 1072 // Look for a matching extension in the foreign type's scope. 1073 for (int i = 0; i < type->extension_count(); i++) { 1074 const FieldDescriptor* extension = type->extension(i); 1075 if (extension->containing_type() == descriptor_ && 1076 extension->type() == FieldDescriptor::TYPE_MESSAGE && 1077 extension->is_optional() && 1078 extension->message_type() == type) { 1079 // Found it. 1080 return extension; 1081 } 1082 } 1083 } 1084 } 1085 1086 return NULL; 1087 } 1088 1089 const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByNumber( 1090 int number) const { 1091 if (extensions_offset_ == -1) return NULL; 1092 return descriptor_pool_->FindExtensionByNumber(descriptor_, number); 1093 } 1094 1095 // =================================================================== 1096 // Some private helpers. 1097 1098 // These simple template accessors obtain pointers (or references) to 1099 // the given field. 1100 template <typename Type> 1101 inline const Type& GeneratedMessageReflection::GetRaw( 1102 const Message& message, const FieldDescriptor* field) const { 1103 const void* ptr = reinterpret_cast<const uint8*>(&message) + 1104 offsets_[field->index()]; 1105 return *reinterpret_cast<const Type*>(ptr); 1106 } 1107 1108 template <typename Type> 1109 inline Type* GeneratedMessageReflection::MutableRaw( 1110 Message* message, const FieldDescriptor* field) const { 1111 void* ptr = reinterpret_cast<uint8*>(message) + offsets_[field->index()]; 1112 return reinterpret_cast<Type*>(ptr); 1113 } 1114 1115 template <typename Type> 1116 inline const Type& GeneratedMessageReflection::DefaultRaw( 1117 const FieldDescriptor* field) const { 1118 const void* ptr = reinterpret_cast<const uint8*>(default_instance_) + 1119 offsets_[field->index()]; 1120 return *reinterpret_cast<const Type*>(ptr); 1121 } 1122 1123 inline const uint32* GeneratedMessageReflection::GetHasBits( 1124 const Message& message) const { 1125 const void* ptr = reinterpret_cast<const uint8*>(&message) + has_bits_offset_; 1126 return reinterpret_cast<const uint32*>(ptr); 1127 } 1128 inline uint32* GeneratedMessageReflection::MutableHasBits( 1129 Message* message) const { 1130 void* ptr = reinterpret_cast<uint8*>(message) + has_bits_offset_; 1131 return reinterpret_cast<uint32*>(ptr); 1132 } 1133 1134 inline const ExtensionSet& GeneratedMessageReflection::GetExtensionSet( 1135 const Message& message) const { 1136 GOOGLE_DCHECK_NE(extensions_offset_, -1); 1137 const void* ptr = reinterpret_cast<const uint8*>(&message) + 1138 extensions_offset_; 1139 return *reinterpret_cast<const ExtensionSet*>(ptr); 1140 } 1141 inline ExtensionSet* GeneratedMessageReflection::MutableExtensionSet( 1142 Message* message) const { 1143 GOOGLE_DCHECK_NE(extensions_offset_, -1); 1144 void* ptr = reinterpret_cast<uint8*>(message) + extensions_offset_; 1145 return reinterpret_cast<ExtensionSet*>(ptr); 1146 } 1147 1148 // Simple accessors for manipulating has_bits_. 1149 inline bool GeneratedMessageReflection::HasBit( 1150 const Message& message, const FieldDescriptor* field) const { 1151 return GetHasBits(message)[field->index() / 32] & 1152 (1 << (field->index() % 32)); 1153 } 1154 1155 inline void GeneratedMessageReflection::SetBit( 1156 Message* message, const FieldDescriptor* field) const { 1157 MutableHasBits(message)[field->index() / 32] |= (1 << (field->index() % 32)); 1158 } 1159 1160 inline void GeneratedMessageReflection::ClearBit( 1161 Message* message, const FieldDescriptor* field) const { 1162 MutableHasBits(message)[field->index() / 32] &= ~(1 << (field->index() % 32)); 1163 } 1164 1165 // Template implementations of basic accessors. Inline because each 1166 // template instance is only called from one location. These are 1167 // used for all types except messages. 1168 template <typename Type> 1169 inline const Type& GeneratedMessageReflection::GetField( 1170 const Message& message, const FieldDescriptor* field) const { 1171 return GetRaw<Type>(message, field); 1172 } 1173 1174 template <typename Type> 1175 inline void GeneratedMessageReflection::SetField( 1176 Message* message, const FieldDescriptor* field, const Type& value) const { 1177 *MutableRaw<Type>(message, field) = value; 1178 SetBit(message, field); 1179 } 1180 1181 template <typename Type> 1182 inline Type* GeneratedMessageReflection::MutableField( 1183 Message* message, const FieldDescriptor* field) const { 1184 SetBit(message, field); 1185 return MutableRaw<Type>(message, field); 1186 } 1187 1188 template <typename Type> 1189 inline const Type& GeneratedMessageReflection::GetRepeatedField( 1190 const Message& message, const FieldDescriptor* field, int index) const { 1191 return GetRaw<RepeatedField<Type> >(message, field).Get(index); 1192 } 1193 1194 template <typename Type> 1195 inline const Type& GeneratedMessageReflection::GetRepeatedPtrField( 1196 const Message& message, const FieldDescriptor* field, int index) const { 1197 return GetRaw<RepeatedPtrField<Type> >(message, field).Get(index); 1198 } 1199 1200 template <typename Type> 1201 inline void GeneratedMessageReflection::SetRepeatedField( 1202 Message* message, const FieldDescriptor* field, 1203 int index, Type value) const { 1204 MutableRaw<RepeatedField<Type> >(message, field)->Set(index, value); 1205 } 1206 1207 template <typename Type> 1208 inline Type* GeneratedMessageReflection::MutableRepeatedField( 1209 Message* message, const FieldDescriptor* field, int index) const { 1210 RepeatedPtrField<Type>* repeated = 1211 MutableRaw<RepeatedPtrField<Type> >(message, field); 1212 return repeated->Mutable(index); 1213 } 1214 1215 template <typename Type> 1216 inline void GeneratedMessageReflection::AddField( 1217 Message* message, const FieldDescriptor* field, const Type& value) const { 1218 MutableRaw<RepeatedField<Type> >(message, field)->Add(value); 1219 } 1220 1221 template <typename Type> 1222 inline Type* GeneratedMessageReflection::AddField( 1223 Message* message, const FieldDescriptor* field) const { 1224 RepeatedPtrField<Type>* repeated = 1225 MutableRaw<RepeatedPtrField<Type> >(message, field); 1226 return repeated->Add(); 1227 } 1228 1229 } // namespace internal 1230 } // namespace protobuf 1231 } // namespace google 1232