blob: eee024ee073910754be1897244a7448c7a97dc09 [file] [log] [blame]
Brian Silverman9c614bc2016-02-15 20:20:02 -05001// 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
38#include <google/protobuf/stubs/logging.h>
39#include <google/protobuf/stubs/common.h>
40#include <google/protobuf/descriptor.pb.h>
41#include <google/protobuf/descriptor.h>
42#include <google/protobuf/extension_set.h>
43#include <google/protobuf/generated_message_reflection.h>
44#include <google/protobuf/generated_message_util.h>
45#include <google/protobuf/map_field.h>
46#include <google/protobuf/repeated_field.h>
47
48
49#define GOOGLE_PROTOBUF_HAS_ONEOF
50
51namespace google {
52namespace protobuf {
53namespace internal {
54
55namespace {
56bool IsMapFieldInApi(const FieldDescriptor* field) {
57 return field->is_map();
58}
59} // anonymous namespace
60
61bool ParseNamedEnum(const EnumDescriptor* descriptor,
62 const string& name,
63 int* value) {
64 const EnumValueDescriptor* d = descriptor->FindValueByName(name);
65 if (d == NULL) return false;
66 *value = d->number();
67 return true;
68}
69
70const string& NameOfEnum(const EnumDescriptor* descriptor, int value) {
71 const EnumValueDescriptor* d = descriptor->FindValueByNumber(value);
72 return (d == NULL ? GetEmptyString() : d->name());
73}
74
75namespace {
76inline bool SupportsArenas(const Descriptor* descriptor) {
77 return descriptor->file()->options().cc_enable_arenas();
78}
79} // anonymous namespace
80
81// ===================================================================
82// Helpers for reporting usage errors (e.g. trying to use GetInt32() on
83// a string field).
84
85namespace {
86
87void ReportReflectionUsageError(
88 const Descriptor* descriptor, const FieldDescriptor* field,
89 const char* method, const char* description) {
90 GOOGLE_LOG(FATAL)
91 << "Protocol Buffer reflection usage error:\n"
92 " Method : google::protobuf::Reflection::" << method << "\n"
93 " Message type: " << descriptor->full_name() << "\n"
94 " Field : " << field->full_name() << "\n"
95 " Problem : " << description;
96}
97
98const char* cpptype_names_[FieldDescriptor::MAX_CPPTYPE + 1] = {
99 "INVALID_CPPTYPE",
100 "CPPTYPE_INT32",
101 "CPPTYPE_INT64",
102 "CPPTYPE_UINT32",
103 "CPPTYPE_UINT64",
104 "CPPTYPE_DOUBLE",
105 "CPPTYPE_FLOAT",
106 "CPPTYPE_BOOL",
107 "CPPTYPE_ENUM",
108 "CPPTYPE_STRING",
109 "CPPTYPE_MESSAGE"
110};
111
112static void ReportReflectionUsageTypeError(
113 const Descriptor* descriptor, const FieldDescriptor* field,
114 const char* method,
115 FieldDescriptor::CppType expected_type) {
116 GOOGLE_LOG(FATAL)
117 << "Protocol Buffer reflection usage error:\n"
118 " Method : google::protobuf::Reflection::" << method << "\n"
119 " Message type: " << descriptor->full_name() << "\n"
120 " Field : " << field->full_name() << "\n"
121 " Problem : Field is not the right type for this message:\n"
122 " Expected : " << cpptype_names_[expected_type] << "\n"
123 " Field type: " << cpptype_names_[field->cpp_type()];
124}
125
126static void ReportReflectionUsageEnumTypeError(
127 const Descriptor* descriptor, const FieldDescriptor* field,
128 const char* method, const EnumValueDescriptor* value) {
129 GOOGLE_LOG(FATAL)
130 << "Protocol Buffer reflection usage error:\n"
131 " Method : google::protobuf::Reflection::" << method << "\n"
132 " Message type: " << descriptor->full_name() << "\n"
133 " Field : " << field->full_name() << "\n"
134 " Problem : Enum value did not match field type:\n"
135 " Expected : " << field->enum_type()->full_name() << "\n"
136 " Actual : " << value->full_name();
137}
138
139#define USAGE_CHECK(CONDITION, METHOD, ERROR_DESCRIPTION) \
140 if (!(CONDITION)) \
141 ReportReflectionUsageError(descriptor_, field, #METHOD, ERROR_DESCRIPTION)
142#define USAGE_CHECK_EQ(A, B, METHOD, ERROR_DESCRIPTION) \
143 USAGE_CHECK((A) == (B), METHOD, ERROR_DESCRIPTION)
144#define USAGE_CHECK_NE(A, B, METHOD, ERROR_DESCRIPTION) \
145 USAGE_CHECK((A) != (B), METHOD, ERROR_DESCRIPTION)
146
147#define USAGE_CHECK_TYPE(METHOD, CPPTYPE) \
148 if (field->cpp_type() != FieldDescriptor::CPPTYPE_##CPPTYPE) \
149 ReportReflectionUsageTypeError(descriptor_, field, #METHOD, \
150 FieldDescriptor::CPPTYPE_##CPPTYPE)
151
152#define USAGE_CHECK_ENUM_VALUE(METHOD) \
153 if (value->type() != field->enum_type()) \
154 ReportReflectionUsageEnumTypeError(descriptor_, field, #METHOD, value)
155
156#define USAGE_CHECK_MESSAGE_TYPE(METHOD) \
157 USAGE_CHECK_EQ(field->containing_type(), descriptor_, \
158 METHOD, "Field does not match message type.");
159#define USAGE_CHECK_SINGULAR(METHOD) \
160 USAGE_CHECK_NE(field->label(), FieldDescriptor::LABEL_REPEATED, METHOD, \
161 "Field is repeated; the method requires a singular field.")
162#define USAGE_CHECK_REPEATED(METHOD) \
163 USAGE_CHECK_EQ(field->label(), FieldDescriptor::LABEL_REPEATED, METHOD, \
164 "Field is singular; the method requires a repeated field.")
165
166#define USAGE_CHECK_ALL(METHOD, LABEL, CPPTYPE) \
167 USAGE_CHECK_MESSAGE_TYPE(METHOD); \
168 USAGE_CHECK_##LABEL(METHOD); \
169 USAGE_CHECK_TYPE(METHOD, CPPTYPE)
170
171} // namespace
172
173// ===================================================================
174
175GeneratedMessageReflection::GeneratedMessageReflection(
176 const Descriptor* descriptor,
177 const Message* default_instance,
178 const int offsets[],
179 int has_bits_offset,
180 int unknown_fields_offset,
181 int extensions_offset,
182 const DescriptorPool* descriptor_pool,
183 MessageFactory* factory,
184 int object_size,
185 int arena_offset,
186 int is_default_instance_offset)
187 : descriptor_ (descriptor),
188 default_instance_ (default_instance),
189 offsets_ (offsets),
190 has_bits_offset_ (has_bits_offset),
191 unknown_fields_offset_(unknown_fields_offset),
192 extensions_offset_(extensions_offset),
193 arena_offset_ (arena_offset),
194 is_default_instance_offset_(is_default_instance_offset),
195 object_size_ (object_size),
196 descriptor_pool_ ((descriptor_pool == NULL) ?
197 DescriptorPool::generated_pool() :
198 descriptor_pool),
199 message_factory_ (factory) {
200}
201
202GeneratedMessageReflection::GeneratedMessageReflection(
203 const Descriptor* descriptor,
204 const Message* default_instance,
205 const int offsets[],
206 int has_bits_offset,
207 int unknown_fields_offset,
208 int extensions_offset,
209 const void* default_oneof_instance,
210 int oneof_case_offset,
211 const DescriptorPool* descriptor_pool,
212 MessageFactory* factory,
213 int object_size,
214 int arena_offset,
215 int is_default_instance_offset)
216 : descriptor_ (descriptor),
217 default_instance_ (default_instance),
218 default_oneof_instance_ (default_oneof_instance),
219 offsets_ (offsets),
220 has_bits_offset_ (has_bits_offset),
221 oneof_case_offset_(oneof_case_offset),
222 unknown_fields_offset_(unknown_fields_offset),
223 extensions_offset_(extensions_offset),
224 arena_offset_ (arena_offset),
225 is_default_instance_offset_(is_default_instance_offset),
226 object_size_ (object_size),
227 descriptor_pool_ ((descriptor_pool == NULL) ?
228 DescriptorPool::generated_pool() :
229 descriptor_pool),
230 message_factory_ (factory) {
231}
232
233GeneratedMessageReflection::~GeneratedMessageReflection() {}
234
235namespace {
236UnknownFieldSet* empty_unknown_field_set_ = NULL;
237GOOGLE_PROTOBUF_DECLARE_ONCE(empty_unknown_field_set_once_);
238
239void DeleteEmptyUnknownFieldSet() {
240 delete empty_unknown_field_set_;
241 empty_unknown_field_set_ = NULL;
242}
243
244void InitEmptyUnknownFieldSet() {
245 empty_unknown_field_set_ = new UnknownFieldSet;
246 internal::OnShutdown(&DeleteEmptyUnknownFieldSet);
247}
248
249const UnknownFieldSet& GetEmptyUnknownFieldSet() {
250 ::google::protobuf::GoogleOnceInit(&empty_unknown_field_set_once_, &InitEmptyUnknownFieldSet);
251 return *empty_unknown_field_set_;
252}
253} // namespace
254
255const UnknownFieldSet& GeneratedMessageReflection::GetUnknownFields(
256 const Message& message) const {
257 if (descriptor_->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) {
258 return GetEmptyUnknownFieldSet();
259 }
260 if (unknown_fields_offset_ == kUnknownFieldSetInMetadata) {
261 return GetInternalMetadataWithArena(message).unknown_fields();
262 }
263 const void* ptr = reinterpret_cast<const uint8*>(&message) +
264 unknown_fields_offset_;
265 return *reinterpret_cast<const UnknownFieldSet*>(ptr);
266}
267
268UnknownFieldSet* GeneratedMessageReflection::MutableUnknownFields(
269 Message* message) const {
270 if (unknown_fields_offset_ == kUnknownFieldSetInMetadata) {
271 return MutableInternalMetadataWithArena(message)->
272 mutable_unknown_fields();
273 }
274 void* ptr = reinterpret_cast<uint8*>(message) + unknown_fields_offset_;
275 return reinterpret_cast<UnknownFieldSet*>(ptr);
276}
277
278int GeneratedMessageReflection::SpaceUsed(const Message& message) const {
279 // object_size_ already includes the in-memory representation of each field
280 // in the message, so we only need to account for additional memory used by
281 // the fields.
282 int total_size = object_size_;
283
284 total_size += GetUnknownFields(message).SpaceUsedExcludingSelf();
285
286 if (extensions_offset_ != -1) {
287 total_size += GetExtensionSet(message).SpaceUsedExcludingSelf();
288 }
289
290 for (int i = 0; i < descriptor_->field_count(); i++) {
291 const FieldDescriptor* field = descriptor_->field(i);
292
293 if (field->is_repeated()) {
294 switch (field->cpp_type()) {
295#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
296 case FieldDescriptor::CPPTYPE_##UPPERCASE : \
297 total_size += GetRaw<RepeatedField<LOWERCASE> >(message, field) \
298 .SpaceUsedExcludingSelf(); \
299 break
300
301 HANDLE_TYPE( INT32, int32);
302 HANDLE_TYPE( INT64, int64);
303 HANDLE_TYPE(UINT32, uint32);
304 HANDLE_TYPE(UINT64, uint64);
305 HANDLE_TYPE(DOUBLE, double);
306 HANDLE_TYPE( FLOAT, float);
307 HANDLE_TYPE( BOOL, bool);
308 HANDLE_TYPE( ENUM, int);
309#undef HANDLE_TYPE
310
311 case FieldDescriptor::CPPTYPE_STRING:
312 switch (field->options().ctype()) {
313 default: // TODO(kenton): Support other string reps.
314 case FieldOptions::STRING:
315 total_size += GetRaw<RepeatedPtrField<string> >(message, field)
316 .SpaceUsedExcludingSelf();
317 break;
318 }
319 break;
320
321 case FieldDescriptor::CPPTYPE_MESSAGE:
322 if (IsMapFieldInApi(field)) {
323 total_size +=
324 GetRaw<MapFieldBase>(message, field).SpaceUsedExcludingSelf();
325 } else {
326 // We don't know which subclass of RepeatedPtrFieldBase the type is,
327 // so we use RepeatedPtrFieldBase directly.
328 total_size +=
329 GetRaw<RepeatedPtrFieldBase>(message, field)
330 .SpaceUsedExcludingSelf<GenericTypeHandler<Message> >();
331 }
332
333 break;
334 }
335 } else {
336 if (field->containing_oneof() && !HasOneofField(message, field)) {
337 continue;
338 }
339 switch (field->cpp_type()) {
340 case FieldDescriptor::CPPTYPE_INT32 :
341 case FieldDescriptor::CPPTYPE_INT64 :
342 case FieldDescriptor::CPPTYPE_UINT32:
343 case FieldDescriptor::CPPTYPE_UINT64:
344 case FieldDescriptor::CPPTYPE_DOUBLE:
345 case FieldDescriptor::CPPTYPE_FLOAT :
346 case FieldDescriptor::CPPTYPE_BOOL :
347 case FieldDescriptor::CPPTYPE_ENUM :
348 // Field is inline, so we've already counted it.
349 break;
350
351 case FieldDescriptor::CPPTYPE_STRING: {
352 switch (field->options().ctype()) {
353 default: // TODO(kenton): Support other string reps.
354 case FieldOptions::STRING: {
355 // Initially, the string points to the default value stored in
356 // the prototype. Only count the string if it has been changed
357 // from the default value.
358 const string* default_ptr =
359 &DefaultRaw<ArenaStringPtr>(field).Get(NULL);
360 const string* ptr =
361 &GetField<ArenaStringPtr>(message, field).Get(default_ptr);
362
363 if (ptr != default_ptr) {
364 // string fields are represented by just a pointer, so also
365 // include sizeof(string) as well.
366 total_size += sizeof(*ptr) + StringSpaceUsedExcludingSelf(*ptr);
367 }
368 break;
369 }
370 }
371 break;
372 }
373
374 case FieldDescriptor::CPPTYPE_MESSAGE:
375 if (&message == default_instance_) {
376 // For singular fields, the prototype just stores a pointer to the
377 // external type's prototype, so there is no extra memory usage.
378 } else {
379 const Message* sub_message = GetRaw<const Message*>(message, field);
380 if (sub_message != NULL) {
381 total_size += sub_message->SpaceUsed();
382 }
383 }
384 break;
385 }
386 }
387 }
388
389 return total_size;
390}
391
392void GeneratedMessageReflection::SwapField(
393 Message* message1,
394 Message* message2,
395 const FieldDescriptor* field) const {
396 if (field->is_repeated()) {
397 switch (field->cpp_type()) {
398#define SWAP_ARRAYS(CPPTYPE, TYPE) \
399 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
400 MutableRaw<RepeatedField<TYPE> >(message1, field)->Swap( \
401 MutableRaw<RepeatedField<TYPE> >(message2, field)); \
402 break;
403
404 SWAP_ARRAYS(INT32 , int32 );
405 SWAP_ARRAYS(INT64 , int64 );
406 SWAP_ARRAYS(UINT32, uint32);
407 SWAP_ARRAYS(UINT64, uint64);
408 SWAP_ARRAYS(FLOAT , float );
409 SWAP_ARRAYS(DOUBLE, double);
410 SWAP_ARRAYS(BOOL , bool );
411 SWAP_ARRAYS(ENUM , int );
412#undef SWAP_ARRAYS
413
414 case FieldDescriptor::CPPTYPE_STRING:
415 case FieldDescriptor::CPPTYPE_MESSAGE:
416 if (IsMapFieldInApi(field)) {
417 MutableRaw<MapFieldBase>(message1, field)->
418 MutableRepeatedField()->
419 Swap<GenericTypeHandler<google::protobuf::Message> >(
420 MutableRaw<MapFieldBase>(message2, field)->
421 MutableRepeatedField());
422 } else {
423 MutableRaw<RepeatedPtrFieldBase>(message1, field)->
424 Swap<GenericTypeHandler<google::protobuf::Message> >(
425 MutableRaw<RepeatedPtrFieldBase>(message2, field));
426 }
427 break;
428
429 default:
430 GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
431 }
432 } else {
433 switch (field->cpp_type()) {
434#define SWAP_VALUES(CPPTYPE, TYPE) \
435 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
436 std::swap(*MutableRaw<TYPE>(message1, field), \
437 *MutableRaw<TYPE>(message2, field)); \
438 break;
439
440 SWAP_VALUES(INT32 , int32 );
441 SWAP_VALUES(INT64 , int64 );
442 SWAP_VALUES(UINT32, uint32);
443 SWAP_VALUES(UINT64, uint64);
444 SWAP_VALUES(FLOAT , float );
445 SWAP_VALUES(DOUBLE, double);
446 SWAP_VALUES(BOOL , bool );
447 SWAP_VALUES(ENUM , int );
448#undef SWAP_VALUES
449 case FieldDescriptor::CPPTYPE_MESSAGE:
450 std::swap(*MutableRaw<Message*>(message1, field),
451 *MutableRaw<Message*>(message2, field));
452 break;
453
454 case FieldDescriptor::CPPTYPE_STRING:
455 switch (field->options().ctype()) {
456 default: // TODO(kenton): Support other string reps.
457 case FieldOptions::STRING:
458 MutableRaw<ArenaStringPtr>(message1, field)->Swap(
459 MutableRaw<ArenaStringPtr>(message2, field));
460 break;
461 }
462 break;
463
464 default:
465 GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
466 }
467 }
468}
469
470void GeneratedMessageReflection::SwapOneofField(
471 Message* message1,
472 Message* message2,
473 const OneofDescriptor* oneof_descriptor) const {
474 uint32 oneof_case1 = GetOneofCase(*message1, oneof_descriptor);
475 uint32 oneof_case2 = GetOneofCase(*message2, oneof_descriptor);
476
477 int32 temp_int32;
478 int64 temp_int64;
479 uint32 temp_uint32;
480 uint64 temp_uint64;
481 float temp_float;
482 double temp_double;
483 bool temp_bool;
484 int temp_int;
485 Message* temp_message = NULL;
486 string temp_string;
487
488 // Stores message1's oneof field to a temp variable.
489 const FieldDescriptor* field1 = NULL;
490 if (oneof_case1 > 0) {
491 field1 = descriptor_->FindFieldByNumber(oneof_case1);
492 //oneof_descriptor->field(oneof_case1);
493 switch (field1->cpp_type()) {
494#define GET_TEMP_VALUE(CPPTYPE, TYPE) \
495 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
496 temp_##TYPE = GetField<TYPE>(*message1, field1); \
497 break;
498
499 GET_TEMP_VALUE(INT32 , int32 );
500 GET_TEMP_VALUE(INT64 , int64 );
501 GET_TEMP_VALUE(UINT32, uint32);
502 GET_TEMP_VALUE(UINT64, uint64);
503 GET_TEMP_VALUE(FLOAT , float );
504 GET_TEMP_VALUE(DOUBLE, double);
505 GET_TEMP_VALUE(BOOL , bool );
506 GET_TEMP_VALUE(ENUM , int );
507#undef GET_TEMP_VALUE
508 case FieldDescriptor::CPPTYPE_MESSAGE:
509 temp_message = ReleaseMessage(message1, field1);
510 break;
511
512 case FieldDescriptor::CPPTYPE_STRING:
513 temp_string = GetString(*message1, field1);
514 break;
515
516 default:
517 GOOGLE_LOG(FATAL) << "Unimplemented type: " << field1->cpp_type();
518 }
519 }
520
521 // Sets message1's oneof field from the message2's oneof field.
522 if (oneof_case2 > 0) {
523 const FieldDescriptor* field2 =
524 descriptor_->FindFieldByNumber(oneof_case2);
525 switch (field2->cpp_type()) {
526#define SET_ONEOF_VALUE1(CPPTYPE, TYPE) \
527 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
528 SetField<TYPE>(message1, field2, GetField<TYPE>(*message2, field2)); \
529 break;
530
531 SET_ONEOF_VALUE1(INT32 , int32 );
532 SET_ONEOF_VALUE1(INT64 , int64 );
533 SET_ONEOF_VALUE1(UINT32, uint32);
534 SET_ONEOF_VALUE1(UINT64, uint64);
535 SET_ONEOF_VALUE1(FLOAT , float );
536 SET_ONEOF_VALUE1(DOUBLE, double);
537 SET_ONEOF_VALUE1(BOOL , bool );
538 SET_ONEOF_VALUE1(ENUM , int );
539#undef SET_ONEOF_VALUE1
540 case FieldDescriptor::CPPTYPE_MESSAGE:
541 SetAllocatedMessage(message1,
542 ReleaseMessage(message2, field2),
543 field2);
544 break;
545
546 case FieldDescriptor::CPPTYPE_STRING:
547 SetString(message1, field2, GetString(*message2, field2));
548 break;
549
550 default:
551 GOOGLE_LOG(FATAL) << "Unimplemented type: " << field2->cpp_type();
552 }
553 } else {
554 ClearOneof(message1, oneof_descriptor);
555 }
556
557 // Sets message2's oneof field from the temp variable.
558 if (oneof_case1 > 0) {
559 switch (field1->cpp_type()) {
560#define SET_ONEOF_VALUE2(CPPTYPE, TYPE) \
561 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
562 SetField<TYPE>(message2, field1, temp_##TYPE); \
563 break;
564
565 SET_ONEOF_VALUE2(INT32 , int32 );
566 SET_ONEOF_VALUE2(INT64 , int64 );
567 SET_ONEOF_VALUE2(UINT32, uint32);
568 SET_ONEOF_VALUE2(UINT64, uint64);
569 SET_ONEOF_VALUE2(FLOAT , float );
570 SET_ONEOF_VALUE2(DOUBLE, double);
571 SET_ONEOF_VALUE2(BOOL , bool );
572 SET_ONEOF_VALUE2(ENUM , int );
573#undef SET_ONEOF_VALUE2
574 case FieldDescriptor::CPPTYPE_MESSAGE:
575 SetAllocatedMessage(message2, temp_message, field1);
576 break;
577
578 case FieldDescriptor::CPPTYPE_STRING:
579 SetString(message2, field1, temp_string);
580 break;
581
582 default:
583 GOOGLE_LOG(FATAL) << "Unimplemented type: " << field1->cpp_type();
584 }
585 } else {
586 ClearOneof(message2, oneof_descriptor);
587 }
588}
589
590void GeneratedMessageReflection::Swap(
591 Message* message1,
592 Message* message2) const {
593 if (message1 == message2) return;
594
595 // TODO(kenton): Other Reflection methods should probably check this too.
596 GOOGLE_CHECK_EQ(message1->GetReflection(), this)
597 << "First argument to Swap() (of type \""
598 << message1->GetDescriptor()->full_name()
599 << "\") is not compatible with this reflection object (which is for type \""
600 << descriptor_->full_name()
601 << "\"). Note that the exact same class is required; not just the same "
602 "descriptor.";
603 GOOGLE_CHECK_EQ(message2->GetReflection(), this)
604 << "Second argument to Swap() (of type \""
605 << message2->GetDescriptor()->full_name()
606 << "\") is not compatible with this reflection object (which is for type \""
607 << descriptor_->full_name()
608 << "\"). Note that the exact same class is required; not just the same "
609 "descriptor.";
610
611 // Check that both messages are in the same arena (or both on the heap). We
612 // need to copy all data if not, due to ownership semantics.
613 if (GetArena(message1) != GetArena(message2)) {
614 // Slow copy path.
615 // Use our arena as temp space, if available.
616 Message* temp = message1->New(GetArena(message1));
617 temp->MergeFrom(*message1);
618 message1->CopyFrom(*message2);
619 message2->CopyFrom(*temp);
620 if (GetArena(message1) == NULL) {
621 delete temp;
622 }
623 return;
624 }
625
626 if (has_bits_offset_ != -1) {
627 uint32* has_bits1 = MutableHasBits(message1);
628 uint32* has_bits2 = MutableHasBits(message2);
629 int has_bits_size = (descriptor_->field_count() + 31) / 32;
630
631 for (int i = 0; i < has_bits_size; i++) {
632 std::swap(has_bits1[i], has_bits2[i]);
633 }
634 }
635
636 for (int i = 0; i < descriptor_->field_count(); i++) {
637 const FieldDescriptor* field = descriptor_->field(i);
638 if (!field->containing_oneof()) {
639 SwapField(message1, message2, field);
640 }
641 }
642
643 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
644 SwapOneofField(message1, message2, descriptor_->oneof_decl(i));
645 }
646
647 if (extensions_offset_ != -1) {
648 MutableExtensionSet(message1)->Swap(MutableExtensionSet(message2));
649 }
650
651 MutableUnknownFields(message1)->Swap(MutableUnknownFields(message2));
652}
653
654void GeneratedMessageReflection::SwapFields(
655 Message* message1,
656 Message* message2,
657 const vector<const FieldDescriptor*>& fields) const {
658 if (message1 == message2) return;
659
660 // TODO(kenton): Other Reflection methods should probably check this too.
661 GOOGLE_CHECK_EQ(message1->GetReflection(), this)
662 << "First argument to SwapFields() (of type \""
663 << message1->GetDescriptor()->full_name()
664 << "\") is not compatible with this reflection object (which is for type \""
665 << descriptor_->full_name()
666 << "\"). Note that the exact same class is required; not just the same "
667 "descriptor.";
668 GOOGLE_CHECK_EQ(message2->GetReflection(), this)
669 << "Second argument to SwapFields() (of type \""
670 << message2->GetDescriptor()->full_name()
671 << "\") is not compatible with this reflection object (which is for type \""
672 << descriptor_->full_name()
673 << "\"). Note that the exact same class is required; not just the same "
674 "descriptor.";
675
676 std::set<int> swapped_oneof;
677
678 for (int i = 0; i < fields.size(); i++) {
679 const FieldDescriptor* field = fields[i];
680 if (field->is_extension()) {
681 MutableExtensionSet(message1)->SwapExtension(
682 MutableExtensionSet(message2),
683 field->number());
684 } else {
685 if (field->containing_oneof()) {
686 int oneof_index = field->containing_oneof()->index();
687 // Only swap the oneof field once.
688 if (swapped_oneof.find(oneof_index) != swapped_oneof.end()) {
689 continue;
690 }
691 swapped_oneof.insert(oneof_index);
692 SwapOneofField(message1, message2, field->containing_oneof());
693 } else {
694 // Swap has bit.
695 SwapBit(message1, message2, field);
696 // Swap field.
697 SwapField(message1, message2, field);
698 }
699 }
700 }
701}
702
703// -------------------------------------------------------------------
704
705bool GeneratedMessageReflection::HasField(const Message& message,
706 const FieldDescriptor* field) const {
707 USAGE_CHECK_MESSAGE_TYPE(HasField);
708 USAGE_CHECK_SINGULAR(HasField);
709
710 if (field->is_extension()) {
711 return GetExtensionSet(message).Has(field->number());
712 } else {
713 if (field->containing_oneof()) {
714 return HasOneofField(message, field);
715 } else {
716 return HasBit(message, field);
717 }
718 }
719}
720
721int GeneratedMessageReflection::FieldSize(const Message& message,
722 const FieldDescriptor* field) const {
723 USAGE_CHECK_MESSAGE_TYPE(FieldSize);
724 USAGE_CHECK_REPEATED(FieldSize);
725
726 if (field->is_extension()) {
727 return GetExtensionSet(message).ExtensionSize(field->number());
728 } else {
729 switch (field->cpp_type()) {
730#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
731 case FieldDescriptor::CPPTYPE_##UPPERCASE : \
732 return GetRaw<RepeatedField<LOWERCASE> >(message, field).size()
733
734 HANDLE_TYPE( INT32, int32);
735 HANDLE_TYPE( INT64, int64);
736 HANDLE_TYPE(UINT32, uint32);
737 HANDLE_TYPE(UINT64, uint64);
738 HANDLE_TYPE(DOUBLE, double);
739 HANDLE_TYPE( FLOAT, float);
740 HANDLE_TYPE( BOOL, bool);
741 HANDLE_TYPE( ENUM, int);
742#undef HANDLE_TYPE
743
744 case FieldDescriptor::CPPTYPE_STRING:
745 case FieldDescriptor::CPPTYPE_MESSAGE:
746 if (IsMapFieldInApi(field)) {
747 return GetRaw<MapFieldBase>(message, field).GetRepeatedField().size();
748 } else {
749 return GetRaw<RepeatedPtrFieldBase>(message, field).size();
750 }
751 }
752
753 GOOGLE_LOG(FATAL) << "Can't get here.";
754 return 0;
755 }
756}
757
758void GeneratedMessageReflection::ClearField(
759 Message* message, const FieldDescriptor* field) const {
760 USAGE_CHECK_MESSAGE_TYPE(ClearField);
761
762 if (field->is_extension()) {
763 MutableExtensionSet(message)->ClearExtension(field->number());
764 } else if (!field->is_repeated()) {
765 if (field->containing_oneof()) {
766 ClearOneofField(message, field);
767 return;
768 }
769
770 if (HasBit(*message, field)) {
771 ClearBit(message, field);
772
773 // We need to set the field back to its default value.
774 switch (field->cpp_type()) {
775#define CLEAR_TYPE(CPPTYPE, TYPE) \
776 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
777 *MutableRaw<TYPE>(message, field) = \
778 field->default_value_##TYPE(); \
779 break;
780
781 CLEAR_TYPE(INT32 , int32 );
782 CLEAR_TYPE(INT64 , int64 );
783 CLEAR_TYPE(UINT32, uint32);
784 CLEAR_TYPE(UINT64, uint64);
785 CLEAR_TYPE(FLOAT , float );
786 CLEAR_TYPE(DOUBLE, double);
787 CLEAR_TYPE(BOOL , bool );
788#undef CLEAR_TYPE
789
790 case FieldDescriptor::CPPTYPE_ENUM:
791 *MutableRaw<int>(message, field) =
792 field->default_value_enum()->number();
793 break;
794
795 case FieldDescriptor::CPPTYPE_STRING: {
796 switch (field->options().ctype()) {
797 default: // TODO(kenton): Support other string reps.
798 case FieldOptions::STRING: {
799 const string* default_ptr =
800 &DefaultRaw<ArenaStringPtr>(field).Get(NULL);
801 MutableRaw<ArenaStringPtr>(message, field)->Destroy(default_ptr,
802 GetArena(message));
803 break;
804 }
805 }
806 break;
807 }
808
809 case FieldDescriptor::CPPTYPE_MESSAGE:
810 if (has_bits_offset_ == -1) {
811 // Proto3 does not have has-bits and we need to set a message field
812 // to NULL in order to indicate its un-presence.
813 if (GetArena(message) == NULL) {
814 delete *MutableRaw<Message*>(message, field);
815 }
816 *MutableRaw<Message*>(message, field) = NULL;
817 } else {
818 (*MutableRaw<Message*>(message, field))->Clear();
819 }
820 break;
821 }
822 }
823 } else {
824 switch (field->cpp_type()) {
825#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
826 case FieldDescriptor::CPPTYPE_##UPPERCASE : \
827 MutableRaw<RepeatedField<LOWERCASE> >(message, field)->Clear(); \
828 break
829
830 HANDLE_TYPE( INT32, int32);
831 HANDLE_TYPE( INT64, int64);
832 HANDLE_TYPE(UINT32, uint32);
833 HANDLE_TYPE(UINT64, uint64);
834 HANDLE_TYPE(DOUBLE, double);
835 HANDLE_TYPE( FLOAT, float);
836 HANDLE_TYPE( BOOL, bool);
837 HANDLE_TYPE( ENUM, int);
838#undef HANDLE_TYPE
839
840 case FieldDescriptor::CPPTYPE_STRING: {
841 switch (field->options().ctype()) {
842 default: // TODO(kenton): Support other string reps.
843 case FieldOptions::STRING:
844 MutableRaw<RepeatedPtrField<string> >(message, field)->Clear();
845 break;
846 }
847 break;
848 }
849
850 case FieldDescriptor::CPPTYPE_MESSAGE: {
851 if (IsMapFieldInApi(field)) {
852 MutableRaw<MapFieldBase>(message, field)
853 ->MutableRepeatedField()
854 ->Clear<GenericTypeHandler<Message> >();
855 } else {
856 // We don't know which subclass of RepeatedPtrFieldBase the type is,
857 // so we use RepeatedPtrFieldBase directly.
858 MutableRaw<RepeatedPtrFieldBase>(message, field)
859 ->Clear<GenericTypeHandler<Message> >();
860 }
861 break;
862 }
863 }
864 }
865}
866
867void GeneratedMessageReflection::RemoveLast(
868 Message* message,
869 const FieldDescriptor* field) const {
870 USAGE_CHECK_MESSAGE_TYPE(RemoveLast);
871 USAGE_CHECK_REPEATED(RemoveLast);
872
873 if (field->is_extension()) {
874 MutableExtensionSet(message)->RemoveLast(field->number());
875 } else {
876 switch (field->cpp_type()) {
877#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
878 case FieldDescriptor::CPPTYPE_##UPPERCASE : \
879 MutableRaw<RepeatedField<LOWERCASE> >(message, field)->RemoveLast(); \
880 break
881
882 HANDLE_TYPE( INT32, int32);
883 HANDLE_TYPE( INT64, int64);
884 HANDLE_TYPE(UINT32, uint32);
885 HANDLE_TYPE(UINT64, uint64);
886 HANDLE_TYPE(DOUBLE, double);
887 HANDLE_TYPE( FLOAT, float);
888 HANDLE_TYPE( BOOL, bool);
889 HANDLE_TYPE( ENUM, int);
890#undef HANDLE_TYPE
891
892 case FieldDescriptor::CPPTYPE_STRING:
893 switch (field->options().ctype()) {
894 default: // TODO(kenton): Support other string reps.
895 case FieldOptions::STRING:
896 MutableRaw<RepeatedPtrField<string> >(message, field)->RemoveLast();
897 break;
898 }
899 break;
900
901 case FieldDescriptor::CPPTYPE_MESSAGE:
902 if (IsMapFieldInApi(field)) {
903 MutableRaw<MapFieldBase>(message, field)
904 ->MutableRepeatedField()
905 ->RemoveLast<GenericTypeHandler<Message> >();
906 } else {
907 MutableRaw<RepeatedPtrFieldBase>(message, field)
908 ->RemoveLast<GenericTypeHandler<Message> >();
909 }
910 break;
911 }
912 }
913}
914
915Message* GeneratedMessageReflection::ReleaseLast(
916 Message* message,
917 const FieldDescriptor* field) const {
918 USAGE_CHECK_ALL(ReleaseLast, REPEATED, MESSAGE);
919
920 if (field->is_extension()) {
921 return static_cast<Message*>(
922 MutableExtensionSet(message)->ReleaseLast(field->number()));
923 } else {
924 if (IsMapFieldInApi(field)) {
925 return MutableRaw<MapFieldBase>(message, field)
926 ->MutableRepeatedField()
927 ->ReleaseLast<GenericTypeHandler<Message> >();
928 } else {
929 return MutableRaw<RepeatedPtrFieldBase>(message, field)
930 ->ReleaseLast<GenericTypeHandler<Message> >();
931 }
932 }
933}
934
935void GeneratedMessageReflection::SwapElements(
936 Message* message,
937 const FieldDescriptor* field,
938 int index1,
939 int index2) const {
940 USAGE_CHECK_MESSAGE_TYPE(Swap);
941 USAGE_CHECK_REPEATED(Swap);
942
943 if (field->is_extension()) {
944 MutableExtensionSet(message)->SwapElements(field->number(), index1, index2);
945 } else {
946 switch (field->cpp_type()) {
947#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
948 case FieldDescriptor::CPPTYPE_##UPPERCASE : \
949 MutableRaw<RepeatedField<LOWERCASE> >(message, field) \
950 ->SwapElements(index1, index2); \
951 break
952
953 HANDLE_TYPE( INT32, int32);
954 HANDLE_TYPE( INT64, int64);
955 HANDLE_TYPE(UINT32, uint32);
956 HANDLE_TYPE(UINT64, uint64);
957 HANDLE_TYPE(DOUBLE, double);
958 HANDLE_TYPE( FLOAT, float);
959 HANDLE_TYPE( BOOL, bool);
960 HANDLE_TYPE( ENUM, int);
961#undef HANDLE_TYPE
962
963 case FieldDescriptor::CPPTYPE_STRING:
964 case FieldDescriptor::CPPTYPE_MESSAGE:
965 if (IsMapFieldInApi(field)) {
966 MutableRaw<MapFieldBase>(message, field)
967 ->MutableRepeatedField()
968 ->SwapElements(index1, index2);
969 } else {
970 MutableRaw<RepeatedPtrFieldBase>(message, field)
971 ->SwapElements(index1, index2);
972 }
973 break;
974 }
975 }
976}
977
978namespace {
979// Comparison functor for sorting FieldDescriptors by field number.
980struct FieldNumberSorter {
981 bool operator()(const FieldDescriptor* left,
982 const FieldDescriptor* right) const {
983 return left->number() < right->number();
984 }
985};
986} // namespace
987
988void GeneratedMessageReflection::ListFields(
989 const Message& message,
990 vector<const FieldDescriptor*>* output) const {
991 output->clear();
992
993 // Optimization: The default instance never has any fields set.
994 if (&message == default_instance_) return;
995
996 output->reserve(descriptor_->field_count());
997 for (int i = 0; i < descriptor_->field_count(); i++) {
998 const FieldDescriptor* field = descriptor_->field(i);
999 if (field->is_repeated()) {
1000 if (FieldSize(message, field) > 0) {
1001 output->push_back(field);
1002 }
1003 } else {
1004 if (field->containing_oneof()) {
1005 if (HasOneofField(message, field)) {
1006 output->push_back(field);
1007 }
1008 } else if (HasBit(message, field)) {
1009 output->push_back(field);
1010 }
1011 }
1012 }
1013
1014 if (extensions_offset_ != -1) {
1015 GetExtensionSet(message).AppendToList(descriptor_, descriptor_pool_,
1016 output);
1017 }
1018
1019 // ListFields() must sort output by field number.
1020 std::sort(output->begin(), output->end(), FieldNumberSorter());
1021}
1022
1023// -------------------------------------------------------------------
1024
1025#undef DEFINE_PRIMITIVE_ACCESSORS
1026#define DEFINE_PRIMITIVE_ACCESSORS(TYPENAME, TYPE, PASSTYPE, CPPTYPE) \
1027 PASSTYPE GeneratedMessageReflection::Get##TYPENAME( \
1028 const Message& message, const FieldDescriptor* field) const { \
1029 USAGE_CHECK_ALL(Get##TYPENAME, SINGULAR, CPPTYPE); \
1030 if (field->is_extension()) { \
1031 return GetExtensionSet(message).Get##TYPENAME( \
1032 field->number(), field->default_value_##PASSTYPE()); \
1033 } else { \
1034 return GetField<TYPE>(message, field); \
1035 } \
1036 } \
1037 \
1038 void GeneratedMessageReflection::Set##TYPENAME( \
1039 Message* message, const FieldDescriptor* field, \
1040 PASSTYPE value) const { \
1041 USAGE_CHECK_ALL(Set##TYPENAME, SINGULAR, CPPTYPE); \
1042 if (field->is_extension()) { \
1043 return MutableExtensionSet(message)->Set##TYPENAME( \
1044 field->number(), field->type(), value, field); \
1045 } else { \
1046 SetField<TYPE>(message, field, value); \
1047 } \
1048 } \
1049 \
1050 PASSTYPE GeneratedMessageReflection::GetRepeated##TYPENAME( \
1051 const Message& message, \
1052 const FieldDescriptor* field, int index) const { \
1053 USAGE_CHECK_ALL(GetRepeated##TYPENAME, REPEATED, CPPTYPE); \
1054 if (field->is_extension()) { \
1055 return GetExtensionSet(message).GetRepeated##TYPENAME( \
1056 field->number(), index); \
1057 } else { \
1058 return GetRepeatedField<TYPE>(message, field, index); \
1059 } \
1060 } \
1061 \
1062 void GeneratedMessageReflection::SetRepeated##TYPENAME( \
1063 Message* message, const FieldDescriptor* field, \
1064 int index, PASSTYPE value) const { \
1065 USAGE_CHECK_ALL(SetRepeated##TYPENAME, REPEATED, CPPTYPE); \
1066 if (field->is_extension()) { \
1067 MutableExtensionSet(message)->SetRepeated##TYPENAME( \
1068 field->number(), index, value); \
1069 } else { \
1070 SetRepeatedField<TYPE>(message, field, index, value); \
1071 } \
1072 } \
1073 \
1074 void GeneratedMessageReflection::Add##TYPENAME( \
1075 Message* message, const FieldDescriptor* field, \
1076 PASSTYPE value) const { \
1077 USAGE_CHECK_ALL(Add##TYPENAME, REPEATED, CPPTYPE); \
1078 if (field->is_extension()) { \
1079 MutableExtensionSet(message)->Add##TYPENAME( \
1080 field->number(), field->type(), field->options().packed(), value, \
1081 field); \
1082 } else { \
1083 AddField<TYPE>(message, field, value); \
1084 } \
1085 }
1086
1087DEFINE_PRIMITIVE_ACCESSORS(Int32 , int32 , int32 , INT32 )
1088DEFINE_PRIMITIVE_ACCESSORS(Int64 , int64 , int64 , INT64 )
1089DEFINE_PRIMITIVE_ACCESSORS(UInt32, uint32, uint32, UINT32)
1090DEFINE_PRIMITIVE_ACCESSORS(UInt64, uint64, uint64, UINT64)
1091DEFINE_PRIMITIVE_ACCESSORS(Float , float , float , FLOAT )
1092DEFINE_PRIMITIVE_ACCESSORS(Double, double, double, DOUBLE)
1093DEFINE_PRIMITIVE_ACCESSORS(Bool , bool , bool , BOOL )
1094#undef DEFINE_PRIMITIVE_ACCESSORS
1095
1096// -------------------------------------------------------------------
1097
1098string GeneratedMessageReflection::GetString(
1099 const Message& message, const FieldDescriptor* field) const {
1100 USAGE_CHECK_ALL(GetString, SINGULAR, STRING);
1101 if (field->is_extension()) {
1102 return GetExtensionSet(message).GetString(field->number(),
1103 field->default_value_string());
1104 } else {
1105 switch (field->options().ctype()) {
1106 default: // TODO(kenton): Support other string reps.
1107 case FieldOptions::STRING: {
1108 const string* default_ptr =
1109 &DefaultRaw<ArenaStringPtr>(field).Get(NULL);
1110 return GetField<ArenaStringPtr>(message, field).Get(default_ptr);
1111 }
1112 }
1113
1114 GOOGLE_LOG(FATAL) << "Can't get here.";
1115 return GetEmptyString(); // Make compiler happy.
1116 }
1117}
1118
1119const string& GeneratedMessageReflection::GetStringReference(
1120 const Message& message,
1121 const FieldDescriptor* field, string* scratch) const {
1122 USAGE_CHECK_ALL(GetStringReference, SINGULAR, STRING);
1123 if (field->is_extension()) {
1124 return GetExtensionSet(message).GetString(field->number(),
1125 field->default_value_string());
1126 } else {
1127 switch (field->options().ctype()) {
1128 default: // TODO(kenton): Support other string reps.
1129 case FieldOptions::STRING: {
1130 const string* default_ptr =
1131 &DefaultRaw<ArenaStringPtr>(field).Get(NULL);
1132 return GetField<ArenaStringPtr>(message, field).Get(default_ptr);
1133 }
1134 }
1135
1136 GOOGLE_LOG(FATAL) << "Can't get here.";
1137 return GetEmptyString(); // Make compiler happy.
1138 }
1139}
1140
1141
1142void GeneratedMessageReflection::SetString(
1143 Message* message, const FieldDescriptor* field,
1144 const string& value) const {
1145 USAGE_CHECK_ALL(SetString, SINGULAR, STRING);
1146 if (field->is_extension()) {
1147 return MutableExtensionSet(message)->SetString(field->number(),
1148 field->type(), value, field);
1149 } else {
1150 switch (field->options().ctype()) {
1151 default: // TODO(kenton): Support other string reps.
1152 case FieldOptions::STRING: {
1153 const string* default_ptr =
1154 &DefaultRaw<ArenaStringPtr>(field).Get(NULL);
1155 if (field->containing_oneof() && !HasOneofField(*message, field)) {
1156 ClearOneof(message, field->containing_oneof());
1157 MutableField<ArenaStringPtr>(message, field)->UnsafeSetDefault(
1158 default_ptr);
1159 }
1160 MutableField<ArenaStringPtr>(message, field)->Set(default_ptr,
1161 value, GetArena(message));
1162 break;
1163 }
1164 }
1165 }
1166}
1167
1168
1169string GeneratedMessageReflection::GetRepeatedString(
1170 const Message& message, const FieldDescriptor* field, int index) const {
1171 USAGE_CHECK_ALL(GetRepeatedString, REPEATED, STRING);
1172 if (field->is_extension()) {
1173 return GetExtensionSet(message).GetRepeatedString(field->number(), index);
1174 } else {
1175 switch (field->options().ctype()) {
1176 default: // TODO(kenton): Support other string reps.
1177 case FieldOptions::STRING:
1178 return GetRepeatedPtrField<string>(message, field, index);
1179 }
1180
1181 GOOGLE_LOG(FATAL) << "Can't get here.";
1182 return GetEmptyString(); // Make compiler happy.
1183 }
1184}
1185
1186const string& GeneratedMessageReflection::GetRepeatedStringReference(
1187 const Message& message, const FieldDescriptor* field,
1188 int index, string* scratch) const {
1189 USAGE_CHECK_ALL(GetRepeatedStringReference, REPEATED, STRING);
1190 if (field->is_extension()) {
1191 return GetExtensionSet(message).GetRepeatedString(field->number(), index);
1192 } else {
1193 switch (field->options().ctype()) {
1194 default: // TODO(kenton): Support other string reps.
1195 case FieldOptions::STRING:
1196 return GetRepeatedPtrField<string>(message, field, index);
1197 }
1198
1199 GOOGLE_LOG(FATAL) << "Can't get here.";
1200 return GetEmptyString(); // Make compiler happy.
1201 }
1202}
1203
1204
1205void GeneratedMessageReflection::SetRepeatedString(
1206 Message* message, const FieldDescriptor* field,
1207 int index, const string& value) const {
1208 USAGE_CHECK_ALL(SetRepeatedString, REPEATED, STRING);
1209 if (field->is_extension()) {
1210 MutableExtensionSet(message)->SetRepeatedString(
1211 field->number(), index, value);
1212 } else {
1213 switch (field->options().ctype()) {
1214 default: // TODO(kenton): Support other string reps.
1215 case FieldOptions::STRING:
1216 *MutableRepeatedField<string>(message, field, index) = value;
1217 break;
1218 }
1219 }
1220}
1221
1222
1223void GeneratedMessageReflection::AddString(
1224 Message* message, const FieldDescriptor* field,
1225 const string& value) const {
1226 USAGE_CHECK_ALL(AddString, REPEATED, STRING);
1227 if (field->is_extension()) {
1228 MutableExtensionSet(message)->AddString(field->number(),
1229 field->type(), value, field);
1230 } else {
1231 switch (field->options().ctype()) {
1232 default: // TODO(kenton): Support other string reps.
1233 case FieldOptions::STRING:
1234 *AddField<string>(message, field) = value;
1235 break;
1236 }
1237 }
1238}
1239
1240
1241// -------------------------------------------------------------------
1242
1243inline bool CreateUnknownEnumValues(const FileDescriptor* file) {
1244 return file->syntax() == FileDescriptor::SYNTAX_PROTO3;
1245}
1246
1247const EnumValueDescriptor* GeneratedMessageReflection::GetEnum(
1248 const Message& message, const FieldDescriptor* field) const {
1249 // Usage checked by GetEnumValue.
1250 int value = GetEnumValue(message, field);
1251 return field->enum_type()->FindValueByNumberCreatingIfUnknown(value);
1252}
1253
1254int GeneratedMessageReflection::GetEnumValue(
1255 const Message& message, const FieldDescriptor* field) const {
1256 USAGE_CHECK_ALL(GetEnumValue, SINGULAR, ENUM);
1257
1258 int32 value;
1259 if (field->is_extension()) {
1260 value = GetExtensionSet(message).GetEnum(
1261 field->number(), field->default_value_enum()->number());
1262 } else {
1263 value = GetField<int>(message, field);
1264 }
1265 return value;
1266}
1267
1268void GeneratedMessageReflection::SetEnum(
1269 Message* message, const FieldDescriptor* field,
1270 const EnumValueDescriptor* value) const {
1271 // Usage checked by SetEnumValue.
1272 USAGE_CHECK_ENUM_VALUE(SetEnum);
1273 SetEnumValueInternal(message, field, value->number());
1274}
1275
1276void GeneratedMessageReflection::SetEnumValue(
1277 Message* message, const FieldDescriptor* field,
1278 int value) const {
1279 USAGE_CHECK_ALL(SetEnumValue, SINGULAR, ENUM);
1280 if (!CreateUnknownEnumValues(descriptor_->file())) {
1281 // Check that the value is valid if we don't support direct storage of
1282 // unknown enum values.
1283 const EnumValueDescriptor* value_desc =
1284 field->enum_type()->FindValueByNumber(value);
1285 if (value_desc == NULL) {
1286 GOOGLE_LOG(DFATAL) << "SetEnumValue accepts only valid integer values: value "
1287 << value << " unexpected for field " << field->full_name();
1288 // In production builds, DFATAL will not terminate the program, so we have
1289 // to do something reasonable: just set the default value.
1290 value = field->default_value_enum()->number();
1291 }
1292 }
1293 SetEnumValueInternal(message, field, value);
1294}
1295
1296void GeneratedMessageReflection::SetEnumValueInternal(
1297 Message* message, const FieldDescriptor* field,
1298 int value) const {
1299 if (field->is_extension()) {
1300 MutableExtensionSet(message)->SetEnum(field->number(), field->type(),
1301 value, field);
1302 } else {
1303 SetField<int>(message, field, value);
1304 }
1305}
1306
1307const EnumValueDescriptor* GeneratedMessageReflection::GetRepeatedEnum(
1308 const Message& message, const FieldDescriptor* field, int index) const {
1309 // Usage checked by GetRepeatedEnumValue.
1310 int value = GetRepeatedEnumValue(message, field, index);
1311 return field->enum_type()->FindValueByNumberCreatingIfUnknown(value);
1312}
1313
1314int GeneratedMessageReflection::GetRepeatedEnumValue(
1315 const Message& message, const FieldDescriptor* field, int index) const {
1316 USAGE_CHECK_ALL(GetRepeatedEnumValue, REPEATED, ENUM);
1317
1318 int value;
1319 if (field->is_extension()) {
1320 value = GetExtensionSet(message).GetRepeatedEnum(field->number(), index);
1321 } else {
1322 value = GetRepeatedField<int>(message, field, index);
1323 }
1324 return value;
1325}
1326
1327void GeneratedMessageReflection::SetRepeatedEnum(
1328 Message* message,
1329 const FieldDescriptor* field, int index,
1330 const EnumValueDescriptor* value) const {
1331 // Usage checked by SetRepeatedEnumValue.
1332 USAGE_CHECK_ENUM_VALUE(SetRepeatedEnum);
1333 SetRepeatedEnumValueInternal(message, field, index, value->number());
1334}
1335
1336void GeneratedMessageReflection::SetRepeatedEnumValue(
1337 Message* message,
1338 const FieldDescriptor* field, int index,
1339 int value) const {
1340 USAGE_CHECK_ALL(SetRepeatedEnum, REPEATED, ENUM);
1341 if (!CreateUnknownEnumValues(descriptor_->file())) {
1342 // Check that the value is valid if we don't support direct storage of
1343 // unknown enum values.
1344 const EnumValueDescriptor* value_desc =
1345 field->enum_type()->FindValueByNumber(value);
1346 if (value_desc == NULL) {
1347 GOOGLE_LOG(DFATAL) << "SetRepeatedEnumValue accepts only valid integer values: "
1348 << "value " << value << " unexpected for field "
1349 << field->full_name();
1350 // In production builds, DFATAL will not terminate the program, so we have
1351 // to do something reasonable: just set the default value.
1352 value = field->default_value_enum()->number();
1353 }
1354 }
1355 SetRepeatedEnumValueInternal(message, field, index, value);
1356}
1357
1358void GeneratedMessageReflection::SetRepeatedEnumValueInternal(
1359 Message* message,
1360 const FieldDescriptor* field, int index,
1361 int value) const {
1362 if (field->is_extension()) {
1363 MutableExtensionSet(message)->SetRepeatedEnum(
1364 field->number(), index, value);
1365 } else {
1366 SetRepeatedField<int>(message, field, index, value);
1367 }
1368}
1369
1370void GeneratedMessageReflection::AddEnum(
1371 Message* message, const FieldDescriptor* field,
1372 const EnumValueDescriptor* value) const {
1373 // Usage checked by AddEnumValue.
1374 USAGE_CHECK_ENUM_VALUE(AddEnum);
1375 AddEnumValueInternal(message, field, value->number());
1376}
1377
1378void GeneratedMessageReflection::AddEnumValue(
1379 Message* message, const FieldDescriptor* field,
1380 int value) const {
1381 USAGE_CHECK_ALL(AddEnum, REPEATED, ENUM);
1382 if (!CreateUnknownEnumValues(descriptor_->file())) {
1383 // Check that the value is valid if we don't support direct storage of
1384 // unknown enum values.
1385 const EnumValueDescriptor* value_desc =
1386 field->enum_type()->FindValueByNumber(value);
1387 if (value_desc == NULL) {
1388 GOOGLE_LOG(DFATAL) << "AddEnumValue accepts only valid integer values: value "
1389 << value << " unexpected for field " << field->full_name();
1390 // In production builds, DFATAL will not terminate the program, so we have
1391 // to do something reasonable: just set the default value.
1392 value = field->default_value_enum()->number();
1393 }
1394 }
1395 AddEnumValueInternal(message, field, value);
1396}
1397
1398void GeneratedMessageReflection::AddEnumValueInternal(
1399 Message* message, const FieldDescriptor* field,
1400 int value) const {
1401 if (field->is_extension()) {
1402 MutableExtensionSet(message)->AddEnum(field->number(), field->type(),
1403 field->options().packed(),
1404 value, field);
1405 } else {
1406 AddField<int>(message, field, value);
1407 }
1408}
1409
1410// -------------------------------------------------------------------
1411
1412const Message& GeneratedMessageReflection::GetMessage(
1413 const Message& message, const FieldDescriptor* field,
1414 MessageFactory* factory) const {
1415 USAGE_CHECK_ALL(GetMessage, SINGULAR, MESSAGE);
1416
1417 if (factory == NULL) factory = message_factory_;
1418
1419 if (field->is_extension()) {
1420 return static_cast<const Message&>(
1421 GetExtensionSet(message).GetMessage(
1422 field->number(), field->message_type(), factory));
1423 } else {
1424 const Message* result;
1425 result = GetRaw<const Message*>(message, field);
1426 if (result == NULL) {
1427 result = DefaultRaw<const Message*>(field);
1428 }
1429 return *result;
1430 }
1431}
1432
1433Message* GeneratedMessageReflection::MutableMessage(
1434 Message* message, const FieldDescriptor* field,
1435 MessageFactory* factory) const {
1436 USAGE_CHECK_ALL(MutableMessage, SINGULAR, MESSAGE);
1437
1438 if (factory == NULL) factory = message_factory_;
1439
1440 if (field->is_extension()) {
1441 return static_cast<Message*>(
1442 MutableExtensionSet(message)->MutableMessage(field, factory));
1443 } else {
1444 Message* result;
1445 Message** result_holder = MutableRaw<Message*>(message, field);
1446
1447 if (field->containing_oneof()) {
1448 if (!HasOneofField(*message, field)) {
1449 ClearOneof(message, field->containing_oneof());
1450 result_holder = MutableField<Message*>(message, field);
1451 const Message* default_message = DefaultRaw<const Message*>(field);
1452 *result_holder = default_message->New(message->GetArena());
1453 }
1454 } else {
1455 SetBit(message, field);
1456 }
1457
1458 if (*result_holder == NULL) {
1459 const Message* default_message = DefaultRaw<const Message*>(field);
1460 *result_holder = default_message->New(message->GetArena());
1461 }
1462 result = *result_holder;
1463 return result;
1464 }
1465}
1466
1467void GeneratedMessageReflection::UnsafeArenaSetAllocatedMessage(
1468 Message* message,
1469 Message* sub_message,
1470 const FieldDescriptor* field) const {
1471 USAGE_CHECK_ALL(SetAllocatedMessage, SINGULAR, MESSAGE);
1472
1473 if (field->is_extension()) {
1474 MutableExtensionSet(message)->SetAllocatedMessage(
1475 field->number(), field->type(), field, sub_message);
1476 } else {
1477 if (field->containing_oneof()) {
1478 if (sub_message == NULL) {
1479 ClearOneof(message, field->containing_oneof());
1480 return;
1481 }
1482 ClearOneof(message, field->containing_oneof());
1483 *MutableRaw<Message*>(message, field) = sub_message;
1484 SetOneofCase(message, field);
1485 return;
1486 }
1487
1488 if (sub_message == NULL) {
1489 ClearBit(message, field);
1490 } else {
1491 SetBit(message, field);
1492 }
1493 Message** sub_message_holder = MutableRaw<Message*>(message, field);
1494 if (GetArena(message) == NULL) {
1495 delete *sub_message_holder;
1496 }
1497 *sub_message_holder = sub_message;
1498 }
1499}
1500
1501void GeneratedMessageReflection::SetAllocatedMessage(
1502 Message* message,
1503 Message* sub_message,
1504 const FieldDescriptor* field) const {
1505 // If message and sub-message are in different memory ownership domains
1506 // (different arenas, or one is on heap and one is not), then we may need to
1507 // do a copy.
1508 if (sub_message != NULL &&
1509 sub_message->GetArena() != message->GetArena()) {
1510 if (sub_message->GetArena() == NULL && message->GetArena() != NULL) {
1511 // Case 1: parent is on an arena and child is heap-allocated. We can add
1512 // the child to the arena's Own() list to free on arena destruction, then
1513 // set our pointer.
1514 message->GetArena()->Own(sub_message);
1515 UnsafeArenaSetAllocatedMessage(message, sub_message, field);
1516 } else {
1517 // Case 2: all other cases. We need to make a copy. MutableMessage() will
1518 // either get the existing message object, or instantiate a new one as
1519 // appropriate w.r.t. our arena.
1520 Message* sub_message_copy = MutableMessage(message, field);
1521 sub_message_copy->CopyFrom(*sub_message);
1522 }
1523 } else {
1524 // Same memory ownership domains.
1525 UnsafeArenaSetAllocatedMessage(message, sub_message, field);
1526 }
1527}
1528
1529Message* GeneratedMessageReflection::UnsafeArenaReleaseMessage(
1530 Message* message,
1531 const FieldDescriptor* field,
1532 MessageFactory* factory) const {
1533 USAGE_CHECK_ALL(ReleaseMessage, SINGULAR, MESSAGE);
1534
1535 if (factory == NULL) factory = message_factory_;
1536
1537 if (field->is_extension()) {
1538 return static_cast<Message*>(
1539 MutableExtensionSet(message)->ReleaseMessage(field, factory));
1540 } else {
1541 ClearBit(message, field);
1542 if (field->containing_oneof()) {
1543 if (HasOneofField(*message, field)) {
1544 *MutableOneofCase(message, field->containing_oneof()) = 0;
1545 } else {
1546 return NULL;
1547 }
1548 }
1549 Message** result = MutableRaw<Message*>(message, field);
1550 Message* ret = *result;
1551 *result = NULL;
1552 return ret;
1553 }
1554}
1555
1556Message* GeneratedMessageReflection::ReleaseMessage(
1557 Message* message,
1558 const FieldDescriptor* field,
1559 MessageFactory* factory) const {
1560 Message* released = UnsafeArenaReleaseMessage(message, field, factory);
1561 if (GetArena(message) != NULL && released != NULL) {
1562 Message* copy_from_arena = released->New();
1563 copy_from_arena->CopyFrom(*released);
1564 released = copy_from_arena;
1565 }
1566 return released;
1567}
1568
1569const Message& GeneratedMessageReflection::GetRepeatedMessage(
1570 const Message& message, const FieldDescriptor* field, int index) const {
1571 USAGE_CHECK_ALL(GetRepeatedMessage, REPEATED, MESSAGE);
1572
1573 if (field->is_extension()) {
1574 return static_cast<const Message&>(
1575 GetExtensionSet(message).GetRepeatedMessage(field->number(), index));
1576 } else {
1577 if (IsMapFieldInApi(field)) {
1578 return GetRaw<MapFieldBase>(message, field)
1579 .GetRepeatedField()
1580 .Get<GenericTypeHandler<Message> >(index);
1581 } else {
1582 return GetRaw<RepeatedPtrFieldBase>(message, field)
1583 .Get<GenericTypeHandler<Message> >(index);
1584 }
1585 }
1586}
1587
1588Message* GeneratedMessageReflection::MutableRepeatedMessage(
1589 Message* message, const FieldDescriptor* field, int index) const {
1590 USAGE_CHECK_ALL(MutableRepeatedMessage, REPEATED, MESSAGE);
1591
1592 if (field->is_extension()) {
1593 return static_cast<Message*>(
1594 MutableExtensionSet(message)->MutableRepeatedMessage(
1595 field->number(), index));
1596 } else {
1597 if (IsMapFieldInApi(field)) {
1598 return MutableRaw<MapFieldBase>(message, field)
1599 ->MutableRepeatedField()
1600 ->Mutable<GenericTypeHandler<Message> >(index);
1601 } else {
1602 return MutableRaw<RepeatedPtrFieldBase>(message, field)
1603 ->Mutable<GenericTypeHandler<Message> >(index);
1604 }
1605 }
1606}
1607
1608Message* GeneratedMessageReflection::AddMessage(
1609 Message* message, const FieldDescriptor* field,
1610 MessageFactory* factory) const {
1611 USAGE_CHECK_ALL(AddMessage, REPEATED, MESSAGE);
1612
1613 if (factory == NULL) factory = message_factory_;
1614
1615 if (field->is_extension()) {
1616 return static_cast<Message*>(
1617 MutableExtensionSet(message)->AddMessage(field, factory));
1618 } else {
1619 Message* result = NULL;
1620
1621 // We can't use AddField<Message>() because RepeatedPtrFieldBase doesn't
1622 // know how to allocate one.
1623 RepeatedPtrFieldBase* repeated = NULL;
1624 if (IsMapFieldInApi(field)) {
1625 repeated =
1626 MutableRaw<MapFieldBase>(message, field)->MutableRepeatedField();
1627 } else {
1628 repeated = MutableRaw<RepeatedPtrFieldBase>(message, field);
1629 }
1630 result = repeated->AddFromCleared<GenericTypeHandler<Message> >();
1631 if (result == NULL) {
1632 // We must allocate a new object.
1633 const Message* prototype;
1634 if (repeated->size() == 0) {
1635 prototype = factory->GetPrototype(field->message_type());
1636 } else {
1637 prototype = &repeated->Get<GenericTypeHandler<Message> >(0);
1638 }
1639 result = prototype->New(message->GetArena());
1640 // We can guarantee here that repeated and result are either both heap
1641 // allocated or arena owned. So it is safe to call the unsafe version
1642 // of AddAllocated.
1643 repeated->UnsafeArenaAddAllocated<GenericTypeHandler<Message> >(result);
1644 }
1645
1646 return result;
1647 }
1648}
1649
1650void GeneratedMessageReflection::AddAllocatedMessage(
1651 Message* message, const FieldDescriptor* field,
1652 Message* new_entry) const {
1653 USAGE_CHECK_ALL(AddAllocatedMessage, REPEATED, MESSAGE);
1654
1655 if (field->is_extension()) {
1656 MutableExtensionSet(message)->AddAllocatedMessage(field, new_entry);
1657 } else {
1658 RepeatedPtrFieldBase* repeated = NULL;
1659 if (IsMapFieldInApi(field)) {
1660 repeated =
1661 MutableRaw<MapFieldBase>(message, field)->MutableRepeatedField();
1662 } else {
1663 repeated = MutableRaw<RepeatedPtrFieldBase>(message, field);
1664 }
1665 repeated->AddAllocated<GenericTypeHandler<Message> >(new_entry);
1666 }
1667}
1668
1669void* GeneratedMessageReflection::MutableRawRepeatedField(
1670 Message* message, const FieldDescriptor* field,
1671 FieldDescriptor::CppType cpptype,
1672 int ctype, const Descriptor* desc) const {
1673 USAGE_CHECK_REPEATED("MutableRawRepeatedField");
1674 if (field->cpp_type() != cpptype)
1675 ReportReflectionUsageTypeError(descriptor_,
1676 field, "MutableRawRepeatedField", cpptype);
1677 if (ctype >= 0)
1678 GOOGLE_CHECK_EQ(field->options().ctype(), ctype) << "subtype mismatch";
1679 if (desc != NULL)
1680 GOOGLE_CHECK_EQ(field->message_type(), desc) << "wrong submessage type";
1681 if (field->is_extension()) {
1682 return MutableExtensionSet(message)->MutableRawRepeatedField(
1683 field->number(), field->type(), field->is_packed(), field);
1684 } else {
1685 // Trigger transform for MapField
1686 if (IsMapFieldInApi(field)) {
1687 return reinterpret_cast<MapFieldBase*>(reinterpret_cast<uint8*>(message) +
1688 offsets_[field->index()])
1689 ->MutableRepeatedField();
1690 }
1691 return reinterpret_cast<uint8*>(message) + offsets_[field->index()];
1692 }
1693}
1694
1695const void* GeneratedMessageReflection::GetRawRepeatedField(
1696 const Message& message, const FieldDescriptor* field,
1697 FieldDescriptor::CppType cpptype,
1698 int ctype, const Descriptor* desc) const {
1699 USAGE_CHECK_REPEATED("GetRawRepeatedField");
1700 if (field->cpp_type() != cpptype)
1701 ReportReflectionUsageTypeError(descriptor_,
1702 field, "GetRawRepeatedField", cpptype);
1703 if (ctype >= 0)
1704 GOOGLE_CHECK_EQ(field->options().ctype(), ctype) << "subtype mismatch";
1705 if (desc != NULL)
1706 GOOGLE_CHECK_EQ(field->message_type(), desc) << "wrong submessage type";
1707 if (field->is_extension()) {
1708 // Should use extension_set::GetRawRepeatedField. However, the required
1709 // parameter "default repeated value" is not very easy to get here.
1710 // Map is not supported in extensions, it is acceptable to use
1711 // extension_set::MutableRawRepeatedField which does not change the message.
1712 return MutableExtensionSet(const_cast<Message*>(&message))
1713 ->MutableRawRepeatedField(
1714 field->number(), field->type(), field->is_packed(), field);
1715 } else {
1716 // Trigger transform for MapField
1717 if (IsMapFieldInApi(field)) {
1718 return &(reinterpret_cast<const MapFieldBase*>(
1719 reinterpret_cast<const uint8*>(&message) +
1720 offsets_[field->index()])->GetRepeatedField());
1721 }
1722 return reinterpret_cast<const uint8*>(&message) + offsets_[field->index()];
1723 }
1724}
1725
1726const FieldDescriptor* GeneratedMessageReflection::GetOneofFieldDescriptor(
1727 const Message& message,
1728 const OneofDescriptor* oneof_descriptor) const {
1729 uint32 field_number = GetOneofCase(message, oneof_descriptor);
1730 if (field_number == 0) {
1731 return NULL;
1732 }
1733 return descriptor_->FindFieldByNumber(field_number);
1734}
1735
1736bool GeneratedMessageReflection::ContainsMapKey(
1737 const Message& message,
1738 const FieldDescriptor* field,
1739 const MapKey& key) const {
1740 USAGE_CHECK(IsMapFieldInApi(field),
1741 "LookupMapValue",
1742 "Field is not a map field.");
1743 return GetRaw<MapFieldBase>(message, field).ContainsMapKey(key);
1744}
1745
1746bool GeneratedMessageReflection::InsertOrLookupMapValue(
1747 Message* message,
1748 const FieldDescriptor* field,
1749 const MapKey& key,
1750 MapValueRef* val) const {
1751 USAGE_CHECK(IsMapFieldInApi(field),
1752 "InsertOrLookupMapValue",
1753 "Field is not a map field.");
1754 val->SetType(field->message_type()->FindFieldByName("value")->cpp_type());
1755 return MutableRaw<MapFieldBase>(message, field)->InsertMapValue(key, val);
1756}
1757
1758bool GeneratedMessageReflection::DeleteMapValue(
1759 Message* message,
1760 const FieldDescriptor* field,
1761 const MapKey& key) const {
1762 USAGE_CHECK(IsMapFieldInApi(field),
1763 "DeleteMapValue",
1764 "Field is not a map field.");
1765 return MutableRaw<MapFieldBase>(message, field)->DeleteMapValue(key);
1766}
1767
1768MapIterator GeneratedMessageReflection::MapBegin(
1769 Message* message,
1770 const FieldDescriptor* field) const {
1771 USAGE_CHECK(IsMapFieldInApi(field),
1772 "MapBegin",
1773 "Field is not a map field.");
1774 MapIterator iter(message, field);
1775 GetRaw<MapFieldBase>(*message, field).MapBegin(&iter);
1776 return iter;
1777}
1778
1779MapIterator GeneratedMessageReflection::MapEnd(
1780 Message* message,
1781 const FieldDescriptor* field) const {
1782 USAGE_CHECK(IsMapFieldInApi(field),
1783 "MapEnd",
1784 "Field is not a map field.");
1785 MapIterator iter(message, field);
1786 GetRaw<MapFieldBase>(*message, field).MapEnd(&iter);
1787 return iter;
1788}
1789
1790int GeneratedMessageReflection::MapSize(
1791 const Message& message,
1792 const FieldDescriptor* field) const {
1793 USAGE_CHECK(IsMapFieldInApi(field),
1794 "MapSize",
1795 "Field is not a map field.");
1796 return GetRaw<MapFieldBase>(message, field).size();
1797}
1798
1799// -----------------------------------------------------------------------------
1800
1801const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByName(
1802 const string& name) const {
1803 if (extensions_offset_ == -1) return NULL;
1804
1805 const FieldDescriptor* result = descriptor_pool_->FindExtensionByName(name);
1806 if (result != NULL && result->containing_type() == descriptor_) {
1807 return result;
1808 }
1809
1810 if (descriptor_->options().message_set_wire_format()) {
1811 // MessageSet extensions may be identified by type name.
1812 const Descriptor* type = descriptor_pool_->FindMessageTypeByName(name);
1813 if (type != NULL) {
1814 // Look for a matching extension in the foreign type's scope.
1815 for (int i = 0; i < type->extension_count(); i++) {
1816 const FieldDescriptor* extension = type->extension(i);
1817 if (extension->containing_type() == descriptor_ &&
1818 extension->type() == FieldDescriptor::TYPE_MESSAGE &&
1819 extension->is_optional() &&
1820 extension->message_type() == type) {
1821 // Found it.
1822 return extension;
1823 }
1824 }
1825 }
1826 }
1827
1828 return NULL;
1829}
1830
1831const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByNumber(
1832 int number) const {
1833 if (extensions_offset_ == -1) return NULL;
1834 return descriptor_pool_->FindExtensionByNumber(descriptor_, number);
1835}
1836
1837bool GeneratedMessageReflection::SupportsUnknownEnumValues() const {
1838 return CreateUnknownEnumValues(descriptor_->file());
1839}
1840
1841// ===================================================================
1842// Some private helpers.
1843
1844// These simple template accessors obtain pointers (or references) to
1845// the given field.
1846template <typename Type>
1847inline const Type& GeneratedMessageReflection::GetRaw(
1848 const Message& message, const FieldDescriptor* field) const {
1849 if (field->containing_oneof() && !HasOneofField(message, field)) {
1850 return DefaultRaw<Type>(field);
1851 }
1852 int index = field->containing_oneof() ?
1853 descriptor_->field_count() + field->containing_oneof()->index() :
1854 field->index();
1855 const void* ptr = reinterpret_cast<const uint8*>(&message) +
1856 offsets_[index];
1857 return *reinterpret_cast<const Type*>(ptr);
1858}
1859
1860template <typename Type>
1861inline Type* GeneratedMessageReflection::MutableRaw(
1862 Message* message, const FieldDescriptor* field) const {
1863 int index = field->containing_oneof() ?
1864 descriptor_->field_count() + field->containing_oneof()->index() :
1865 field->index();
1866 void* ptr = reinterpret_cast<uint8*>(message) + offsets_[index];
1867 return reinterpret_cast<Type*>(ptr);
1868}
1869
1870template <typename Type>
1871inline const Type& GeneratedMessageReflection::DefaultRaw(
1872 const FieldDescriptor* field) const {
1873 const void* ptr = field->containing_oneof() ?
1874 reinterpret_cast<const uint8*>(default_oneof_instance_) +
1875 offsets_[field->index()] :
1876 reinterpret_cast<const uint8*>(default_instance_) +
1877 offsets_[field->index()];
1878 return *reinterpret_cast<const Type*>(ptr);
1879}
1880
1881inline const uint32* GeneratedMessageReflection::GetHasBits(
1882 const Message& message) const {
1883 if (has_bits_offset_ == -1) { // proto3 with no has-bits.
1884 return NULL;
1885 }
1886 const void* ptr = reinterpret_cast<const uint8*>(&message) + has_bits_offset_;
1887 return reinterpret_cast<const uint32*>(ptr);
1888}
1889inline uint32* GeneratedMessageReflection::MutableHasBits(
1890 Message* message) const {
1891 if (has_bits_offset_ == -1) {
1892 return NULL;
1893 }
1894 void* ptr = reinterpret_cast<uint8*>(message) + has_bits_offset_;
1895 return reinterpret_cast<uint32*>(ptr);
1896}
1897
1898inline uint32 GeneratedMessageReflection::GetOneofCase(
1899 const Message& message,
1900 const OneofDescriptor* oneof_descriptor) const {
1901 const void* ptr = reinterpret_cast<const uint8*>(&message)
1902 + oneof_case_offset_;
1903 return reinterpret_cast<const uint32*>(ptr)[oneof_descriptor->index()];
1904}
1905
1906inline uint32* GeneratedMessageReflection::MutableOneofCase(
1907 Message* message,
1908 const OneofDescriptor* oneof_descriptor) const {
1909 void* ptr = reinterpret_cast<uint8*>(message) + oneof_case_offset_;
1910 return &(reinterpret_cast<uint32*>(ptr)[oneof_descriptor->index()]);
1911}
1912
1913inline const ExtensionSet& GeneratedMessageReflection::GetExtensionSet(
1914 const Message& message) const {
1915 GOOGLE_DCHECK_NE(extensions_offset_, -1);
1916 const void* ptr = reinterpret_cast<const uint8*>(&message) +
1917 extensions_offset_;
1918 return *reinterpret_cast<const ExtensionSet*>(ptr);
1919}
1920inline ExtensionSet* GeneratedMessageReflection::MutableExtensionSet(
1921 Message* message) const {
1922 GOOGLE_DCHECK_NE(extensions_offset_, -1);
1923 void* ptr = reinterpret_cast<uint8*>(message) + extensions_offset_;
1924 return reinterpret_cast<ExtensionSet*>(ptr);
1925}
1926
1927inline Arena* GeneratedMessageReflection::GetArena(Message* message) const {
1928 if (arena_offset_ == kNoArenaPointer) {
1929 return NULL;
1930 }
1931
1932 if (unknown_fields_offset_ == kUnknownFieldSetInMetadata) {
1933 // zero-overhead arena pointer overloading UnknownFields
1934 return GetInternalMetadataWithArena(*message).arena();
1935 }
1936
1937 // Baseline case: message class has a dedicated arena pointer.
1938 void* ptr = reinterpret_cast<uint8*>(message) + arena_offset_;
1939 return *reinterpret_cast<Arena**>(ptr);
1940}
1941
1942inline const InternalMetadataWithArena&
1943GeneratedMessageReflection::GetInternalMetadataWithArena(
1944 const Message& message) const {
1945 const void* ptr = reinterpret_cast<const uint8*>(&message) + arena_offset_;
1946 return *reinterpret_cast<const InternalMetadataWithArena*>(ptr);
1947}
1948
1949inline InternalMetadataWithArena*
1950GeneratedMessageReflection::MutableInternalMetadataWithArena(
1951 Message* message) const {
1952 void* ptr = reinterpret_cast<uint8*>(message) + arena_offset_;
1953 return reinterpret_cast<InternalMetadataWithArena*>(ptr);
1954}
1955
1956inline bool
1957GeneratedMessageReflection::GetIsDefaultInstance(
1958 const Message& message) const {
1959 if (is_default_instance_offset_ == kHasNoDefaultInstanceField) {
1960 return false;
1961 }
1962 const void* ptr = reinterpret_cast<const uint8*>(&message) +
1963 is_default_instance_offset_;
1964 return *reinterpret_cast<const bool*>(ptr);
1965}
1966
1967// Simple accessors for manipulating has_bits_.
1968inline bool GeneratedMessageReflection::HasBit(
1969 const Message& message, const FieldDescriptor* field) const {
1970 if (has_bits_offset_ == -1) {
1971 // proto3: no has-bits. All fields present except messages, which are
1972 // present only if their message-field pointer is non-NULL.
1973 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
1974 return !GetIsDefaultInstance(message) &&
1975 GetRaw<const Message*>(message, field) != NULL;
1976 } else {
1977 // Non-message field (and non-oneof, since that was handled in HasField()
1978 // before calling us), and singular (again, checked in HasField). So, this
1979 // field must be a scalar.
1980
1981 // Scalar primitive (numeric or string/bytes) fields are present if
1982 // their value is non-zero (numeric) or non-empty (string/bytes). N.B.:
1983 // we must use this definition here, rather than the "scalar fields
1984 // always present" in the proto3 docs, because MergeFrom() semantics
1985 // require presence as "present on wire", and reflection-based merge
1986 // (which uses HasField()) needs to be consistent with this.
1987 switch (field->cpp_type()) {
1988 case FieldDescriptor::CPPTYPE_STRING:
1989 switch (field->options().ctype()) {
1990 default: {
1991 const string* default_ptr =
1992 &DefaultRaw<ArenaStringPtr>(field).Get(NULL);
1993 return GetField<ArenaStringPtr>(message, field).Get(
1994 default_ptr).size() > 0;
1995 }
1996 }
1997 return false;
1998 case FieldDescriptor::CPPTYPE_BOOL:
1999 return GetRaw<bool>(message, field) != false;
2000 case FieldDescriptor::CPPTYPE_INT32:
2001 return GetRaw<int32>(message, field) != 0;
2002 case FieldDescriptor::CPPTYPE_INT64:
2003 return GetRaw<int64>(message, field) != 0;
2004 case FieldDescriptor::CPPTYPE_UINT32:
2005 return GetRaw<uint32>(message, field) != 0;
2006 case FieldDescriptor::CPPTYPE_UINT64:
2007 return GetRaw<uint64>(message, field) != 0;
2008 case FieldDescriptor::CPPTYPE_FLOAT:
2009 return GetRaw<float>(message, field) != 0.0;
2010 case FieldDescriptor::CPPTYPE_DOUBLE:
2011 return GetRaw<double>(message, field) != 0.0;
2012 case FieldDescriptor::CPPTYPE_ENUM:
2013 return GetRaw<int>(message, field) != 0;
2014 case FieldDescriptor::CPPTYPE_MESSAGE:
2015 // handled above; avoid warning
2016 GOOGLE_LOG(FATAL) << "Reached impossible case in HasBit().";
2017 break;
2018 }
2019 }
2020 }
2021 return GetHasBits(message)[field->index() / 32] &
2022 (1 << (field->index() % 32));
2023}
2024
2025inline void GeneratedMessageReflection::SetBit(
2026 Message* message, const FieldDescriptor* field) const {
2027 if (has_bits_offset_ == -1) {
2028 return;
2029 }
2030 MutableHasBits(message)[field->index() / 32] |= (1 << (field->index() % 32));
2031}
2032
2033inline void GeneratedMessageReflection::ClearBit(
2034 Message* message, const FieldDescriptor* field) const {
2035 if (has_bits_offset_ == -1) {
2036 return;
2037 }
2038 MutableHasBits(message)[field->index() / 32] &= ~(1 << (field->index() % 32));
2039}
2040
2041inline void GeneratedMessageReflection::SwapBit(
2042 Message* message1, Message* message2, const FieldDescriptor* field) const {
2043 if (has_bits_offset_ == -1) {
2044 return;
2045 }
2046 bool temp_has_bit = HasBit(*message1, field);
2047 if (HasBit(*message2, field)) {
2048 SetBit(message1, field);
2049 } else {
2050 ClearBit(message1, field);
2051 }
2052 if (temp_has_bit) {
2053 SetBit(message2, field);
2054 } else {
2055 ClearBit(message2, field);
2056 }
2057}
2058
2059inline bool GeneratedMessageReflection::HasOneof(
2060 const Message& message, const OneofDescriptor* oneof_descriptor) const {
2061 return (GetOneofCase(message, oneof_descriptor) > 0);
2062}
2063
2064inline bool GeneratedMessageReflection::HasOneofField(
2065 const Message& message, const FieldDescriptor* field) const {
2066 return (GetOneofCase(message, field->containing_oneof()) == field->number());
2067}
2068
2069inline void GeneratedMessageReflection::SetOneofCase(
2070 Message* message, const FieldDescriptor* field) const {
2071 *MutableOneofCase(message, field->containing_oneof()) = field->number();
2072}
2073
2074inline void GeneratedMessageReflection::ClearOneofField(
2075 Message* message, const FieldDescriptor* field) const {
2076 if (HasOneofField(*message, field)) {
2077 ClearOneof(message, field->containing_oneof());
2078 }
2079}
2080
2081inline void GeneratedMessageReflection::ClearOneof(
2082 Message* message, const OneofDescriptor* oneof_descriptor) const {
2083 // TODO(jieluo): Consider to cache the unused object instead of deleting
2084 // it. It will be much faster if an aplication switches a lot from
2085 // a few oneof fields. Time/space tradeoff
2086 uint32 oneof_case = GetOneofCase(*message, oneof_descriptor);
2087 if (oneof_case > 0) {
2088 const FieldDescriptor* field = descriptor_->FindFieldByNumber(oneof_case);
2089 if (GetArena(message) == NULL) {
2090 switch (field->cpp_type()) {
2091 case FieldDescriptor::CPPTYPE_STRING: {
2092 switch (field->options().ctype()) {
2093 default: // TODO(kenton): Support other string reps.
2094 case FieldOptions::STRING: {
2095 const string* default_ptr =
2096 &DefaultRaw<ArenaStringPtr>(field).Get(NULL);
2097 MutableField<ArenaStringPtr>(message, field)->
2098 Destroy(default_ptr, GetArena(message));
2099 break;
2100 }
2101 }
2102 break;
2103 }
2104
2105 case FieldDescriptor::CPPTYPE_MESSAGE:
2106 delete *MutableRaw<Message*>(message, field);
2107 break;
2108 default:
2109 break;
2110 }
2111 }
2112
2113 *MutableOneofCase(message, oneof_descriptor) = 0;
2114 }
2115}
2116
2117// Template implementations of basic accessors. Inline because each
2118// template instance is only called from one location. These are
2119// used for all types except messages.
2120template <typename Type>
2121inline const Type& GeneratedMessageReflection::GetField(
2122 const Message& message, const FieldDescriptor* field) const {
2123 return GetRaw<Type>(message, field);
2124}
2125
2126template <typename Type>
2127inline void GeneratedMessageReflection::SetField(
2128 Message* message, const FieldDescriptor* field, const Type& value) const {
2129 if (field->containing_oneof() && !HasOneofField(*message, field)) {
2130 ClearOneof(message, field->containing_oneof());
2131 }
2132 *MutableRaw<Type>(message, field) = value;
2133 field->containing_oneof() ?
2134 SetOneofCase(message, field) : SetBit(message, field);
2135}
2136
2137template <typename Type>
2138inline Type* GeneratedMessageReflection::MutableField(
2139 Message* message, const FieldDescriptor* field) const {
2140 field->containing_oneof() ?
2141 SetOneofCase(message, field) : SetBit(message, field);
2142 return MutableRaw<Type>(message, field);
2143}
2144
2145template <typename Type>
2146inline const Type& GeneratedMessageReflection::GetRepeatedField(
2147 const Message& message, const FieldDescriptor* field, int index) const {
2148 return GetRaw<RepeatedField<Type> >(message, field).Get(index);
2149}
2150
2151template <typename Type>
2152inline const Type& GeneratedMessageReflection::GetRepeatedPtrField(
2153 const Message& message, const FieldDescriptor* field, int index) const {
2154 return GetRaw<RepeatedPtrField<Type> >(message, field).Get(index);
2155}
2156
2157template <typename Type>
2158inline void GeneratedMessageReflection::SetRepeatedField(
2159 Message* message, const FieldDescriptor* field,
2160 int index, Type value) const {
2161 MutableRaw<RepeatedField<Type> >(message, field)->Set(index, value);
2162}
2163
2164template <typename Type>
2165inline Type* GeneratedMessageReflection::MutableRepeatedField(
2166 Message* message, const FieldDescriptor* field, int index) const {
2167 RepeatedPtrField<Type>* repeated =
2168 MutableRaw<RepeatedPtrField<Type> >(message, field);
2169 return repeated->Mutable(index);
2170}
2171
2172template <typename Type>
2173inline void GeneratedMessageReflection::AddField(
2174 Message* message, const FieldDescriptor* field, const Type& value) const {
2175 MutableRaw<RepeatedField<Type> >(message, field)->Add(value);
2176}
2177
2178template <typename Type>
2179inline Type* GeneratedMessageReflection::AddField(
2180 Message* message, const FieldDescriptor* field) const {
2181 RepeatedPtrField<Type>* repeated =
2182 MutableRaw<RepeatedPtrField<Type> >(message, field);
2183 return repeated->Add();
2184}
2185
2186MessageFactory* GeneratedMessageReflection::GetMessageFactory() const {
2187 return message_factory_;
2188}
2189
2190void* GeneratedMessageReflection::RepeatedFieldData(
2191 Message* message, const FieldDescriptor* field,
2192 FieldDescriptor::CppType cpp_type,
2193 const Descriptor* message_type) const {
2194 GOOGLE_CHECK(field->is_repeated());
2195 GOOGLE_CHECK(field->cpp_type() == cpp_type ||
2196 (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM &&
2197 cpp_type == FieldDescriptor::CPPTYPE_INT32))
2198 << "The type parameter T in RepeatedFieldRef<T> API doesn't match "
2199 << "the actual field type (for enums T should be the generated enum "
2200 << "type or int32).";
2201 if (message_type != NULL) {
2202 GOOGLE_CHECK_EQ(message_type, field->message_type());
2203 }
2204 if (field->is_extension()) {
2205 return MutableExtensionSet(message)->MutableRawRepeatedField(
2206 field->number(), field->type(), field->is_packed(), field);
2207 } else {
2208 return reinterpret_cast<uint8*>(message) + offsets_[field->index()];
2209 }
2210}
2211
2212MapFieldBase* GeneratedMessageReflection::MapData(
2213 Message* message, const FieldDescriptor* field) const {
2214 USAGE_CHECK(IsMapFieldInApi(field),
2215 "GetMapData",
2216 "Field is not a map field.");
2217 return MutableRaw<MapFieldBase>(message, field);
2218}
2219
2220GeneratedMessageReflection*
2221GeneratedMessageReflection::NewGeneratedMessageReflection(
2222 const Descriptor* descriptor,
2223 const Message* default_instance,
2224 const int offsets[],
2225 int has_bits_offset,
2226 int unknown_fields_offset,
2227 int extensions_offset,
2228 const void* default_oneof_instance,
2229 int oneof_case_offset,
2230 int object_size,
2231 int arena_offset,
2232 int is_default_instance_offset) {
2233 return new GeneratedMessageReflection(descriptor,
2234 default_instance,
2235 offsets,
2236 has_bits_offset,
2237 unknown_fields_offset,
2238 extensions_offset,
2239 default_oneof_instance,
2240 oneof_case_offset,
2241 DescriptorPool::generated_pool(),
2242 MessageFactory::generated_factory(),
2243 object_size,
2244 arena_offset,
2245 is_default_instance_offset);
2246}
2247
2248GeneratedMessageReflection*
2249GeneratedMessageReflection::NewGeneratedMessageReflection(
2250 const Descriptor* descriptor,
2251 const Message* default_instance,
2252 const int offsets[],
2253 int has_bits_offset,
2254 int unknown_fields_offset,
2255 int extensions_offset,
2256 int object_size,
2257 int arena_offset,
2258 int is_default_instance_offset) {
2259 return new GeneratedMessageReflection(descriptor,
2260 default_instance,
2261 offsets,
2262 has_bits_offset,
2263 unknown_fields_offset,
2264 extensions_offset,
2265 DescriptorPool::generated_pool(),
2266 MessageFactory::generated_factory(),
2267 object_size,
2268 arena_offset,
2269 is_default_instance_offset);
2270}
2271
2272} // namespace internal
2273} // namespace protobuf
2274} // namespace google