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 <google/protobuf/generated_message_reflection.h>
36
37 #include <algorithm>
38 #include <set>
39
40 #include <google/protobuf/stubs/logging.h>
41 #include <google/protobuf/stubs/common.h>
42 #include <google/protobuf/descriptor.pb.h>
43 #include <google/protobuf/descriptor.h>
44 #include <google/protobuf/extension_set.h>
45 #include <google/protobuf/generated_message_util.h>
46 #include <google/protobuf/inlined_string_field.h>
47 #include <google/protobuf/map_field.h>
48 #include <google/protobuf/map_field_inl.h>
49 #include <google/protobuf/stubs/mutex.h>
50 #include <google/protobuf/repeated_field.h>
51 #include <google/protobuf/unknown_field_set.h>
52 #include <google/protobuf/wire_format.h>
53 #include <google/protobuf/stubs/strutil.h>
54
55
56 #include <google/protobuf/port_def.inc>
57
58 #define GOOGLE_PROTOBUF_HAS_ONEOF
59
60 using google::protobuf::internal::ArenaStringPtr;
61 using google::protobuf::internal::DescriptorTable;
62 using google::protobuf::internal::ExtensionSet;
63 using google::protobuf::internal::GenericTypeHandler;
64 using google::protobuf::internal::GetEmptyString;
65 using google::protobuf::internal::InlinedStringField;
66 using google::protobuf::internal::InternalMetadata;
67 using google::protobuf::internal::LazyField;
68 using google::protobuf::internal::MapFieldBase;
69 using google::protobuf::internal::MigrationSchema;
70 using google::protobuf::internal::OnShutdownDelete;
71 using google::protobuf::internal::ReflectionSchema;
72 using google::protobuf::internal::RepeatedPtrFieldBase;
73 using google::protobuf::internal::StringSpaceUsedExcludingSelfLong;
74 using google::protobuf::internal::WrappedMutex;
75
76 namespace google {
77 namespace protobuf {
78
79 namespace {
IsMapFieldInApi(const FieldDescriptor * field)80 bool IsMapFieldInApi(const FieldDescriptor* field) { return field->is_map(); }
81 } // anonymous namespace
82
83 namespace internal {
84
ParseNamedEnum(const EnumDescriptor * descriptor,ConstStringParam name,int * value)85 bool ParseNamedEnum(const EnumDescriptor* descriptor, ConstStringParam name,
86 int* value) {
87 const EnumValueDescriptor* d = descriptor->FindValueByName(name);
88 if (d == nullptr) return false;
89 *value = d->number();
90 return true;
91 }
92
NameOfEnum(const EnumDescriptor * descriptor,int value)93 const std::string& NameOfEnum(const EnumDescriptor* descriptor, int value) {
94 const EnumValueDescriptor* d = descriptor->FindValueByNumber(value);
95 return (d == nullptr ? GetEmptyString() : d->name());
96 }
97
98 } // namespace internal
99
100 // ===================================================================
101 // Helpers for reporting usage errors (e.g. trying to use GetInt32() on
102 // a string field).
103
104 namespace {
105
106 using internal::GetConstPointerAtOffset;
107 using internal::GetConstRefAtOffset;
108 using internal::GetPointerAtOffset;
109
ReportReflectionUsageError(const Descriptor * descriptor,const FieldDescriptor * field,const char * method,const char * description)110 void ReportReflectionUsageError(const Descriptor* descriptor,
111 const FieldDescriptor* field,
112 const char* method, const char* description) {
113 GOOGLE_LOG(FATAL) << "Protocol Buffer reflection usage error:\n"
114 " Method : google::protobuf::Reflection::"
115 << method
116 << "\n"
117 " Message type: "
118 << descriptor->full_name()
119 << "\n"
120 " Field : "
121 << field->full_name()
122 << "\n"
123 " Problem : "
124 << description;
125 }
126
127 const char* cpptype_names_[FieldDescriptor::MAX_CPPTYPE + 1] = {
128 "INVALID_CPPTYPE", "CPPTYPE_INT32", "CPPTYPE_INT64", "CPPTYPE_UINT32",
129 "CPPTYPE_UINT64", "CPPTYPE_DOUBLE", "CPPTYPE_FLOAT", "CPPTYPE_BOOL",
130 "CPPTYPE_ENUM", "CPPTYPE_STRING", "CPPTYPE_MESSAGE"};
131
ReportReflectionUsageTypeError(const Descriptor * descriptor,const FieldDescriptor * field,const char * method,FieldDescriptor::CppType expected_type)132 static void ReportReflectionUsageTypeError(
133 const Descriptor* descriptor, const FieldDescriptor* field,
134 const char* method, FieldDescriptor::CppType expected_type) {
135 GOOGLE_LOG(FATAL)
136 << "Protocol Buffer reflection usage error:\n"
137 " Method : google::protobuf::Reflection::"
138 << method
139 << "\n"
140 " Message type: "
141 << descriptor->full_name()
142 << "\n"
143 " Field : "
144 << field->full_name()
145 << "\n"
146 " Problem : Field is not the right type for this message:\n"
147 " Expected : "
148 << cpptype_names_[expected_type]
149 << "\n"
150 " Field type: "
151 << cpptype_names_[field->cpp_type()];
152 }
153
ReportReflectionUsageEnumTypeError(const Descriptor * descriptor,const FieldDescriptor * field,const char * method,const EnumValueDescriptor * value)154 static void ReportReflectionUsageEnumTypeError(
155 const Descriptor* descriptor, const FieldDescriptor* field,
156 const char* method, const EnumValueDescriptor* value) {
157 GOOGLE_LOG(FATAL) << "Protocol Buffer reflection usage error:\n"
158 " Method : google::protobuf::Reflection::"
159 << method
160 << "\n"
161 " Message type: "
162 << descriptor->full_name()
163 << "\n"
164 " Field : "
165 << field->full_name()
166 << "\n"
167 " Problem : Enum value did not match field type:\n"
168 " Expected : "
169 << field->enum_type()->full_name()
170 << "\n"
171 " Actual : "
172 << value->full_name();
173 }
174
CheckInvalidAccess(const internal::ReflectionSchema & schema,const FieldDescriptor * field)175 inline void CheckInvalidAccess(const internal::ReflectionSchema& schema,
176 const FieldDescriptor* field) {
177 GOOGLE_CHECK(!schema.IsFieldStripped(field))
178 << "invalid access to a stripped field " << field->full_name();
179 }
180
181 #define USAGE_CHECK(CONDITION, METHOD, ERROR_DESCRIPTION) \
182 if (!(CONDITION)) \
183 ReportReflectionUsageError(descriptor_, field, #METHOD, ERROR_DESCRIPTION)
184 #define USAGE_CHECK_EQ(A, B, METHOD, ERROR_DESCRIPTION) \
185 USAGE_CHECK((A) == (B), METHOD, ERROR_DESCRIPTION)
186 #define USAGE_CHECK_NE(A, B, METHOD, ERROR_DESCRIPTION) \
187 USAGE_CHECK((A) != (B), METHOD, ERROR_DESCRIPTION)
188
189 #define USAGE_CHECK_TYPE(METHOD, CPPTYPE) \
190 if (field->cpp_type() != FieldDescriptor::CPPTYPE_##CPPTYPE) \
191 ReportReflectionUsageTypeError(descriptor_, field, #METHOD, \
192 FieldDescriptor::CPPTYPE_##CPPTYPE)
193
194 #define USAGE_CHECK_ENUM_VALUE(METHOD) \
195 if (value->type() != field->enum_type()) \
196 ReportReflectionUsageEnumTypeError(descriptor_, field, #METHOD, value)
197
198 #define USAGE_CHECK_MESSAGE_TYPE(METHOD) \
199 USAGE_CHECK_EQ(field->containing_type(), descriptor_, METHOD, \
200 "Field does not match message type.");
201 #define USAGE_CHECK_SINGULAR(METHOD) \
202 USAGE_CHECK_NE(field->label(), FieldDescriptor::LABEL_REPEATED, METHOD, \
203 "Field is repeated; the method requires a singular field.")
204 #define USAGE_CHECK_REPEATED(METHOD) \
205 USAGE_CHECK_EQ(field->label(), FieldDescriptor::LABEL_REPEATED, METHOD, \
206 "Field is singular; the method requires a repeated field.")
207
208 #define USAGE_CHECK_ALL(METHOD, LABEL, CPPTYPE) \
209 USAGE_CHECK_MESSAGE_TYPE(METHOD); \
210 USAGE_CHECK_##LABEL(METHOD); \
211 USAGE_CHECK_TYPE(METHOD, CPPTYPE)
212
213 } // namespace
214
215 // ===================================================================
216
Reflection(const Descriptor * descriptor,const internal::ReflectionSchema & schema,const DescriptorPool * pool,MessageFactory * factory)217 Reflection::Reflection(const Descriptor* descriptor,
218 const internal::ReflectionSchema& schema,
219 const DescriptorPool* pool, MessageFactory* factory)
220 : descriptor_(descriptor),
221 schema_(schema),
222 descriptor_pool_(
223 (pool == nullptr) ? DescriptorPool::internal_generated_pool() : pool),
224 message_factory_(factory),
225 last_non_weak_field_index_(-1) {
226 last_non_weak_field_index_ = descriptor_->field_count() - 1;
227 }
228
GetUnknownFields(const Message & message) const229 const UnknownFieldSet& Reflection::GetUnknownFields(
230 const Message& message) const {
231 return GetInternalMetadata(message).unknown_fields<UnknownFieldSet>(
232 UnknownFieldSet::default_instance);
233 }
234
MutableUnknownFields(Message * message) const235 UnknownFieldSet* Reflection::MutableUnknownFields(Message* message) const {
236 return MutableInternalMetadata(message)
237 ->mutable_unknown_fields<UnknownFieldSet>();
238 }
239
SpaceUsedLong(const Message & message) const240 size_t Reflection::SpaceUsedLong(const Message& message) const {
241 // object_size_ already includes the in-memory representation of each field
242 // in the message, so we only need to account for additional memory used by
243 // the fields.
244 size_t total_size = schema_.GetObjectSize();
245
246 total_size += GetUnknownFields(message).SpaceUsedExcludingSelfLong();
247
248 if (schema_.HasExtensionSet()) {
249 total_size += GetExtensionSet(message).SpaceUsedExcludingSelfLong();
250 }
251 for (int i = 0; i <= last_non_weak_field_index_; i++) {
252 const FieldDescriptor* field = descriptor_->field(i);
253 if (field->is_repeated()) {
254 switch (field->cpp_type()) {
255 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
256 case FieldDescriptor::CPPTYPE_##UPPERCASE: \
257 total_size += GetRaw<RepeatedField<LOWERCASE> >(message, field) \
258 .SpaceUsedExcludingSelfLong(); \
259 break
260
261 HANDLE_TYPE(INT32, int32);
262 HANDLE_TYPE(INT64, int64);
263 HANDLE_TYPE(UINT32, uint32);
264 HANDLE_TYPE(UINT64, uint64);
265 HANDLE_TYPE(DOUBLE, double);
266 HANDLE_TYPE(FLOAT, float);
267 HANDLE_TYPE(BOOL, bool);
268 HANDLE_TYPE(ENUM, int);
269 #undef HANDLE_TYPE
270
271 case FieldDescriptor::CPPTYPE_STRING:
272 switch (field->options().ctype()) {
273 default: // TODO(kenton): Support other string reps.
274 case FieldOptions::STRING:
275 total_size +=
276 GetRaw<RepeatedPtrField<std::string> >(message, field)
277 .SpaceUsedExcludingSelfLong();
278 break;
279 }
280 break;
281
282 case FieldDescriptor::CPPTYPE_MESSAGE:
283 if (IsMapFieldInApi(field)) {
284 total_size += GetRaw<internal::MapFieldBase>(message, field)
285 .SpaceUsedExcludingSelfLong();
286 } else {
287 // We don't know which subclass of RepeatedPtrFieldBase the type is,
288 // so we use RepeatedPtrFieldBase directly.
289 total_size +=
290 GetRaw<RepeatedPtrFieldBase>(message, field)
291 .SpaceUsedExcludingSelfLong<GenericTypeHandler<Message> >();
292 }
293
294 break;
295 }
296 } else {
297 if (schema_.InRealOneof(field) && !HasOneofField(message, field)) {
298 continue;
299 }
300 switch (field->cpp_type()) {
301 case FieldDescriptor::CPPTYPE_INT32:
302 case FieldDescriptor::CPPTYPE_INT64:
303 case FieldDescriptor::CPPTYPE_UINT32:
304 case FieldDescriptor::CPPTYPE_UINT64:
305 case FieldDescriptor::CPPTYPE_DOUBLE:
306 case FieldDescriptor::CPPTYPE_FLOAT:
307 case FieldDescriptor::CPPTYPE_BOOL:
308 case FieldDescriptor::CPPTYPE_ENUM:
309 // Field is inline, so we've already counted it.
310 break;
311
312 case FieldDescriptor::CPPTYPE_STRING: {
313 switch (field->options().ctype()) {
314 default: // TODO(kenton): Support other string reps.
315 case FieldOptions::STRING: {
316 if (IsInlined(field)) {
317 const std::string* ptr =
318 &GetField<InlinedStringField>(message, field).GetNoArena();
319 total_size += StringSpaceUsedExcludingSelfLong(*ptr);
320 break;
321 }
322
323 // Initially, the string points to the default value stored
324 // in the prototype. Only count the string if it has been
325 // changed from the default value.
326 const std::string* default_ptr =
327 &DefaultRaw<ArenaStringPtr>(field).Get();
328 const std::string* ptr =
329 &GetField<ArenaStringPtr>(message, field).Get();
330
331 if (ptr != default_ptr) {
332 // string fields are represented by just a pointer, so also
333 // include sizeof(string) as well.
334 total_size +=
335 sizeof(*ptr) + StringSpaceUsedExcludingSelfLong(*ptr);
336 }
337 break;
338 }
339 }
340 break;
341 }
342
343 case FieldDescriptor::CPPTYPE_MESSAGE:
344 if (schema_.IsDefaultInstance(message)) {
345 // For singular fields, the prototype just stores a pointer to the
346 // external type's prototype, so there is no extra memory usage.
347 } else {
348 const Message* sub_message = GetRaw<const Message*>(message, field);
349 if (sub_message != nullptr) {
350 total_size += sub_message->SpaceUsedLong();
351 }
352 }
353 break;
354 }
355 }
356 }
357 return total_size;
358 }
359
SwapField(Message * message1,Message * message2,const FieldDescriptor * field) const360 void Reflection::SwapField(Message* message1, Message* message2,
361 const FieldDescriptor* field) const {
362 CheckInvalidAccess(schema_, field);
363
364 if (field->is_repeated()) {
365 switch (field->cpp_type()) {
366 #define SWAP_ARRAYS(CPPTYPE, TYPE) \
367 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
368 MutableRaw<RepeatedField<TYPE> >(message1, field) \
369 ->Swap(MutableRaw<RepeatedField<TYPE> >(message2, field)); \
370 break;
371
372 SWAP_ARRAYS(INT32, int32);
373 SWAP_ARRAYS(INT64, int64);
374 SWAP_ARRAYS(UINT32, uint32);
375 SWAP_ARRAYS(UINT64, uint64);
376 SWAP_ARRAYS(FLOAT, float);
377 SWAP_ARRAYS(DOUBLE, double);
378 SWAP_ARRAYS(BOOL, bool);
379 SWAP_ARRAYS(ENUM, int);
380 #undef SWAP_ARRAYS
381
382 case FieldDescriptor::CPPTYPE_STRING:
383 switch (field->options().ctype()) {
384 default: // TODO(kenton): Support other string reps.
385 case FieldOptions::STRING:
386 MutableRaw<RepeatedPtrFieldBase>(message1, field)
387 ->Swap<GenericTypeHandler<std::string> >(
388 MutableRaw<RepeatedPtrFieldBase>(message2, field));
389 break;
390 }
391 break;
392 case FieldDescriptor::CPPTYPE_MESSAGE:
393 if (IsMapFieldInApi(field)) {
394 MutableRaw<MapFieldBase>(message1, field)
395 ->Swap(MutableRaw<MapFieldBase>(message2, field));
396 } else {
397 MutableRaw<RepeatedPtrFieldBase>(message1, field)
398 ->Swap<GenericTypeHandler<Message> >(
399 MutableRaw<RepeatedPtrFieldBase>(message2, field));
400 }
401 break;
402
403 default:
404 GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
405 }
406 } else {
407 switch (field->cpp_type()) {
408 #define SWAP_VALUES(CPPTYPE, TYPE) \
409 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
410 std::swap(*MutableRaw<TYPE>(message1, field), \
411 *MutableRaw<TYPE>(message2, field)); \
412 break;
413
414 SWAP_VALUES(INT32, int32);
415 SWAP_VALUES(INT64, int64);
416 SWAP_VALUES(UINT32, uint32);
417 SWAP_VALUES(UINT64, uint64);
418 SWAP_VALUES(FLOAT, float);
419 SWAP_VALUES(DOUBLE, double);
420 SWAP_VALUES(BOOL, bool);
421 SWAP_VALUES(ENUM, int);
422 #undef SWAP_VALUES
423 case FieldDescriptor::CPPTYPE_MESSAGE:
424 if (GetArena(message1) == GetArena(message2)) {
425 std::swap(*MutableRaw<Message*>(message1, field),
426 *MutableRaw<Message*>(message2, field));
427 } else {
428 Message** sub_msg1 = MutableRaw<Message*>(message1, field);
429 Message** sub_msg2 = MutableRaw<Message*>(message2, field);
430 if (*sub_msg1 == nullptr && *sub_msg2 == nullptr) break;
431 if (*sub_msg1 && *sub_msg2) {
432 (*sub_msg1)->GetReflection()->Swap(*sub_msg1, *sub_msg2);
433 break;
434 }
435 if (*sub_msg1 == nullptr) {
436 *sub_msg1 = (*sub_msg2)->New(message1->GetArena());
437 (*sub_msg1)->CopyFrom(**sub_msg2);
438 ClearField(message2, field);
439 } else {
440 *sub_msg2 = (*sub_msg1)->New(message2->GetArena());
441 (*sub_msg2)->CopyFrom(**sub_msg1);
442 ClearField(message1, field);
443 }
444 }
445 break;
446
447 case FieldDescriptor::CPPTYPE_STRING:
448 switch (field->options().ctype()) {
449 default: // TODO(kenton): Support other string reps.
450 case FieldOptions::STRING: {
451 Arena* arena1 = GetArena(message1);
452 Arena* arena2 = GetArena(message2);
453
454 if (IsInlined(field)) {
455 InlinedStringField* string1 =
456 MutableRaw<InlinedStringField>(message1, field);
457 InlinedStringField* string2 =
458 MutableRaw<InlinedStringField>(message2, field);
459 string1->Swap(string2);
460 break;
461 }
462
463 ArenaStringPtr* string1 =
464 MutableRaw<ArenaStringPtr>(message1, field);
465 ArenaStringPtr* string2 =
466 MutableRaw<ArenaStringPtr>(message2, field);
467 const std::string* default_ptr =
468 &DefaultRaw<ArenaStringPtr>(field).Get();
469 if (arena1 == arena2) {
470 string1->Swap(string2, default_ptr, arena1);
471 } else {
472 const std::string temp = string1->Get();
473 string1->Set(default_ptr, string2->Get(), arena1);
474 string2->Set(default_ptr, temp, arena2);
475 }
476 } break;
477 }
478 break;
479
480 default:
481 GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
482 }
483 }
484 }
485
SwapOneofField(Message * message1,Message * message2,const OneofDescriptor * oneof_descriptor) const486 void Reflection::SwapOneofField(Message* message1, Message* message2,
487 const OneofDescriptor* oneof_descriptor) const {
488 GOOGLE_DCHECK(!oneof_descriptor->is_synthetic());
489 uint32 oneof_case1 = GetOneofCase(*message1, oneof_descriptor);
490 uint32 oneof_case2 = GetOneofCase(*message2, oneof_descriptor);
491
492 int32 temp_int32;
493 int64 temp_int64;
494 uint32 temp_uint32;
495 uint64 temp_uint64;
496 float temp_float;
497 double temp_double;
498 bool temp_bool;
499 int temp_int;
500 Message* temp_message = nullptr;
501 std::string temp_string;
502
503 // Stores message1's oneof field to a temp variable.
504 const FieldDescriptor* field1 = nullptr;
505 if (oneof_case1 > 0) {
506 field1 = descriptor_->FindFieldByNumber(oneof_case1);
507 // oneof_descriptor->field(oneof_case1);
508 switch (field1->cpp_type()) {
509 #define GET_TEMP_VALUE(CPPTYPE, TYPE) \
510 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
511 temp_##TYPE = GetField<TYPE>(*message1, field1); \
512 break;
513
514 GET_TEMP_VALUE(INT32, int32);
515 GET_TEMP_VALUE(INT64, int64);
516 GET_TEMP_VALUE(UINT32, uint32);
517 GET_TEMP_VALUE(UINT64, uint64);
518 GET_TEMP_VALUE(FLOAT, float);
519 GET_TEMP_VALUE(DOUBLE, double);
520 GET_TEMP_VALUE(BOOL, bool);
521 GET_TEMP_VALUE(ENUM, int);
522 #undef GET_TEMP_VALUE
523 case FieldDescriptor::CPPTYPE_MESSAGE:
524 temp_message = ReleaseMessage(message1, field1);
525 break;
526
527 case FieldDescriptor::CPPTYPE_STRING:
528 temp_string = GetString(*message1, field1);
529 break;
530
531 default:
532 GOOGLE_LOG(FATAL) << "Unimplemented type: " << field1->cpp_type();
533 }
534 }
535
536 // Sets message1's oneof field from the message2's oneof field.
537 if (oneof_case2 > 0) {
538 const FieldDescriptor* field2 = descriptor_->FindFieldByNumber(oneof_case2);
539 switch (field2->cpp_type()) {
540 #define SET_ONEOF_VALUE1(CPPTYPE, TYPE) \
541 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
542 SetField<TYPE>(message1, field2, GetField<TYPE>(*message2, field2)); \
543 break;
544
545 SET_ONEOF_VALUE1(INT32, int32);
546 SET_ONEOF_VALUE1(INT64, int64);
547 SET_ONEOF_VALUE1(UINT32, uint32);
548 SET_ONEOF_VALUE1(UINT64, uint64);
549 SET_ONEOF_VALUE1(FLOAT, float);
550 SET_ONEOF_VALUE1(DOUBLE, double);
551 SET_ONEOF_VALUE1(BOOL, bool);
552 SET_ONEOF_VALUE1(ENUM, int);
553 #undef SET_ONEOF_VALUE1
554 case FieldDescriptor::CPPTYPE_MESSAGE:
555 SetAllocatedMessage(message1, ReleaseMessage(message2, field2), field2);
556 break;
557
558 case FieldDescriptor::CPPTYPE_STRING:
559 SetString(message1, field2, GetString(*message2, field2));
560 break;
561
562 default:
563 GOOGLE_LOG(FATAL) << "Unimplemented type: " << field2->cpp_type();
564 }
565 } else {
566 ClearOneof(message1, oneof_descriptor);
567 }
568
569 // Sets message2's oneof field from the temp variable.
570 if (oneof_case1 > 0) {
571 switch (field1->cpp_type()) {
572 #define SET_ONEOF_VALUE2(CPPTYPE, TYPE) \
573 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
574 SetField<TYPE>(message2, field1, temp_##TYPE); \
575 break;
576
577 SET_ONEOF_VALUE2(INT32, int32);
578 SET_ONEOF_VALUE2(INT64, int64);
579 SET_ONEOF_VALUE2(UINT32, uint32);
580 SET_ONEOF_VALUE2(UINT64, uint64);
581 SET_ONEOF_VALUE2(FLOAT, float);
582 SET_ONEOF_VALUE2(DOUBLE, double);
583 SET_ONEOF_VALUE2(BOOL, bool);
584 SET_ONEOF_VALUE2(ENUM, int);
585 #undef SET_ONEOF_VALUE2
586 case FieldDescriptor::CPPTYPE_MESSAGE:
587 SetAllocatedMessage(message2, temp_message, field1);
588 break;
589
590 case FieldDescriptor::CPPTYPE_STRING:
591 SetString(message2, field1, temp_string);
592 break;
593
594 default:
595 GOOGLE_LOG(FATAL) << "Unimplemented type: " << field1->cpp_type();
596 }
597 } else {
598 ClearOneof(message2, oneof_descriptor);
599 }
600 }
601
Swap(Message * message1,Message * message2) const602 void Reflection::Swap(Message* message1, Message* message2) const {
603 if (message1 == message2) return;
604
605 // TODO(kenton): Other Reflection methods should probably check this too.
606 GOOGLE_CHECK_EQ(message1->GetReflection(), this)
607 << "First argument to Swap() (of type \""
608 << message1->GetDescriptor()->full_name()
609 << "\") is not compatible with this reflection object (which is for type "
610 "\""
611 << descriptor_->full_name()
612 << "\"). Note that the exact same class is required; not just the same "
613 "descriptor.";
614 GOOGLE_CHECK_EQ(message2->GetReflection(), this)
615 << "Second argument to Swap() (of type \""
616 << message2->GetDescriptor()->full_name()
617 << "\") is not compatible with this reflection object (which is for type "
618 "\""
619 << descriptor_->full_name()
620 << "\"). Note that the exact same class is required; not just the same "
621 "descriptor.";
622
623 // Check that both messages are in the same arena (or both on the heap). We
624 // need to copy all data if not, due to ownership semantics.
625 if (GetArena(message1) != GetArena(message2)) {
626 // Slow copy path.
627 // Use our arena as temp space, if available.
628 Message* temp = message1->New(GetArena(message1));
629 temp->MergeFrom(*message2);
630 message2->CopyFrom(*message1);
631 Swap(message1, temp);
632 if (GetArena(message1) == nullptr) {
633 delete temp;
634 }
635 return;
636 }
637
638 if (schema_.HasHasbits()) {
639 uint32* has_bits1 = MutableHasBits(message1);
640 uint32* has_bits2 = MutableHasBits(message2);
641
642 int fields_with_has_bits = 0;
643 for (int i = 0; i < descriptor_->field_count(); i++) {
644 const FieldDescriptor* field = descriptor_->field(i);
645 if (field->is_repeated() || schema_.InRealOneof(field)) {
646 continue;
647 }
648 fields_with_has_bits++;
649 }
650
651 int has_bits_size = (fields_with_has_bits + 31) / 32;
652
653 for (int i = 0; i < has_bits_size; i++) {
654 std::swap(has_bits1[i], has_bits2[i]);
655 }
656 }
657
658 for (int i = 0; i <= last_non_weak_field_index_; i++) {
659 const FieldDescriptor* field = descriptor_->field(i);
660 if (schema_.InRealOneof(field)) continue;
661 if (schema_.IsFieldStripped(field)) continue;
662 SwapField(message1, message2, field);
663 }
664 const int oneof_decl_count = descriptor_->oneof_decl_count();
665 for (int i = 0; i < oneof_decl_count; i++) {
666 const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
667 if (!oneof->is_synthetic()) {
668 SwapOneofField(message1, message2, oneof);
669 }
670 }
671
672 if (schema_.HasExtensionSet()) {
673 MutableExtensionSet(message1)->Swap(MutableExtensionSet(message2));
674 }
675
676 MutableUnknownFields(message1)->Swap(MutableUnknownFields(message2));
677 }
678
SwapFields(Message * message1,Message * message2,const std::vector<const FieldDescriptor * > & fields) const679 void Reflection::SwapFields(
680 Message* message1, Message* message2,
681 const std::vector<const FieldDescriptor*>& fields) const {
682 if (message1 == message2) return;
683
684 // TODO(kenton): Other Reflection methods should probably check this too.
685 GOOGLE_CHECK_EQ(message1->GetReflection(), this)
686 << "First argument to SwapFields() (of type \""
687 << message1->GetDescriptor()->full_name()
688 << "\") is not compatible with this reflection object (which is for type "
689 "\""
690 << descriptor_->full_name()
691 << "\"). Note that the exact same class is required; not just the same "
692 "descriptor.";
693 GOOGLE_CHECK_EQ(message2->GetReflection(), this)
694 << "Second argument to SwapFields() (of type \""
695 << message2->GetDescriptor()->full_name()
696 << "\") is not compatible with this reflection object (which is for type "
697 "\""
698 << descriptor_->full_name()
699 << "\"). Note that the exact same class is required; not just the same "
700 "descriptor.";
701
702 std::set<int> swapped_oneof;
703
704 const int fields_size = static_cast<int>(fields.size());
705 for (int i = 0; i < fields_size; i++) {
706 const FieldDescriptor* field = fields[i];
707 CheckInvalidAccess(schema_, field);
708 if (field->is_extension()) {
709 MutableExtensionSet(message1)->SwapExtension(
710 MutableExtensionSet(message2), field->number());
711 } else {
712 if (schema_.InRealOneof(field)) {
713 int oneof_index = field->containing_oneof()->index();
714 // Only swap the oneof field once.
715 if (swapped_oneof.find(oneof_index) != swapped_oneof.end()) {
716 continue;
717 }
718 swapped_oneof.insert(oneof_index);
719 SwapOneofField(message1, message2, field->containing_oneof());
720 } else {
721 // Swap has bit for non-repeated fields. We have already checked for
722 // oneof already.
723 if (!field->is_repeated()) {
724 SwapBit(message1, message2, field);
725 }
726 // Swap field.
727 SwapField(message1, message2, field);
728 }
729 }
730 }
731 }
732
733 // -------------------------------------------------------------------
734
HasField(const Message & message,const FieldDescriptor * field) const735 bool Reflection::HasField(const Message& message,
736 const FieldDescriptor* field) const {
737 USAGE_CHECK_MESSAGE_TYPE(HasField);
738 USAGE_CHECK_SINGULAR(HasField);
739 CheckInvalidAccess(schema_, field);
740
741 if (field->is_extension()) {
742 return GetExtensionSet(message).Has(field->number());
743 } else {
744 if (schema_.InRealOneof(field)) {
745 return HasOneofField(message, field);
746 } else {
747 return HasBit(message, field);
748 }
749 }
750 }
751
FieldSize(const Message & message,const FieldDescriptor * field) const752 int Reflection::FieldSize(const Message& message,
753 const FieldDescriptor* field) const {
754 USAGE_CHECK_MESSAGE_TYPE(FieldSize);
755 USAGE_CHECK_REPEATED(FieldSize);
756 CheckInvalidAccess(schema_, field);
757
758 if (field->is_extension()) {
759 return GetExtensionSet(message).ExtensionSize(field->number());
760 } else {
761 switch (field->cpp_type()) {
762 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
763 case FieldDescriptor::CPPTYPE_##UPPERCASE: \
764 return GetRaw<RepeatedField<LOWERCASE> >(message, field).size()
765
766 HANDLE_TYPE(INT32, int32);
767 HANDLE_TYPE(INT64, int64);
768 HANDLE_TYPE(UINT32, uint32);
769 HANDLE_TYPE(UINT64, uint64);
770 HANDLE_TYPE(DOUBLE, double);
771 HANDLE_TYPE(FLOAT, float);
772 HANDLE_TYPE(BOOL, bool);
773 HANDLE_TYPE(ENUM, int);
774 #undef HANDLE_TYPE
775
776 case FieldDescriptor::CPPTYPE_STRING:
777 case FieldDescriptor::CPPTYPE_MESSAGE:
778 if (IsMapFieldInApi(field)) {
779 const internal::MapFieldBase& map =
780 GetRaw<MapFieldBase>(message, field);
781 if (map.IsRepeatedFieldValid()) {
782 return map.GetRepeatedField().size();
783 } else {
784 // No need to materialize the repeated field if it is out of sync:
785 // its size will be the same as the map's size.
786 return map.size();
787 }
788 } else {
789 return GetRaw<RepeatedPtrFieldBase>(message, field).size();
790 }
791 }
792
793 GOOGLE_LOG(FATAL) << "Can't get here.";
794 return 0;
795 }
796 }
797
ClearField(Message * message,const FieldDescriptor * field) const798 void Reflection::ClearField(Message* message,
799 const FieldDescriptor* field) const {
800 USAGE_CHECK_MESSAGE_TYPE(ClearField);
801 CheckInvalidAccess(schema_, field);
802
803 if (field->is_extension()) {
804 MutableExtensionSet(message)->ClearExtension(field->number());
805 } else if (!field->is_repeated()) {
806 if (schema_.InRealOneof(field)) {
807 ClearOneofField(message, field);
808 return;
809 }
810 if (HasBit(*message, field)) {
811 ClearBit(message, field);
812
813 // We need to set the field back to its default value.
814 switch (field->cpp_type()) {
815 #define CLEAR_TYPE(CPPTYPE, TYPE) \
816 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
817 *MutableRaw<TYPE>(message, field) = field->default_value_##TYPE(); \
818 break;
819
820 CLEAR_TYPE(INT32, int32);
821 CLEAR_TYPE(INT64, int64);
822 CLEAR_TYPE(UINT32, uint32);
823 CLEAR_TYPE(UINT64, uint64);
824 CLEAR_TYPE(FLOAT, float);
825 CLEAR_TYPE(DOUBLE, double);
826 CLEAR_TYPE(BOOL, bool);
827 #undef CLEAR_TYPE
828
829 case FieldDescriptor::CPPTYPE_ENUM:
830 *MutableRaw<int>(message, field) =
831 field->default_value_enum()->number();
832 break;
833
834 case FieldDescriptor::CPPTYPE_STRING: {
835 switch (field->options().ctype()) {
836 default: // TODO(kenton): Support other string reps.
837 case FieldOptions::STRING: {
838 if (IsInlined(field)) {
839 const std::string* default_ptr =
840 &DefaultRaw<InlinedStringField>(field).GetNoArena();
841 MutableRaw<InlinedStringField>(message, field)
842 ->SetNoArena(default_ptr, *default_ptr);
843 break;
844 }
845
846 const std::string* default_ptr =
847 &DefaultRaw<ArenaStringPtr>(field).Get();
848 MutableRaw<ArenaStringPtr>(message, field)
849 ->SetAllocated(default_ptr, nullptr, GetArena(message));
850 break;
851 }
852 }
853 break;
854 }
855
856 case FieldDescriptor::CPPTYPE_MESSAGE:
857 if (schema_.HasBitIndex(field) == -1) {
858 // Proto3 does not have has-bits and we need to set a message field
859 // to nullptr in order to indicate its un-presence.
860 if (GetArena(message) == nullptr) {
861 delete *MutableRaw<Message*>(message, field);
862 }
863 *MutableRaw<Message*>(message, field) = nullptr;
864 } else {
865 (*MutableRaw<Message*>(message, field))->Clear();
866 }
867 break;
868 }
869 }
870 } else {
871 switch (field->cpp_type()) {
872 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
873 case FieldDescriptor::CPPTYPE_##UPPERCASE: \
874 MutableRaw<RepeatedField<LOWERCASE> >(message, field)->Clear(); \
875 break
876
877 HANDLE_TYPE(INT32, int32);
878 HANDLE_TYPE(INT64, int64);
879 HANDLE_TYPE(UINT32, uint32);
880 HANDLE_TYPE(UINT64, uint64);
881 HANDLE_TYPE(DOUBLE, double);
882 HANDLE_TYPE(FLOAT, float);
883 HANDLE_TYPE(BOOL, bool);
884 HANDLE_TYPE(ENUM, int);
885 #undef HANDLE_TYPE
886
887 case FieldDescriptor::CPPTYPE_STRING: {
888 switch (field->options().ctype()) {
889 default: // TODO(kenton): Support other string reps.
890 case FieldOptions::STRING:
891 MutableRaw<RepeatedPtrField<std::string> >(message, field)->Clear();
892 break;
893 }
894 break;
895 }
896
897 case FieldDescriptor::CPPTYPE_MESSAGE: {
898 if (IsMapFieldInApi(field)) {
899 MutableRaw<MapFieldBase>(message, field)->Clear();
900 } else {
901 // We don't know which subclass of RepeatedPtrFieldBase the type is,
902 // so we use RepeatedPtrFieldBase directly.
903 MutableRaw<RepeatedPtrFieldBase>(message, field)
904 ->Clear<GenericTypeHandler<Message> >();
905 }
906 break;
907 }
908 }
909 }
910 }
911
RemoveLast(Message * message,const FieldDescriptor * field) const912 void Reflection::RemoveLast(Message* message,
913 const FieldDescriptor* field) const {
914 USAGE_CHECK_MESSAGE_TYPE(RemoveLast);
915 USAGE_CHECK_REPEATED(RemoveLast);
916 CheckInvalidAccess(schema_, field);
917
918 if (field->is_extension()) {
919 MutableExtensionSet(message)->RemoveLast(field->number());
920 } else {
921 switch (field->cpp_type()) {
922 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
923 case FieldDescriptor::CPPTYPE_##UPPERCASE: \
924 MutableRaw<RepeatedField<LOWERCASE> >(message, field)->RemoveLast(); \
925 break
926
927 HANDLE_TYPE(INT32, int32);
928 HANDLE_TYPE(INT64, int64);
929 HANDLE_TYPE(UINT32, uint32);
930 HANDLE_TYPE(UINT64, uint64);
931 HANDLE_TYPE(DOUBLE, double);
932 HANDLE_TYPE(FLOAT, float);
933 HANDLE_TYPE(BOOL, bool);
934 HANDLE_TYPE(ENUM, int);
935 #undef HANDLE_TYPE
936
937 case FieldDescriptor::CPPTYPE_STRING:
938 switch (field->options().ctype()) {
939 default: // TODO(kenton): Support other string reps.
940 case FieldOptions::STRING:
941 MutableRaw<RepeatedPtrField<std::string> >(message, field)
942 ->RemoveLast();
943 break;
944 }
945 break;
946
947 case FieldDescriptor::CPPTYPE_MESSAGE:
948 if (IsMapFieldInApi(field)) {
949 MutableRaw<MapFieldBase>(message, field)
950 ->MutableRepeatedField()
951 ->RemoveLast<GenericTypeHandler<Message> >();
952 } else {
953 MutableRaw<RepeatedPtrFieldBase>(message, field)
954 ->RemoveLast<GenericTypeHandler<Message> >();
955 }
956 break;
957 }
958 }
959 }
960
ReleaseLast(Message * message,const FieldDescriptor * field) const961 Message* Reflection::ReleaseLast(Message* message,
962 const FieldDescriptor* field) const {
963 USAGE_CHECK_ALL(ReleaseLast, REPEATED, MESSAGE);
964 CheckInvalidAccess(schema_, field);
965
966 if (field->is_extension()) {
967 return static_cast<Message*>(
968 MutableExtensionSet(message)->ReleaseLast(field->number()));
969 } else {
970 if (IsMapFieldInApi(field)) {
971 return MutableRaw<MapFieldBase>(message, field)
972 ->MutableRepeatedField()
973 ->ReleaseLast<GenericTypeHandler<Message> >();
974 } else {
975 return MutableRaw<RepeatedPtrFieldBase>(message, field)
976 ->ReleaseLast<GenericTypeHandler<Message> >();
977 }
978 }
979 }
980
SwapElements(Message * message,const FieldDescriptor * field,int index1,int index2) const981 void Reflection::SwapElements(Message* message, const FieldDescriptor* field,
982 int index1, int index2) const {
983 USAGE_CHECK_MESSAGE_TYPE(Swap);
984 USAGE_CHECK_REPEATED(Swap);
985 CheckInvalidAccess(schema_, field);
986
987 if (field->is_extension()) {
988 MutableExtensionSet(message)->SwapElements(field->number(), index1, index2);
989 } else {
990 switch (field->cpp_type()) {
991 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
992 case FieldDescriptor::CPPTYPE_##UPPERCASE: \
993 MutableRaw<RepeatedField<LOWERCASE> >(message, field) \
994 ->SwapElements(index1, index2); \
995 break
996
997 HANDLE_TYPE(INT32, int32);
998 HANDLE_TYPE(INT64, int64);
999 HANDLE_TYPE(UINT32, uint32);
1000 HANDLE_TYPE(UINT64, uint64);
1001 HANDLE_TYPE(DOUBLE, double);
1002 HANDLE_TYPE(FLOAT, float);
1003 HANDLE_TYPE(BOOL, bool);
1004 HANDLE_TYPE(ENUM, int);
1005 #undef HANDLE_TYPE
1006
1007 case FieldDescriptor::CPPTYPE_STRING:
1008 case FieldDescriptor::CPPTYPE_MESSAGE:
1009 if (IsMapFieldInApi(field)) {
1010 MutableRaw<MapFieldBase>(message, field)
1011 ->MutableRepeatedField()
1012 ->SwapElements(index1, index2);
1013 } else {
1014 MutableRaw<RepeatedPtrFieldBase>(message, field)
1015 ->SwapElements(index1, index2);
1016 }
1017 break;
1018 }
1019 }
1020 }
1021
1022 namespace {
1023 // Comparison functor for sorting FieldDescriptors by field number.
1024 struct FieldNumberSorter {
operator ()google::protobuf::__anonf7e405f80311::FieldNumberSorter1025 bool operator()(const FieldDescriptor* left,
1026 const FieldDescriptor* right) const {
1027 return left->number() < right->number();
1028 }
1029 };
1030
IsIndexInHasBitSet(const uint32 * has_bit_set,uint32 has_bit_index)1031 bool IsIndexInHasBitSet(const uint32* has_bit_set, uint32 has_bit_index) {
1032 GOOGLE_DCHECK_NE(has_bit_index, ~0u);
1033 return ((has_bit_set[has_bit_index / 32] >> (has_bit_index % 32)) &
1034 static_cast<uint32>(1)) != 0;
1035 }
1036
CreateUnknownEnumValues(const FileDescriptor * file)1037 bool CreateUnknownEnumValues(const FileDescriptor* file) {
1038 return file->syntax() == FileDescriptor::SYNTAX_PROTO3;
1039 }
1040 } // namespace
1041
1042 namespace internal {
CreateUnknownEnumValues(const FieldDescriptor * field)1043 bool CreateUnknownEnumValues(const FieldDescriptor* field) {
1044 bool open_enum = false;
1045 return field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 || open_enum;
1046 }
1047 } // namespace internal
1048 using internal::CreateUnknownEnumValues;
1049
ListFieldsMayFailOnStripped(const Message & message,bool should_fail,std::vector<const FieldDescriptor * > * output) const1050 void Reflection::ListFieldsMayFailOnStripped(
1051 const Message& message, bool should_fail,
1052 std::vector<const FieldDescriptor*>* output) const {
1053 output->clear();
1054
1055 // Optimization: The default instance never has any fields set.
1056 if (schema_.IsDefaultInstance(message)) return;
1057
1058 // Optimization: Avoid calling GetHasBits() and HasOneofField() many times
1059 // within the field loop. We allow this violation of ReflectionSchema
1060 // encapsulation because this function takes a noticeable about of CPU
1061 // fleetwide and properly allowing this optimization through public interfaces
1062 // seems more trouble than it is worth.
1063 const uint32* const has_bits =
1064 schema_.HasHasbits() ? GetHasBits(message) : nullptr;
1065 const uint32* const has_bits_indices = schema_.has_bit_indices_;
1066 output->reserve(descriptor_->field_count());
1067 for (int i = 0; i <= last_non_weak_field_index_; i++) {
1068 const FieldDescriptor* field = descriptor_->field(i);
1069 if (!should_fail && schema_.IsFieldStripped(field)) {
1070 continue;
1071 }
1072 if (field->is_repeated()) {
1073 if (FieldSize(message, field) > 0) {
1074 output->push_back(field);
1075 }
1076 } else {
1077 const OneofDescriptor* containing_oneof = field->containing_oneof();
1078 if (schema_.InRealOneof(field)) {
1079 const uint32* const oneof_case_array = GetConstPointerAtOffset<uint32>(
1080 &message, schema_.oneof_case_offset_);
1081 // Equivalent to: HasOneofField(message, field)
1082 if (oneof_case_array[containing_oneof->index()] == field->number()) {
1083 output->push_back(field);
1084 }
1085 } else if (has_bits && has_bits_indices[i] != -1) {
1086 // Equivalent to: HasBit(message, field)
1087 if (IsIndexInHasBitSet(has_bits, has_bits_indices[i])) {
1088 output->push_back(field);
1089 }
1090 } else if (HasBit(message, field)) { // Fall back on proto3-style HasBit.
1091 output->push_back(field);
1092 }
1093 }
1094 }
1095 if (schema_.HasExtensionSet()) {
1096 GetExtensionSet(message).AppendToList(descriptor_, descriptor_pool_,
1097 output);
1098 }
1099
1100 // ListFields() must sort output by field number.
1101 std::sort(output->begin(), output->end(), FieldNumberSorter());
1102 }
1103
ListFields(const Message & message,std::vector<const FieldDescriptor * > * output) const1104 void Reflection::ListFields(const Message& message,
1105 std::vector<const FieldDescriptor*>* output) const {
1106 ListFieldsMayFailOnStripped(message, true, output);
1107 }
1108
ListFieldsOmitStripped(const Message & message,std::vector<const FieldDescriptor * > * output) const1109 void Reflection::ListFieldsOmitStripped(
1110 const Message& message, std::vector<const FieldDescriptor*>* output) const {
1111 ListFieldsMayFailOnStripped(message, false, output);
1112 }
1113
1114 // -------------------------------------------------------------------
1115
1116 #undef DEFINE_PRIMITIVE_ACCESSORS
1117 #define DEFINE_PRIMITIVE_ACCESSORS(TYPENAME, TYPE, PASSTYPE, CPPTYPE) \
1118 PASSTYPE Reflection::Get##TYPENAME(const Message& message, \
1119 const FieldDescriptor* field) const { \
1120 USAGE_CHECK_ALL(Get##TYPENAME, SINGULAR, CPPTYPE); \
1121 if (field->is_extension()) { \
1122 return GetExtensionSet(message).Get##TYPENAME( \
1123 field->number(), field->default_value_##PASSTYPE()); \
1124 } else { \
1125 return GetField<TYPE>(message, field); \
1126 } \
1127 } \
1128 \
1129 void Reflection::Set##TYPENAME( \
1130 Message* message, const FieldDescriptor* field, PASSTYPE value) const { \
1131 USAGE_CHECK_ALL(Set##TYPENAME, SINGULAR, CPPTYPE); \
1132 if (field->is_extension()) { \
1133 return MutableExtensionSet(message)->Set##TYPENAME( \
1134 field->number(), field->type(), value, field); \
1135 } else { \
1136 SetField<TYPE>(message, field, value); \
1137 } \
1138 } \
1139 \
1140 PASSTYPE Reflection::GetRepeated##TYPENAME( \
1141 const Message& message, const FieldDescriptor* field, int index) const { \
1142 USAGE_CHECK_ALL(GetRepeated##TYPENAME, REPEATED, CPPTYPE); \
1143 if (field->is_extension()) { \
1144 return GetExtensionSet(message).GetRepeated##TYPENAME(field->number(), \
1145 index); \
1146 } else { \
1147 return GetRepeatedField<TYPE>(message, field, index); \
1148 } \
1149 } \
1150 \
1151 void Reflection::SetRepeated##TYPENAME(Message* message, \
1152 const FieldDescriptor* field, \
1153 int index, PASSTYPE value) const { \
1154 USAGE_CHECK_ALL(SetRepeated##TYPENAME, REPEATED, CPPTYPE); \
1155 if (field->is_extension()) { \
1156 MutableExtensionSet(message)->SetRepeated##TYPENAME(field->number(), \
1157 index, value); \
1158 } else { \
1159 SetRepeatedField<TYPE>(message, field, index, value); \
1160 } \
1161 } \
1162 \
1163 void Reflection::Add##TYPENAME( \
1164 Message* message, const FieldDescriptor* field, PASSTYPE value) const { \
1165 USAGE_CHECK_ALL(Add##TYPENAME, REPEATED, CPPTYPE); \
1166 if (field->is_extension()) { \
1167 MutableExtensionSet(message)->Add##TYPENAME( \
1168 field->number(), field->type(), field->options().packed(), value, \
1169 field); \
1170 } else { \
1171 AddField<TYPE>(message, field, value); \
1172 } \
1173 }
1174
DEFINE_PRIMITIVE_ACCESSORS(Int32,int32,int32,INT32)1175 DEFINE_PRIMITIVE_ACCESSORS(Int32, int32, int32, INT32)
1176 DEFINE_PRIMITIVE_ACCESSORS(Int64, int64, int64, INT64)
1177 DEFINE_PRIMITIVE_ACCESSORS(UInt32, uint32, uint32, UINT32)
1178 DEFINE_PRIMITIVE_ACCESSORS(UInt64, uint64, uint64, UINT64)
1179 DEFINE_PRIMITIVE_ACCESSORS(Float, float, float, FLOAT)
1180 DEFINE_PRIMITIVE_ACCESSORS(Double, double, double, DOUBLE)
1181 DEFINE_PRIMITIVE_ACCESSORS(Bool, bool, bool, BOOL)
1182 #undef DEFINE_PRIMITIVE_ACCESSORS
1183
1184 // -------------------------------------------------------------------
1185
1186 std::string Reflection::GetString(const Message& message,
1187 const FieldDescriptor* field) const {
1188 USAGE_CHECK_ALL(GetString, SINGULAR, STRING);
1189 if (field->is_extension()) {
1190 return GetExtensionSet(message).GetString(field->number(),
1191 field->default_value_string());
1192 } else {
1193 switch (field->options().ctype()) {
1194 default: // TODO(kenton): Support other string reps.
1195 case FieldOptions::STRING: {
1196 if (IsInlined(field)) {
1197 return GetField<InlinedStringField>(message, field).GetNoArena();
1198 }
1199
1200 return GetField<ArenaStringPtr>(message, field).Get();
1201 }
1202 }
1203 }
1204 }
1205
GetStringReference(const Message & message,const FieldDescriptor * field,std::string * scratch) const1206 const std::string& Reflection::GetStringReference(const Message& message,
1207 const FieldDescriptor* field,
1208 std::string* scratch) const {
1209 USAGE_CHECK_ALL(GetStringReference, SINGULAR, STRING);
1210 if (field->is_extension()) {
1211 return GetExtensionSet(message).GetString(field->number(),
1212 field->default_value_string());
1213 } else {
1214 switch (field->options().ctype()) {
1215 default: // TODO(kenton): Support other string reps.
1216 case FieldOptions::STRING: {
1217 if (IsInlined(field)) {
1218 return GetField<InlinedStringField>(message, field).GetNoArena();
1219 }
1220
1221 return GetField<ArenaStringPtr>(message, field).Get();
1222 }
1223 }
1224 }
1225 }
1226
1227
SetString(Message * message,const FieldDescriptor * field,std::string value) const1228 void Reflection::SetString(Message* message, const FieldDescriptor* field,
1229 std::string value) const {
1230 USAGE_CHECK_ALL(SetString, SINGULAR, STRING);
1231 if (field->is_extension()) {
1232 return MutableExtensionSet(message)->SetString(
1233 field->number(), field->type(), std::move(value), field);
1234 } else {
1235 switch (field->options().ctype()) {
1236 default: // TODO(kenton): Support other string reps.
1237 case FieldOptions::STRING: {
1238 if (IsInlined(field)) {
1239 MutableField<InlinedStringField>(message, field)
1240 ->SetNoArena(nullptr, std::move(value));
1241 break;
1242 }
1243
1244 const std::string* default_ptr =
1245 &DefaultRaw<ArenaStringPtr>(field).Get();
1246 if (schema_.InRealOneof(field) && !HasOneofField(*message, field)) {
1247 ClearOneof(message, field->containing_oneof());
1248 MutableField<ArenaStringPtr>(message, field)
1249 ->UnsafeSetDefault(default_ptr);
1250 }
1251 MutableField<ArenaStringPtr>(message, field)
1252 ->Mutable(default_ptr, GetArena(message))
1253 ->assign(std::move(value));
1254 break;
1255 }
1256 }
1257 }
1258 }
1259
1260
GetRepeatedString(const Message & message,const FieldDescriptor * field,int index) const1261 std::string Reflection::GetRepeatedString(const Message& message,
1262 const FieldDescriptor* field,
1263 int index) const {
1264 USAGE_CHECK_ALL(GetRepeatedString, REPEATED, STRING);
1265 if (field->is_extension()) {
1266 return GetExtensionSet(message).GetRepeatedString(field->number(), index);
1267 } else {
1268 switch (field->options().ctype()) {
1269 default: // TODO(kenton): Support other string reps.
1270 case FieldOptions::STRING:
1271 return GetRepeatedPtrField<std::string>(message, field, index);
1272 }
1273 }
1274 }
1275
GetRepeatedStringReference(const Message & message,const FieldDescriptor * field,int index,std::string * scratch) const1276 const std::string& Reflection::GetRepeatedStringReference(
1277 const Message& message, const FieldDescriptor* field, int index,
1278 std::string* scratch) const {
1279 USAGE_CHECK_ALL(GetRepeatedStringReference, REPEATED, STRING);
1280 if (field->is_extension()) {
1281 return GetExtensionSet(message).GetRepeatedString(field->number(), index);
1282 } else {
1283 switch (field->options().ctype()) {
1284 default: // TODO(kenton): Support other string reps.
1285 case FieldOptions::STRING:
1286 return GetRepeatedPtrField<std::string>(message, field, index);
1287 }
1288 }
1289 }
1290
1291
SetRepeatedString(Message * message,const FieldDescriptor * field,int index,std::string value) const1292 void Reflection::SetRepeatedString(Message* message,
1293 const FieldDescriptor* field, int index,
1294 std::string value) const {
1295 USAGE_CHECK_ALL(SetRepeatedString, REPEATED, STRING);
1296 if (field->is_extension()) {
1297 MutableExtensionSet(message)->SetRepeatedString(field->number(), index,
1298 std::move(value));
1299 } else {
1300 switch (field->options().ctype()) {
1301 default: // TODO(kenton): Support other string reps.
1302 case FieldOptions::STRING:
1303 MutableRepeatedField<std::string>(message, field, index)
1304 ->assign(std::move(value));
1305 break;
1306 }
1307 }
1308 }
1309
1310
AddString(Message * message,const FieldDescriptor * field,std::string value) const1311 void Reflection::AddString(Message* message, const FieldDescriptor* field,
1312 std::string value) const {
1313 USAGE_CHECK_ALL(AddString, REPEATED, STRING);
1314 if (field->is_extension()) {
1315 MutableExtensionSet(message)->AddString(field->number(), field->type(),
1316 std::move(value), field);
1317 } else {
1318 switch (field->options().ctype()) {
1319 default: // TODO(kenton): Support other string reps.
1320 case FieldOptions::STRING:
1321 AddField<std::string>(message, field)->assign(std::move(value));
1322 break;
1323 }
1324 }
1325 }
1326
1327
1328 // -------------------------------------------------------------------
1329
GetEnum(const Message & message,const FieldDescriptor * field) const1330 const EnumValueDescriptor* Reflection::GetEnum(
1331 const Message& message, const FieldDescriptor* field) const {
1332 // Usage checked by GetEnumValue.
1333 int value = GetEnumValue(message, field);
1334 return field->enum_type()->FindValueByNumberCreatingIfUnknown(value);
1335 }
1336
GetEnumValue(const Message & message,const FieldDescriptor * field) const1337 int Reflection::GetEnumValue(const Message& message,
1338 const FieldDescriptor* field) const {
1339 USAGE_CHECK_ALL(GetEnumValue, SINGULAR, ENUM);
1340
1341 int32 value;
1342 if (field->is_extension()) {
1343 value = GetExtensionSet(message).GetEnum(
1344 field->number(), field->default_value_enum()->number());
1345 } else {
1346 value = GetField<int>(message, field);
1347 }
1348 return value;
1349 }
1350
SetEnum(Message * message,const FieldDescriptor * field,const EnumValueDescriptor * value) const1351 void Reflection::SetEnum(Message* message, const FieldDescriptor* field,
1352 const EnumValueDescriptor* value) const {
1353 // Usage checked by SetEnumValue.
1354 USAGE_CHECK_ENUM_VALUE(SetEnum);
1355 SetEnumValueInternal(message, field, value->number());
1356 }
1357
SetEnumValue(Message * message,const FieldDescriptor * field,int value) const1358 void Reflection::SetEnumValue(Message* message, const FieldDescriptor* field,
1359 int value) const {
1360 USAGE_CHECK_ALL(SetEnumValue, SINGULAR, ENUM);
1361 if (!CreateUnknownEnumValues(field)) {
1362 // Check that the value is valid if we don't support direct storage of
1363 // unknown enum values.
1364 const EnumValueDescriptor* value_desc =
1365 field->enum_type()->FindValueByNumber(value);
1366 if (value_desc == nullptr) {
1367 MutableUnknownFields(message)->AddVarint(field->number(), value);
1368 return;
1369 }
1370 }
1371 SetEnumValueInternal(message, field, value);
1372 }
1373
SetEnumValueInternal(Message * message,const FieldDescriptor * field,int value) const1374 void Reflection::SetEnumValueInternal(Message* message,
1375 const FieldDescriptor* field,
1376 int value) const {
1377 if (field->is_extension()) {
1378 MutableExtensionSet(message)->SetEnum(field->number(), field->type(), value,
1379 field);
1380 } else {
1381 SetField<int>(message, field, value);
1382 }
1383 }
1384
GetRepeatedEnum(const Message & message,const FieldDescriptor * field,int index) const1385 const EnumValueDescriptor* Reflection::GetRepeatedEnum(
1386 const Message& message, const FieldDescriptor* field, int index) const {
1387 // Usage checked by GetRepeatedEnumValue.
1388 int value = GetRepeatedEnumValue(message, field, index);
1389 return field->enum_type()->FindValueByNumberCreatingIfUnknown(value);
1390 }
1391
GetRepeatedEnumValue(const Message & message,const FieldDescriptor * field,int index) const1392 int Reflection::GetRepeatedEnumValue(const Message& message,
1393 const FieldDescriptor* field,
1394 int index) const {
1395 USAGE_CHECK_ALL(GetRepeatedEnumValue, REPEATED, ENUM);
1396
1397 int value;
1398 if (field->is_extension()) {
1399 value = GetExtensionSet(message).GetRepeatedEnum(field->number(), index);
1400 } else {
1401 value = GetRepeatedField<int>(message, field, index);
1402 }
1403 return value;
1404 }
1405
SetRepeatedEnum(Message * message,const FieldDescriptor * field,int index,const EnumValueDescriptor * value) const1406 void Reflection::SetRepeatedEnum(Message* message, const FieldDescriptor* field,
1407 int index,
1408 const EnumValueDescriptor* value) const {
1409 // Usage checked by SetRepeatedEnumValue.
1410 USAGE_CHECK_ENUM_VALUE(SetRepeatedEnum);
1411 SetRepeatedEnumValueInternal(message, field, index, value->number());
1412 }
1413
SetRepeatedEnumValue(Message * message,const FieldDescriptor * field,int index,int value) const1414 void Reflection::SetRepeatedEnumValue(Message* message,
1415 const FieldDescriptor* field, int index,
1416 int value) const {
1417 USAGE_CHECK_ALL(SetRepeatedEnum, REPEATED, ENUM);
1418 if (!CreateUnknownEnumValues(field)) {
1419 // Check that the value is valid if we don't support direct storage of
1420 // unknown enum values.
1421 const EnumValueDescriptor* value_desc =
1422 field->enum_type()->FindValueByNumber(value);
1423 if (value_desc == nullptr) {
1424 MutableUnknownFields(message)->AddVarint(field->number(), value);
1425 return;
1426 }
1427 }
1428 SetRepeatedEnumValueInternal(message, field, index, value);
1429 }
1430
SetRepeatedEnumValueInternal(Message * message,const FieldDescriptor * field,int index,int value) const1431 void Reflection::SetRepeatedEnumValueInternal(Message* message,
1432 const FieldDescriptor* field,
1433 int index, int value) const {
1434 if (field->is_extension()) {
1435 MutableExtensionSet(message)->SetRepeatedEnum(field->number(), index,
1436 value);
1437 } else {
1438 SetRepeatedField<int>(message, field, index, value);
1439 }
1440 }
1441
AddEnum(Message * message,const FieldDescriptor * field,const EnumValueDescriptor * value) const1442 void Reflection::AddEnum(Message* message, const FieldDescriptor* field,
1443 const EnumValueDescriptor* value) const {
1444 // Usage checked by AddEnumValue.
1445 USAGE_CHECK_ENUM_VALUE(AddEnum);
1446 AddEnumValueInternal(message, field, value->number());
1447 }
1448
AddEnumValue(Message * message,const FieldDescriptor * field,int value) const1449 void Reflection::AddEnumValue(Message* message, const FieldDescriptor* field,
1450 int value) const {
1451 USAGE_CHECK_ALL(AddEnum, REPEATED, ENUM);
1452 if (!CreateUnknownEnumValues(field)) {
1453 // Check that the value is valid if we don't support direct storage of
1454 // unknown enum values.
1455 const EnumValueDescriptor* value_desc =
1456 field->enum_type()->FindValueByNumber(value);
1457 if (value_desc == nullptr) {
1458 MutableUnknownFields(message)->AddVarint(field->number(), value);
1459 return;
1460 }
1461 }
1462 AddEnumValueInternal(message, field, value);
1463 }
1464
AddEnumValueInternal(Message * message,const FieldDescriptor * field,int value) const1465 void Reflection::AddEnumValueInternal(Message* message,
1466 const FieldDescriptor* field,
1467 int value) const {
1468 if (field->is_extension()) {
1469 MutableExtensionSet(message)->AddEnum(field->number(), field->type(),
1470 field->options().packed(), value,
1471 field);
1472 } else {
1473 AddField<int>(message, field, value);
1474 }
1475 }
1476
1477 // -------------------------------------------------------------------
1478
GetMessage(const Message & message,const FieldDescriptor * field,MessageFactory * factory) const1479 const Message& Reflection::GetMessage(const Message& message,
1480 const FieldDescriptor* field,
1481 MessageFactory* factory) const {
1482 USAGE_CHECK_ALL(GetMessage, SINGULAR, MESSAGE);
1483 CheckInvalidAccess(schema_, field);
1484
1485 if (factory == nullptr) factory = message_factory_;
1486
1487 if (field->is_extension()) {
1488 return static_cast<const Message&>(GetExtensionSet(message).GetMessage(
1489 field->number(), field->message_type(), factory));
1490 } else {
1491 const Message* result = GetRaw<const Message*>(message, field);
1492 if (result == nullptr) {
1493 result = DefaultRaw<const Message*>(field);
1494 }
1495 return *result;
1496 }
1497 }
1498
MutableMessage(Message * message,const FieldDescriptor * field,MessageFactory * factory) const1499 Message* Reflection::MutableMessage(Message* message,
1500 const FieldDescriptor* field,
1501 MessageFactory* factory) const {
1502 USAGE_CHECK_ALL(MutableMessage, SINGULAR, MESSAGE);
1503 CheckInvalidAccess(schema_, field);
1504
1505 if (factory == nullptr) factory = message_factory_;
1506
1507 if (field->is_extension()) {
1508 return static_cast<Message*>(
1509 MutableExtensionSet(message)->MutableMessage(field, factory));
1510 } else {
1511 Message* result;
1512
1513 Message** result_holder = MutableRaw<Message*>(message, field);
1514
1515 if (schema_.InRealOneof(field)) {
1516 if (!HasOneofField(*message, field)) {
1517 ClearOneof(message, field->containing_oneof());
1518 result_holder = MutableField<Message*>(message, field);
1519 const Message* default_message = DefaultRaw<const Message*>(field);
1520 *result_holder = default_message->New(message->GetArena());
1521 }
1522 } else {
1523 SetBit(message, field);
1524 }
1525
1526 if (*result_holder == nullptr) {
1527 const Message* default_message = DefaultRaw<const Message*>(field);
1528 *result_holder = default_message->New(message->GetArena());
1529 }
1530 result = *result_holder;
1531 return result;
1532 }
1533 }
1534
UnsafeArenaSetAllocatedMessage(Message * message,Message * sub_message,const FieldDescriptor * field) const1535 void Reflection::UnsafeArenaSetAllocatedMessage(
1536 Message* message, Message* sub_message,
1537 const FieldDescriptor* field) const {
1538 USAGE_CHECK_ALL(SetAllocatedMessage, SINGULAR, MESSAGE);
1539 CheckInvalidAccess(schema_, field);
1540
1541 if (field->is_extension()) {
1542 MutableExtensionSet(message)->UnsafeArenaSetAllocatedMessage(
1543 field->number(), field->type(), field, sub_message);
1544 } else {
1545 if (schema_.InRealOneof(field)) {
1546 if (sub_message == nullptr) {
1547 ClearOneof(message, field->containing_oneof());
1548 return;
1549 }
1550 ClearOneof(message, field->containing_oneof());
1551 *MutableRaw<Message*>(message, field) = sub_message;
1552 SetOneofCase(message, field);
1553 return;
1554 }
1555
1556 if (sub_message == nullptr) {
1557 ClearBit(message, field);
1558 } else {
1559 SetBit(message, field);
1560 }
1561 Message** sub_message_holder = MutableRaw<Message*>(message, field);
1562 if (GetArena(message) == nullptr) {
1563 delete *sub_message_holder;
1564 }
1565 *sub_message_holder = sub_message;
1566 }
1567 }
1568
SetAllocatedMessage(Message * message,Message * sub_message,const FieldDescriptor * field) const1569 void Reflection::SetAllocatedMessage(Message* message, Message* sub_message,
1570 const FieldDescriptor* field) const {
1571 CheckInvalidAccess(schema_, field);
1572
1573 // If message and sub-message are in different memory ownership domains
1574 // (different arenas, or one is on heap and one is not), then we may need to
1575 // do a copy.
1576 if (sub_message != nullptr &&
1577 sub_message->GetArena() != message->GetArena()) {
1578 if (sub_message->GetArena() == nullptr && message->GetArena() != nullptr) {
1579 // Case 1: parent is on an arena and child is heap-allocated. We can add
1580 // the child to the arena's Own() list to free on arena destruction, then
1581 // set our pointer.
1582 message->GetArena()->Own(sub_message);
1583 UnsafeArenaSetAllocatedMessage(message, sub_message, field);
1584 } else {
1585 // Case 2: all other cases. We need to make a copy. MutableMessage() will
1586 // either get the existing message object, or instantiate a new one as
1587 // appropriate w.r.t. our arena.
1588 Message* sub_message_copy = MutableMessage(message, field);
1589 sub_message_copy->CopyFrom(*sub_message);
1590 }
1591 } else {
1592 // Same memory ownership domains.
1593 UnsafeArenaSetAllocatedMessage(message, sub_message, field);
1594 }
1595 }
1596
UnsafeArenaReleaseMessage(Message * message,const FieldDescriptor * field,MessageFactory * factory) const1597 Message* Reflection::UnsafeArenaReleaseMessage(Message* message,
1598 const FieldDescriptor* field,
1599 MessageFactory* factory) const {
1600 USAGE_CHECK_ALL(ReleaseMessage, SINGULAR, MESSAGE);
1601 CheckInvalidAccess(schema_, field);
1602
1603 if (factory == nullptr) factory = message_factory_;
1604
1605 if (field->is_extension()) {
1606 return static_cast<Message*>(
1607 MutableExtensionSet(message)->UnsafeArenaReleaseMessage(field,
1608 factory));
1609 } else {
1610 if (!(field->is_repeated() || schema_.InRealOneof(field))) {
1611 ClearBit(message, field);
1612 }
1613 if (schema_.InRealOneof(field)) {
1614 if (HasOneofField(*message, field)) {
1615 *MutableOneofCase(message, field->containing_oneof()) = 0;
1616 } else {
1617 return nullptr;
1618 }
1619 }
1620 Message** result = MutableRaw<Message*>(message, field);
1621 Message* ret = *result;
1622 *result = nullptr;
1623 return ret;
1624 }
1625 }
1626
ReleaseMessage(Message * message,const FieldDescriptor * field,MessageFactory * factory) const1627 Message* Reflection::ReleaseMessage(Message* message,
1628 const FieldDescriptor* field,
1629 MessageFactory* factory) const {
1630 CheckInvalidAccess(schema_, field);
1631
1632 Message* released = UnsafeArenaReleaseMessage(message, field, factory);
1633 if (GetArena(message) != nullptr && released != nullptr) {
1634 Message* copy_from_arena = released->New();
1635 copy_from_arena->CopyFrom(*released);
1636 released = copy_from_arena;
1637 }
1638 return released;
1639 }
1640
GetRepeatedMessage(const Message & message,const FieldDescriptor * field,int index) const1641 const Message& Reflection::GetRepeatedMessage(const Message& message,
1642 const FieldDescriptor* field,
1643 int index) const {
1644 USAGE_CHECK_ALL(GetRepeatedMessage, REPEATED, MESSAGE);
1645 CheckInvalidAccess(schema_, field);
1646
1647 if (field->is_extension()) {
1648 return static_cast<const Message&>(
1649 GetExtensionSet(message).GetRepeatedMessage(field->number(), index));
1650 } else {
1651 if (IsMapFieldInApi(field)) {
1652 return GetRaw<MapFieldBase>(message, field)
1653 .GetRepeatedField()
1654 .Get<GenericTypeHandler<Message> >(index);
1655 } else {
1656 return GetRaw<RepeatedPtrFieldBase>(message, field)
1657 .Get<GenericTypeHandler<Message> >(index);
1658 }
1659 }
1660 }
1661
MutableRepeatedMessage(Message * message,const FieldDescriptor * field,int index) const1662 Message* Reflection::MutableRepeatedMessage(Message* message,
1663 const FieldDescriptor* field,
1664 int index) const {
1665 USAGE_CHECK_ALL(MutableRepeatedMessage, REPEATED, MESSAGE);
1666 CheckInvalidAccess(schema_, field);
1667
1668 if (field->is_extension()) {
1669 return static_cast<Message*>(
1670 MutableExtensionSet(message)->MutableRepeatedMessage(field->number(),
1671 index));
1672 } else {
1673 if (IsMapFieldInApi(field)) {
1674 return MutableRaw<MapFieldBase>(message, field)
1675 ->MutableRepeatedField()
1676 ->Mutable<GenericTypeHandler<Message> >(index);
1677 } else {
1678 return MutableRaw<RepeatedPtrFieldBase>(message, field)
1679 ->Mutable<GenericTypeHandler<Message> >(index);
1680 }
1681 }
1682 }
1683
AddMessage(Message * message,const FieldDescriptor * field,MessageFactory * factory) const1684 Message* Reflection::AddMessage(Message* message, const FieldDescriptor* field,
1685 MessageFactory* factory) const {
1686 USAGE_CHECK_ALL(AddMessage, REPEATED, MESSAGE);
1687 CheckInvalidAccess(schema_, field);
1688
1689 if (factory == nullptr) factory = message_factory_;
1690
1691 if (field->is_extension()) {
1692 return static_cast<Message*>(
1693 MutableExtensionSet(message)->AddMessage(field, factory));
1694 } else {
1695 Message* result = nullptr;
1696
1697 // We can't use AddField<Message>() because RepeatedPtrFieldBase doesn't
1698 // know how to allocate one.
1699 RepeatedPtrFieldBase* repeated = nullptr;
1700 if (IsMapFieldInApi(field)) {
1701 repeated =
1702 MutableRaw<MapFieldBase>(message, field)->MutableRepeatedField();
1703 } else {
1704 repeated = MutableRaw<RepeatedPtrFieldBase>(message, field);
1705 }
1706 result = repeated->AddFromCleared<GenericTypeHandler<Message> >();
1707 if (result == nullptr) {
1708 // We must allocate a new object.
1709 const Message* prototype;
1710 if (repeated->size() == 0) {
1711 prototype = factory->GetPrototype(field->message_type());
1712 } else {
1713 prototype = &repeated->Get<GenericTypeHandler<Message> >(0);
1714 }
1715 result = prototype->New(message->GetArena());
1716 // We can guarantee here that repeated and result are either both heap
1717 // allocated or arena owned. So it is safe to call the unsafe version
1718 // of AddAllocated.
1719 repeated->UnsafeArenaAddAllocated<GenericTypeHandler<Message> >(result);
1720 }
1721
1722 return result;
1723 }
1724 }
1725
AddAllocatedMessage(Message * message,const FieldDescriptor * field,Message * new_entry) const1726 void Reflection::AddAllocatedMessage(Message* message,
1727 const FieldDescriptor* field,
1728 Message* new_entry) const {
1729 USAGE_CHECK_ALL(AddAllocatedMessage, REPEATED, MESSAGE);
1730 CheckInvalidAccess(schema_, field);
1731
1732 if (field->is_extension()) {
1733 MutableExtensionSet(message)->AddAllocatedMessage(field, new_entry);
1734 } else {
1735 RepeatedPtrFieldBase* repeated = nullptr;
1736 if (IsMapFieldInApi(field)) {
1737 repeated =
1738 MutableRaw<MapFieldBase>(message, field)->MutableRepeatedField();
1739 } else {
1740 repeated = MutableRaw<RepeatedPtrFieldBase>(message, field);
1741 }
1742 repeated->AddAllocated<GenericTypeHandler<Message> >(new_entry);
1743 }
1744 }
1745
MutableRawRepeatedField(Message * message,const FieldDescriptor * field,FieldDescriptor::CppType cpptype,int ctype,const Descriptor * desc) const1746 void* Reflection::MutableRawRepeatedField(Message* message,
1747 const FieldDescriptor* field,
1748 FieldDescriptor::CppType cpptype,
1749 int ctype,
1750 const Descriptor* desc) const {
1751 USAGE_CHECK_REPEATED("MutableRawRepeatedField");
1752 CheckInvalidAccess(schema_, field);
1753
1754 if (field->cpp_type() != cpptype &&
1755 (field->cpp_type() != FieldDescriptor::CPPTYPE_ENUM ||
1756 cpptype != FieldDescriptor::CPPTYPE_INT32))
1757 ReportReflectionUsageTypeError(descriptor_, field,
1758 "MutableRawRepeatedField", cpptype);
1759 if (desc != nullptr)
1760 GOOGLE_CHECK_EQ(field->message_type(), desc) << "wrong submessage type";
1761 if (field->is_extension()) {
1762 return MutableExtensionSet(message)->MutableRawRepeatedField(
1763 field->number(), field->type(), field->is_packed(), field);
1764 } else {
1765 // Trigger transform for MapField
1766 if (IsMapFieldInApi(field)) {
1767 return MutableRawNonOneof<MapFieldBase>(message, field)
1768 ->MutableRepeatedField();
1769 }
1770 return MutableRawNonOneof<void>(message, field);
1771 }
1772 }
1773
GetRawRepeatedField(const Message & message,const FieldDescriptor * field,FieldDescriptor::CppType cpptype,int ctype,const Descriptor * desc) const1774 const void* Reflection::GetRawRepeatedField(const Message& message,
1775 const FieldDescriptor* field,
1776 FieldDescriptor::CppType cpptype,
1777 int ctype,
1778 const Descriptor* desc) const {
1779 USAGE_CHECK_REPEATED("GetRawRepeatedField");
1780 if (field->cpp_type() != cpptype)
1781 ReportReflectionUsageTypeError(descriptor_, field, "GetRawRepeatedField",
1782 cpptype);
1783 if (ctype >= 0)
1784 GOOGLE_CHECK_EQ(field->options().ctype(), ctype) << "subtype mismatch";
1785 if (desc != nullptr)
1786 GOOGLE_CHECK_EQ(field->message_type(), desc) << "wrong submessage type";
1787 if (field->is_extension()) {
1788 // Should use extension_set::GetRawRepeatedField. However, the required
1789 // parameter "default repeated value" is not very easy to get here.
1790 // Map is not supported in extensions, it is acceptable to use
1791 // extension_set::MutableRawRepeatedField which does not change the message.
1792 return MutableExtensionSet(const_cast<Message*>(&message))
1793 ->MutableRawRepeatedField(field->number(), field->type(),
1794 field->is_packed(), field);
1795 } else {
1796 // Trigger transform for MapField
1797 if (IsMapFieldInApi(field)) {
1798 return &(GetRawNonOneof<MapFieldBase>(message, field).GetRepeatedField());
1799 }
1800 return &GetRawNonOneof<char>(message, field);
1801 }
1802 }
1803
GetOneofFieldDescriptor(const Message & message,const OneofDescriptor * oneof_descriptor) const1804 const FieldDescriptor* Reflection::GetOneofFieldDescriptor(
1805 const Message& message, const OneofDescriptor* oneof_descriptor) const {
1806 if (oneof_descriptor->is_synthetic()) {
1807 const FieldDescriptor* field = oneof_descriptor->field(0);
1808 return HasField(message, field) ? field : nullptr;
1809 }
1810 uint32 field_number = GetOneofCase(message, oneof_descriptor);
1811 if (field_number == 0) {
1812 return nullptr;
1813 }
1814 return descriptor_->FindFieldByNumber(field_number);
1815 }
1816
ContainsMapKey(const Message & message,const FieldDescriptor * field,const MapKey & key) const1817 bool Reflection::ContainsMapKey(const Message& message,
1818 const FieldDescriptor* field,
1819 const MapKey& key) const {
1820 USAGE_CHECK(IsMapFieldInApi(field), "LookupMapValue",
1821 "Field is not a map field.");
1822 return GetRaw<MapFieldBase>(message, field).ContainsMapKey(key);
1823 }
1824
InsertOrLookupMapValue(Message * message,const FieldDescriptor * field,const MapKey & key,MapValueRef * val) const1825 bool Reflection::InsertOrLookupMapValue(Message* message,
1826 const FieldDescriptor* field,
1827 const MapKey& key,
1828 MapValueRef* val) const {
1829 USAGE_CHECK(IsMapFieldInApi(field), "InsertOrLookupMapValue",
1830 "Field is not a map field.");
1831 val->SetType(field->message_type()->FindFieldByName("value")->cpp_type());
1832 return MutableRaw<MapFieldBase>(message, field)
1833 ->InsertOrLookupMapValue(key, val);
1834 }
1835
DeleteMapValue(Message * message,const FieldDescriptor * field,const MapKey & key) const1836 bool Reflection::DeleteMapValue(Message* message, const FieldDescriptor* field,
1837 const MapKey& key) const {
1838 USAGE_CHECK(IsMapFieldInApi(field), "DeleteMapValue",
1839 "Field is not a map field.");
1840 return MutableRaw<MapFieldBase>(message, field)->DeleteMapValue(key);
1841 }
1842
MapBegin(Message * message,const FieldDescriptor * field) const1843 MapIterator Reflection::MapBegin(Message* message,
1844 const FieldDescriptor* field) const {
1845 USAGE_CHECK(IsMapFieldInApi(field), "MapBegin", "Field is not a map field.");
1846 MapIterator iter(message, field);
1847 GetRaw<MapFieldBase>(*message, field).MapBegin(&iter);
1848 return iter;
1849 }
1850
MapEnd(Message * message,const FieldDescriptor * field) const1851 MapIterator Reflection::MapEnd(Message* message,
1852 const FieldDescriptor* field) const {
1853 USAGE_CHECK(IsMapFieldInApi(field), "MapEnd", "Field is not a map field.");
1854 MapIterator iter(message, field);
1855 GetRaw<MapFieldBase>(*message, field).MapEnd(&iter);
1856 return iter;
1857 }
1858
MapSize(const Message & message,const FieldDescriptor * field) const1859 int Reflection::MapSize(const Message& message,
1860 const FieldDescriptor* field) const {
1861 USAGE_CHECK(IsMapFieldInApi(field), "MapSize", "Field is not a map field.");
1862 return GetRaw<MapFieldBase>(message, field).size();
1863 }
1864
1865 // -----------------------------------------------------------------------------
1866
FindKnownExtensionByName(const std::string & name) const1867 const FieldDescriptor* Reflection::FindKnownExtensionByName(
1868 const std::string& name) const {
1869 if (!schema_.HasExtensionSet()) return nullptr;
1870 return descriptor_pool_->FindExtensionByPrintableName(descriptor_, name);
1871 }
1872
FindKnownExtensionByNumber(int number) const1873 const FieldDescriptor* Reflection::FindKnownExtensionByNumber(
1874 int number) const {
1875 if (!schema_.HasExtensionSet()) return nullptr;
1876 return descriptor_pool_->FindExtensionByNumber(descriptor_, number);
1877 }
1878
SupportsUnknownEnumValues() const1879 bool Reflection::SupportsUnknownEnumValues() const {
1880 return CreateUnknownEnumValues(descriptor_->file());
1881 }
1882
1883 // ===================================================================
1884 // Some private helpers.
1885
1886 // These simple template accessors obtain pointers (or references) to
1887 // the given field.
1888
1889 template <class Type>
GetRawNonOneof(const Message & message,const FieldDescriptor * field) const1890 const Type& Reflection::GetRawNonOneof(const Message& message,
1891 const FieldDescriptor* field) const {
1892 return GetConstRefAtOffset<Type>(message,
1893 schema_.GetFieldOffsetNonOneof(field));
1894 }
1895
1896 template <class Type>
MutableRawNonOneof(Message * message,const FieldDescriptor * field) const1897 Type* Reflection::MutableRawNonOneof(Message* message,
1898 const FieldDescriptor* field) const {
1899 return GetPointerAtOffset<Type>(message,
1900 schema_.GetFieldOffsetNonOneof(field));
1901 }
1902
1903 template <typename Type>
GetRaw(const Message & message,const FieldDescriptor * field) const1904 const Type& Reflection::GetRaw(const Message& message,
1905 const FieldDescriptor* field) const {
1906 if (schema_.InRealOneof(field) && !HasOneofField(message, field)) {
1907 return DefaultRaw<Type>(field);
1908 }
1909 return GetConstRefAtOffset<Type>(message, schema_.GetFieldOffset(field));
1910 }
1911
IsInlined(const FieldDescriptor * field) const1912 bool Reflection::IsInlined(const FieldDescriptor* field) const {
1913 return schema_.IsFieldInlined(field);
1914 }
1915
1916 template <typename Type>
MutableRaw(Message * message,const FieldDescriptor * field) const1917 Type* Reflection::MutableRaw(Message* message,
1918 const FieldDescriptor* field) const {
1919 return GetPointerAtOffset<Type>(message, schema_.GetFieldOffset(field));
1920 }
1921
GetHasBits(const Message & message) const1922 const uint32* Reflection::GetHasBits(const Message& message) const {
1923 GOOGLE_DCHECK(schema_.HasHasbits());
1924 return &GetConstRefAtOffset<uint32>(message, schema_.HasBitsOffset());
1925 }
1926
MutableHasBits(Message * message) const1927 uint32* Reflection::MutableHasBits(Message* message) const {
1928 GOOGLE_DCHECK(schema_.HasHasbits());
1929 return GetPointerAtOffset<uint32>(message, schema_.HasBitsOffset());
1930 }
1931
GetOneofCase(const Message & message,const OneofDescriptor * oneof_descriptor) const1932 uint32 Reflection::GetOneofCase(const Message& message,
1933 const OneofDescriptor* oneof_descriptor) const {
1934 GOOGLE_DCHECK(!oneof_descriptor->is_synthetic());
1935 return GetConstRefAtOffset<uint32>(
1936 message, schema_.GetOneofCaseOffset(oneof_descriptor));
1937 }
1938
MutableOneofCase(Message * message,const OneofDescriptor * oneof_descriptor) const1939 uint32* Reflection::MutableOneofCase(
1940 Message* message, const OneofDescriptor* oneof_descriptor) const {
1941 GOOGLE_DCHECK(!oneof_descriptor->is_synthetic());
1942 return GetPointerAtOffset<uint32>(
1943 message, schema_.GetOneofCaseOffset(oneof_descriptor));
1944 }
1945
GetExtensionSet(const Message & message) const1946 const ExtensionSet& Reflection::GetExtensionSet(const Message& message) const {
1947 return GetConstRefAtOffset<ExtensionSet>(message,
1948 schema_.GetExtensionSetOffset());
1949 }
1950
MutableExtensionSet(Message * message) const1951 ExtensionSet* Reflection::MutableExtensionSet(Message* message) const {
1952 return GetPointerAtOffset<ExtensionSet>(message,
1953 schema_.GetExtensionSetOffset());
1954 }
1955
GetArena(Message * message) const1956 Arena* Reflection::GetArena(Message* message) const {
1957 return GetInternalMetadata(*message).arena();
1958 }
1959
GetInternalMetadata(const Message & message) const1960 const InternalMetadata& Reflection::GetInternalMetadata(
1961 const Message& message) const {
1962 return GetConstRefAtOffset<InternalMetadata>(message,
1963 schema_.GetMetadataOffset());
1964 }
1965
MutableInternalMetadata(Message * message) const1966 InternalMetadata* Reflection::MutableInternalMetadata(Message* message) const {
1967 return GetPointerAtOffset<InternalMetadata>(message,
1968 schema_.GetMetadataOffset());
1969 }
1970
1971 // Simple accessors for manipulating has_bits_.
HasBit(const Message & message,const FieldDescriptor * field) const1972 bool Reflection::HasBit(const Message& message,
1973 const FieldDescriptor* field) const {
1974 GOOGLE_DCHECK(!field->options().weak());
1975 if (schema_.HasBitIndex(field) != -1) {
1976 return IsIndexInHasBitSet(GetHasBits(message), schema_.HasBitIndex(field));
1977 }
1978
1979 // Intentionally check here because HasBitIndex(field) != -1 means valid.
1980 CheckInvalidAccess(schema_, field);
1981
1982 // proto3: no has-bits. All fields present except messages, which are
1983 // present only if their message-field pointer is non-null.
1984 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
1985 return !schema_.IsDefaultInstance(message) &&
1986 GetRaw<const Message*>(message, field) != nullptr;
1987 } else {
1988 // Non-message field (and non-oneof, since that was handled in HasField()
1989 // before calling us), and singular (again, checked in HasField). So, this
1990 // field must be a scalar.
1991
1992 // Scalar primitive (numeric or string/bytes) fields are present if
1993 // their value is non-zero (numeric) or non-empty (string/bytes). N.B.:
1994 // we must use this definition here, rather than the "scalar fields
1995 // always present" in the proto3 docs, because MergeFrom() semantics
1996 // require presence as "present on wire", and reflection-based merge
1997 // (which uses HasField()) needs to be consistent with this.
1998 switch (field->cpp_type()) {
1999 case FieldDescriptor::CPPTYPE_STRING:
2000 switch (field->options().ctype()) {
2001 default: {
2002 if (IsInlined(field)) {
2003 return !GetField<InlinedStringField>(message, field)
2004 .GetNoArena()
2005 .empty();
2006 }
2007 return GetField<ArenaStringPtr>(message, field).Get().size() > 0;
2008 }
2009 }
2010 return false;
2011 case FieldDescriptor::CPPTYPE_BOOL:
2012 return GetRaw<bool>(message, field) != false;
2013 case FieldDescriptor::CPPTYPE_INT32:
2014 return GetRaw<int32>(message, field) != 0;
2015 case FieldDescriptor::CPPTYPE_INT64:
2016 return GetRaw<int64>(message, field) != 0;
2017 case FieldDescriptor::CPPTYPE_UINT32:
2018 return GetRaw<uint32>(message, field) != 0;
2019 case FieldDescriptor::CPPTYPE_UINT64:
2020 return GetRaw<uint64>(message, field) != 0;
2021 case FieldDescriptor::CPPTYPE_FLOAT:
2022 return GetRaw<float>(message, field) != 0.0;
2023 case FieldDescriptor::CPPTYPE_DOUBLE:
2024 return GetRaw<double>(message, field) != 0.0;
2025 case FieldDescriptor::CPPTYPE_ENUM:
2026 return GetRaw<int>(message, field) != 0;
2027 case FieldDescriptor::CPPTYPE_MESSAGE:
2028 // handled above; avoid warning
2029 break;
2030 }
2031 GOOGLE_LOG(FATAL) << "Reached impossible case in HasBit().";
2032 return false;
2033 }
2034 }
2035
SetBit(Message * message,const FieldDescriptor * field) const2036 void Reflection::SetBit(Message* message, const FieldDescriptor* field) const {
2037 GOOGLE_DCHECK(!field->options().weak());
2038 const uint32 index = schema_.HasBitIndex(field);
2039 if (index == -1) return;
2040 MutableHasBits(message)[index / 32] |=
2041 (static_cast<uint32>(1) << (index % 32));
2042 }
2043
ClearBit(Message * message,const FieldDescriptor * field) const2044 void Reflection::ClearBit(Message* message,
2045 const FieldDescriptor* field) const {
2046 GOOGLE_DCHECK(!field->options().weak());
2047 if (!schema_.HasHasbits()) {
2048 return;
2049 }
2050 const uint32 index = schema_.HasBitIndex(field);
2051 if (index == -1) return;
2052 MutableHasBits(message)[index / 32] &=
2053 ~(static_cast<uint32>(1) << (index % 32));
2054 }
2055
SwapBit(Message * message1,Message * message2,const FieldDescriptor * field) const2056 void Reflection::SwapBit(Message* message1, Message* message2,
2057 const FieldDescriptor* field) const {
2058 GOOGLE_DCHECK(!field->options().weak());
2059 if (!schema_.HasHasbits()) {
2060 return;
2061 }
2062 bool temp_has_bit = HasBit(*message1, field);
2063 if (HasBit(*message2, field)) {
2064 SetBit(message1, field);
2065 } else {
2066 ClearBit(message1, field);
2067 }
2068 if (temp_has_bit) {
2069 SetBit(message2, field);
2070 } else {
2071 ClearBit(message2, field);
2072 }
2073 }
2074
HasOneof(const Message & message,const OneofDescriptor * oneof_descriptor) const2075 bool Reflection::HasOneof(const Message& message,
2076 const OneofDescriptor* oneof_descriptor) const {
2077 if (oneof_descriptor->is_synthetic()) {
2078 return HasField(message, oneof_descriptor->field(0));
2079 }
2080 return (GetOneofCase(message, oneof_descriptor) > 0);
2081 }
2082
HasOneofField(const Message & message,const FieldDescriptor * field) const2083 bool Reflection::HasOneofField(const Message& message,
2084 const FieldDescriptor* field) const {
2085 return (GetOneofCase(message, field->containing_oneof()) == field->number());
2086 }
2087
SetOneofCase(Message * message,const FieldDescriptor * field) const2088 void Reflection::SetOneofCase(Message* message,
2089 const FieldDescriptor* field) const {
2090 *MutableOneofCase(message, field->containing_oneof()) = field->number();
2091 }
2092
ClearOneofField(Message * message,const FieldDescriptor * field) const2093 void Reflection::ClearOneofField(Message* message,
2094 const FieldDescriptor* field) const {
2095 if (HasOneofField(*message, field)) {
2096 ClearOneof(message, field->containing_oneof());
2097 }
2098 }
2099
ClearOneof(Message * message,const OneofDescriptor * oneof_descriptor) const2100 void Reflection::ClearOneof(Message* message,
2101 const OneofDescriptor* oneof_descriptor) const {
2102 if (oneof_descriptor->is_synthetic()) {
2103 ClearField(message, oneof_descriptor->field(0));
2104 return;
2105 }
2106 // TODO(jieluo): Consider to cache the unused object instead of deleting
2107 // it. It will be much faster if an application switches a lot from
2108 // a few oneof fields. Time/space tradeoff
2109 uint32 oneof_case = GetOneofCase(*message, oneof_descriptor);
2110 if (oneof_case > 0) {
2111 const FieldDescriptor* field = descriptor_->FindFieldByNumber(oneof_case);
2112 if (GetArena(message) == nullptr) {
2113 switch (field->cpp_type()) {
2114 case FieldDescriptor::CPPTYPE_STRING: {
2115 switch (field->options().ctype()) {
2116 default: // TODO(kenton): Support other string reps.
2117 case FieldOptions::STRING: {
2118 const std::string* default_ptr =
2119 &DefaultRaw<ArenaStringPtr>(field).Get();
2120 MutableField<ArenaStringPtr>(message, field)
2121 ->Destroy(default_ptr, GetArena(message));
2122 break;
2123 }
2124 }
2125 break;
2126 }
2127
2128 case FieldDescriptor::CPPTYPE_MESSAGE:
2129 delete *MutableRaw<Message*>(message, field);
2130 break;
2131 default:
2132 break;
2133 }
2134 }
2135
2136 *MutableOneofCase(message, oneof_descriptor) = 0;
2137 }
2138 }
2139
2140 #define HANDLE_TYPE(TYPE, CPPTYPE, CTYPE) \
2141 template <> \
2142 const RepeatedField<TYPE>& Reflection::GetRepeatedFieldInternal<TYPE>( \
2143 const Message& message, const FieldDescriptor* field) const { \
2144 return *static_cast<RepeatedField<TYPE>*>(MutableRawRepeatedField( \
2145 const_cast<Message*>(&message), field, CPPTYPE, CTYPE, NULL)); \
2146 } \
2147 \
2148 template <> \
2149 RepeatedField<TYPE>* Reflection::MutableRepeatedFieldInternal<TYPE>( \
2150 Message * message, const FieldDescriptor* field) const { \
2151 return static_cast<RepeatedField<TYPE>*>( \
2152 MutableRawRepeatedField(message, field, CPPTYPE, CTYPE, NULL)); \
2153 }
2154
2155 HANDLE_TYPE(int32, FieldDescriptor::CPPTYPE_INT32, -1);
2156 HANDLE_TYPE(int64, FieldDescriptor::CPPTYPE_INT64, -1);
2157 HANDLE_TYPE(uint32, FieldDescriptor::CPPTYPE_UINT32, -1);
2158 HANDLE_TYPE(uint64, FieldDescriptor::CPPTYPE_UINT64, -1);
2159 HANDLE_TYPE(float, FieldDescriptor::CPPTYPE_FLOAT, -1);
2160 HANDLE_TYPE(double, FieldDescriptor::CPPTYPE_DOUBLE, -1);
2161 HANDLE_TYPE(bool, FieldDescriptor::CPPTYPE_BOOL, -1);
2162
2163
2164 #undef HANDLE_TYPE
2165
MutableRawRepeatedString(Message * message,const FieldDescriptor * field,bool is_string) const2166 void* Reflection::MutableRawRepeatedString(Message* message,
2167 const FieldDescriptor* field,
2168 bool is_string) const {
2169 return MutableRawRepeatedField(message, field,
2170 FieldDescriptor::CPPTYPE_STRING,
2171 FieldOptions::STRING, NULL);
2172 }
2173
2174 // Template implementations of basic accessors. Inline because each
2175 // template instance is only called from one location. These are
2176 // used for all types except messages.
2177 template <typename Type>
GetField(const Message & message,const FieldDescriptor * field) const2178 const Type& Reflection::GetField(const Message& message,
2179 const FieldDescriptor* field) const {
2180 return GetRaw<Type>(message, field);
2181 }
2182
2183 template <typename Type>
SetField(Message * message,const FieldDescriptor * field,const Type & value) const2184 void Reflection::SetField(Message* message, const FieldDescriptor* field,
2185 const Type& value) const {
2186 bool real_oneof = schema_.InRealOneof(field);
2187 if (real_oneof && !HasOneofField(*message, field)) {
2188 ClearOneof(message, field->containing_oneof());
2189 }
2190 *MutableRaw<Type>(message, field) = value;
2191 real_oneof ? SetOneofCase(message, field) : SetBit(message, field);
2192 }
2193
2194 template <typename Type>
MutableField(Message * message,const FieldDescriptor * field) const2195 Type* Reflection::MutableField(Message* message,
2196 const FieldDescriptor* field) const {
2197 schema_.InRealOneof(field) ? SetOneofCase(message, field)
2198 : SetBit(message, field);
2199 return MutableRaw<Type>(message, field);
2200 }
2201
2202 template <typename Type>
GetRepeatedField(const Message & message,const FieldDescriptor * field,int index) const2203 const Type& Reflection::GetRepeatedField(const Message& message,
2204 const FieldDescriptor* field,
2205 int index) const {
2206 return GetRaw<RepeatedField<Type> >(message, field).Get(index);
2207 }
2208
2209 template <typename Type>
GetRepeatedPtrField(const Message & message,const FieldDescriptor * field,int index) const2210 const Type& Reflection::GetRepeatedPtrField(const Message& message,
2211 const FieldDescriptor* field,
2212 int index) const {
2213 return GetRaw<RepeatedPtrField<Type> >(message, field).Get(index);
2214 }
2215
2216 template <typename Type>
SetRepeatedField(Message * message,const FieldDescriptor * field,int index,Type value) const2217 void Reflection::SetRepeatedField(Message* message,
2218 const FieldDescriptor* field, int index,
2219 Type value) const {
2220 MutableRaw<RepeatedField<Type> >(message, field)->Set(index, value);
2221 }
2222
2223 template <typename Type>
MutableRepeatedField(Message * message,const FieldDescriptor * field,int index) const2224 Type* Reflection::MutableRepeatedField(Message* message,
2225 const FieldDescriptor* field,
2226 int index) const {
2227 RepeatedPtrField<Type>* repeated =
2228 MutableRaw<RepeatedPtrField<Type> >(message, field);
2229 return repeated->Mutable(index);
2230 }
2231
2232 template <typename Type>
AddField(Message * message,const FieldDescriptor * field,const Type & value) const2233 void Reflection::AddField(Message* message, const FieldDescriptor* field,
2234 const Type& value) const {
2235 MutableRaw<RepeatedField<Type> >(message, field)->Add(value);
2236 }
2237
2238 template <typename Type>
AddField(Message * message,const FieldDescriptor * field) const2239 Type* Reflection::AddField(Message* message,
2240 const FieldDescriptor* field) const {
2241 RepeatedPtrField<Type>* repeated =
2242 MutableRaw<RepeatedPtrField<Type> >(message, field);
2243 return repeated->Add();
2244 }
2245
GetMessageFactory() const2246 MessageFactory* Reflection::GetMessageFactory() const {
2247 return message_factory_;
2248 }
2249
RepeatedFieldData(Message * message,const FieldDescriptor * field,FieldDescriptor::CppType cpp_type,const Descriptor * message_type) const2250 void* Reflection::RepeatedFieldData(Message* message,
2251 const FieldDescriptor* field,
2252 FieldDescriptor::CppType cpp_type,
2253 const Descriptor* message_type) const {
2254 GOOGLE_CHECK(field->is_repeated());
2255 GOOGLE_CHECK(field->cpp_type() == cpp_type ||
2256 (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM &&
2257 cpp_type == FieldDescriptor::CPPTYPE_INT32))
2258 << "The type parameter T in RepeatedFieldRef<T> API doesn't match "
2259 << "the actual field type (for enums T should be the generated enum "
2260 << "type or int32).";
2261 if (message_type != nullptr) {
2262 GOOGLE_CHECK_EQ(message_type, field->message_type());
2263 }
2264 if (field->is_extension()) {
2265 return MutableExtensionSet(message)->MutableRawRepeatedField(
2266 field->number(), field->type(), field->is_packed(), field);
2267 } else {
2268 return MutableRawNonOneof<char>(message, field);
2269 }
2270 }
2271
MutableMapData(Message * message,const FieldDescriptor * field) const2272 MapFieldBase* Reflection::MutableMapData(Message* message,
2273 const FieldDescriptor* field) const {
2274 USAGE_CHECK(IsMapFieldInApi(field), "GetMapData",
2275 "Field is not a map field.");
2276 return MutableRaw<MapFieldBase>(message, field);
2277 }
2278
GetMapData(const Message & message,const FieldDescriptor * field) const2279 const MapFieldBase* Reflection::GetMapData(const Message& message,
2280 const FieldDescriptor* field) const {
2281 USAGE_CHECK(IsMapFieldInApi(field), "GetMapData",
2282 "Field is not a map field.");
2283 return &(GetRaw<MapFieldBase>(message, field));
2284 }
2285
2286 namespace {
2287
2288 // Helper function to transform migration schema into reflection schema.
MigrationToReflectionSchema(const Message * const * default_instance,const uint32 * offsets,MigrationSchema migration_schema)2289 ReflectionSchema MigrationToReflectionSchema(
2290 const Message* const* default_instance, const uint32* offsets,
2291 MigrationSchema migration_schema) {
2292 ReflectionSchema result;
2293 result.default_instance_ = *default_instance;
2294 // First 6 offsets are offsets to the special fields. The following offsets
2295 // are the proto fields.
2296 result.offsets_ = offsets + migration_schema.offsets_index + 5;
2297 result.has_bit_indices_ = offsets + migration_schema.has_bit_indices_index;
2298 result.has_bits_offset_ = offsets[migration_schema.offsets_index + 0];
2299 result.metadata_offset_ = offsets[migration_schema.offsets_index + 1];
2300 result.extensions_offset_ = offsets[migration_schema.offsets_index + 2];
2301 result.oneof_case_offset_ = offsets[migration_schema.offsets_index + 3];
2302 result.object_size_ = migration_schema.object_size;
2303 result.weak_field_map_offset_ = offsets[migration_schema.offsets_index + 4];
2304 return result;
2305 }
2306
2307 } // namespace
2308
2309 class AssignDescriptorsHelper {
2310 public:
AssignDescriptorsHelper(MessageFactory * factory,Metadata * file_level_metadata,const EnumDescriptor ** file_level_enum_descriptors,const MigrationSchema * schemas,const Message * const * default_instance_data,const uint32 * offsets)2311 AssignDescriptorsHelper(MessageFactory* factory,
2312 Metadata* file_level_metadata,
2313 const EnumDescriptor** file_level_enum_descriptors,
2314 const MigrationSchema* schemas,
2315 const Message* const* default_instance_data,
2316 const uint32* offsets)
2317 : factory_(factory),
2318 file_level_metadata_(file_level_metadata),
2319 file_level_enum_descriptors_(file_level_enum_descriptors),
2320 schemas_(schemas),
2321 default_instance_data_(default_instance_data),
2322 offsets_(offsets) {}
2323
AssignMessageDescriptor(const Descriptor * descriptor)2324 void AssignMessageDescriptor(const Descriptor* descriptor) {
2325 for (int i = 0; i < descriptor->nested_type_count(); i++) {
2326 AssignMessageDescriptor(descriptor->nested_type(i));
2327 }
2328
2329 file_level_metadata_->descriptor = descriptor;
2330
2331 file_level_metadata_->reflection =
2332 new Reflection(descriptor,
2333 MigrationToReflectionSchema(default_instance_data_,
2334 offsets_, *schemas_),
2335 DescriptorPool::internal_generated_pool(), factory_);
2336 for (int i = 0; i < descriptor->enum_type_count(); i++) {
2337 AssignEnumDescriptor(descriptor->enum_type(i));
2338 }
2339 schemas_++;
2340 default_instance_data_++;
2341 file_level_metadata_++;
2342 }
2343
AssignEnumDescriptor(const EnumDescriptor * descriptor)2344 void AssignEnumDescriptor(const EnumDescriptor* descriptor) {
2345 *file_level_enum_descriptors_ = descriptor;
2346 file_level_enum_descriptors_++;
2347 }
2348
GetCurrentMetadataPtr() const2349 const Metadata* GetCurrentMetadataPtr() const { return file_level_metadata_; }
2350
2351 private:
2352 MessageFactory* factory_;
2353 Metadata* file_level_metadata_;
2354 const EnumDescriptor** file_level_enum_descriptors_;
2355 const MigrationSchema* schemas_;
2356 const Message* const* default_instance_data_;
2357 const uint32* offsets_;
2358 };
2359
2360 namespace {
2361
2362 // We have the routines that assign descriptors and build reflection
2363 // automatically delete the allocated reflection. MetadataOwner owns
2364 // all the allocated reflection instances.
2365 struct MetadataOwner {
~MetadataOwnergoogle::protobuf::__anonf7e405f80511::MetadataOwner2366 ~MetadataOwner() {
2367 for (auto range : metadata_arrays_) {
2368 for (const Metadata* m = range.first; m < range.second; m++) {
2369 delete m->reflection;
2370 }
2371 }
2372 }
2373
AddArraygoogle::protobuf::__anonf7e405f80511::MetadataOwner2374 void AddArray(const Metadata* begin, const Metadata* end) {
2375 mu_.Lock();
2376 metadata_arrays_.push_back(std::make_pair(begin, end));
2377 mu_.Unlock();
2378 }
2379
Instancegoogle::protobuf::__anonf7e405f80511::MetadataOwner2380 static MetadataOwner* Instance() {
2381 static MetadataOwner* res = OnShutdownDelete(new MetadataOwner);
2382 return res;
2383 }
2384
2385 private:
2386 MetadataOwner() = default; // private because singleton
2387
2388 WrappedMutex mu_;
2389 std::vector<std::pair<const Metadata*, const Metadata*> > metadata_arrays_;
2390 };
2391
AssignDescriptorsImpl(const DescriptorTable * table,bool eager)2392 void AssignDescriptorsImpl(const DescriptorTable* table, bool eager) {
2393 // Ensure the file descriptor is added to the pool.
2394 {
2395 // This only happens once per proto file. So a global mutex to serialize
2396 // calls to AddDescriptors.
2397 static WrappedMutex mu{GOOGLE_PROTOBUF_LINKER_INITIALIZED};
2398 mu.Lock();
2399 AddDescriptors(table);
2400 mu.Unlock();
2401 }
2402 if (eager) {
2403 // Normally we do not want to eagerly build descriptors of our deps.
2404 // However if this proto is optimized for code size (ie using reflection)
2405 // and it has a message extending a custom option of a descriptor with that
2406 // message being optimized for code size as well. Building the descriptors
2407 // in this file requires parsing the serialized file descriptor, which now
2408 // requires parsing the message extension, which potentially requires
2409 // building the descriptor of the message extending one of the options.
2410 // However we are already updating descriptor pool under a lock. To prevent
2411 // this the compiler statically looks for this case and we just make sure we
2412 // first build the descriptors of all our dependencies, preventing the
2413 // deadlock.
2414 int num_deps = table->num_deps;
2415 for (int i = 0; i < num_deps; i++) {
2416 // In case of weak fields deps[i] could be null.
2417 if (table->deps[i]) AssignDescriptors(table->deps[i], true);
2418 }
2419 }
2420
2421 // Fill the arrays with pointers to descriptors and reflection classes.
2422 const FileDescriptor* file =
2423 DescriptorPool::internal_generated_pool()->FindFileByName(
2424 table->filename);
2425 GOOGLE_CHECK(file != nullptr);
2426
2427 MessageFactory* factory = MessageFactory::generated_factory();
2428
2429 AssignDescriptorsHelper helper(
2430 factory, table->file_level_metadata, table->file_level_enum_descriptors,
2431 table->schemas, table->default_instances, table->offsets);
2432
2433 for (int i = 0; i < file->message_type_count(); i++) {
2434 helper.AssignMessageDescriptor(file->message_type(i));
2435 }
2436
2437 for (int i = 0; i < file->enum_type_count(); i++) {
2438 helper.AssignEnumDescriptor(file->enum_type(i));
2439 }
2440 if (file->options().cc_generic_services()) {
2441 for (int i = 0; i < file->service_count(); i++) {
2442 table->file_level_service_descriptors[i] = file->service(i);
2443 }
2444 }
2445 MetadataOwner::Instance()->AddArray(table->file_level_metadata,
2446 helper.GetCurrentMetadataPtr());
2447 }
2448
AddDescriptorsImpl(const DescriptorTable * table)2449 void AddDescriptorsImpl(const DescriptorTable* table) {
2450 // Reflection refers to the default instances so make sure they are
2451 // initialized.
2452 for (int i = 0; i < table->num_sccs; i++) {
2453 internal::InitSCC(table->init_default_instances[i]);
2454 }
2455
2456 // Ensure all dependent descriptors are registered to the generated descriptor
2457 // pool and message factory.
2458 int num_deps = table->num_deps;
2459 for (int i = 0; i < num_deps; i++) {
2460 // In case of weak fields deps[i] could be null.
2461 if (table->deps[i]) AddDescriptors(table->deps[i]);
2462 }
2463
2464 // Register the descriptor of this file.
2465 DescriptorPool::InternalAddGeneratedFile(table->descriptor, table->size);
2466 MessageFactory::InternalRegisterGeneratedFile(table);
2467 }
2468
2469 } // namespace
2470
2471 // Separate function because it needs to be a friend of
2472 // Reflection
RegisterAllTypesInternal(const Metadata * file_level_metadata,int size)2473 void RegisterAllTypesInternal(const Metadata* file_level_metadata, int size) {
2474 for (int i = 0; i < size; i++) {
2475 const Reflection* reflection = file_level_metadata[i].reflection;
2476 MessageFactory::InternalRegisterGeneratedMessage(
2477 file_level_metadata[i].descriptor,
2478 reflection->schema_.default_instance_);
2479 }
2480 }
2481
2482 namespace internal {
2483
AssignDescriptors(const DescriptorTable * table,bool eager)2484 void AssignDescriptors(const DescriptorTable* table, bool eager) {
2485 if (!eager) eager = table->is_eager;
2486 call_once(*table->once, AssignDescriptorsImpl, table, eager);
2487 }
2488
AddDescriptors(const DescriptorTable * table)2489 void AddDescriptors(const DescriptorTable* table) {
2490 // AddDescriptors is not thread safe. Callers need to ensure calls are
2491 // properly serialized. This function is only called pre-main by global
2492 // descriptors and we can assume single threaded access or it's called
2493 // by AssignDescriptorImpl which uses a mutex to sequence calls.
2494 if (table->is_initialized) return;
2495 table->is_initialized = true;
2496 AddDescriptorsImpl(table);
2497 }
2498
RegisterFileLevelMetadata(const DescriptorTable * table)2499 void RegisterFileLevelMetadata(const DescriptorTable* table) {
2500 AssignDescriptors(table);
2501 RegisterAllTypesInternal(table->file_level_metadata, table->num_messages);
2502 }
2503
UnknownFieldSetSerializer(const uint8 * base,uint32 offset,uint32 tag,uint32 has_offset,io::CodedOutputStream * output)2504 void UnknownFieldSetSerializer(const uint8* base, uint32 offset, uint32 tag,
2505 uint32 has_offset,
2506 io::CodedOutputStream* output) {
2507 const void* ptr = base + offset;
2508 const InternalMetadata* metadata = static_cast<const InternalMetadata*>(ptr);
2509 if (metadata->have_unknown_fields()) {
2510 internal::WireFormat::SerializeUnknownFields(
2511 metadata->unknown_fields<UnknownFieldSet>(
2512 UnknownFieldSet::default_instance),
2513 output);
2514 }
2515 }
2516
2517 } // namespace internal
2518 } // namespace protobuf
2519 } // namespace google
2520