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 <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
StringSpaceUsedExcludingSelf(const string & str)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
ParseNamedEnum(const EnumDescriptor * descriptor,const string & name,int * value)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
NameOfEnum(const EnumDescriptor * descriptor,int value)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
ReportReflectionUsageError(const Descriptor * descriptor,const FieldDescriptor * field,const char * method,const char * description)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
ReportReflectionUsageTypeError(const Descriptor * descriptor,const FieldDescriptor * field,const char * method,FieldDescriptor::CppType expected_type)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
ReportReflectionUsageEnumTypeError(const Descriptor * descriptor,const FieldDescriptor * field,const char * method,const EnumValueDescriptor * value)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
GeneratedMessageReflection(const Descriptor * descriptor,const Message * default_instance,const int offsets[],int has_bits_offset,int unknown_fields_offset,int extensions_offset,const DescriptorPool * descriptor_pool,MessageFactory * factory,int object_size)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
~GeneratedMessageReflection()194 GeneratedMessageReflection::~GeneratedMessageReflection() {}
195
GetUnknownFields(const Message & message) const196 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 }
MutableUnknownFields(Message * message) const202 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
SpaceUsed(const Message & message) const208 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
Swap(Message * message1,Message * message2) const312 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
HasField(const Message & message,const FieldDescriptor * field) const414 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
FieldSize(const Message & message,const FieldDescriptor * field) const426 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
ClearField(Message * message,const FieldDescriptor * field) const459 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
RemoveLast(Message * message,const FieldDescriptor * field) const552 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
SwapElements(Message * message,const FieldDescriptor * field,int index1,int index2) const594 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 {
operator ()google::protobuf::internal::__anoneb99ef490311::FieldNumberSorter634 bool operator()(const FieldDescriptor* left,
635 const FieldDescriptor* right) const {
636 return left->number() < right->number();
637 }
638 };
639 } // namespace
640
ListFields(const Message & message,vector<const FieldDescriptor * > * output) const641 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
DEFINE_PRIMITIVE_ACCESSORS(Int32,int32,int32,INT32)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
GetStringReference(const Message & message,const FieldDescriptor * field,string * scratch) const764 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
SetString(Message * message,const FieldDescriptor * field,const string & value) const784 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
GetRepeatedString(const Message & message,const FieldDescriptor * field,int index) const808 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
GetRepeatedStringReference(const Message & message,const FieldDescriptor * field,int index,string * scratch) const825 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
SetRepeatedString(Message * message,const FieldDescriptor * field,int index,const string & value) const844 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
AddString(Message * message,const FieldDescriptor * field,const string & value) const862 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
GetEnum(const Message & message,const FieldDescriptor * field) const882 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
SetEnum(Message * message,const FieldDescriptor * field,const EnumValueDescriptor * value) const899 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
GetRepeatedEnum(const Message & message,const FieldDescriptor * field,int index) const913 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
SetRepeatedEnum(Message * message,const FieldDescriptor * field,int index,const EnumValueDescriptor * value) const929 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
AddEnum(Message * message,const FieldDescriptor * field,const EnumValueDescriptor * value) const944 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
GetMessage(const Message & message,const FieldDescriptor * field,MessageFactory * factory) const961 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
MutableMessage(Message * message,const FieldDescriptor * field,MessageFactory * factory) const980 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
GetRepeatedMessage(const Message & message,const FieldDescriptor * field,int index) const999 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
MutableRepeatedMessage(Message * message,const FieldDescriptor * field,int index) const1012 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
AddMessage(Message * message,const FieldDescriptor * field,MessageFactory * factory) const1026 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
FindKnownExtensionByName(const string & name) const1059 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
FindKnownExtensionByNumber(int number) const1089 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>
GetRaw(const Message & message,const FieldDescriptor * field) const1101 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>
MutableRaw(Message * message,const FieldDescriptor * field) const1109 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>
DefaultRaw(const FieldDescriptor * field) const1116 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
GetHasBits(const Message & message) const1123 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 }
MutableHasBits(Message * message) const1128 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
GetExtensionSet(const Message & message) const1134 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 }
MutableExtensionSet(Message * message) const1141 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_.
HasBit(const Message & message,const FieldDescriptor * field) const1149 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
SetBit(Message * message,const FieldDescriptor * field) const1155 inline void GeneratedMessageReflection::SetBit(
1156 Message* message, const FieldDescriptor* field) const {
1157 MutableHasBits(message)[field->index() / 32] |= (1 << (field->index() % 32));
1158 }
1159
ClearBit(Message * message,const FieldDescriptor * field) const1160 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>
GetField(const Message & message,const FieldDescriptor * field) const1169 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>
SetField(Message * message,const FieldDescriptor * field,const Type & value) const1175 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>
MutableField(Message * message,const FieldDescriptor * field) const1182 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>
GetRepeatedField(const Message & message,const FieldDescriptor * field,int index) const1189 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>
GetRepeatedPtrField(const Message & message,const FieldDescriptor * field,int index) const1195 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>
SetRepeatedField(Message * message,const FieldDescriptor * field,int index,Type value) const1201 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>
MutableRepeatedField(Message * message,const FieldDescriptor * field,int index) const1208 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>
AddField(Message * message,const FieldDescriptor * field,const Type & value) const1216 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>
AddField(Message * message,const FieldDescriptor * field) const1222 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