1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
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 <set>
37 #include <google/protobuf/descriptor.pb.h>
38 #include <google/protobuf/generated_message_reflection.h>
39 #include <google/protobuf/descriptor.h>
40 #include <google/protobuf/repeated_field.h>
41 #include <google/protobuf/extension_set.h>
42 #include <google/protobuf/generated_message_util.h>
43 #include <google/protobuf/stubs/common.h>
44
45 #define GOOGLE_PROTOBUF_HAS_ONEOF
46
47 namespace google {
48 namespace protobuf {
49 namespace internal {
50
StringSpaceUsedExcludingSelf(const string & str)51 int StringSpaceUsedExcludingSelf(const string& str) {
52 const void* start = &str;
53 const void* end = &str + 1;
54
55 if (start <= str.data() && str.data() < end) {
56 // The string's data is stored inside the string object itself.
57 return 0;
58 } else {
59 return str.capacity();
60 }
61 }
62
ParseNamedEnum(const EnumDescriptor * descriptor,const string & name,int * value)63 bool ParseNamedEnum(const EnumDescriptor* descriptor,
64 const string& name,
65 int* value) {
66 const EnumValueDescriptor* d = descriptor->FindValueByName(name);
67 if (d == NULL) return false;
68 *value = d->number();
69 return true;
70 }
71
NameOfEnum(const EnumDescriptor * descriptor,int value)72 const string& NameOfEnum(const EnumDescriptor* descriptor, int value) {
73 const EnumValueDescriptor* d = descriptor->FindValueByNumber(value);
74 return (d == NULL ? GetEmptyString() : 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(const Descriptor * descriptor,const Message * default_instance,const int offsets[],int has_bits_offset,int unknown_fields_offset,int extensions_offset,const void * default_oneof_instance,int oneof_case_offset,const DescriptorPool * descriptor_pool,MessageFactory * factory,int object_size)194 GeneratedMessageReflection::GeneratedMessageReflection(
195 const Descriptor* descriptor,
196 const Message* default_instance,
197 const int offsets[],
198 int has_bits_offset,
199 int unknown_fields_offset,
200 int extensions_offset,
201 const void* default_oneof_instance,
202 int oneof_case_offset,
203 const DescriptorPool* descriptor_pool,
204 MessageFactory* factory,
205 int object_size)
206 : descriptor_ (descriptor),
207 default_instance_ (default_instance),
208 default_oneof_instance_ (default_oneof_instance),
209 offsets_ (offsets),
210 has_bits_offset_ (has_bits_offset),
211 oneof_case_offset_(oneof_case_offset),
212 unknown_fields_offset_(unknown_fields_offset),
213 extensions_offset_(extensions_offset),
214 object_size_ (object_size),
215 descriptor_pool_ ((descriptor_pool == NULL) ?
216 DescriptorPool::generated_pool() :
217 descriptor_pool),
218 message_factory_ (factory) {
219 }
220
~GeneratedMessageReflection()221 GeneratedMessageReflection::~GeneratedMessageReflection() {}
222
GetUnknownFields(const Message & message) const223 const UnknownFieldSet& GeneratedMessageReflection::GetUnknownFields(
224 const Message& message) const {
225 const void* ptr = reinterpret_cast<const uint8*>(&message) +
226 unknown_fields_offset_;
227 return *reinterpret_cast<const UnknownFieldSet*>(ptr);
228 }
MutableUnknownFields(Message * message) const229 UnknownFieldSet* GeneratedMessageReflection::MutableUnknownFields(
230 Message* message) const {
231 void* ptr = reinterpret_cast<uint8*>(message) + unknown_fields_offset_;
232 return reinterpret_cast<UnknownFieldSet*>(ptr);
233 }
234
SpaceUsed(const Message & message) const235 int GeneratedMessageReflection::SpaceUsed(const Message& message) const {
236 // object_size_ already includes the in-memory representation of each field
237 // in the message, so we only need to account for additional memory used by
238 // the fields.
239 int total_size = object_size_;
240
241 total_size += GetUnknownFields(message).SpaceUsedExcludingSelf();
242
243 if (extensions_offset_ != -1) {
244 total_size += GetExtensionSet(message).SpaceUsedExcludingSelf();
245 }
246
247 for (int i = 0; i < descriptor_->field_count(); i++) {
248 const FieldDescriptor* field = descriptor_->field(i);
249
250 if (field->is_repeated()) {
251 switch (field->cpp_type()) {
252 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
253 case FieldDescriptor::CPPTYPE_##UPPERCASE : \
254 total_size += GetRaw<RepeatedField<LOWERCASE> >(message, field) \
255 .SpaceUsedExcludingSelf(); \
256 break
257
258 HANDLE_TYPE( INT32, int32);
259 HANDLE_TYPE( INT64, int64);
260 HANDLE_TYPE(UINT32, uint32);
261 HANDLE_TYPE(UINT64, uint64);
262 HANDLE_TYPE(DOUBLE, double);
263 HANDLE_TYPE( FLOAT, float);
264 HANDLE_TYPE( BOOL, bool);
265 HANDLE_TYPE( ENUM, int);
266 #undef HANDLE_TYPE
267
268 case FieldDescriptor::CPPTYPE_STRING:
269 switch (field->options().ctype()) {
270 default: // TODO(kenton): Support other string reps.
271 case FieldOptions::STRING:
272 total_size += GetRaw<RepeatedPtrField<string> >(message, field)
273 .SpaceUsedExcludingSelf();
274 break;
275 }
276 break;
277
278 case FieldDescriptor::CPPTYPE_MESSAGE:
279 // We don't know which subclass of RepeatedPtrFieldBase the type is,
280 // so we use RepeatedPtrFieldBase directly.
281 total_size +=
282 GetRaw<RepeatedPtrFieldBase>(message, field)
283 .SpaceUsedExcludingSelf<GenericTypeHandler<Message> >();
284 break;
285 }
286 } else {
287 if (field->containing_oneof() && !HasOneofField(message, field)) {
288 continue;
289 }
290 switch (field->cpp_type()) {
291 case FieldDescriptor::CPPTYPE_INT32 :
292 case FieldDescriptor::CPPTYPE_INT64 :
293 case FieldDescriptor::CPPTYPE_UINT32:
294 case FieldDescriptor::CPPTYPE_UINT64:
295 case FieldDescriptor::CPPTYPE_DOUBLE:
296 case FieldDescriptor::CPPTYPE_FLOAT :
297 case FieldDescriptor::CPPTYPE_BOOL :
298 case FieldDescriptor::CPPTYPE_ENUM :
299 // Field is inline, so we've already counted it.
300 break;
301
302 case FieldDescriptor::CPPTYPE_STRING: {
303 switch (field->options().ctype()) {
304 default: // TODO(kenton): Support other string reps.
305 case FieldOptions::STRING: {
306 const string* ptr = GetField<const string*>(message, field);
307
308 // Initially, the string points to the default value stored in
309 // the prototype. Only count the string if it has been changed
310 // from the default value.
311 const string* default_ptr = DefaultRaw<const string*>(field);
312
313 if (ptr != default_ptr) {
314 // string fields are represented by just a pointer, so also
315 // include sizeof(string) as well.
316 total_size += sizeof(*ptr) + StringSpaceUsedExcludingSelf(*ptr);
317 }
318 break;
319 }
320 }
321 break;
322 }
323
324 case FieldDescriptor::CPPTYPE_MESSAGE:
325 if (&message == default_instance_) {
326 // For singular fields, the prototype just stores a pointer to the
327 // external type's prototype, so there is no extra memory usage.
328 } else {
329 const Message* sub_message = GetRaw<const Message*>(message, field);
330 if (sub_message != NULL) {
331 total_size += sub_message->SpaceUsed();
332 }
333 }
334 break;
335 }
336 }
337 }
338
339 return total_size;
340 }
341
SwapField(Message * message1,Message * message2,const FieldDescriptor * field) const342 void GeneratedMessageReflection::SwapField(
343 Message* message1,
344 Message* message2,
345 const FieldDescriptor* field) const {
346 if (field->is_repeated()) {
347 switch (field->cpp_type()) {
348 #define SWAP_ARRAYS(CPPTYPE, TYPE) \
349 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
350 MutableRaw<RepeatedField<TYPE> >(message1, field)->Swap( \
351 MutableRaw<RepeatedField<TYPE> >(message2, field)); \
352 break;
353
354 SWAP_ARRAYS(INT32 , int32 );
355 SWAP_ARRAYS(INT64 , int64 );
356 SWAP_ARRAYS(UINT32, uint32);
357 SWAP_ARRAYS(UINT64, uint64);
358 SWAP_ARRAYS(FLOAT , float );
359 SWAP_ARRAYS(DOUBLE, double);
360 SWAP_ARRAYS(BOOL , bool );
361 SWAP_ARRAYS(ENUM , int );
362 #undef SWAP_ARRAYS
363
364 case FieldDescriptor::CPPTYPE_STRING:
365 case FieldDescriptor::CPPTYPE_MESSAGE:
366 MutableRaw<RepeatedPtrFieldBase>(message1, field)->Swap(
367 MutableRaw<RepeatedPtrFieldBase>(message2, field));
368 break;
369
370 default:
371 GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
372 }
373 } else {
374 switch (field->cpp_type()) {
375 #define SWAP_VALUES(CPPTYPE, TYPE) \
376 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
377 std::swap(*MutableRaw<TYPE>(message1, field), \
378 *MutableRaw<TYPE>(message2, field)); \
379 break;
380
381 SWAP_VALUES(INT32 , int32 );
382 SWAP_VALUES(INT64 , int64 );
383 SWAP_VALUES(UINT32, uint32);
384 SWAP_VALUES(UINT64, uint64);
385 SWAP_VALUES(FLOAT , float );
386 SWAP_VALUES(DOUBLE, double);
387 SWAP_VALUES(BOOL , bool );
388 SWAP_VALUES(ENUM , int );
389 #undef SWAP_VALUES
390 case FieldDescriptor::CPPTYPE_MESSAGE:
391 std::swap(*MutableRaw<Message*>(message1, field),
392 *MutableRaw<Message*>(message2, field));
393 break;
394
395 case FieldDescriptor::CPPTYPE_STRING:
396 switch (field->options().ctype()) {
397 default: // TODO(kenton): Support other string reps.
398 case FieldOptions::STRING:
399 std::swap(*MutableRaw<string*>(message1, field),
400 *MutableRaw<string*>(message2, field));
401 break;
402 }
403 break;
404
405 default:
406 GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
407 }
408 }
409 }
410
SwapOneofField(Message * message1,Message * message2,const OneofDescriptor * oneof_descriptor) const411 void GeneratedMessageReflection::SwapOneofField(
412 Message* message1,
413 Message* message2,
414 const OneofDescriptor* oneof_descriptor) const {
415 uint32 oneof_case1 = GetOneofCase(*message1, oneof_descriptor);
416 uint32 oneof_case2 = GetOneofCase(*message2, oneof_descriptor);
417
418 int32 temp_int32;
419 int64 temp_int64;
420 uint32 temp_uint32;
421 uint64 temp_uint64;
422 float temp_float;
423 double temp_double;
424 bool temp_bool;
425 int temp_int;
426 Message* temp_message;
427 string temp_string;
428
429 // Stores message1's oneof field to a temp variable.
430 const FieldDescriptor* field1;
431 if (oneof_case1 > 0) {
432 field1 = descriptor_->FindFieldByNumber(oneof_case1);
433 //oneof_descriptor->field(oneof_case1);
434 switch (field1->cpp_type()) {
435 #define GET_TEMP_VALUE(CPPTYPE, TYPE) \
436 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
437 temp_##TYPE = GetField<TYPE>(*message1, field1); \
438 break;
439
440 GET_TEMP_VALUE(INT32 , int32 );
441 GET_TEMP_VALUE(INT64 , int64 );
442 GET_TEMP_VALUE(UINT32, uint32);
443 GET_TEMP_VALUE(UINT64, uint64);
444 GET_TEMP_VALUE(FLOAT , float );
445 GET_TEMP_VALUE(DOUBLE, double);
446 GET_TEMP_VALUE(BOOL , bool );
447 GET_TEMP_VALUE(ENUM , int );
448 #undef GET_TEMP_VALUE
449 case FieldDescriptor::CPPTYPE_MESSAGE:
450 temp_message = ReleaseMessage(message1, field1);
451 break;
452
453 case FieldDescriptor::CPPTYPE_STRING:
454 temp_string = GetString(*message1, field1);
455 break;
456
457 default:
458 GOOGLE_LOG(FATAL) << "Unimplemented type: " << field1->cpp_type();
459 }
460 }
461
462 // Sets message1's oneof field from the message2's oneof field.
463 if (oneof_case2 > 0) {
464 const FieldDescriptor* field2 =
465 descriptor_->FindFieldByNumber(oneof_case2);
466 switch (field2->cpp_type()) {
467 #define SET_ONEOF_VALUE1(CPPTYPE, TYPE) \
468 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
469 SetField<TYPE>(message1, field2, GetField<TYPE>(*message2, field2)); \
470 break;
471
472 SET_ONEOF_VALUE1(INT32 , int32 );
473 SET_ONEOF_VALUE1(INT64 , int64 );
474 SET_ONEOF_VALUE1(UINT32, uint32);
475 SET_ONEOF_VALUE1(UINT64, uint64);
476 SET_ONEOF_VALUE1(FLOAT , float );
477 SET_ONEOF_VALUE1(DOUBLE, double);
478 SET_ONEOF_VALUE1(BOOL , bool );
479 SET_ONEOF_VALUE1(ENUM , int );
480 #undef SET_ONEOF_VALUE1
481 case FieldDescriptor::CPPTYPE_MESSAGE:
482 SetAllocatedMessage(message1,
483 ReleaseMessage(message2, field2),
484 field2);
485 break;
486
487 case FieldDescriptor::CPPTYPE_STRING:
488 SetString(message1, field2, GetString(*message2, field2));
489 break;
490
491 default:
492 GOOGLE_LOG(FATAL) << "Unimplemented type: " << field2->cpp_type();
493 }
494 } else {
495 ClearOneof(message1, oneof_descriptor);
496 }
497
498 // Sets message2's oneof field from the temp variable.
499 if (oneof_case1 > 0) {
500 switch (field1->cpp_type()) {
501 #define SET_ONEOF_VALUE2(CPPTYPE, TYPE) \
502 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
503 SetField<TYPE>(message2, field1, temp_##TYPE); \
504 break;
505
506 SET_ONEOF_VALUE2(INT32 , int32 );
507 SET_ONEOF_VALUE2(INT64 , int64 );
508 SET_ONEOF_VALUE2(UINT32, uint32);
509 SET_ONEOF_VALUE2(UINT64, uint64);
510 SET_ONEOF_VALUE2(FLOAT , float );
511 SET_ONEOF_VALUE2(DOUBLE, double);
512 SET_ONEOF_VALUE2(BOOL , bool );
513 SET_ONEOF_VALUE2(ENUM , int );
514 #undef SET_ONEOF_VALUE2
515 case FieldDescriptor::CPPTYPE_MESSAGE:
516 SetAllocatedMessage(message2, temp_message, field1);
517 break;
518
519 case FieldDescriptor::CPPTYPE_STRING:
520 SetString(message2, field1, temp_string);
521 break;
522
523 default:
524 GOOGLE_LOG(FATAL) << "Unimplemented type: " << field1->cpp_type();
525 }
526 } else {
527 ClearOneof(message2, oneof_descriptor);
528 }
529 }
530
Swap(Message * message1,Message * message2) const531 void GeneratedMessageReflection::Swap(
532 Message* message1,
533 Message* message2) const {
534 if (message1 == message2) return;
535
536 // TODO(kenton): Other Reflection methods should probably check this too.
537 GOOGLE_CHECK_EQ(message1->GetReflection(), this)
538 << "First argument to Swap() (of type \""
539 << message1->GetDescriptor()->full_name()
540 << "\") is not compatible with this reflection object (which is for type \""
541 << descriptor_->full_name()
542 << "\"). Note that the exact same class is required; not just the same "
543 "descriptor.";
544 GOOGLE_CHECK_EQ(message2->GetReflection(), this)
545 << "Second argument to Swap() (of type \""
546 << message2->GetDescriptor()->full_name()
547 << "\") is not compatible with this reflection object (which is for type \""
548 << descriptor_->full_name()
549 << "\"). Note that the exact same class is required; not just the same "
550 "descriptor.";
551
552 uint32* has_bits1 = MutableHasBits(message1);
553 uint32* has_bits2 = MutableHasBits(message2);
554 int has_bits_size = (descriptor_->field_count() + 31) / 32;
555
556 for (int i = 0; i < has_bits_size; i++) {
557 std::swap(has_bits1[i], has_bits2[i]);
558 }
559
560 for (int i = 0; i < descriptor_->field_count(); i++) {
561 const FieldDescriptor* field = descriptor_->field(i);
562 if (!field->containing_oneof()) {
563 SwapField(message1, message2, field);
564 }
565 }
566
567 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
568 SwapOneofField(message1, message2, descriptor_->oneof_decl(i));
569 }
570
571 if (extensions_offset_ != -1) {
572 MutableExtensionSet(message1)->Swap(MutableExtensionSet(message2));
573 }
574
575 MutableUnknownFields(message1)->Swap(MutableUnknownFields(message2));
576 }
577
SwapFields(Message * message1,Message * message2,const vector<const FieldDescriptor * > & fields) const578 void GeneratedMessageReflection::SwapFields(
579 Message* message1,
580 Message* message2,
581 const vector<const FieldDescriptor*>& fields) const {
582 if (message1 == message2) return;
583
584 // TODO(kenton): Other Reflection methods should probably check this too.
585 GOOGLE_CHECK_EQ(message1->GetReflection(), this)
586 << "First argument to SwapFields() (of type \""
587 << message1->GetDescriptor()->full_name()
588 << "\") is not compatible with this reflection object (which is for type \""
589 << descriptor_->full_name()
590 << "\"). Note that the exact same class is required; not just the same "
591 "descriptor.";
592 GOOGLE_CHECK_EQ(message2->GetReflection(), this)
593 << "Second argument to SwapFields() (of type \""
594 << message2->GetDescriptor()->full_name()
595 << "\") is not compatible with this reflection object (which is for type \""
596 << descriptor_->full_name()
597 << "\"). Note that the exact same class is required; not just the same "
598 "descriptor.";
599
600 std::set<int> swapped_oneof;
601
602 for (int i = 0; i < fields.size(); i++) {
603 const FieldDescriptor* field = fields[i];
604 if (field->is_extension()) {
605 MutableExtensionSet(message1)->SwapExtension(
606 MutableExtensionSet(message2),
607 field->number());
608 } else {
609 if (field->containing_oneof()) {
610 int oneof_index = field->containing_oneof()->index();
611 // Only swap the oneof field once.
612 if (swapped_oneof.find(oneof_index) != swapped_oneof.end()) {
613 continue;
614 }
615 swapped_oneof.insert(oneof_index);
616 SwapOneofField(message1, message2, field->containing_oneof());
617 } else {
618 // Swap has bit.
619 SwapBit(message1, message2, field);
620 // Swap field.
621 SwapField(message1, message2, field);
622 }
623 }
624 }
625 }
626
627 // -------------------------------------------------------------------
628
HasField(const Message & message,const FieldDescriptor * field) const629 bool GeneratedMessageReflection::HasField(const Message& message,
630 const FieldDescriptor* field) const {
631 USAGE_CHECK_MESSAGE_TYPE(HasField);
632 USAGE_CHECK_SINGULAR(HasField);
633
634 if (field->is_extension()) {
635 return GetExtensionSet(message).Has(field->number());
636 } else {
637 if (field->containing_oneof()) {
638 return HasOneofField(message, field);
639 } else {
640 return HasBit(message, field);
641 }
642 }
643 }
644
FieldSize(const Message & message,const FieldDescriptor * field) const645 int GeneratedMessageReflection::FieldSize(const Message& message,
646 const FieldDescriptor* field) const {
647 USAGE_CHECK_MESSAGE_TYPE(FieldSize);
648 USAGE_CHECK_REPEATED(FieldSize);
649
650 if (field->is_extension()) {
651 return GetExtensionSet(message).ExtensionSize(field->number());
652 } else {
653 switch (field->cpp_type()) {
654 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
655 case FieldDescriptor::CPPTYPE_##UPPERCASE : \
656 return GetRaw<RepeatedField<LOWERCASE> >(message, field).size()
657
658 HANDLE_TYPE( INT32, int32);
659 HANDLE_TYPE( INT64, int64);
660 HANDLE_TYPE(UINT32, uint32);
661 HANDLE_TYPE(UINT64, uint64);
662 HANDLE_TYPE(DOUBLE, double);
663 HANDLE_TYPE( FLOAT, float);
664 HANDLE_TYPE( BOOL, bool);
665 HANDLE_TYPE( ENUM, int);
666 #undef HANDLE_TYPE
667
668 case FieldDescriptor::CPPTYPE_STRING:
669 case FieldDescriptor::CPPTYPE_MESSAGE:
670 return GetRaw<RepeatedPtrFieldBase>(message, field).size();
671 }
672
673 GOOGLE_LOG(FATAL) << "Can't get here.";
674 return 0;
675 }
676 }
677
ClearField(Message * message,const FieldDescriptor * field) const678 void GeneratedMessageReflection::ClearField(
679 Message* message, const FieldDescriptor* field) const {
680 USAGE_CHECK_MESSAGE_TYPE(ClearField);
681
682 if (field->is_extension()) {
683 MutableExtensionSet(message)->ClearExtension(field->number());
684 } else if (!field->is_repeated()) {
685 if (field->containing_oneof()) {
686 ClearOneofField(message, field);
687 return;
688 }
689
690 if (HasBit(*message, field)) {
691 ClearBit(message, field);
692
693 // We need to set the field back to its default value.
694 switch (field->cpp_type()) {
695 #define CLEAR_TYPE(CPPTYPE, TYPE) \
696 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
697 *MutableRaw<TYPE>(message, field) = \
698 field->default_value_##TYPE(); \
699 break;
700
701 CLEAR_TYPE(INT32 , int32 );
702 CLEAR_TYPE(INT64 , int64 );
703 CLEAR_TYPE(UINT32, uint32);
704 CLEAR_TYPE(UINT64, uint64);
705 CLEAR_TYPE(FLOAT , float );
706 CLEAR_TYPE(DOUBLE, double);
707 CLEAR_TYPE(BOOL , bool );
708 #undef CLEAR_TYPE
709
710 case FieldDescriptor::CPPTYPE_ENUM:
711 *MutableRaw<int>(message, field) =
712 field->default_value_enum()->number();
713 break;
714
715 case FieldDescriptor::CPPTYPE_STRING: {
716 switch (field->options().ctype()) {
717 default: // TODO(kenton): Support other string reps.
718 case FieldOptions::STRING:
719 const string* default_ptr = DefaultRaw<const string*>(field);
720 string** value = MutableRaw<string*>(message, field);
721 if (*value != default_ptr) {
722 if (field->has_default_value()) {
723 (*value)->assign(field->default_value_string());
724 } else {
725 (*value)->clear();
726 }
727 }
728 break;
729 }
730 break;
731 }
732
733 case FieldDescriptor::CPPTYPE_MESSAGE:
734 (*MutableRaw<Message*>(message, field))->Clear();
735 break;
736 }
737 }
738 } else {
739 switch (field->cpp_type()) {
740 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
741 case FieldDescriptor::CPPTYPE_##UPPERCASE : \
742 MutableRaw<RepeatedField<LOWERCASE> >(message, field)->Clear(); \
743 break
744
745 HANDLE_TYPE( INT32, int32);
746 HANDLE_TYPE( INT64, int64);
747 HANDLE_TYPE(UINT32, uint32);
748 HANDLE_TYPE(UINT64, uint64);
749 HANDLE_TYPE(DOUBLE, double);
750 HANDLE_TYPE( FLOAT, float);
751 HANDLE_TYPE( BOOL, bool);
752 HANDLE_TYPE( ENUM, int);
753 #undef HANDLE_TYPE
754
755 case FieldDescriptor::CPPTYPE_STRING: {
756 switch (field->options().ctype()) {
757 default: // TODO(kenton): Support other string reps.
758 case FieldOptions::STRING:
759 MutableRaw<RepeatedPtrField<string> >(message, field)->Clear();
760 break;
761 }
762 break;
763 }
764
765 case FieldDescriptor::CPPTYPE_MESSAGE: {
766 // We don't know which subclass of RepeatedPtrFieldBase the type is,
767 // so we use RepeatedPtrFieldBase directly.
768 MutableRaw<RepeatedPtrFieldBase>(message, field)
769 ->Clear<GenericTypeHandler<Message> >();
770 break;
771 }
772 }
773 }
774 }
775
RemoveLast(Message * message,const FieldDescriptor * field) const776 void GeneratedMessageReflection::RemoveLast(
777 Message* message,
778 const FieldDescriptor* field) const {
779 USAGE_CHECK_MESSAGE_TYPE(RemoveLast);
780 USAGE_CHECK_REPEATED(RemoveLast);
781
782 if (field->is_extension()) {
783 MutableExtensionSet(message)->RemoveLast(field->number());
784 } else {
785 switch (field->cpp_type()) {
786 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
787 case FieldDescriptor::CPPTYPE_##UPPERCASE : \
788 MutableRaw<RepeatedField<LOWERCASE> >(message, field)->RemoveLast(); \
789 break
790
791 HANDLE_TYPE( INT32, int32);
792 HANDLE_TYPE( INT64, int64);
793 HANDLE_TYPE(UINT32, uint32);
794 HANDLE_TYPE(UINT64, uint64);
795 HANDLE_TYPE(DOUBLE, double);
796 HANDLE_TYPE( FLOAT, float);
797 HANDLE_TYPE( BOOL, bool);
798 HANDLE_TYPE( ENUM, int);
799 #undef HANDLE_TYPE
800
801 case FieldDescriptor::CPPTYPE_STRING:
802 switch (field->options().ctype()) {
803 default: // TODO(kenton): Support other string reps.
804 case FieldOptions::STRING:
805 MutableRaw<RepeatedPtrField<string> >(message, field)->RemoveLast();
806 break;
807 }
808 break;
809
810 case FieldDescriptor::CPPTYPE_MESSAGE:
811 MutableRaw<RepeatedPtrFieldBase>(message, field)
812 ->RemoveLast<GenericTypeHandler<Message> >();
813 break;
814 }
815 }
816 }
817
ReleaseLast(Message * message,const FieldDescriptor * field) const818 Message* GeneratedMessageReflection::ReleaseLast(
819 Message* message,
820 const FieldDescriptor* field) const {
821 USAGE_CHECK_ALL(ReleaseLast, REPEATED, MESSAGE);
822
823 if (field->is_extension()) {
824 return static_cast<Message*>(
825 MutableExtensionSet(message)->ReleaseLast(field->number()));
826 } else {
827 return MutableRaw<RepeatedPtrFieldBase>(message, field)
828 ->ReleaseLast<GenericTypeHandler<Message> >();
829 }
830 }
831
SwapElements(Message * message,const FieldDescriptor * field,int index1,int index2) const832 void GeneratedMessageReflection::SwapElements(
833 Message* message,
834 const FieldDescriptor* field,
835 int index1,
836 int index2) const {
837 USAGE_CHECK_MESSAGE_TYPE(Swap);
838 USAGE_CHECK_REPEATED(Swap);
839
840 if (field->is_extension()) {
841 MutableExtensionSet(message)->SwapElements(field->number(), index1, index2);
842 } else {
843 switch (field->cpp_type()) {
844 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
845 case FieldDescriptor::CPPTYPE_##UPPERCASE : \
846 MutableRaw<RepeatedField<LOWERCASE> >(message, field) \
847 ->SwapElements(index1, index2); \
848 break
849
850 HANDLE_TYPE( INT32, int32);
851 HANDLE_TYPE( INT64, int64);
852 HANDLE_TYPE(UINT32, uint32);
853 HANDLE_TYPE(UINT64, uint64);
854 HANDLE_TYPE(DOUBLE, double);
855 HANDLE_TYPE( FLOAT, float);
856 HANDLE_TYPE( BOOL, bool);
857 HANDLE_TYPE( ENUM, int);
858 #undef HANDLE_TYPE
859
860 case FieldDescriptor::CPPTYPE_STRING:
861 case FieldDescriptor::CPPTYPE_MESSAGE:
862 MutableRaw<RepeatedPtrFieldBase>(message, field)
863 ->SwapElements(index1, index2);
864 break;
865 }
866 }
867 }
868
869 namespace {
870 // Comparison functor for sorting FieldDescriptors by field number.
871 struct FieldNumberSorter {
operator ()google::protobuf::internal::__anonb2f59ce50211::FieldNumberSorter872 bool operator()(const FieldDescriptor* left,
873 const FieldDescriptor* right) const {
874 return left->number() < right->number();
875 }
876 };
877 } // namespace
878
ListFields(const Message & message,vector<const FieldDescriptor * > * output) const879 void GeneratedMessageReflection::ListFields(
880 const Message& message,
881 vector<const FieldDescriptor*>* output) const {
882 output->clear();
883
884 // Optimization: The default instance never has any fields set.
885 if (&message == default_instance_) return;
886
887 for (int i = 0; i < descriptor_->field_count(); i++) {
888 const FieldDescriptor* field = descriptor_->field(i);
889 if (field->is_repeated()) {
890 if (FieldSize(message, field) > 0) {
891 output->push_back(field);
892 }
893 } else {
894 if (field->containing_oneof()) {
895 if (HasOneofField(message, field)) {
896 output->push_back(field);
897 }
898 } else if (HasBit(message, field)) {
899 output->push_back(field);
900 }
901 }
902 }
903
904 if (extensions_offset_ != -1) {
905 GetExtensionSet(message).AppendToList(descriptor_, descriptor_pool_,
906 output);
907 }
908
909 // ListFields() must sort output by field number.
910 sort(output->begin(), output->end(), FieldNumberSorter());
911 }
912
913 // -------------------------------------------------------------------
914
915 #undef DEFINE_PRIMITIVE_ACCESSORS
916 #define DEFINE_PRIMITIVE_ACCESSORS(TYPENAME, TYPE, PASSTYPE, CPPTYPE) \
917 PASSTYPE GeneratedMessageReflection::Get##TYPENAME( \
918 const Message& message, const FieldDescriptor* field) const { \
919 USAGE_CHECK_ALL(Get##TYPENAME, SINGULAR, CPPTYPE); \
920 if (field->is_extension()) { \
921 return GetExtensionSet(message).Get##TYPENAME( \
922 field->number(), field->default_value_##PASSTYPE()); \
923 } else { \
924 return GetField<TYPE>(message, field); \
925 } \
926 } \
927 \
928 void GeneratedMessageReflection::Set##TYPENAME( \
929 Message* message, const FieldDescriptor* field, \
930 PASSTYPE value) const { \
931 USAGE_CHECK_ALL(Set##TYPENAME, SINGULAR, CPPTYPE); \
932 if (field->is_extension()) { \
933 return MutableExtensionSet(message)->Set##TYPENAME( \
934 field->number(), field->type(), value, field); \
935 } else { \
936 SetField<TYPE>(message, field, value); \
937 } \
938 } \
939 \
940 PASSTYPE GeneratedMessageReflection::GetRepeated##TYPENAME( \
941 const Message& message, \
942 const FieldDescriptor* field, int index) const { \
943 USAGE_CHECK_ALL(GetRepeated##TYPENAME, REPEATED, CPPTYPE); \
944 if (field->is_extension()) { \
945 return GetExtensionSet(message).GetRepeated##TYPENAME( \
946 field->number(), index); \
947 } else { \
948 return GetRepeatedField<TYPE>(message, field, index); \
949 } \
950 } \
951 \
952 void GeneratedMessageReflection::SetRepeated##TYPENAME( \
953 Message* message, const FieldDescriptor* field, \
954 int index, PASSTYPE value) const { \
955 USAGE_CHECK_ALL(SetRepeated##TYPENAME, REPEATED, CPPTYPE); \
956 if (field->is_extension()) { \
957 MutableExtensionSet(message)->SetRepeated##TYPENAME( \
958 field->number(), index, value); \
959 } else { \
960 SetRepeatedField<TYPE>(message, field, index, value); \
961 } \
962 } \
963 \
964 void GeneratedMessageReflection::Add##TYPENAME( \
965 Message* message, const FieldDescriptor* field, \
966 PASSTYPE value) const { \
967 USAGE_CHECK_ALL(Add##TYPENAME, REPEATED, CPPTYPE); \
968 if (field->is_extension()) { \
969 MutableExtensionSet(message)->Add##TYPENAME( \
970 field->number(), field->type(), field->options().packed(), value, \
971 field); \
972 } else { \
973 AddField<TYPE>(message, field, value); \
974 } \
975 }
976
DEFINE_PRIMITIVE_ACCESSORS(Int32,int32,int32,INT32)977 DEFINE_PRIMITIVE_ACCESSORS(Int32 , int32 , int32 , INT32 )
978 DEFINE_PRIMITIVE_ACCESSORS(Int64 , int64 , int64 , INT64 )
979 DEFINE_PRIMITIVE_ACCESSORS(UInt32, uint32, uint32, UINT32)
980 DEFINE_PRIMITIVE_ACCESSORS(UInt64, uint64, uint64, UINT64)
981 DEFINE_PRIMITIVE_ACCESSORS(Float , float , float , FLOAT )
982 DEFINE_PRIMITIVE_ACCESSORS(Double, double, double, DOUBLE)
983 DEFINE_PRIMITIVE_ACCESSORS(Bool , bool , bool , BOOL )
984 #undef DEFINE_PRIMITIVE_ACCESSORS
985
986 // -------------------------------------------------------------------
987
988 string GeneratedMessageReflection::GetString(
989 const Message& message, const FieldDescriptor* field) const {
990 USAGE_CHECK_ALL(GetString, SINGULAR, STRING);
991 if (field->is_extension()) {
992 return GetExtensionSet(message).GetString(field->number(),
993 field->default_value_string());
994 } else {
995 switch (field->options().ctype()) {
996 default: // TODO(kenton): Support other string reps.
997 case FieldOptions::STRING:
998 return *GetField<const string*>(message, field);
999 }
1000
1001 GOOGLE_LOG(FATAL) << "Can't get here.";
1002 return GetEmptyString(); // Make compiler happy.
1003 }
1004 }
1005
GetStringReference(const Message & message,const FieldDescriptor * field,string * scratch) const1006 const string& GeneratedMessageReflection::GetStringReference(
1007 const Message& message,
1008 const FieldDescriptor* field, string* scratch) const {
1009 USAGE_CHECK_ALL(GetStringReference, SINGULAR, STRING);
1010 if (field->is_extension()) {
1011 return GetExtensionSet(message).GetString(field->number(),
1012 field->default_value_string());
1013 } else {
1014 switch (field->options().ctype()) {
1015 default: // TODO(kenton): Support other string reps.
1016 case FieldOptions::STRING:
1017 return *GetField<const string*>(message, field);
1018 }
1019
1020 GOOGLE_LOG(FATAL) << "Can't get here.";
1021 return GetEmptyString(); // Make compiler happy.
1022 }
1023 }
1024
1025
SetString(Message * message,const FieldDescriptor * field,const string & value) const1026 void GeneratedMessageReflection::SetString(
1027 Message* message, const FieldDescriptor* field,
1028 const string& value) const {
1029 USAGE_CHECK_ALL(SetString, SINGULAR, STRING);
1030 if (field->is_extension()) {
1031 return MutableExtensionSet(message)->SetString(field->number(),
1032 field->type(), value, field);
1033 } else {
1034 switch (field->options().ctype()) {
1035 default: // TODO(kenton): Support other string reps.
1036 case FieldOptions::STRING: {
1037 if (field->containing_oneof() && !HasOneofField(*message, field)) {
1038 ClearOneof(message, field->containing_oneof());
1039 *MutableField<string*>(message, field) = new string;
1040 }
1041 string** ptr = MutableField<string*>(message, field);
1042 if (*ptr == DefaultRaw<const string*>(field)) {
1043 *ptr = new string(value);
1044 } else {
1045 (*ptr)->assign(value);
1046 }
1047 break;
1048 }
1049 }
1050 }
1051 }
1052
1053
GetRepeatedString(const Message & message,const FieldDescriptor * field,int index) const1054 string GeneratedMessageReflection::GetRepeatedString(
1055 const Message& message, const FieldDescriptor* field, int index) const {
1056 USAGE_CHECK_ALL(GetRepeatedString, REPEATED, STRING);
1057 if (field->is_extension()) {
1058 return GetExtensionSet(message).GetRepeatedString(field->number(), index);
1059 } else {
1060 switch (field->options().ctype()) {
1061 default: // TODO(kenton): Support other string reps.
1062 case FieldOptions::STRING:
1063 return GetRepeatedPtrField<string>(message, field, index);
1064 }
1065
1066 GOOGLE_LOG(FATAL) << "Can't get here.";
1067 return GetEmptyString(); // Make compiler happy.
1068 }
1069 }
1070
GetRepeatedStringReference(const Message & message,const FieldDescriptor * field,int index,string * scratch) const1071 const string& GeneratedMessageReflection::GetRepeatedStringReference(
1072 const Message& message, const FieldDescriptor* field,
1073 int index, string* scratch) const {
1074 USAGE_CHECK_ALL(GetRepeatedStringReference, REPEATED, STRING);
1075 if (field->is_extension()) {
1076 return GetExtensionSet(message).GetRepeatedString(field->number(), index);
1077 } else {
1078 switch (field->options().ctype()) {
1079 default: // TODO(kenton): Support other string reps.
1080 case FieldOptions::STRING:
1081 return GetRepeatedPtrField<string>(message, field, index);
1082 }
1083
1084 GOOGLE_LOG(FATAL) << "Can't get here.";
1085 return GetEmptyString(); // Make compiler happy.
1086 }
1087 }
1088
1089
SetRepeatedString(Message * message,const FieldDescriptor * field,int index,const string & value) const1090 void GeneratedMessageReflection::SetRepeatedString(
1091 Message* message, const FieldDescriptor* field,
1092 int index, const string& value) const {
1093 USAGE_CHECK_ALL(SetRepeatedString, REPEATED, STRING);
1094 if (field->is_extension()) {
1095 MutableExtensionSet(message)->SetRepeatedString(
1096 field->number(), index, value);
1097 } else {
1098 switch (field->options().ctype()) {
1099 default: // TODO(kenton): Support other string reps.
1100 case FieldOptions::STRING:
1101 *MutableRepeatedField<string>(message, field, index) = value;
1102 break;
1103 }
1104 }
1105 }
1106
1107
AddString(Message * message,const FieldDescriptor * field,const string & value) const1108 void GeneratedMessageReflection::AddString(
1109 Message* message, const FieldDescriptor* field,
1110 const string& value) const {
1111 USAGE_CHECK_ALL(AddString, REPEATED, STRING);
1112 if (field->is_extension()) {
1113 MutableExtensionSet(message)->AddString(field->number(),
1114 field->type(), value, field);
1115 } else {
1116 switch (field->options().ctype()) {
1117 default: // TODO(kenton): Support other string reps.
1118 case FieldOptions::STRING:
1119 *AddField<string>(message, field) = value;
1120 break;
1121 }
1122 }
1123 }
1124
1125
1126 // -------------------------------------------------------------------
1127
GetEnum(const Message & message,const FieldDescriptor * field) const1128 const EnumValueDescriptor* GeneratedMessageReflection::GetEnum(
1129 const Message& message, const FieldDescriptor* field) const {
1130 USAGE_CHECK_ALL(GetEnum, SINGULAR, ENUM);
1131
1132 int value;
1133 if (field->is_extension()) {
1134 value = GetExtensionSet(message).GetEnum(
1135 field->number(), field->default_value_enum()->number());
1136 } else {
1137 value = GetField<int>(message, field);
1138 }
1139 const EnumValueDescriptor* result =
1140 field->enum_type()->FindValueByNumber(value);
1141 GOOGLE_CHECK(result != NULL) << "Value " << value << " is not valid for field "
1142 << field->full_name() << " of type "
1143 << field->enum_type()->full_name() << ".";
1144 return result;
1145 }
1146
SetEnum(Message * message,const FieldDescriptor * field,const EnumValueDescriptor * value) const1147 void GeneratedMessageReflection::SetEnum(
1148 Message* message, const FieldDescriptor* field,
1149 const EnumValueDescriptor* value) const {
1150 USAGE_CHECK_ALL(SetEnum, SINGULAR, ENUM);
1151 USAGE_CHECK_ENUM_VALUE(SetEnum);
1152
1153 if (field->is_extension()) {
1154 MutableExtensionSet(message)->SetEnum(field->number(), field->type(),
1155 value->number(), field);
1156 } else {
1157 SetField<int>(message, field, value->number());
1158 }
1159 }
1160
GetRepeatedEnum(const Message & message,const FieldDescriptor * field,int index) const1161 const EnumValueDescriptor* GeneratedMessageReflection::GetRepeatedEnum(
1162 const Message& message, const FieldDescriptor* field, int index) const {
1163 USAGE_CHECK_ALL(GetRepeatedEnum, REPEATED, ENUM);
1164
1165 int value;
1166 if (field->is_extension()) {
1167 value = GetExtensionSet(message).GetRepeatedEnum(field->number(), index);
1168 } else {
1169 value = GetRepeatedField<int>(message, field, index);
1170 }
1171 const EnumValueDescriptor* result =
1172 field->enum_type()->FindValueByNumber(value);
1173 GOOGLE_CHECK(result != NULL) << "Value " << value << " is not valid for field "
1174 << field->full_name() << " of type "
1175 << field->enum_type()->full_name() << ".";
1176 return result;
1177 }
1178
SetRepeatedEnum(Message * message,const FieldDescriptor * field,int index,const EnumValueDescriptor * value) const1179 void GeneratedMessageReflection::SetRepeatedEnum(
1180 Message* message,
1181 const FieldDescriptor* field, int index,
1182 const EnumValueDescriptor* value) const {
1183 USAGE_CHECK_ALL(SetRepeatedEnum, REPEATED, ENUM);
1184 USAGE_CHECK_ENUM_VALUE(SetRepeatedEnum);
1185
1186 if (field->is_extension()) {
1187 MutableExtensionSet(message)->SetRepeatedEnum(
1188 field->number(), index, value->number());
1189 } else {
1190 SetRepeatedField<int>(message, field, index, value->number());
1191 }
1192 }
1193
AddEnum(Message * message,const FieldDescriptor * field,const EnumValueDescriptor * value) const1194 void GeneratedMessageReflection::AddEnum(
1195 Message* message, const FieldDescriptor* field,
1196 const EnumValueDescriptor* value) const {
1197 USAGE_CHECK_ALL(AddEnum, REPEATED, ENUM);
1198 USAGE_CHECK_ENUM_VALUE(AddEnum);
1199
1200 if (field->is_extension()) {
1201 MutableExtensionSet(message)->AddEnum(field->number(), field->type(),
1202 field->options().packed(),
1203 value->number(), field);
1204 } else {
1205 AddField<int>(message, field, value->number());
1206 }
1207 }
1208
1209 // -------------------------------------------------------------------
1210
GetMessage(const Message & message,const FieldDescriptor * field,MessageFactory * factory) const1211 const Message& GeneratedMessageReflection::GetMessage(
1212 const Message& message, const FieldDescriptor* field,
1213 MessageFactory* factory) const {
1214 USAGE_CHECK_ALL(GetMessage, SINGULAR, MESSAGE);
1215
1216 if (factory == NULL) factory = message_factory_;
1217
1218 if (field->is_extension()) {
1219 return static_cast<const Message&>(
1220 GetExtensionSet(message).GetMessage(
1221 field->number(), field->message_type(), factory));
1222 } else {
1223 const Message* result;
1224 result = GetRaw<const Message*>(message, field);
1225 if (result == NULL) {
1226 result = DefaultRaw<const Message*>(field);
1227 }
1228 return *result;
1229 }
1230 }
1231
MutableMessage(Message * message,const FieldDescriptor * field,MessageFactory * factory) const1232 Message* GeneratedMessageReflection::MutableMessage(
1233 Message* message, const FieldDescriptor* field,
1234 MessageFactory* factory) const {
1235 if (factory == NULL) factory = message_factory_;
1236
1237 if (field->is_extension()) {
1238 return static_cast<Message*>(
1239 MutableExtensionSet(message)->MutableMessage(field, factory));
1240 } else {
1241 Message* result;
1242 Message** result_holder = MutableRaw<Message*>(message, field);
1243
1244 if (field->containing_oneof()) {
1245 if (!HasOneofField(*message, field)) {
1246 ClearOneof(message, field->containing_oneof());
1247 result_holder = MutableField<Message*>(message, field);
1248 const Message* default_message = DefaultRaw<const Message*>(field);
1249 *result_holder = default_message->New();
1250 }
1251 } else {
1252 SetBit(message, field);
1253 }
1254
1255 if (*result_holder == NULL) {
1256 const Message* default_message = DefaultRaw<const Message*>(field);
1257 *result_holder = default_message->New();
1258 }
1259 result = *result_holder;
1260 return result;
1261 }
1262 }
1263
SetAllocatedMessage(Message * message,Message * sub_message,const FieldDescriptor * field) const1264 void GeneratedMessageReflection::SetAllocatedMessage(
1265 Message* message,
1266 Message* sub_message,
1267 const FieldDescriptor* field) const {
1268 USAGE_CHECK_ALL(SetAllocatedMessage, SINGULAR, MESSAGE);
1269
1270 if (field->is_extension()) {
1271 MutableExtensionSet(message)->SetAllocatedMessage(
1272 field->number(), field->type(), field, sub_message);
1273 } else {
1274 if (field->containing_oneof()) {
1275 if (sub_message == NULL) {
1276 ClearOneof(message, field->containing_oneof());
1277 return;
1278 }
1279 ClearOneof(message, field->containing_oneof());
1280 *MutableRaw<Message*>(message, field) = sub_message;
1281 SetOneofCase(message, field);
1282 return;
1283 }
1284
1285 if (sub_message == NULL) {
1286 ClearBit(message, field);
1287 } else {
1288 SetBit(message, field);
1289 }
1290 Message** sub_message_holder = MutableRaw<Message*>(message, field);
1291 delete *sub_message_holder;
1292 *sub_message_holder = sub_message;
1293 }
1294 }
1295
ReleaseMessage(Message * message,const FieldDescriptor * field,MessageFactory * factory) const1296 Message* GeneratedMessageReflection::ReleaseMessage(
1297 Message* message,
1298 const FieldDescriptor* field,
1299 MessageFactory* factory) const {
1300 USAGE_CHECK_ALL(ReleaseMessage, SINGULAR, MESSAGE);
1301
1302 if (factory == NULL) factory = message_factory_;
1303
1304 if (field->is_extension()) {
1305 return static_cast<Message*>(
1306 MutableExtensionSet(message)->ReleaseMessage(field, factory));
1307 } else {
1308 ClearBit(message, field);
1309 if (field->containing_oneof()) {
1310 if (HasOneofField(*message, field)) {
1311 *MutableOneofCase(message, field->containing_oneof()) = 0;
1312 } else {
1313 return NULL;
1314 }
1315 }
1316 Message** result = MutableRaw<Message*>(message, field);
1317 Message* ret = *result;
1318 *result = NULL;
1319 return ret;
1320 }
1321 }
1322
GetRepeatedMessage(const Message & message,const FieldDescriptor * field,int index) const1323 const Message& GeneratedMessageReflection::GetRepeatedMessage(
1324 const Message& message, const FieldDescriptor* field, int index) const {
1325 USAGE_CHECK_ALL(GetRepeatedMessage, REPEATED, MESSAGE);
1326
1327 if (field->is_extension()) {
1328 return static_cast<const Message&>(
1329 GetExtensionSet(message).GetRepeatedMessage(field->number(), index));
1330 } else {
1331 return GetRaw<RepeatedPtrFieldBase>(message, field)
1332 .Get<GenericTypeHandler<Message> >(index);
1333 }
1334 }
1335
MutableRepeatedMessage(Message * message,const FieldDescriptor * field,int index) const1336 Message* GeneratedMessageReflection::MutableRepeatedMessage(
1337 Message* message, const FieldDescriptor* field, int index) const {
1338 USAGE_CHECK_ALL(MutableRepeatedMessage, REPEATED, MESSAGE);
1339
1340 if (field->is_extension()) {
1341 return static_cast<Message*>(
1342 MutableExtensionSet(message)->MutableRepeatedMessage(
1343 field->number(), index));
1344 } else {
1345 return MutableRaw<RepeatedPtrFieldBase>(message, field)
1346 ->Mutable<GenericTypeHandler<Message> >(index);
1347 }
1348 }
1349
AddMessage(Message * message,const FieldDescriptor * field,MessageFactory * factory) const1350 Message* GeneratedMessageReflection::AddMessage(
1351 Message* message, const FieldDescriptor* field,
1352 MessageFactory* factory) const {
1353 USAGE_CHECK_ALL(AddMessage, REPEATED, MESSAGE);
1354
1355 if (factory == NULL) factory = message_factory_;
1356
1357 if (field->is_extension()) {
1358 return static_cast<Message*>(
1359 MutableExtensionSet(message)->AddMessage(field, factory));
1360 } else {
1361 // We can't use AddField<Message>() because RepeatedPtrFieldBase doesn't
1362 // know how to allocate one.
1363 RepeatedPtrFieldBase* repeated =
1364 MutableRaw<RepeatedPtrFieldBase>(message, field);
1365 Message* result = repeated->AddFromCleared<GenericTypeHandler<Message> >();
1366 if (result == NULL) {
1367 // We must allocate a new object.
1368 const Message* prototype;
1369 if (repeated->size() == 0) {
1370 prototype = factory->GetPrototype(field->message_type());
1371 } else {
1372 prototype = &repeated->Get<GenericTypeHandler<Message> >(0);
1373 }
1374 result = prototype->New();
1375 repeated->AddAllocated<GenericTypeHandler<Message> >(result);
1376 }
1377 return result;
1378 }
1379 }
1380
MutableRawRepeatedField(Message * message,const FieldDescriptor * field,FieldDescriptor::CppType cpptype,int ctype,const Descriptor * desc) const1381 void* GeneratedMessageReflection::MutableRawRepeatedField(
1382 Message* message, const FieldDescriptor* field,
1383 FieldDescriptor::CppType cpptype,
1384 int ctype, const Descriptor* desc) const {
1385 USAGE_CHECK_REPEATED("MutableRawRepeatedField");
1386 if (field->cpp_type() != cpptype)
1387 ReportReflectionUsageTypeError(descriptor_,
1388 field, "MutableRawRepeatedField", cpptype);
1389 if (ctype >= 0)
1390 GOOGLE_CHECK_EQ(field->options().ctype(), ctype) << "subtype mismatch";
1391 if (desc != NULL)
1392 GOOGLE_CHECK_EQ(field->message_type(), desc) << "wrong submessage type";
1393 if (field->is_extension())
1394 return MutableExtensionSet(message)->MutableRawRepeatedField(
1395 field->number(), field->type(), field->is_packed(), field);
1396 else
1397 return reinterpret_cast<uint8*>(message) + offsets_[field->index()];
1398 }
1399
GetOneofFieldDescriptor(const Message & message,const OneofDescriptor * oneof_descriptor) const1400 const FieldDescriptor* GeneratedMessageReflection::GetOneofFieldDescriptor(
1401 const Message& message,
1402 const OneofDescriptor* oneof_descriptor) const {
1403 uint32 field_number = GetOneofCase(message, oneof_descriptor);
1404 if (field_number == 0) {
1405 return NULL;
1406 }
1407 return descriptor_->FindFieldByNumber(field_number);
1408 }
1409
1410 // -----------------------------------------------------------------------------
1411
FindKnownExtensionByName(const string & name) const1412 const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByName(
1413 const string& name) const {
1414 if (extensions_offset_ == -1) return NULL;
1415
1416 const FieldDescriptor* result = descriptor_pool_->FindExtensionByName(name);
1417 if (result != NULL && result->containing_type() == descriptor_) {
1418 return result;
1419 }
1420
1421 if (descriptor_->options().message_set_wire_format()) {
1422 // MessageSet extensions may be identified by type name.
1423 const Descriptor* type = descriptor_pool_->FindMessageTypeByName(name);
1424 if (type != NULL) {
1425 // Look for a matching extension in the foreign type's scope.
1426 for (int i = 0; i < type->extension_count(); i++) {
1427 const FieldDescriptor* extension = type->extension(i);
1428 if (extension->containing_type() == descriptor_ &&
1429 extension->type() == FieldDescriptor::TYPE_MESSAGE &&
1430 extension->is_optional() &&
1431 extension->message_type() == type) {
1432 // Found it.
1433 return extension;
1434 }
1435 }
1436 }
1437 }
1438
1439 return NULL;
1440 }
1441
FindKnownExtensionByNumber(int number) const1442 const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByNumber(
1443 int number) const {
1444 if (extensions_offset_ == -1) return NULL;
1445 return descriptor_pool_->FindExtensionByNumber(descriptor_, number);
1446 }
1447
1448 // ===================================================================
1449 // Some private helpers.
1450
1451 // These simple template accessors obtain pointers (or references) to
1452 // the given field.
1453 template <typename Type>
GetRaw(const Message & message,const FieldDescriptor * field) const1454 inline const Type& GeneratedMessageReflection::GetRaw(
1455 const Message& message, const FieldDescriptor* field) const {
1456 if (field->containing_oneof() && !HasOneofField(message, field)) {
1457 return DefaultRaw<Type>(field);
1458 }
1459 int index = field->containing_oneof() ?
1460 descriptor_->field_count() + field->containing_oneof()->index() :
1461 field->index();
1462 const void* ptr = reinterpret_cast<const uint8*>(&message) +
1463 offsets_[index];
1464 return *reinterpret_cast<const Type*>(ptr);
1465 }
1466
1467 template <typename Type>
MutableRaw(Message * message,const FieldDescriptor * field) const1468 inline Type* GeneratedMessageReflection::MutableRaw(
1469 Message* message, const FieldDescriptor* field) const {
1470 int index = field->containing_oneof() ?
1471 descriptor_->field_count() + field->containing_oneof()->index() :
1472 field->index();
1473 void* ptr = reinterpret_cast<uint8*>(message) + offsets_[index];
1474 return reinterpret_cast<Type*>(ptr);
1475 }
1476
1477 template <typename Type>
DefaultRaw(const FieldDescriptor * field) const1478 inline const Type& GeneratedMessageReflection::DefaultRaw(
1479 const FieldDescriptor* field) const {
1480 const void* ptr = field->containing_oneof() ?
1481 reinterpret_cast<const uint8*>(default_oneof_instance_) +
1482 offsets_[field->index()] :
1483 reinterpret_cast<const uint8*>(default_instance_) +
1484 offsets_[field->index()];
1485 return *reinterpret_cast<const Type*>(ptr);
1486 }
1487
GetHasBits(const Message & message) const1488 inline const uint32* GeneratedMessageReflection::GetHasBits(
1489 const Message& message) const {
1490 const void* ptr = reinterpret_cast<const uint8*>(&message) + has_bits_offset_;
1491 return reinterpret_cast<const uint32*>(ptr);
1492 }
MutableHasBits(Message * message) const1493 inline uint32* GeneratedMessageReflection::MutableHasBits(
1494 Message* message) const {
1495 void* ptr = reinterpret_cast<uint8*>(message) + has_bits_offset_;
1496 return reinterpret_cast<uint32*>(ptr);
1497 }
1498
GetOneofCase(const Message & message,const OneofDescriptor * oneof_descriptor) const1499 inline uint32 GeneratedMessageReflection::GetOneofCase(
1500 const Message& message,
1501 const OneofDescriptor* oneof_descriptor) const {
1502 const void* ptr = reinterpret_cast<const uint8*>(&message)
1503 + oneof_case_offset_;
1504 return reinterpret_cast<const uint32*>(ptr)[oneof_descriptor->index()];
1505 }
1506
MutableOneofCase(Message * message,const OneofDescriptor * oneof_descriptor) const1507 inline uint32* GeneratedMessageReflection::MutableOneofCase(
1508 Message* message,
1509 const OneofDescriptor* oneof_descriptor) const {
1510 void* ptr = reinterpret_cast<uint8*>(message) + oneof_case_offset_;
1511 return &(reinterpret_cast<uint32*>(ptr)[oneof_descriptor->index()]);
1512 }
1513
GetExtensionSet(const Message & message) const1514 inline const ExtensionSet& GeneratedMessageReflection::GetExtensionSet(
1515 const Message& message) const {
1516 GOOGLE_DCHECK_NE(extensions_offset_, -1);
1517 const void* ptr = reinterpret_cast<const uint8*>(&message) +
1518 extensions_offset_;
1519 return *reinterpret_cast<const ExtensionSet*>(ptr);
1520 }
MutableExtensionSet(Message * message) const1521 inline ExtensionSet* GeneratedMessageReflection::MutableExtensionSet(
1522 Message* message) const {
1523 GOOGLE_DCHECK_NE(extensions_offset_, -1);
1524 void* ptr = reinterpret_cast<uint8*>(message) + extensions_offset_;
1525 return reinterpret_cast<ExtensionSet*>(ptr);
1526 }
1527
1528 // Simple accessors for manipulating has_bits_.
HasBit(const Message & message,const FieldDescriptor * field) const1529 inline bool GeneratedMessageReflection::HasBit(
1530 const Message& message, const FieldDescriptor* field) const {
1531 return GetHasBits(message)[field->index() / 32] &
1532 (1 << (field->index() % 32));
1533 }
1534
SetBit(Message * message,const FieldDescriptor * field) const1535 inline void GeneratedMessageReflection::SetBit(
1536 Message* message, const FieldDescriptor* field) const {
1537 MutableHasBits(message)[field->index() / 32] |= (1 << (field->index() % 32));
1538 }
1539
ClearBit(Message * message,const FieldDescriptor * field) const1540 inline void GeneratedMessageReflection::ClearBit(
1541 Message* message, const FieldDescriptor* field) const {
1542 MutableHasBits(message)[field->index() / 32] &= ~(1 << (field->index() % 32));
1543 }
1544
SwapBit(Message * message1,Message * message2,const FieldDescriptor * field) const1545 inline void GeneratedMessageReflection::SwapBit(
1546 Message* message1, Message* message2, const FieldDescriptor* field) const {
1547 bool temp_has_bit = HasBit(*message1, field);
1548 if (HasBit(*message2, field)) {
1549 SetBit(message1, field);
1550 } else {
1551 ClearBit(message1, field);
1552 }
1553 if (temp_has_bit) {
1554 SetBit(message2, field);
1555 } else {
1556 ClearBit(message2, field);
1557 }
1558 }
1559
HasOneof(const Message & message,const OneofDescriptor * oneof_descriptor) const1560 inline bool GeneratedMessageReflection::HasOneof(
1561 const Message& message, const OneofDescriptor* oneof_descriptor) const {
1562 return (GetOneofCase(message, oneof_descriptor) > 0);
1563 }
1564
HasOneofField(const Message & message,const FieldDescriptor * field) const1565 inline bool GeneratedMessageReflection::HasOneofField(
1566 const Message& message, const FieldDescriptor* field) const {
1567 return (GetOneofCase(message, field->containing_oneof()) == field->number());
1568 }
1569
SetOneofCase(Message * message,const FieldDescriptor * field) const1570 inline void GeneratedMessageReflection::SetOneofCase(
1571 Message* message, const FieldDescriptor* field) const {
1572 *MutableOneofCase(message, field->containing_oneof()) = field->number();
1573 }
1574
ClearOneofField(Message * message,const FieldDescriptor * field) const1575 inline void GeneratedMessageReflection::ClearOneofField(
1576 Message* message, const FieldDescriptor* field) const {
1577 if (HasOneofField(*message, field)) {
1578 ClearOneof(message, field->containing_oneof());
1579 }
1580 }
1581
ClearOneof(Message * message,const OneofDescriptor * oneof_descriptor) const1582 inline void GeneratedMessageReflection::ClearOneof(
1583 Message* message, const OneofDescriptor* oneof_descriptor) const {
1584 // TODO(jieluo): Consider to cache the unused object instead of deleting
1585 // it. It will be much faster if an aplication switches a lot from
1586 // a few oneof fields. Time/space tradeoff
1587 uint32 oneof_case = GetOneofCase(*message, oneof_descriptor);
1588 if (oneof_case > 0) {
1589 const FieldDescriptor* field = descriptor_->FindFieldByNumber(oneof_case);
1590 switch (field->cpp_type()) {
1591 case FieldDescriptor::CPPTYPE_STRING: {
1592 switch (field->options().ctype()) {
1593 default: // TODO(kenton): Support other string reps.
1594 case FieldOptions::STRING:
1595 delete *MutableRaw<string*>(message, field);
1596 break;
1597 }
1598 break;
1599 }
1600
1601 case FieldDescriptor::CPPTYPE_MESSAGE:
1602 delete *MutableRaw<Message*>(message, field);
1603 break;
1604 default:
1605 break;
1606 }
1607
1608 *MutableOneofCase(message, oneof_descriptor) = 0;
1609 }
1610 }
1611
1612 // Template implementations of basic accessors. Inline because each
1613 // template instance is only called from one location. These are
1614 // used for all types except messages.
1615 template <typename Type>
GetField(const Message & message,const FieldDescriptor * field) const1616 inline const Type& GeneratedMessageReflection::GetField(
1617 const Message& message, const FieldDescriptor* field) const {
1618 return GetRaw<Type>(message, field);
1619 }
1620
1621 template <typename Type>
SetField(Message * message,const FieldDescriptor * field,const Type & value) const1622 inline void GeneratedMessageReflection::SetField(
1623 Message* message, const FieldDescriptor* field, const Type& value) const {
1624 if (field->containing_oneof() && !HasOneofField(*message, field)) {
1625 ClearOneof(message, field->containing_oneof());
1626 }
1627 *MutableRaw<Type>(message, field) = value;
1628 field->containing_oneof() ?
1629 SetOneofCase(message, field) : SetBit(message, field);
1630 }
1631
1632 template <typename Type>
MutableField(Message * message,const FieldDescriptor * field) const1633 inline Type* GeneratedMessageReflection::MutableField(
1634 Message* message, const FieldDescriptor* field) const {
1635 field->containing_oneof() ?
1636 SetOneofCase(message, field) : SetBit(message, field);
1637 return MutableRaw<Type>(message, field);
1638 }
1639
1640 template <typename Type>
GetRepeatedField(const Message & message,const FieldDescriptor * field,int index) const1641 inline const Type& GeneratedMessageReflection::GetRepeatedField(
1642 const Message& message, const FieldDescriptor* field, int index) const {
1643 return GetRaw<RepeatedField<Type> >(message, field).Get(index);
1644 }
1645
1646 template <typename Type>
GetRepeatedPtrField(const Message & message,const FieldDescriptor * field,int index) const1647 inline const Type& GeneratedMessageReflection::GetRepeatedPtrField(
1648 const Message& message, const FieldDescriptor* field, int index) const {
1649 return GetRaw<RepeatedPtrField<Type> >(message, field).Get(index);
1650 }
1651
1652 template <typename Type>
SetRepeatedField(Message * message,const FieldDescriptor * field,int index,Type value) const1653 inline void GeneratedMessageReflection::SetRepeatedField(
1654 Message* message, const FieldDescriptor* field,
1655 int index, Type value) const {
1656 MutableRaw<RepeatedField<Type> >(message, field)->Set(index, value);
1657 }
1658
1659 template <typename Type>
MutableRepeatedField(Message * message,const FieldDescriptor * field,int index) const1660 inline Type* GeneratedMessageReflection::MutableRepeatedField(
1661 Message* message, const FieldDescriptor* field, int index) const {
1662 RepeatedPtrField<Type>* repeated =
1663 MutableRaw<RepeatedPtrField<Type> >(message, field);
1664 return repeated->Mutable(index);
1665 }
1666
1667 template <typename Type>
AddField(Message * message,const FieldDescriptor * field,const Type & value) const1668 inline void GeneratedMessageReflection::AddField(
1669 Message* message, const FieldDescriptor* field, const Type& value) const {
1670 MutableRaw<RepeatedField<Type> >(message, field)->Add(value);
1671 }
1672
1673 template <typename Type>
AddField(Message * message,const FieldDescriptor * field) const1674 inline Type* GeneratedMessageReflection::AddField(
1675 Message* message, const FieldDescriptor* field) const {
1676 RepeatedPtrField<Type>* repeated =
1677 MutableRaw<RepeatedPtrField<Type> >(message, field);
1678 return repeated->Add();
1679 }
1680
1681 } // namespace internal
1682 } // namespace protobuf
1683 } // namespace google
1684