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::__anonf2ed1b540311::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,std::string value) const1193 void Reflection::SetString(Message* message, const FieldDescriptor* field,
1194 std::string value) const {
1195 USAGE_CHECK_ALL(SetString, SINGULAR, STRING);
1196 if (field->is_extension()) {
1197 return MutableExtensionSet(message)->SetString(
1198 field->number(), field->type(), std::move(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, std::move(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(std::move(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,std::string value) const1257 void Reflection::SetRepeatedString(Message* message,
1258 const FieldDescriptor* field, int index,
1259 std::string value) const {
1260 USAGE_CHECK_ALL(SetRepeatedString, REPEATED, STRING);
1261 if (field->is_extension()) {
1262 MutableExtensionSet(message)->SetRepeatedString(field->number(), index,
1263 std::move(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)
1269 ->assign(std::move(value));
1270 break;
1271 }
1272 }
1273 }
1274
1275
AddString(Message * message,const FieldDescriptor * field,std::string value) const1276 void Reflection::AddString(Message* message, const FieldDescriptor* field,
1277 std::string value) const {
1278 USAGE_CHECK_ALL(AddString, REPEATED, STRING);
1279 if (field->is_extension()) {
1280 MutableExtensionSet(message)->AddString(field->number(), field->type(),
1281 std::move(value), field);
1282 } else {
1283 switch (field->options().ctype()) {
1284 default: // TODO(kenton): Support other string reps.
1285 case FieldOptions::STRING:
1286 AddField<std::string>(message, field)->assign(std::move(value));
1287 break;
1288 }
1289 }
1290 }
1291
1292
1293 // -------------------------------------------------------------------
1294
GetEnum(const Message & message,const FieldDescriptor * field) const1295 const EnumValueDescriptor* Reflection::GetEnum(
1296 const Message& message, const FieldDescriptor* field) const {
1297 // Usage checked by GetEnumValue.
1298 int value = GetEnumValue(message, field);
1299 return field->enum_type()->FindValueByNumberCreatingIfUnknown(value);
1300 }
1301
GetEnumValue(const Message & message,const FieldDescriptor * field) const1302 int Reflection::GetEnumValue(const Message& message,
1303 const FieldDescriptor* field) const {
1304 USAGE_CHECK_ALL(GetEnumValue, SINGULAR, ENUM);
1305
1306 int32 value;
1307 if (field->is_extension()) {
1308 value = GetExtensionSet(message).GetEnum(
1309 field->number(), field->default_value_enum()->number());
1310 } else {
1311 value = GetField<int>(message, field);
1312 }
1313 return value;
1314 }
1315
SetEnum(Message * message,const FieldDescriptor * field,const EnumValueDescriptor * value) const1316 void Reflection::SetEnum(Message* message, const FieldDescriptor* field,
1317 const EnumValueDescriptor* value) const {
1318 // Usage checked by SetEnumValue.
1319 USAGE_CHECK_ENUM_VALUE(SetEnum);
1320 SetEnumValueInternal(message, field, value->number());
1321 }
1322
SetEnumValue(Message * message,const FieldDescriptor * field,int value) const1323 void Reflection::SetEnumValue(Message* message, const FieldDescriptor* field,
1324 int value) const {
1325 USAGE_CHECK_ALL(SetEnumValue, SINGULAR, ENUM);
1326 if (!CreateUnknownEnumValues(descriptor_->file())) {
1327 // Check that the value is valid if we don't support direct storage of
1328 // unknown enum values.
1329 const EnumValueDescriptor* value_desc =
1330 field->enum_type()->FindValueByNumber(value);
1331 if (value_desc == nullptr) {
1332 MutableUnknownFields(message)->AddVarint(field->number(), value);
1333 return;
1334 }
1335 }
1336 SetEnumValueInternal(message, field, value);
1337 }
1338
SetEnumValueInternal(Message * message,const FieldDescriptor * field,int value) const1339 void Reflection::SetEnumValueInternal(Message* message,
1340 const FieldDescriptor* field,
1341 int value) const {
1342 if (field->is_extension()) {
1343 MutableExtensionSet(message)->SetEnum(field->number(), field->type(), value,
1344 field);
1345 } else {
1346 SetField<int>(message, field, value);
1347 }
1348 }
1349
GetRepeatedEnum(const Message & message,const FieldDescriptor * field,int index) const1350 const EnumValueDescriptor* Reflection::GetRepeatedEnum(
1351 const Message& message, const FieldDescriptor* field, int index) const {
1352 // Usage checked by GetRepeatedEnumValue.
1353 int value = GetRepeatedEnumValue(message, field, index);
1354 return field->enum_type()->FindValueByNumberCreatingIfUnknown(value);
1355 }
1356
GetRepeatedEnumValue(const Message & message,const FieldDescriptor * field,int index) const1357 int Reflection::GetRepeatedEnumValue(const Message& message,
1358 const FieldDescriptor* field,
1359 int index) const {
1360 USAGE_CHECK_ALL(GetRepeatedEnumValue, REPEATED, ENUM);
1361
1362 int value;
1363 if (field->is_extension()) {
1364 value = GetExtensionSet(message).GetRepeatedEnum(field->number(), index);
1365 } else {
1366 value = GetRepeatedField<int>(message, field, index);
1367 }
1368 return value;
1369 }
1370
SetRepeatedEnum(Message * message,const FieldDescriptor * field,int index,const EnumValueDescriptor * value) const1371 void Reflection::SetRepeatedEnum(Message* message, const FieldDescriptor* field,
1372 int index,
1373 const EnumValueDescriptor* value) const {
1374 // Usage checked by SetRepeatedEnumValue.
1375 USAGE_CHECK_ENUM_VALUE(SetRepeatedEnum);
1376 SetRepeatedEnumValueInternal(message, field, index, value->number());
1377 }
1378
SetRepeatedEnumValue(Message * message,const FieldDescriptor * field,int index,int value) const1379 void Reflection::SetRepeatedEnumValue(Message* message,
1380 const FieldDescriptor* field, int index,
1381 int value) const {
1382 USAGE_CHECK_ALL(SetRepeatedEnum, REPEATED, ENUM);
1383 if (!CreateUnknownEnumValues(descriptor_->file())) {
1384 // Check that the value is valid if we don't support direct storage of
1385 // unknown enum values.
1386 const EnumValueDescriptor* value_desc =
1387 field->enum_type()->FindValueByNumber(value);
1388 if (value_desc == nullptr) {
1389 MutableUnknownFields(message)->AddVarint(field->number(), value);
1390 return;
1391 }
1392 }
1393 SetRepeatedEnumValueInternal(message, field, index, value);
1394 }
1395
SetRepeatedEnumValueInternal(Message * message,const FieldDescriptor * field,int index,int value) const1396 void Reflection::SetRepeatedEnumValueInternal(Message* message,
1397 const FieldDescriptor* field,
1398 int index, int value) const {
1399 if (field->is_extension()) {
1400 MutableExtensionSet(message)->SetRepeatedEnum(field->number(), index,
1401 value);
1402 } else {
1403 SetRepeatedField<int>(message, field, index, value);
1404 }
1405 }
1406
AddEnum(Message * message,const FieldDescriptor * field,const EnumValueDescriptor * value) const1407 void Reflection::AddEnum(Message* message, const FieldDescriptor* field,
1408 const EnumValueDescriptor* value) const {
1409 // Usage checked by AddEnumValue.
1410 USAGE_CHECK_ENUM_VALUE(AddEnum);
1411 AddEnumValueInternal(message, field, value->number());
1412 }
1413
AddEnumValue(Message * message,const FieldDescriptor * field,int value) const1414 void Reflection::AddEnumValue(Message* message, const FieldDescriptor* field,
1415 int value) const {
1416 USAGE_CHECK_ALL(AddEnum, REPEATED, ENUM);
1417 if (!CreateUnknownEnumValues(descriptor_->file())) {
1418 // Check that the value is valid if we don't support direct storage of
1419 // unknown enum values.
1420 const EnumValueDescriptor* value_desc =
1421 field->enum_type()->FindValueByNumber(value);
1422 if (value_desc == nullptr) {
1423 MutableUnknownFields(message)->AddVarint(field->number(), value);
1424 return;
1425 }
1426 }
1427 AddEnumValueInternal(message, field, value);
1428 }
1429
AddEnumValueInternal(Message * message,const FieldDescriptor * field,int value) const1430 void Reflection::AddEnumValueInternal(Message* message,
1431 const FieldDescriptor* field,
1432 int value) const {
1433 if (field->is_extension()) {
1434 MutableExtensionSet(message)->AddEnum(field->number(), field->type(),
1435 field->options().packed(), value,
1436 field);
1437 } else {
1438 AddField<int>(message, field, value);
1439 }
1440 }
1441
1442 // -------------------------------------------------------------------
1443
GetMessage(const Message & message,const FieldDescriptor * field,MessageFactory * factory) const1444 const Message& Reflection::GetMessage(const Message& message,
1445 const FieldDescriptor* field,
1446 MessageFactory* factory) const {
1447 USAGE_CHECK_ALL(GetMessage, SINGULAR, MESSAGE);
1448
1449 if (factory == nullptr) factory = message_factory_;
1450
1451 if (field->is_extension()) {
1452 return static_cast<const Message&>(GetExtensionSet(message).GetMessage(
1453 field->number(), field->message_type(), factory));
1454 } else {
1455 const Message* result = GetRaw<const Message*>(message, field);
1456 if (result == nullptr) {
1457 result = DefaultRaw<const Message*>(field);
1458 }
1459 return *result;
1460 }
1461 }
1462
MutableMessage(Message * message,const FieldDescriptor * field,MessageFactory * factory) const1463 Message* Reflection::MutableMessage(Message* message,
1464 const FieldDescriptor* field,
1465 MessageFactory* factory) const {
1466 USAGE_CHECK_ALL(MutableMessage, SINGULAR, MESSAGE);
1467
1468 if (factory == nullptr) factory = message_factory_;
1469
1470 if (field->is_extension()) {
1471 return static_cast<Message*>(
1472 MutableExtensionSet(message)->MutableMessage(field, factory));
1473 } else {
1474 Message* result;
1475
1476 Message** result_holder = MutableRaw<Message*>(message, field);
1477
1478 if (field->containing_oneof()) {
1479 if (!HasOneofField(*message, field)) {
1480 ClearOneof(message, field->containing_oneof());
1481 result_holder = MutableField<Message*>(message, field);
1482 const Message* default_message = DefaultRaw<const Message*>(field);
1483 *result_holder = default_message->New(message->GetArena());
1484 }
1485 } else {
1486 SetBit(message, field);
1487 }
1488
1489 if (*result_holder == nullptr) {
1490 const Message* default_message = DefaultRaw<const Message*>(field);
1491 *result_holder = default_message->New(message->GetArena());
1492 }
1493 result = *result_holder;
1494 return result;
1495 }
1496 }
1497
UnsafeArenaSetAllocatedMessage(Message * message,Message * sub_message,const FieldDescriptor * field) const1498 void Reflection::UnsafeArenaSetAllocatedMessage(
1499 Message* message, Message* sub_message,
1500 const FieldDescriptor* field) const {
1501 USAGE_CHECK_ALL(SetAllocatedMessage, SINGULAR, MESSAGE);
1502
1503 if (field->is_extension()) {
1504 MutableExtensionSet(message)->UnsafeArenaSetAllocatedMessage(
1505 field->number(), field->type(), field, sub_message);
1506 } else {
1507 if (field->containing_oneof()) {
1508 if (sub_message == nullptr) {
1509 ClearOneof(message, field->containing_oneof());
1510 return;
1511 }
1512 ClearOneof(message, field->containing_oneof());
1513 *MutableRaw<Message*>(message, field) = sub_message;
1514 SetOneofCase(message, field);
1515 return;
1516 }
1517
1518 if (sub_message == nullptr) {
1519 ClearBit(message, field);
1520 } else {
1521 SetBit(message, field);
1522 }
1523 Message** sub_message_holder = MutableRaw<Message*>(message, field);
1524 if (GetArena(message) == nullptr) {
1525 delete *sub_message_holder;
1526 }
1527 *sub_message_holder = sub_message;
1528 }
1529 }
1530
SetAllocatedMessage(Message * message,Message * sub_message,const FieldDescriptor * field) const1531 void Reflection::SetAllocatedMessage(Message* message, Message* sub_message,
1532 const FieldDescriptor* field) const {
1533 // If message and sub-message are in different memory ownership domains
1534 // (different arenas, or one is on heap and one is not), then we may need to
1535 // do a copy.
1536 if (sub_message != nullptr &&
1537 sub_message->GetArena() != message->GetArena()) {
1538 if (sub_message->GetArena() == nullptr && message->GetArena() != nullptr) {
1539 // Case 1: parent is on an arena and child is heap-allocated. We can add
1540 // the child to the arena's Own() list to free on arena destruction, then
1541 // set our pointer.
1542 message->GetArena()->Own(sub_message);
1543 UnsafeArenaSetAllocatedMessage(message, sub_message, field);
1544 } else {
1545 // Case 2: all other cases. We need to make a copy. MutableMessage() will
1546 // either get the existing message object, or instantiate a new one as
1547 // appropriate w.r.t. our arena.
1548 Message* sub_message_copy = MutableMessage(message, field);
1549 sub_message_copy->CopyFrom(*sub_message);
1550 }
1551 } else {
1552 // Same memory ownership domains.
1553 UnsafeArenaSetAllocatedMessage(message, sub_message, field);
1554 }
1555 }
1556
UnsafeArenaReleaseMessage(Message * message,const FieldDescriptor * field,MessageFactory * factory) const1557 Message* Reflection::UnsafeArenaReleaseMessage(Message* message,
1558 const FieldDescriptor* field,
1559 MessageFactory* factory) const {
1560 USAGE_CHECK_ALL(ReleaseMessage, SINGULAR, MESSAGE);
1561
1562 if (factory == nullptr) factory = message_factory_;
1563
1564 if (field->is_extension()) {
1565 return static_cast<Message*>(
1566 MutableExtensionSet(message)->UnsafeArenaReleaseMessage(field,
1567 factory));
1568 } else {
1569 if (!(field->is_repeated() || field->containing_oneof())) {
1570 ClearBit(message, field);
1571 }
1572 if (field->containing_oneof()) {
1573 if (HasOneofField(*message, field)) {
1574 *MutableOneofCase(message, field->containing_oneof()) = 0;
1575 } else {
1576 return nullptr;
1577 }
1578 }
1579 Message** result = MutableRaw<Message*>(message, field);
1580 Message* ret = *result;
1581 *result = nullptr;
1582 return ret;
1583 }
1584 }
1585
ReleaseMessage(Message * message,const FieldDescriptor * field,MessageFactory * factory) const1586 Message* Reflection::ReleaseMessage(Message* message,
1587 const FieldDescriptor* field,
1588 MessageFactory* factory) const {
1589 Message* released = UnsafeArenaReleaseMessage(message, field, factory);
1590 if (GetArena(message) != nullptr && released != nullptr) {
1591 Message* copy_from_arena = released->New();
1592 copy_from_arena->CopyFrom(*released);
1593 released = copy_from_arena;
1594 }
1595 return released;
1596 }
1597
GetRepeatedMessage(const Message & message,const FieldDescriptor * field,int index) const1598 const Message& Reflection::GetRepeatedMessage(const Message& message,
1599 const FieldDescriptor* field,
1600 int index) const {
1601 USAGE_CHECK_ALL(GetRepeatedMessage, REPEATED, MESSAGE);
1602
1603 if (field->is_extension()) {
1604 return static_cast<const Message&>(
1605 GetExtensionSet(message).GetRepeatedMessage(field->number(), index));
1606 } else {
1607 if (IsMapFieldInApi(field)) {
1608 return GetRaw<MapFieldBase>(message, field)
1609 .GetRepeatedField()
1610 .Get<GenericTypeHandler<Message> >(index);
1611 } else {
1612 return GetRaw<RepeatedPtrFieldBase>(message, field)
1613 .Get<GenericTypeHandler<Message> >(index);
1614 }
1615 }
1616 }
1617
MutableRepeatedMessage(Message * message,const FieldDescriptor * field,int index) const1618 Message* Reflection::MutableRepeatedMessage(Message* message,
1619 const FieldDescriptor* field,
1620 int index) const {
1621 USAGE_CHECK_ALL(MutableRepeatedMessage, REPEATED, MESSAGE);
1622
1623 if (field->is_extension()) {
1624 return static_cast<Message*>(
1625 MutableExtensionSet(message)->MutableRepeatedMessage(field->number(),
1626 index));
1627 } else {
1628 if (IsMapFieldInApi(field)) {
1629 return MutableRaw<MapFieldBase>(message, field)
1630 ->MutableRepeatedField()
1631 ->Mutable<GenericTypeHandler<Message> >(index);
1632 } else {
1633 return MutableRaw<RepeatedPtrFieldBase>(message, field)
1634 ->Mutable<GenericTypeHandler<Message> >(index);
1635 }
1636 }
1637 }
1638
AddMessage(Message * message,const FieldDescriptor * field,MessageFactory * factory) const1639 Message* Reflection::AddMessage(Message* message, const FieldDescriptor* field,
1640 MessageFactory* factory) const {
1641 USAGE_CHECK_ALL(AddMessage, REPEATED, MESSAGE);
1642
1643 if (factory == nullptr) factory = message_factory_;
1644
1645 if (field->is_extension()) {
1646 return static_cast<Message*>(
1647 MutableExtensionSet(message)->AddMessage(field, factory));
1648 } else {
1649 Message* result = nullptr;
1650
1651 // We can't use AddField<Message>() because RepeatedPtrFieldBase doesn't
1652 // know how to allocate one.
1653 RepeatedPtrFieldBase* repeated = nullptr;
1654 if (IsMapFieldInApi(field)) {
1655 repeated =
1656 MutableRaw<MapFieldBase>(message, field)->MutableRepeatedField();
1657 } else {
1658 repeated = MutableRaw<RepeatedPtrFieldBase>(message, field);
1659 }
1660 result = repeated->AddFromCleared<GenericTypeHandler<Message> >();
1661 if (result == nullptr) {
1662 // We must allocate a new object.
1663 const Message* prototype;
1664 if (repeated->size() == 0) {
1665 prototype = factory->GetPrototype(field->message_type());
1666 } else {
1667 prototype = &repeated->Get<GenericTypeHandler<Message> >(0);
1668 }
1669 result = prototype->New(message->GetArena());
1670 // We can guarantee here that repeated and result are either both heap
1671 // allocated or arena owned. So it is safe to call the unsafe version
1672 // of AddAllocated.
1673 repeated->UnsafeArenaAddAllocated<GenericTypeHandler<Message> >(result);
1674 }
1675
1676 return result;
1677 }
1678 }
1679
AddAllocatedMessage(Message * message,const FieldDescriptor * field,Message * new_entry) const1680 void Reflection::AddAllocatedMessage(Message* message,
1681 const FieldDescriptor* field,
1682 Message* new_entry) const {
1683 USAGE_CHECK_ALL(AddAllocatedMessage, REPEATED, MESSAGE);
1684
1685 if (field->is_extension()) {
1686 MutableExtensionSet(message)->AddAllocatedMessage(field, new_entry);
1687 } else {
1688 RepeatedPtrFieldBase* repeated = nullptr;
1689 if (IsMapFieldInApi(field)) {
1690 repeated =
1691 MutableRaw<MapFieldBase>(message, field)->MutableRepeatedField();
1692 } else {
1693 repeated = MutableRaw<RepeatedPtrFieldBase>(message, field);
1694 }
1695 repeated->AddAllocated<GenericTypeHandler<Message> >(new_entry);
1696 }
1697 }
1698
MutableRawRepeatedField(Message * message,const FieldDescriptor * field,FieldDescriptor::CppType cpptype,int ctype,const Descriptor * desc) const1699 void* Reflection::MutableRawRepeatedField(Message* message,
1700 const FieldDescriptor* field,
1701 FieldDescriptor::CppType cpptype,
1702 int ctype,
1703 const Descriptor* desc) const {
1704 USAGE_CHECK_REPEATED("MutableRawRepeatedField");
1705 if (field->cpp_type() != cpptype &&
1706 (field->cpp_type() != FieldDescriptor::CPPTYPE_ENUM ||
1707 cpptype != FieldDescriptor::CPPTYPE_INT32))
1708 ReportReflectionUsageTypeError(descriptor_, field,
1709 "MutableRawRepeatedField", cpptype);
1710 if (desc != nullptr)
1711 GOOGLE_CHECK_EQ(field->message_type(), desc) << "wrong submessage type";
1712 if (field->is_extension()) {
1713 return MutableExtensionSet(message)->MutableRawRepeatedField(
1714 field->number(), field->type(), field->is_packed(), field);
1715 } else {
1716 // Trigger transform for MapField
1717 if (IsMapFieldInApi(field)) {
1718 return MutableRawNonOneof<MapFieldBase>(message, field)
1719 ->MutableRepeatedField();
1720 }
1721 return MutableRawNonOneof<void>(message, field);
1722 }
1723 }
1724
GetRawRepeatedField(const Message & message,const FieldDescriptor * field,FieldDescriptor::CppType cpptype,int ctype,const Descriptor * desc) const1725 const void* Reflection::GetRawRepeatedField(const Message& message,
1726 const FieldDescriptor* field,
1727 FieldDescriptor::CppType cpptype,
1728 int ctype,
1729 const Descriptor* desc) const {
1730 USAGE_CHECK_REPEATED("GetRawRepeatedField");
1731 if (field->cpp_type() != cpptype)
1732 ReportReflectionUsageTypeError(descriptor_, field, "GetRawRepeatedField",
1733 cpptype);
1734 if (ctype >= 0)
1735 GOOGLE_CHECK_EQ(field->options().ctype(), ctype) << "subtype mismatch";
1736 if (desc != nullptr)
1737 GOOGLE_CHECK_EQ(field->message_type(), desc) << "wrong submessage type";
1738 if (field->is_extension()) {
1739 // Should use extension_set::GetRawRepeatedField. However, the required
1740 // parameter "default repeated value" is not very easy to get here.
1741 // Map is not supported in extensions, it is acceptable to use
1742 // extension_set::MutableRawRepeatedField which does not change the message.
1743 return MutableExtensionSet(const_cast<Message*>(&message))
1744 ->MutableRawRepeatedField(field->number(), field->type(),
1745 field->is_packed(), field);
1746 } else {
1747 // Trigger transform for MapField
1748 if (IsMapFieldInApi(field)) {
1749 return &(GetRawNonOneof<MapFieldBase>(message, field).GetRepeatedField());
1750 }
1751 return &GetRawNonOneof<char>(message, field);
1752 }
1753 }
1754
GetOneofFieldDescriptor(const Message & message,const OneofDescriptor * oneof_descriptor) const1755 const FieldDescriptor* Reflection::GetOneofFieldDescriptor(
1756 const Message& message, const OneofDescriptor* oneof_descriptor) const {
1757 uint32 field_number = GetOneofCase(message, oneof_descriptor);
1758 if (field_number == 0) {
1759 return nullptr;
1760 }
1761 return descriptor_->FindFieldByNumber(field_number);
1762 }
1763
ContainsMapKey(const Message & message,const FieldDescriptor * field,const MapKey & key) const1764 bool Reflection::ContainsMapKey(const Message& message,
1765 const FieldDescriptor* field,
1766 const MapKey& key) const {
1767 USAGE_CHECK(IsMapFieldInApi(field), "LookupMapValue",
1768 "Field is not a map field.");
1769 return GetRaw<MapFieldBase>(message, field).ContainsMapKey(key);
1770 }
1771
InsertOrLookupMapValue(Message * message,const FieldDescriptor * field,const MapKey & key,MapValueRef * val) const1772 bool Reflection::InsertOrLookupMapValue(Message* message,
1773 const FieldDescriptor* field,
1774 const MapKey& key,
1775 MapValueRef* val) const {
1776 USAGE_CHECK(IsMapFieldInApi(field), "InsertOrLookupMapValue",
1777 "Field is not a map field.");
1778 val->SetType(field->message_type()->FindFieldByName("value")->cpp_type());
1779 return MutableRaw<MapFieldBase>(message, field)
1780 ->InsertOrLookupMapValue(key, val);
1781 }
1782
DeleteMapValue(Message * message,const FieldDescriptor * field,const MapKey & key) const1783 bool Reflection::DeleteMapValue(Message* message, const FieldDescriptor* field,
1784 const MapKey& key) const {
1785 USAGE_CHECK(IsMapFieldInApi(field), "DeleteMapValue",
1786 "Field is not a map field.");
1787 return MutableRaw<MapFieldBase>(message, field)->DeleteMapValue(key);
1788 }
1789
MapBegin(Message * message,const FieldDescriptor * field) const1790 MapIterator Reflection::MapBegin(Message* message,
1791 const FieldDescriptor* field) const {
1792 USAGE_CHECK(IsMapFieldInApi(field), "MapBegin", "Field is not a map field.");
1793 MapIterator iter(message, field);
1794 GetRaw<MapFieldBase>(*message, field).MapBegin(&iter);
1795 return iter;
1796 }
1797
MapEnd(Message * message,const FieldDescriptor * field) const1798 MapIterator Reflection::MapEnd(Message* message,
1799 const FieldDescriptor* field) const {
1800 USAGE_CHECK(IsMapFieldInApi(field), "MapEnd", "Field is not a map field.");
1801 MapIterator iter(message, field);
1802 GetRaw<MapFieldBase>(*message, field).MapEnd(&iter);
1803 return iter;
1804 }
1805
MapSize(const Message & message,const FieldDescriptor * field) const1806 int Reflection::MapSize(const Message& message,
1807 const FieldDescriptor* field) const {
1808 USAGE_CHECK(IsMapFieldInApi(field), "MapSize", "Field is not a map field.");
1809 return GetRaw<MapFieldBase>(message, field).size();
1810 }
1811
1812 // -----------------------------------------------------------------------------
1813
FindKnownExtensionByName(const std::string & name) const1814 const FieldDescriptor* Reflection::FindKnownExtensionByName(
1815 const std::string& name) const {
1816 if (!schema_.HasExtensionSet()) return nullptr;
1817 return descriptor_pool_->FindExtensionByPrintableName(descriptor_, name);
1818 }
1819
FindKnownExtensionByNumber(int number) const1820 const FieldDescriptor* Reflection::FindKnownExtensionByNumber(
1821 int number) const {
1822 if (!schema_.HasExtensionSet()) return nullptr;
1823 return descriptor_pool_->FindExtensionByNumber(descriptor_, number);
1824 }
1825
SupportsUnknownEnumValues() const1826 bool Reflection::SupportsUnknownEnumValues() const {
1827 return CreateUnknownEnumValues(descriptor_->file());
1828 }
1829
1830 // ===================================================================
1831 // Some private helpers.
1832
1833 // These simple template accessors obtain pointers (or references) to
1834 // the given field.
1835
1836 template <class Type>
GetRawNonOneof(const Message & message,const FieldDescriptor * field) const1837 const Type& Reflection::GetRawNonOneof(const Message& message,
1838 const FieldDescriptor* field) const {
1839 return GetConstRefAtOffset<Type>(message,
1840 schema_.GetFieldOffsetNonOneof(field));
1841 }
1842
1843 template <class Type>
MutableRawNonOneof(Message * message,const FieldDescriptor * field) const1844 Type* Reflection::MutableRawNonOneof(Message* message,
1845 const FieldDescriptor* field) const {
1846 return GetPointerAtOffset<Type>(message,
1847 schema_.GetFieldOffsetNonOneof(field));
1848 }
1849
1850 template <typename Type>
GetRaw(const Message & message,const FieldDescriptor * field) const1851 const Type& Reflection::GetRaw(const Message& message,
1852 const FieldDescriptor* field) const {
1853 if (field->containing_oneof() && !HasOneofField(message, field)) {
1854 return DefaultRaw<Type>(field);
1855 }
1856 return GetConstRefAtOffset<Type>(message, schema_.GetFieldOffset(field));
1857 }
1858
IsInlined(const FieldDescriptor * field) const1859 bool Reflection::IsInlined(const FieldDescriptor* field) const {
1860 return schema_.IsFieldInlined(field);
1861 }
1862
1863 template <typename Type>
MutableRaw(Message * message,const FieldDescriptor * field) const1864 Type* Reflection::MutableRaw(Message* message,
1865 const FieldDescriptor* field) const {
1866 return GetPointerAtOffset<Type>(message, schema_.GetFieldOffset(field));
1867 }
1868
GetHasBits(const Message & message) const1869 const uint32* Reflection::GetHasBits(const Message& message) const {
1870 GOOGLE_DCHECK(schema_.HasHasbits());
1871 return &GetConstRefAtOffset<uint32>(message, schema_.HasBitsOffset());
1872 }
1873
MutableHasBits(Message * message) const1874 uint32* Reflection::MutableHasBits(Message* message) const {
1875 GOOGLE_DCHECK(schema_.HasHasbits());
1876 return GetPointerAtOffset<uint32>(message, schema_.HasBitsOffset());
1877 }
1878
GetOneofCase(const Message & message,const OneofDescriptor * oneof_descriptor) const1879 uint32 Reflection::GetOneofCase(const Message& message,
1880 const OneofDescriptor* oneof_descriptor) const {
1881 return GetConstRefAtOffset<uint32>(
1882 message, schema_.GetOneofCaseOffset(oneof_descriptor));
1883 }
1884
MutableOneofCase(Message * message,const OneofDescriptor * oneof_descriptor) const1885 uint32* Reflection::MutableOneofCase(
1886 Message* message, const OneofDescriptor* oneof_descriptor) const {
1887 return GetPointerAtOffset<uint32>(
1888 message, schema_.GetOneofCaseOffset(oneof_descriptor));
1889 }
1890
GetExtensionSet(const Message & message) const1891 const ExtensionSet& Reflection::GetExtensionSet(const Message& message) const {
1892 return GetConstRefAtOffset<ExtensionSet>(message,
1893 schema_.GetExtensionSetOffset());
1894 }
1895
MutableExtensionSet(Message * message) const1896 ExtensionSet* Reflection::MutableExtensionSet(Message* message) const {
1897 return GetPointerAtOffset<ExtensionSet>(message,
1898 schema_.GetExtensionSetOffset());
1899 }
1900
GetArena(Message * message) const1901 Arena* Reflection::GetArena(Message* message) const {
1902 return GetInternalMetadataWithArena(*message).arena();
1903 }
1904
GetInternalMetadataWithArena(const Message & message) const1905 const InternalMetadataWithArena& Reflection::GetInternalMetadataWithArena(
1906 const Message& message) const {
1907 return GetConstRefAtOffset<InternalMetadataWithArena>(
1908 message, schema_.GetMetadataOffset());
1909 }
1910
MutableInternalMetadataWithArena(Message * message) const1911 InternalMetadataWithArena* Reflection::MutableInternalMetadataWithArena(
1912 Message* message) const {
1913 return GetPointerAtOffset<InternalMetadataWithArena>(
1914 message, schema_.GetMetadataOffset());
1915 }
1916
1917 template <typename Type>
DefaultRaw(const FieldDescriptor * field) const1918 const Type& Reflection::DefaultRaw(const FieldDescriptor* field) const {
1919 return *reinterpret_cast<const Type*>(schema_.GetFieldDefault(field));
1920 }
1921
1922 // Simple accessors for manipulating has_bits_.
HasBit(const Message & message,const FieldDescriptor * field) const1923 bool Reflection::HasBit(const Message& message,
1924 const FieldDescriptor* field) const {
1925 GOOGLE_DCHECK(!field->options().weak());
1926 if (schema_.HasHasbits()) {
1927 return IsIndexInHasBitSet(GetHasBits(message), schema_.HasBitIndex(field));
1928 }
1929
1930 // proto3: no has-bits. All fields present except messages, which are
1931 // present only if their message-field pointer is non-null.
1932 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
1933 return !schema_.IsDefaultInstance(message) &&
1934 GetRaw<const Message*>(message, field) != nullptr;
1935 } else {
1936 // Non-message field (and non-oneof, since that was handled in HasField()
1937 // before calling us), and singular (again, checked in HasField). So, this
1938 // field must be a scalar.
1939
1940 // Scalar primitive (numeric or string/bytes) fields are present if
1941 // their value is non-zero (numeric) or non-empty (string/bytes). N.B.:
1942 // we must use this definition here, rather than the "scalar fields
1943 // always present" in the proto3 docs, because MergeFrom() semantics
1944 // require presence as "present on wire", and reflection-based merge
1945 // (which uses HasField()) needs to be consistent with this.
1946 switch (field->cpp_type()) {
1947 case FieldDescriptor::CPPTYPE_STRING:
1948 switch (field->options().ctype()) {
1949 default: {
1950 if (IsInlined(field)) {
1951 return !GetField<InlinedStringField>(message, field)
1952 .GetNoArena()
1953 .empty();
1954 }
1955 return GetField<ArenaStringPtr>(message, field).Get().size() > 0;
1956 }
1957 }
1958 return false;
1959 case FieldDescriptor::CPPTYPE_BOOL:
1960 return GetRaw<bool>(message, field) != false;
1961 case FieldDescriptor::CPPTYPE_INT32:
1962 return GetRaw<int32>(message, field) != 0;
1963 case FieldDescriptor::CPPTYPE_INT64:
1964 return GetRaw<int64>(message, field) != 0;
1965 case FieldDescriptor::CPPTYPE_UINT32:
1966 return GetRaw<uint32>(message, field) != 0;
1967 case FieldDescriptor::CPPTYPE_UINT64:
1968 return GetRaw<uint64>(message, field) != 0;
1969 case FieldDescriptor::CPPTYPE_FLOAT:
1970 return GetRaw<float>(message, field) != 0.0;
1971 case FieldDescriptor::CPPTYPE_DOUBLE:
1972 return GetRaw<double>(message, field) != 0.0;
1973 case FieldDescriptor::CPPTYPE_ENUM:
1974 return GetRaw<int>(message, field) != 0;
1975 case FieldDescriptor::CPPTYPE_MESSAGE:
1976 // handled above; avoid warning
1977 break;
1978 }
1979 GOOGLE_LOG(FATAL) << "Reached impossible case in HasBit().";
1980 return false;
1981 }
1982 }
1983
SetBit(Message * message,const FieldDescriptor * field) const1984 void Reflection::SetBit(Message* message, const FieldDescriptor* field) const {
1985 GOOGLE_DCHECK(!field->options().weak());
1986 if (!schema_.HasHasbits()) {
1987 return;
1988 }
1989 const uint32 index = schema_.HasBitIndex(field);
1990 MutableHasBits(message)[index / 32] |=
1991 (static_cast<uint32>(1) << (index % 32));
1992 }
1993
ClearBit(Message * message,const FieldDescriptor * field) const1994 void Reflection::ClearBit(Message* message,
1995 const FieldDescriptor* field) const {
1996 GOOGLE_DCHECK(!field->options().weak());
1997 if (!schema_.HasHasbits()) {
1998 return;
1999 }
2000 const uint32 index = schema_.HasBitIndex(field);
2001 MutableHasBits(message)[index / 32] &=
2002 ~(static_cast<uint32>(1) << (index % 32));
2003 }
2004
SwapBit(Message * message1,Message * message2,const FieldDescriptor * field) const2005 void Reflection::SwapBit(Message* message1, Message* message2,
2006 const FieldDescriptor* field) const {
2007 GOOGLE_DCHECK(!field->options().weak());
2008 if (!schema_.HasHasbits()) {
2009 return;
2010 }
2011 bool temp_has_bit = HasBit(*message1, field);
2012 if (HasBit(*message2, field)) {
2013 SetBit(message1, field);
2014 } else {
2015 ClearBit(message1, field);
2016 }
2017 if (temp_has_bit) {
2018 SetBit(message2, field);
2019 } else {
2020 ClearBit(message2, field);
2021 }
2022 }
2023
HasOneof(const Message & message,const OneofDescriptor * oneof_descriptor) const2024 bool Reflection::HasOneof(const Message& message,
2025 const OneofDescriptor* oneof_descriptor) const {
2026 return (GetOneofCase(message, oneof_descriptor) > 0);
2027 }
2028
HasOneofField(const Message & message,const FieldDescriptor * field) const2029 bool Reflection::HasOneofField(const Message& message,
2030 const FieldDescriptor* field) const {
2031 return (GetOneofCase(message, field->containing_oneof()) == field->number());
2032 }
2033
SetOneofCase(Message * message,const FieldDescriptor * field) const2034 void Reflection::SetOneofCase(Message* message,
2035 const FieldDescriptor* field) const {
2036 *MutableOneofCase(message, field->containing_oneof()) = field->number();
2037 }
2038
ClearOneofField(Message * message,const FieldDescriptor * field) const2039 void Reflection::ClearOneofField(Message* message,
2040 const FieldDescriptor* field) const {
2041 if (HasOneofField(*message, field)) {
2042 ClearOneof(message, field->containing_oneof());
2043 }
2044 }
2045
ClearOneof(Message * message,const OneofDescriptor * oneof_descriptor) const2046 void Reflection::ClearOneof(Message* message,
2047 const OneofDescriptor* oneof_descriptor) const {
2048 // TODO(jieluo): Consider to cache the unused object instead of deleting
2049 // it. It will be much faster if an application switches a lot from
2050 // a few oneof fields. Time/space tradeoff
2051 uint32 oneof_case = GetOneofCase(*message, oneof_descriptor);
2052 if (oneof_case > 0) {
2053 const FieldDescriptor* field = descriptor_->FindFieldByNumber(oneof_case);
2054 if (GetArena(message) == nullptr) {
2055 switch (field->cpp_type()) {
2056 case FieldDescriptor::CPPTYPE_STRING: {
2057 switch (field->options().ctype()) {
2058 default: // TODO(kenton): Support other string reps.
2059 case FieldOptions::STRING: {
2060 const std::string* default_ptr =
2061 &DefaultRaw<ArenaStringPtr>(field).Get();
2062 MutableField<ArenaStringPtr>(message, field)
2063 ->Destroy(default_ptr, GetArena(message));
2064 break;
2065 }
2066 }
2067 break;
2068 }
2069
2070 case FieldDescriptor::CPPTYPE_MESSAGE:
2071 delete *MutableRaw<Message*>(message, field);
2072 break;
2073 default:
2074 break;
2075 }
2076 }
2077
2078 *MutableOneofCase(message, oneof_descriptor) = 0;
2079 }
2080 }
2081
2082 #define HANDLE_TYPE(TYPE, CPPTYPE, CTYPE) \
2083 template <> \
2084 const RepeatedField<TYPE>& Reflection::GetRepeatedFieldInternal<TYPE>( \
2085 const Message& message, const FieldDescriptor* field) const { \
2086 return *static_cast<RepeatedField<TYPE>*>(MutableRawRepeatedField( \
2087 const_cast<Message*>(&message), field, CPPTYPE, CTYPE, NULL)); \
2088 } \
2089 \
2090 template <> \
2091 RepeatedField<TYPE>* Reflection::MutableRepeatedFieldInternal<TYPE>( \
2092 Message * message, const FieldDescriptor* field) const { \
2093 return static_cast<RepeatedField<TYPE>*>( \
2094 MutableRawRepeatedField(message, field, CPPTYPE, CTYPE, NULL)); \
2095 }
2096
2097 HANDLE_TYPE(int32, FieldDescriptor::CPPTYPE_INT32, -1);
2098 HANDLE_TYPE(int64, FieldDescriptor::CPPTYPE_INT64, -1);
2099 HANDLE_TYPE(uint32, FieldDescriptor::CPPTYPE_UINT32, -1);
2100 HANDLE_TYPE(uint64, FieldDescriptor::CPPTYPE_UINT64, -1);
2101 HANDLE_TYPE(float, FieldDescriptor::CPPTYPE_FLOAT, -1);
2102 HANDLE_TYPE(double, FieldDescriptor::CPPTYPE_DOUBLE, -1);
2103 HANDLE_TYPE(bool, FieldDescriptor::CPPTYPE_BOOL, -1);
2104
2105
2106 #undef HANDLE_TYPE
2107
MutableRawRepeatedString(Message * message,const FieldDescriptor * field,bool is_string) const2108 void* Reflection::MutableRawRepeatedString(Message* message,
2109 const FieldDescriptor* field,
2110 bool is_string) const {
2111 return MutableRawRepeatedField(message, field,
2112 FieldDescriptor::CPPTYPE_STRING,
2113 FieldOptions::STRING, NULL);
2114 }
2115
2116 // Template implementations of basic accessors. Inline because each
2117 // template instance is only called from one location. These are
2118 // used for all types except messages.
2119 template <typename Type>
GetField(const Message & message,const FieldDescriptor * field) const2120 const Type& Reflection::GetField(const Message& message,
2121 const FieldDescriptor* field) const {
2122 return GetRaw<Type>(message, field);
2123 }
2124
2125 template <typename Type>
SetField(Message * message,const FieldDescriptor * field,const Type & value) const2126 void Reflection::SetField(Message* message, const FieldDescriptor* field,
2127 const Type& value) const {
2128 if (field->containing_oneof() && !HasOneofField(*message, field)) {
2129 ClearOneof(message, field->containing_oneof());
2130 }
2131 *MutableRaw<Type>(message, field) = value;
2132 field->containing_oneof() ? SetOneofCase(message, field)
2133 : SetBit(message, field);
2134 }
2135
2136 template <typename Type>
MutableField(Message * message,const FieldDescriptor * field) const2137 Type* Reflection::MutableField(Message* message,
2138 const FieldDescriptor* field) const {
2139 field->containing_oneof() ? SetOneofCase(message, field)
2140 : SetBit(message, field);
2141 return MutableRaw<Type>(message, field);
2142 }
2143
2144 template <typename Type>
GetRepeatedField(const Message & message,const FieldDescriptor * field,int index) const2145 const Type& Reflection::GetRepeatedField(const Message& message,
2146 const FieldDescriptor* field,
2147 int index) const {
2148 return GetRaw<RepeatedField<Type> >(message, field).Get(index);
2149 }
2150
2151 template <typename Type>
GetRepeatedPtrField(const Message & message,const FieldDescriptor * field,int index) const2152 const Type& Reflection::GetRepeatedPtrField(const Message& message,
2153 const FieldDescriptor* field,
2154 int index) const {
2155 return GetRaw<RepeatedPtrField<Type> >(message, field).Get(index);
2156 }
2157
2158 template <typename Type>
SetRepeatedField(Message * message,const FieldDescriptor * field,int index,Type value) const2159 void Reflection::SetRepeatedField(Message* message,
2160 const FieldDescriptor* field, int index,
2161 Type value) const {
2162 MutableRaw<RepeatedField<Type> >(message, field)->Set(index, value);
2163 }
2164
2165 template <typename Type>
MutableRepeatedField(Message * message,const FieldDescriptor * field,int index) const2166 Type* Reflection::MutableRepeatedField(Message* message,
2167 const FieldDescriptor* field,
2168 int index) const {
2169 RepeatedPtrField<Type>* repeated =
2170 MutableRaw<RepeatedPtrField<Type> >(message, field);
2171 return repeated->Mutable(index);
2172 }
2173
2174 template <typename Type>
AddField(Message * message,const FieldDescriptor * field,const Type & value) const2175 void Reflection::AddField(Message* message, const FieldDescriptor* field,
2176 const Type& value) const {
2177 MutableRaw<RepeatedField<Type> >(message, field)->Add(value);
2178 }
2179
2180 template <typename Type>
AddField(Message * message,const FieldDescriptor * field) const2181 Type* Reflection::AddField(Message* message,
2182 const FieldDescriptor* field) const {
2183 RepeatedPtrField<Type>* repeated =
2184 MutableRaw<RepeatedPtrField<Type> >(message, field);
2185 return repeated->Add();
2186 }
2187
GetMessageFactory() const2188 MessageFactory* Reflection::GetMessageFactory() const {
2189 return message_factory_;
2190 }
2191
RepeatedFieldData(Message * message,const FieldDescriptor * field,FieldDescriptor::CppType cpp_type,const Descriptor * message_type) const2192 void* Reflection::RepeatedFieldData(Message* message,
2193 const FieldDescriptor* field,
2194 FieldDescriptor::CppType cpp_type,
2195 const Descriptor* message_type) const {
2196 GOOGLE_CHECK(field->is_repeated());
2197 GOOGLE_CHECK(field->cpp_type() == cpp_type ||
2198 (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM &&
2199 cpp_type == FieldDescriptor::CPPTYPE_INT32))
2200 << "The type parameter T in RepeatedFieldRef<T> API doesn't match "
2201 << "the actual field type (for enums T should be the generated enum "
2202 << "type or int32).";
2203 if (message_type != nullptr) {
2204 GOOGLE_CHECK_EQ(message_type, field->message_type());
2205 }
2206 if (field->is_extension()) {
2207 return MutableExtensionSet(message)->MutableRawRepeatedField(
2208 field->number(), field->type(), field->is_packed(), field);
2209 } else {
2210 return MutableRawNonOneof<char>(message, field);
2211 }
2212 }
2213
MutableMapData(Message * message,const FieldDescriptor * field) const2214 MapFieldBase* Reflection::MutableMapData(Message* message,
2215 const FieldDescriptor* field) const {
2216 USAGE_CHECK(IsMapFieldInApi(field), "GetMapData",
2217 "Field is not a map field.");
2218 return MutableRaw<MapFieldBase>(message, field);
2219 }
2220
GetMapData(const Message & message,const FieldDescriptor * field) const2221 const MapFieldBase* Reflection::GetMapData(const Message& message,
2222 const FieldDescriptor* field) const {
2223 USAGE_CHECK(IsMapFieldInApi(field), "GetMapData",
2224 "Field is not a map field.");
2225 return &(GetRaw<MapFieldBase>(message, field));
2226 }
2227
2228 namespace {
2229
2230 // Helper function to transform migration schema into reflection schema.
MigrationToReflectionSchema(const Message * const * default_instance,const uint32 * offsets,MigrationSchema migration_schema)2231 ReflectionSchema MigrationToReflectionSchema(
2232 const Message* const* default_instance, const uint32* offsets,
2233 MigrationSchema migration_schema) {
2234 ReflectionSchema result;
2235 result.default_instance_ = *default_instance;
2236 // First 6 offsets are offsets to the special fields. The following offsets
2237 // are the proto fields.
2238 result.offsets_ = offsets + migration_schema.offsets_index + 5;
2239 result.has_bit_indices_ = offsets + migration_schema.has_bit_indices_index;
2240 result.has_bits_offset_ = offsets[migration_schema.offsets_index + 0];
2241 result.metadata_offset_ = offsets[migration_schema.offsets_index + 1];
2242 result.extensions_offset_ = offsets[migration_schema.offsets_index + 2];
2243 result.oneof_case_offset_ = offsets[migration_schema.offsets_index + 3];
2244 result.object_size_ = migration_schema.object_size;
2245 result.weak_field_map_offset_ = offsets[migration_schema.offsets_index + 4];
2246 return result;
2247 }
2248
2249 } // namespace
2250
2251 class AssignDescriptorsHelper {
2252 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)2253 AssignDescriptorsHelper(MessageFactory* factory,
2254 Metadata* file_level_metadata,
2255 const EnumDescriptor** file_level_enum_descriptors,
2256 const MigrationSchema* schemas,
2257 const Message* const* default_instance_data,
2258 const uint32* offsets)
2259 : factory_(factory),
2260 file_level_metadata_(file_level_metadata),
2261 file_level_enum_descriptors_(file_level_enum_descriptors),
2262 schemas_(schemas),
2263 default_instance_data_(default_instance_data),
2264 offsets_(offsets) {}
2265
AssignMessageDescriptor(const Descriptor * descriptor)2266 void AssignMessageDescriptor(const Descriptor* descriptor) {
2267 for (int i = 0; i < descriptor->nested_type_count(); i++) {
2268 AssignMessageDescriptor(descriptor->nested_type(i));
2269 }
2270
2271 file_level_metadata_->descriptor = descriptor;
2272
2273 file_level_metadata_->reflection =
2274 new Reflection(descriptor,
2275 MigrationToReflectionSchema(default_instance_data_,
2276 offsets_, *schemas_),
2277 DescriptorPool::internal_generated_pool(), factory_);
2278 for (int i = 0; i < descriptor->enum_type_count(); i++) {
2279 AssignEnumDescriptor(descriptor->enum_type(i));
2280 }
2281 schemas_++;
2282 default_instance_data_++;
2283 file_level_metadata_++;
2284 }
2285
AssignEnumDescriptor(const EnumDescriptor * descriptor)2286 void AssignEnumDescriptor(const EnumDescriptor* descriptor) {
2287 *file_level_enum_descriptors_ = descriptor;
2288 file_level_enum_descriptors_++;
2289 }
2290
GetCurrentMetadataPtr() const2291 const Metadata* GetCurrentMetadataPtr() const { return file_level_metadata_; }
2292
2293 private:
2294 MessageFactory* factory_;
2295 Metadata* file_level_metadata_;
2296 const EnumDescriptor** file_level_enum_descriptors_;
2297 const MigrationSchema* schemas_;
2298 const Message* const* default_instance_data_;
2299 const uint32* offsets_;
2300 };
2301
2302 namespace {
2303
2304 // We have the routines that assign descriptors and build reflection
2305 // automatically delete the allocated reflection. MetadataOwner owns
2306 // all the allocated reflection instances.
2307 struct MetadataOwner {
~MetadataOwnergoogle::protobuf::__anonf2ed1b540511::MetadataOwner2308 ~MetadataOwner() {
2309 for (auto range : metadata_arrays_) {
2310 for (const Metadata* m = range.first; m < range.second; m++) {
2311 delete m->reflection;
2312 }
2313 }
2314 }
2315
AddArraygoogle::protobuf::__anonf2ed1b540511::MetadataOwner2316 void AddArray(const Metadata* begin, const Metadata* end) {
2317 mu_.Lock();
2318 metadata_arrays_.push_back(std::make_pair(begin, end));
2319 mu_.Unlock();
2320 }
2321
Instancegoogle::protobuf::__anonf2ed1b540511::MetadataOwner2322 static MetadataOwner* Instance() {
2323 static MetadataOwner* res = OnShutdownDelete(new MetadataOwner);
2324 return res;
2325 }
2326
2327 private:
2328 MetadataOwner() = default; // private because singleton
2329
2330 WrappedMutex mu_;
2331 std::vector<std::pair<const Metadata*, const Metadata*> > metadata_arrays_;
2332 };
2333
AssignDescriptorsImpl(const DescriptorTable * table)2334 void AssignDescriptorsImpl(const DescriptorTable* table) {
2335 // Ensure the file descriptor is added to the pool.
2336 {
2337 // This only happens once per proto file. So a global mutex to serialize
2338 // calls to AddDescriptors.
2339 static WrappedMutex mu{GOOGLE_PROTOBUF_LINKER_INITIALIZED};
2340 mu.Lock();
2341 AddDescriptors(table);
2342 mu.Unlock();
2343 }
2344 // Fill the arrays with pointers to descriptors and reflection classes.
2345 const FileDescriptor* file =
2346 DescriptorPool::internal_generated_pool()->FindFileByName(
2347 table->filename);
2348 GOOGLE_CHECK(file != nullptr);
2349
2350 MessageFactory* factory = MessageFactory::generated_factory();
2351
2352 AssignDescriptorsHelper helper(
2353 factory, table->file_level_metadata, table->file_level_enum_descriptors,
2354 table->schemas, table->default_instances, table->offsets);
2355
2356 for (int i = 0; i < file->message_type_count(); i++) {
2357 helper.AssignMessageDescriptor(file->message_type(i));
2358 }
2359
2360 for (int i = 0; i < file->enum_type_count(); i++) {
2361 helper.AssignEnumDescriptor(file->enum_type(i));
2362 }
2363 if (file->options().cc_generic_services()) {
2364 for (int i = 0; i < file->service_count(); i++) {
2365 table->file_level_service_descriptors[i] = file->service(i);
2366 }
2367 }
2368 MetadataOwner::Instance()->AddArray(table->file_level_metadata,
2369 helper.GetCurrentMetadataPtr());
2370 }
2371
AddDescriptorsImpl(const DescriptorTable * table)2372 void AddDescriptorsImpl(const DescriptorTable* table) {
2373 // Reflection refers to the default instances so make sure they are
2374 // initialized.
2375 for (int i = 0; i < table->num_sccs; i++) {
2376 internal::InitSCC(table->init_default_instances[i]);
2377 }
2378
2379 // Ensure all dependent descriptors are registered to the generated descriptor
2380 // pool and message factory.
2381 for (int i = 0; i < table->num_deps; i++) {
2382 // In case of weak fields deps[i] could be null.
2383 if (table->deps[i]) AddDescriptors(table->deps[i]);
2384 }
2385
2386 // Register the descriptor of this file.
2387 DescriptorPool::InternalAddGeneratedFile(table->descriptor, table->size);
2388 MessageFactory::InternalRegisterGeneratedFile(table);
2389 }
2390
2391 } // namespace
2392
2393 // Separate function because it needs to be a friend of
2394 // Reflection
RegisterAllTypesInternal(const Metadata * file_level_metadata,int size)2395 void RegisterAllTypesInternal(const Metadata* file_level_metadata, int size) {
2396 for (int i = 0; i < size; i++) {
2397 const Reflection* reflection = file_level_metadata[i].reflection;
2398 MessageFactory::InternalRegisterGeneratedMessage(
2399 file_level_metadata[i].descriptor,
2400 reflection->schema_.default_instance_);
2401 }
2402 }
2403
2404 namespace internal {
2405
AssignDescriptors(const DescriptorTable * table)2406 void AssignDescriptors(const DescriptorTable* table) {
2407 call_once(*table->once, AssignDescriptorsImpl, table);
2408 }
2409
AddDescriptors(const DescriptorTable * table)2410 void AddDescriptors(const DescriptorTable* table) {
2411 // AddDescriptors is not thread safe. Callers need to ensure calls are
2412 // properly serialized. This function is only called pre-main by global
2413 // descriptors and we can assume single threaded access or it's called
2414 // by AssignDescriptorImpl which uses a mutex to sequence calls.
2415 if (*table->is_initialized) return;
2416 *table->is_initialized = true;
2417 AddDescriptorsImpl(table);
2418 }
2419
RegisterFileLevelMetadata(const DescriptorTable * table)2420 void RegisterFileLevelMetadata(const DescriptorTable* table) {
2421 AssignDescriptors(table);
2422 RegisterAllTypesInternal(table->file_level_metadata, table->num_messages);
2423 }
2424
UnknownFieldSetSerializer(const uint8 * base,uint32 offset,uint32 tag,uint32 has_offset,io::CodedOutputStream * output)2425 void UnknownFieldSetSerializer(const uint8* base, uint32 offset, uint32 tag,
2426 uint32 has_offset,
2427 io::CodedOutputStream* output) {
2428 const void* ptr = base + offset;
2429 const InternalMetadataWithArena* metadata =
2430 static_cast<const InternalMetadataWithArena*>(ptr);
2431 if (metadata->have_unknown_fields()) {
2432 internal::WireFormat::SerializeUnknownFields(metadata->unknown_fields(),
2433 output);
2434 }
2435 }
2436
2437 } // namespace internal
2438 } // namespace protobuf
2439 } // namespace google
2440