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