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