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: [email protected] (Kenton Varda)
32 // Based on original Protocol Buffers design by
33 // Sanjay Ghemawat, Jeff Dean, and others.
34
35 #include <google/protobuf/generated_message_reflection.h>
36
37 #include <algorithm>
38 #include <set>
39
40 #include <google/protobuf/stubs/logging.h>
41 #include <google/protobuf/stubs/common.h>
42 #include <google/protobuf/stubs/mutex.h>
43 #include <google/protobuf/stubs/casts.h>
44 #include <google/protobuf/stubs/strutil.h>
45 #include <google/protobuf/descriptor.h>
46 #include <google/protobuf/descriptor.pb.h>
47 #include <google/protobuf/extension_set.h>
48 #include <google/protobuf/generated_message_util.h>
49 #include <google/protobuf/inlined_string_field.h>
50 #include <google/protobuf/map_field.h>
51 #include <google/protobuf/map_field_inl.h>
52 #include <google/protobuf/repeated_field.h>
53 #include <google/protobuf/unknown_field_set.h>
54
55
56 // clang-format off
57 #include <google/protobuf/port_def.inc>
58 // clang-format on
59
60 #define GOOGLE_PROTOBUF_HAS_ONEOF
61
62 using google::protobuf::internal::ArenaStringPtr;
63 using google::protobuf::internal::DescriptorTable;
64 using google::protobuf::internal::ExtensionSet;
65 using google::protobuf::internal::GenericTypeHandler;
66 using google::protobuf::internal::GetEmptyString;
67 using google::protobuf::internal::InlinedStringField;
68 using google::protobuf::internal::InternalMetadata;
69 using google::protobuf::internal::LazyField;
70 using google::protobuf::internal::MapFieldBase;
71 using google::protobuf::internal::MigrationSchema;
72 using google::protobuf::internal::OnShutdownDelete;
73 using google::protobuf::internal::ReflectionSchema;
74 using google::protobuf::internal::RepeatedPtrFieldBase;
75 using google::protobuf::internal::StringSpaceUsedExcludingSelfLong;
76 using google::protobuf::internal::WrappedMutex;
77
78 namespace google {
79 namespace protobuf {
80
81 namespace {
IsMapFieldInApi(const FieldDescriptor * field)82 bool IsMapFieldInApi(const FieldDescriptor* field) { return field->is_map(); }
83
84 #ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
MaybeForceCopy(Arena * arena,Message * msg)85 Message* MaybeForceCopy(Arena* arena, Message* msg) {
86 if (arena != nullptr || msg == nullptr) return msg;
87
88 Message* copy = msg->New();
89 copy->MergeFrom(*msg);
90 delete msg;
91 return copy;
92 }
93 #endif // PROTOBUF_FORCE_COPY_IN_RELEASE
94 } // anonymous namespace
95
96 namespace internal {
97
ParseNamedEnum(const EnumDescriptor * descriptor,ConstStringParam name,int * value)98 bool ParseNamedEnum(const EnumDescriptor* descriptor, ConstStringParam name,
99 int* value) {
100 const EnumValueDescriptor* d = descriptor->FindValueByName(name);
101 if (d == nullptr) return false;
102 *value = d->number();
103 return true;
104 }
105
NameOfEnum(const EnumDescriptor * descriptor,int value)106 const std::string& NameOfEnum(const EnumDescriptor* descriptor, int value) {
107 const EnumValueDescriptor* d = descriptor->FindValueByNumber(value);
108 return (d == nullptr ? GetEmptyString() : d->name());
109 }
110
111 } // namespace internal
112
113 // ===================================================================
114 // Helpers for reporting usage errors (e.g. trying to use GetInt32() on
115 // a string field).
116
117 namespace {
118
119 using internal::GetConstPointerAtOffset;
120 using internal::GetConstRefAtOffset;
121 using internal::GetPointerAtOffset;
122
ReportReflectionUsageError(const Descriptor * descriptor,const FieldDescriptor * field,const char * method,const char * description)123 void ReportReflectionUsageError(const Descriptor* descriptor,
124 const FieldDescriptor* field,
125 const char* method, const char* description) {
126 GOOGLE_LOG(FATAL) << "Protocol Buffer reflection usage error:\n"
127 " Method : google::protobuf::Reflection::"
128 << method
129 << "\n"
130 " Message type: "
131 << descriptor->full_name()
132 << "\n"
133 " Field : "
134 << field->full_name()
135 << "\n"
136 " Problem : "
137 << description;
138 }
139
140 const char* cpptype_names_[FieldDescriptor::MAX_CPPTYPE + 1] = {
141 "INVALID_CPPTYPE", "CPPTYPE_INT32", "CPPTYPE_INT64", "CPPTYPE_UINT32",
142 "CPPTYPE_UINT64", "CPPTYPE_DOUBLE", "CPPTYPE_FLOAT", "CPPTYPE_BOOL",
143 "CPPTYPE_ENUM", "CPPTYPE_STRING", "CPPTYPE_MESSAGE"};
144
ReportReflectionUsageTypeError(const Descriptor * descriptor,const FieldDescriptor * field,const char * method,FieldDescriptor::CppType expected_type)145 static void ReportReflectionUsageTypeError(
146 const Descriptor* descriptor, const FieldDescriptor* field,
147 const char* method, FieldDescriptor::CppType expected_type) {
148 GOOGLE_LOG(FATAL)
149 << "Protocol Buffer reflection usage error:\n"
150 " Method : google::protobuf::Reflection::"
151 << method
152 << "\n"
153 " Message type: "
154 << descriptor->full_name()
155 << "\n"
156 " Field : "
157 << field->full_name()
158 << "\n"
159 " Problem : Field is not the right type for this message:\n"
160 " Expected : "
161 << cpptype_names_[expected_type]
162 << "\n"
163 " Field type: "
164 << cpptype_names_[field->cpp_type()];
165 }
166
ReportReflectionUsageEnumTypeError(const Descriptor * descriptor,const FieldDescriptor * field,const char * method,const EnumValueDescriptor * value)167 static void ReportReflectionUsageEnumTypeError(
168 const Descriptor* descriptor, const FieldDescriptor* field,
169 const char* method, const EnumValueDescriptor* value) {
170 GOOGLE_LOG(FATAL) << "Protocol Buffer reflection usage error:\n"
171 " Method : google::protobuf::Reflection::"
172 << method
173 << "\n"
174 " Message type: "
175 << descriptor->full_name()
176 << "\n"
177 " Field : "
178 << field->full_name()
179 << "\n"
180 " Problem : Enum value did not match field type:\n"
181 " Expected : "
182 << field->enum_type()->full_name()
183 << "\n"
184 " Actual : "
185 << value->full_name();
186 }
187
CheckInvalidAccess(const internal::ReflectionSchema & schema,const FieldDescriptor * field)188 inline void CheckInvalidAccess(const internal::ReflectionSchema& schema,
189 const FieldDescriptor* field) {
190 GOOGLE_CHECK(!schema.IsFieldStripped(field))
191 << "invalid access to a stripped field " << field->full_name();
192 }
193
194 #define USAGE_CHECK(CONDITION, METHOD, ERROR_DESCRIPTION) \
195 if (!(CONDITION)) \
196 ReportReflectionUsageError(descriptor_, field, #METHOD, ERROR_DESCRIPTION)
197 #define USAGE_CHECK_EQ(A, B, METHOD, ERROR_DESCRIPTION) \
198 USAGE_CHECK((A) == (B), METHOD, ERROR_DESCRIPTION)
199 #define USAGE_CHECK_NE(A, B, METHOD, ERROR_DESCRIPTION) \
200 USAGE_CHECK((A) != (B), METHOD, ERROR_DESCRIPTION)
201
202 #define USAGE_CHECK_TYPE(METHOD, CPPTYPE) \
203 if (field->cpp_type() != FieldDescriptor::CPPTYPE_##CPPTYPE) \
204 ReportReflectionUsageTypeError(descriptor_, field, #METHOD, \
205 FieldDescriptor::CPPTYPE_##CPPTYPE)
206
207 #define USAGE_CHECK_ENUM_VALUE(METHOD) \
208 if (value->type() != field->enum_type()) \
209 ReportReflectionUsageEnumTypeError(descriptor_, field, #METHOD, value)
210
211 #define USAGE_CHECK_MESSAGE_TYPE(METHOD) \
212 USAGE_CHECK_EQ(field->containing_type(), descriptor_, METHOD, \
213 "Field does not match message type.");
214 #define USAGE_CHECK_SINGULAR(METHOD) \
215 USAGE_CHECK_NE(field->label(), FieldDescriptor::LABEL_REPEATED, METHOD, \
216 "Field is repeated; the method requires a singular field.")
217 #define USAGE_CHECK_REPEATED(METHOD) \
218 USAGE_CHECK_EQ(field->label(), FieldDescriptor::LABEL_REPEATED, METHOD, \
219 "Field is singular; the method requires a repeated field.")
220
221 #define USAGE_CHECK_ALL(METHOD, LABEL, CPPTYPE) \
222 USAGE_CHECK_MESSAGE_TYPE(METHOD); \
223 USAGE_CHECK_##LABEL(METHOD); \
224 USAGE_CHECK_TYPE(METHOD, CPPTYPE)
225
226 } // namespace
227
228 // ===================================================================
229
Reflection(const Descriptor * descriptor,const internal::ReflectionSchema & schema,const DescriptorPool * pool,MessageFactory * factory)230 Reflection::Reflection(const Descriptor* descriptor,
231 const internal::ReflectionSchema& schema,
232 const DescriptorPool* pool, MessageFactory* factory)
233 : descriptor_(descriptor),
234 schema_(schema),
235 descriptor_pool_(
236 (pool == nullptr) ? DescriptorPool::internal_generated_pool() : pool),
237 message_factory_(factory),
238 last_non_weak_field_index_(-1) {
239 last_non_weak_field_index_ = descriptor_->field_count() - 1;
240 }
241
GetUnknownFields(const Message & message) const242 const UnknownFieldSet& Reflection::GetUnknownFields(
243 const Message& message) const {
244 return GetInternalMetadata(message).unknown_fields<UnknownFieldSet>(
245 UnknownFieldSet::default_instance);
246 }
247
MutableUnknownFields(Message * message) const248 UnknownFieldSet* Reflection::MutableUnknownFields(Message* message) const {
249 return MutableInternalMetadata(message)
250 ->mutable_unknown_fields<UnknownFieldSet>();
251 }
252
IsLazyExtension(const Message & message,const FieldDescriptor * field) const253 bool Reflection::IsLazyExtension(const Message& message,
254 const FieldDescriptor* field) const {
255 return field->is_extension() &&
256 GetExtensionSet(message).HasLazy(field->number());
257 }
258
IsLazilyVerifiedLazyField(const FieldDescriptor * field) const259 bool Reflection::IsLazilyVerifiedLazyField(const FieldDescriptor* field) const {
260 if (field->options().unverified_lazy()) return true;
261
262 // Message fields with [lazy=true] will be eagerly verified
263 // (go/verified-lazy).
264 return field->options().lazy() && !IsEagerlyVerifiedLazyField(field);
265 }
266
IsEagerlyVerifiedLazyField(const FieldDescriptor * field) const267 bool Reflection::IsEagerlyVerifiedLazyField(
268 const FieldDescriptor* field) const {
269 return (field->type() == FieldDescriptor::TYPE_MESSAGE &&
270 schema_.IsEagerlyVerifiedLazyField(field));
271 }
272
IsInlined(const FieldDescriptor * field) const273 bool Reflection::IsInlined(const FieldDescriptor* field) const {
274 return schema_.IsFieldInlined(field);
275 }
276
SpaceUsedLong(const Message & message) const277 size_t Reflection::SpaceUsedLong(const Message& message) const {
278 // object_size_ already includes the in-memory representation of each field
279 // in the message, so we only need to account for additional memory used by
280 // the fields.
281 size_t total_size = schema_.GetObjectSize();
282
283 total_size += GetUnknownFields(message).SpaceUsedExcludingSelfLong();
284
285 // If this message owns an arena, add any unused space that's been allocated.
286 auto* arena = Arena::InternalGetArenaForAllocation(&message);
287 if (arena != nullptr && Arena::InternalGetOwningArena(&message) == nullptr &&
288 arena->InternalIsMessageOwnedArena()) {
289 total_size += arena->SpaceAllocated() - arena->SpaceUsed();
290 }
291
292 if (schema_.HasExtensionSet()) {
293 total_size += GetExtensionSet(message).SpaceUsedExcludingSelfLong();
294 }
295 for (int i = 0; i <= last_non_weak_field_index_; i++) {
296 const FieldDescriptor* field = descriptor_->field(i);
297 if (field->is_repeated()) {
298 switch (field->cpp_type()) {
299 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
300 case FieldDescriptor::CPPTYPE_##UPPERCASE: \
301 total_size += GetRaw<RepeatedField<LOWERCASE> >(message, field) \
302 .SpaceUsedExcludingSelfLong(); \
303 break
304
305 HANDLE_TYPE(INT32, int32_t);
306 HANDLE_TYPE(INT64, int64_t);
307 HANDLE_TYPE(UINT32, uint32_t);
308 HANDLE_TYPE(UINT64, uint64_t);
309 HANDLE_TYPE(DOUBLE, double);
310 HANDLE_TYPE(FLOAT, float);
311 HANDLE_TYPE(BOOL, bool);
312 HANDLE_TYPE(ENUM, int);
313 #undef HANDLE_TYPE
314
315 case FieldDescriptor::CPPTYPE_STRING:
316 switch (field->options().ctype()) {
317 default: // TODO(kenton): Support other string reps.
318 case FieldOptions::STRING:
319 total_size +=
320 GetRaw<RepeatedPtrField<std::string> >(message, field)
321 .SpaceUsedExcludingSelfLong();
322 break;
323 }
324 break;
325
326 case FieldDescriptor::CPPTYPE_MESSAGE:
327 if (IsMapFieldInApi(field)) {
328 total_size += GetRaw<internal::MapFieldBase>(message, field)
329 .SpaceUsedExcludingSelfLong();
330 } else {
331 // We don't know which subclass of RepeatedPtrFieldBase the type is,
332 // so we use RepeatedPtrFieldBase directly.
333 total_size +=
334 GetRaw<RepeatedPtrFieldBase>(message, field)
335 .SpaceUsedExcludingSelfLong<GenericTypeHandler<Message> >();
336 }
337
338 break;
339 }
340 } else {
341 if (schema_.InRealOneof(field) && !HasOneofField(message, field)) {
342 continue;
343 }
344 switch (field->cpp_type()) {
345 case FieldDescriptor::CPPTYPE_INT32:
346 case FieldDescriptor::CPPTYPE_INT64:
347 case FieldDescriptor::CPPTYPE_UINT32:
348 case FieldDescriptor::CPPTYPE_UINT64:
349 case FieldDescriptor::CPPTYPE_DOUBLE:
350 case FieldDescriptor::CPPTYPE_FLOAT:
351 case FieldDescriptor::CPPTYPE_BOOL:
352 case FieldDescriptor::CPPTYPE_ENUM:
353 // Field is inline, so we've already counted it.
354 break;
355
356 case FieldDescriptor::CPPTYPE_STRING: {
357 switch (field->options().ctype()) {
358 default: // TODO(kenton): Support other string reps.
359 case FieldOptions::STRING:
360 if (IsInlined(field)) {
361 const std::string* ptr =
362 &GetField<InlinedStringField>(message, field).GetNoArena();
363 total_size += StringSpaceUsedExcludingSelfLong(*ptr);
364 } else {
365 // Initially, the string points to the default value stored
366 // in the prototype. Only count the string if it has been
367 // changed from the default value.
368 // Except oneof fields, those never point to a default instance,
369 // and there is no default instance to point to.
370 const auto& str = GetField<ArenaStringPtr>(message, field);
371 if (!str.IsDefault() || schema_.InRealOneof(field)) {
372 // string fields are represented by just a pointer, so also
373 // include sizeof(string) as well.
374 total_size += sizeof(std::string) +
375 StringSpaceUsedExcludingSelfLong(str.Get());
376 }
377 }
378 break;
379 }
380 break;
381 }
382
383 case FieldDescriptor::CPPTYPE_MESSAGE:
384 if (schema_.IsDefaultInstance(message)) {
385 // For singular fields, the prototype just stores a pointer to the
386 // external type's prototype, so there is no extra memory usage.
387 } else {
388 const Message* sub_message = GetRaw<const Message*>(message, field);
389 if (sub_message != nullptr) {
390 total_size += sub_message->SpaceUsedLong();
391 }
392 }
393 break;
394 }
395 }
396 }
397 return total_size;
398 }
399
400 namespace {
401
402 template <bool unsafe_shallow_swap>
403 struct OneofFieldMover {
404 template <typename FromType, typename ToType>
operator ()google::protobuf::__anon11acbc3b0311::OneofFieldMover405 void operator()(const FieldDescriptor* field, FromType* from, ToType* to) {
406 switch (field->cpp_type()) {
407 case FieldDescriptor::CPPTYPE_INT32:
408 to->SetInt32(from->GetInt32());
409 break;
410 case FieldDescriptor::CPPTYPE_INT64:
411 to->SetInt64(from->GetInt64());
412 break;
413 case FieldDescriptor::CPPTYPE_UINT32:
414 to->SetUint32(from->GetUint32());
415 break;
416 case FieldDescriptor::CPPTYPE_UINT64:
417 to->SetUint64(from->GetUint64());
418 break;
419 case FieldDescriptor::CPPTYPE_FLOAT:
420 to->SetFloat(from->GetFloat());
421 break;
422 case FieldDescriptor::CPPTYPE_DOUBLE:
423 to->SetDouble(from->GetDouble());
424 break;
425 case FieldDescriptor::CPPTYPE_BOOL:
426 to->SetBool(from->GetBool());
427 break;
428 case FieldDescriptor::CPPTYPE_ENUM:
429 to->SetEnum(from->GetEnum());
430 break;
431 case FieldDescriptor::CPPTYPE_MESSAGE:
432 if (!unsafe_shallow_swap) {
433 to->SetMessage(from->GetMessage());
434 } else {
435 to->UnsafeSetMessage(from->UnsafeGetMessage());
436 }
437 break;
438 case FieldDescriptor::CPPTYPE_STRING:
439 if (!unsafe_shallow_swap) {
440 to->SetString(from->GetString());
441 break;
442 }
443 switch (field->options().ctype()) {
444 default:
445 case FieldOptions::STRING: {
446 to->SetArenaStringPtr(from->GetArenaStringPtr());
447 break;
448 }
449 }
450 break;
451 default:
452 GOOGLE_LOG(FATAL) << "unimplemented type: " << field->cpp_type();
453 }
454 if (unsafe_shallow_swap) {
455 // Not clearing oneof case after move may cause unwanted "ClearOneof"
456 // where the residual message or string value is deleted and causes
457 // use-after-free (only for unsafe swap).
458 from->ClearOneofCase();
459 }
460 }
461 };
462
463 } // namespace
464
465 namespace internal {
466
467 class SwapFieldHelper {
468 public:
469 template <bool unsafe_shallow_swap>
470 static void SwapRepeatedStringField(const Reflection* r, Message* lhs,
471 Message* rhs,
472 const FieldDescriptor* field);
473
474 template <bool unsafe_shallow_swap>
475 static void SwapInlinedStrings(const Reflection* r, Message* lhs,
476 Message* rhs, const FieldDescriptor* field);
477
478 template <bool unsafe_shallow_swap>
479 static void SwapNonInlinedStrings(const Reflection* r, Message* lhs,
480 Message* rhs, const FieldDescriptor* field);
481
482 template <bool unsafe_shallow_swap>
483 static void SwapStringField(const Reflection* r, Message* lhs, Message* rhs,
484 const FieldDescriptor* field);
485
486 static void SwapArenaStringPtr(ArenaStringPtr* lhs, Arena* lhs_arena,
487 ArenaStringPtr* rhs, Arena* rhs_arena);
488
489 template <bool unsafe_shallow_swap>
490 static void SwapRepeatedMessageField(const Reflection* r, Message* lhs,
491 Message* rhs,
492 const FieldDescriptor* field);
493
494 template <bool unsafe_shallow_swap>
495 static void SwapMessageField(const Reflection* r, Message* lhs, Message* rhs,
496 const FieldDescriptor* field);
497
498 static void SwapMessage(const Reflection* r, Message* lhs, Arena* lhs_arena,
499 Message* rhs, Arena* rhs_arena,
500 const FieldDescriptor* field);
501
502 static void SwapNonMessageNonStringField(const Reflection* r, Message* lhs,
503 Message* rhs,
504 const FieldDescriptor* field);
505 };
506
507 template <bool unsafe_shallow_swap>
SwapRepeatedStringField(const Reflection * r,Message * lhs,Message * rhs,const FieldDescriptor * field)508 void SwapFieldHelper::SwapRepeatedStringField(const Reflection* r, Message* lhs,
509 Message* rhs,
510 const FieldDescriptor* field) {
511 switch (field->options().ctype()) {
512 default:
513 case FieldOptions::STRING: {
514 auto* lhs_string = r->MutableRaw<RepeatedPtrFieldBase>(lhs, field);
515 auto* rhs_string = r->MutableRaw<RepeatedPtrFieldBase>(rhs, field);
516 if (unsafe_shallow_swap) {
517 lhs_string->InternalSwap(rhs_string);
518 } else {
519 lhs_string->Swap<GenericTypeHandler<std::string>>(rhs_string);
520 }
521 break;
522 }
523 }
524 }
525
526 template <bool unsafe_shallow_swap>
SwapInlinedStrings(const Reflection * r,Message * lhs,Message * rhs,const FieldDescriptor * field)527 void SwapFieldHelper::SwapInlinedStrings(const Reflection* r, Message* lhs,
528 Message* rhs,
529 const FieldDescriptor* field) {
530 // Inlined string field.
531 Arena* lhs_arena = lhs->GetArenaForAllocation();
532 Arena* rhs_arena = rhs->GetArenaForAllocation();
533 auto* lhs_string = r->MutableRaw<InlinedStringField>(lhs, field);
534 auto* rhs_string = r->MutableRaw<InlinedStringField>(rhs, field);
535 uint32_t index = r->schema_.InlinedStringIndex(field);
536 GOOGLE_DCHECK_GT(index, 0);
537 uint32_t* lhs_array = r->MutableInlinedStringDonatedArray(lhs);
538 uint32_t* rhs_array = r->MutableInlinedStringDonatedArray(rhs);
539 uint32_t* lhs_state = &lhs_array[index / 32];
540 uint32_t* rhs_state = &rhs_array[index / 32];
541 bool lhs_arena_dtor_registered = (lhs_array[0] & 0x1u) == 0;
542 bool rhs_arena_dtor_registered = (rhs_array[0] & 0x1u) == 0;
543 const uint32_t mask = ~(static_cast<uint32_t>(1) << (index % 32));
544 if (unsafe_shallow_swap || lhs_arena == rhs_arena) {
545 InlinedStringField::InternalSwap(lhs_string, lhs_arena,
546 lhs_arena_dtor_registered, lhs, rhs_string,
547 rhs_arena, rhs_arena_dtor_registered, rhs);
548 } else {
549 const std::string temp = lhs_string->Get();
550 lhs_string->Set(rhs_string->Get(), lhs_arena,
551 r->IsInlinedStringDonated(*lhs, field), lhs_state, mask,
552 lhs);
553 rhs_string->Set(temp, rhs_arena, r->IsInlinedStringDonated(*rhs, field),
554 rhs_state, mask, rhs);
555 }
556 }
557
558 template <bool unsafe_shallow_swap>
SwapNonInlinedStrings(const Reflection * r,Message * lhs,Message * rhs,const FieldDescriptor * field)559 void SwapFieldHelper::SwapNonInlinedStrings(const Reflection* r, Message* lhs,
560 Message* rhs,
561 const FieldDescriptor* field) {
562 ArenaStringPtr* lhs_string = r->MutableRaw<ArenaStringPtr>(lhs, field);
563 ArenaStringPtr* rhs_string = r->MutableRaw<ArenaStringPtr>(rhs, field);
564 if (unsafe_shallow_swap) {
565 ArenaStringPtr::UnsafeShallowSwap(lhs_string, rhs_string);
566 } else {
567 SwapFieldHelper::SwapArenaStringPtr(
568 lhs_string, lhs->GetArenaForAllocation(), //
569 rhs_string, rhs->GetArenaForAllocation());
570 }
571 }
572
573 template <bool unsafe_shallow_swap>
SwapStringField(const Reflection * r,Message * lhs,Message * rhs,const FieldDescriptor * field)574 void SwapFieldHelper::SwapStringField(const Reflection* r, Message* lhs,
575 Message* rhs,
576 const FieldDescriptor* field) {
577 switch (field->options().ctype()) {
578 default:
579 case FieldOptions::STRING: {
580 if (r->IsInlined(field)) {
581 SwapFieldHelper::SwapInlinedStrings<unsafe_shallow_swap>(r, lhs, rhs,
582 field);
583 } else {
584 SwapFieldHelper::SwapNonInlinedStrings<unsafe_shallow_swap>(r, lhs, rhs,
585 field);
586 }
587 break;
588 }
589 }
590 }
591
SwapArenaStringPtr(ArenaStringPtr * lhs,Arena * lhs_arena,ArenaStringPtr * rhs,Arena * rhs_arena)592 void SwapFieldHelper::SwapArenaStringPtr(ArenaStringPtr* lhs, Arena* lhs_arena,
593 ArenaStringPtr* rhs,
594 Arena* rhs_arena) {
595 if (lhs_arena == rhs_arena) {
596 ArenaStringPtr::InternalSwap(lhs, lhs_arena, rhs, rhs_arena);
597 } else if (lhs->IsDefault() && rhs->IsDefault()) {
598 // Nothing to do.
599 } else if (lhs->IsDefault()) {
600 lhs->Set(rhs->Get(), lhs_arena);
601 // rhs needs to be destroyed before overwritten.
602 rhs->Destroy();
603 rhs->InitDefault();
604 } else if (rhs->IsDefault()) {
605 rhs->Set(lhs->Get(), rhs_arena);
606 // lhs needs to be destroyed before overwritten.
607 lhs->Destroy();
608 lhs->InitDefault();
609 } else {
610 std::string temp = lhs->Get();
611 lhs->Set(rhs->Get(), lhs_arena);
612 rhs->Set(std::move(temp), rhs_arena);
613 }
614 }
615
616 template <bool unsafe_shallow_swap>
SwapRepeatedMessageField(const Reflection * r,Message * lhs,Message * rhs,const FieldDescriptor * field)617 void SwapFieldHelper::SwapRepeatedMessageField(const Reflection* r,
618 Message* lhs, Message* rhs,
619 const FieldDescriptor* field) {
620 if (IsMapFieldInApi(field)) {
621 auto* lhs_map = r->MutableRaw<MapFieldBase>(lhs, field);
622 auto* rhs_map = r->MutableRaw<MapFieldBase>(rhs, field);
623 if (unsafe_shallow_swap) {
624 lhs_map->UnsafeShallowSwap(rhs_map);
625 } else {
626 lhs_map->Swap(rhs_map);
627 }
628 } else {
629 auto* lhs_rm = r->MutableRaw<RepeatedPtrFieldBase>(lhs, field);
630 auto* rhs_rm = r->MutableRaw<RepeatedPtrFieldBase>(rhs, field);
631 if (unsafe_shallow_swap) {
632 lhs_rm->InternalSwap(rhs_rm);
633 } else {
634 lhs_rm->Swap<GenericTypeHandler<Message>>(rhs_rm);
635 }
636 }
637 }
638
639 template <bool unsafe_shallow_swap>
SwapMessageField(const Reflection * r,Message * lhs,Message * rhs,const FieldDescriptor * field)640 void SwapFieldHelper::SwapMessageField(const Reflection* r, Message* lhs,
641 Message* rhs,
642 const FieldDescriptor* field) {
643 if (unsafe_shallow_swap) {
644 std::swap(*r->MutableRaw<Message*>(lhs, field),
645 *r->MutableRaw<Message*>(rhs, field));
646 } else {
647 SwapMessage(r, lhs, lhs->GetArenaForAllocation(), rhs,
648 rhs->GetArenaForAllocation(), field);
649 }
650 }
651
SwapMessage(const Reflection * r,Message * lhs,Arena * lhs_arena,Message * rhs,Arena * rhs_arena,const FieldDescriptor * field)652 void SwapFieldHelper::SwapMessage(const Reflection* r, Message* lhs,
653 Arena* lhs_arena, Message* rhs,
654 Arena* rhs_arena,
655 const FieldDescriptor* field) {
656 Message** lhs_sub = r->MutableRaw<Message*>(lhs, field);
657 Message** rhs_sub = r->MutableRaw<Message*>(rhs, field);
658
659 if (*lhs_sub == *rhs_sub) return;
660
661 #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
662 if (lhs_arena != nullptr && lhs_arena == rhs_arena) {
663 #else // PROTOBUF_FORCE_COPY_IN_SWAP
664 if (lhs_arena == rhs_arena) {
665 #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
666 std::swap(*lhs_sub, *rhs_sub);
667 return;
668 }
669
670 if (*lhs_sub != nullptr && *rhs_sub != nullptr) {
671 (*lhs_sub)->GetReflection()->Swap(*lhs_sub, *rhs_sub);
672 } else if (*lhs_sub == nullptr && r->HasBit(*rhs, field)) {
673 *lhs_sub = (*rhs_sub)->New(lhs_arena);
674 (*lhs_sub)->CopyFrom(**rhs_sub);
675 r->ClearField(rhs, field);
676 // Ensures has bit is unchanged after ClearField.
677 r->SetBit(rhs, field);
678 } else if (*rhs_sub == nullptr && r->HasBit(*lhs, field)) {
679 *rhs_sub = (*lhs_sub)->New(rhs_arena);
680 (*rhs_sub)->CopyFrom(**lhs_sub);
681 r->ClearField(lhs, field);
682 // Ensures has bit is unchanged after ClearField.
683 r->SetBit(lhs, field);
684 }
685 }
686
687 void SwapFieldHelper::SwapNonMessageNonStringField(
688 const Reflection* r, Message* lhs, Message* rhs,
689 const FieldDescriptor* field) {
690 switch (field->cpp_type()) {
691 #define SWAP_VALUES(CPPTYPE, TYPE) \
692 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
693 std::swap(*r->MutableRaw<TYPE>(lhs, field), \
694 *r->MutableRaw<TYPE>(rhs, field)); \
695 break;
696
697 SWAP_VALUES(INT32, int32_t);
698 SWAP_VALUES(INT64, int64_t);
699 SWAP_VALUES(UINT32, uint32_t);
700 SWAP_VALUES(UINT64, uint64_t);
701 SWAP_VALUES(FLOAT, float);
702 SWAP_VALUES(DOUBLE, double);
703 SWAP_VALUES(BOOL, bool);
704 SWAP_VALUES(ENUM, int);
705 #undef SWAP_VALUES
706 default:
707 GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
708 }
709 }
710
711 } // namespace internal
712
SwapField(Message * message1,Message * message2,const FieldDescriptor * field) const713 void Reflection::SwapField(Message* message1, Message* message2,
714 const FieldDescriptor* field) const {
715 if (field->is_repeated()) {
716 switch (field->cpp_type()) {
717 #define SWAP_ARRAYS(CPPTYPE, TYPE) \
718 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
719 MutableRaw<RepeatedField<TYPE> >(message1, field) \
720 ->Swap(MutableRaw<RepeatedField<TYPE> >(message2, field)); \
721 break;
722
723 SWAP_ARRAYS(INT32, int32_t);
724 SWAP_ARRAYS(INT64, int64_t);
725 SWAP_ARRAYS(UINT32, uint32_t);
726 SWAP_ARRAYS(UINT64, uint64_t);
727 SWAP_ARRAYS(FLOAT, float);
728 SWAP_ARRAYS(DOUBLE, double);
729 SWAP_ARRAYS(BOOL, bool);
730 SWAP_ARRAYS(ENUM, int);
731 #undef SWAP_ARRAYS
732
733 case FieldDescriptor::CPPTYPE_STRING:
734 internal::SwapFieldHelper::SwapRepeatedStringField<false>(
735 this, message1, message2, field);
736 break;
737 case FieldDescriptor::CPPTYPE_MESSAGE:
738 internal::SwapFieldHelper::SwapRepeatedMessageField<false>(
739 this, message1, message2, field);
740 break;
741
742 default:
743 GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
744 }
745 } else {
746 switch (field->cpp_type()) {
747 case FieldDescriptor::CPPTYPE_MESSAGE:
748 internal::SwapFieldHelper::SwapMessageField<false>(this, message1,
749 message2, field);
750 break;
751
752 case FieldDescriptor::CPPTYPE_STRING:
753 internal::SwapFieldHelper::SwapStringField<false>(this, message1,
754 message2, field);
755 break;
756 default:
757 internal::SwapFieldHelper::SwapNonMessageNonStringField(
758 this, message1, message2, field);
759 }
760 }
761 }
762
UnsafeShallowSwapField(Message * message1,Message * message2,const FieldDescriptor * field) const763 void Reflection::UnsafeShallowSwapField(Message* message1, Message* message2,
764 const FieldDescriptor* field) const {
765 if (!field->is_repeated()) {
766 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
767 internal::SwapFieldHelper::SwapMessageField<true>(this, message1,
768 message2, field);
769 } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
770 internal::SwapFieldHelper::SwapStringField<true>(this, message1, message2,
771 field);
772 } else {
773 internal::SwapFieldHelper::SwapNonMessageNonStringField(this, message1,
774 message2, field);
775 }
776 return;
777 }
778
779 switch (field->cpp_type()) {
780 #define SHALLOW_SWAP_ARRAYS(CPPTYPE, TYPE) \
781 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
782 MutableRaw<RepeatedField<TYPE>>(message1, field) \
783 ->InternalSwap(MutableRaw<RepeatedField<TYPE>>(message2, field)); \
784 break;
785
786 SHALLOW_SWAP_ARRAYS(INT32, int32_t);
787 SHALLOW_SWAP_ARRAYS(INT64, int64_t);
788 SHALLOW_SWAP_ARRAYS(UINT32, uint32_t);
789 SHALLOW_SWAP_ARRAYS(UINT64, uint64_t);
790 SHALLOW_SWAP_ARRAYS(FLOAT, float);
791 SHALLOW_SWAP_ARRAYS(DOUBLE, double);
792 SHALLOW_SWAP_ARRAYS(BOOL, bool);
793 SHALLOW_SWAP_ARRAYS(ENUM, int);
794 #undef SHALLOW_SWAP_ARRAYS
795
796 case FieldDescriptor::CPPTYPE_STRING:
797 internal::SwapFieldHelper::SwapRepeatedStringField<true>(this, message1,
798 message2, field);
799 break;
800 case FieldDescriptor::CPPTYPE_MESSAGE:
801 internal::SwapFieldHelper::SwapRepeatedMessageField<true>(
802 this, message1, message2, field);
803 break;
804
805 default:
806 GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
807 }
808 }
809
810 // Swaps oneof field between lhs and rhs. If unsafe_shallow_swap is true, it
811 // directly swaps oneof values; otherwise, it may involve copy/delete. Note that
812 // two messages may have different oneof cases. So, it has to be done in three
813 // steps (i.e. lhs -> temp, rhs -> lhs, temp -> rhs).
814 template <bool unsafe_shallow_swap>
SwapOneofField(Message * lhs,Message * rhs,const OneofDescriptor * oneof_descriptor) const815 void Reflection::SwapOneofField(Message* lhs, Message* rhs,
816 const OneofDescriptor* oneof_descriptor) const {
817 // Wraps a local variable to temporarily store oneof value.
818 struct LocalVarWrapper {
819 #define LOCAL_VAR_ACCESSOR(type, var, name) \
820 type Get##name() const { return oneof_val.type_##var; } \
821 void Set##name(type v) { oneof_val.type_##var = v; }
822
823 LOCAL_VAR_ACCESSOR(int32_t, int32, Int32);
824 LOCAL_VAR_ACCESSOR(int64_t, int64, Int64);
825 LOCAL_VAR_ACCESSOR(uint32_t, uint32, Uint32);
826 LOCAL_VAR_ACCESSOR(uint64_t, uint64, Uint64);
827 LOCAL_VAR_ACCESSOR(float, float, Float);
828 LOCAL_VAR_ACCESSOR(double, double, Double);
829 LOCAL_VAR_ACCESSOR(bool, bool, Bool);
830 LOCAL_VAR_ACCESSOR(int, enum, Enum);
831 LOCAL_VAR_ACCESSOR(Message*, message, Message);
832 LOCAL_VAR_ACCESSOR(ArenaStringPtr, arena_string_ptr, ArenaStringPtr);
833 const std::string& GetString() const { return string_val; }
834 void SetString(const std::string& v) { string_val = v; }
835 Message* UnsafeGetMessage() const { return GetMessage(); }
836 void UnsafeSetMessage(Message* v) { SetMessage(v); }
837 void ClearOneofCase() {}
838
839 union {
840 int32_t type_int32;
841 int64_t type_int64;
842 uint32_t type_uint32;
843 uint64_t type_uint64;
844 float type_float;
845 double type_double;
846 bool type_bool;
847 int type_enum;
848 Message* type_message;
849 internal::ArenaStringPtr type_arena_string_ptr;
850 } oneof_val;
851
852 // std::string cannot be in union.
853 std::string string_val;
854 };
855
856 // Wraps a message pointer to read and write a field.
857 struct MessageWrapper {
858 #define MESSAGE_FIELD_ACCESSOR(type, var, name) \
859 type Get##name() const { \
860 return reflection->GetField<type>(*message, field); \
861 } \
862 void Set##name(type v) { reflection->SetField<type>(message, field, v); }
863
864 MESSAGE_FIELD_ACCESSOR(int32_t, int32, Int32);
865 MESSAGE_FIELD_ACCESSOR(int64_t, int64, Int64);
866 MESSAGE_FIELD_ACCESSOR(uint32_t, uint32, Uint32);
867 MESSAGE_FIELD_ACCESSOR(uint64_t, uint64, Uint64);
868 MESSAGE_FIELD_ACCESSOR(float, float, Float);
869 MESSAGE_FIELD_ACCESSOR(double, double, Double);
870 MESSAGE_FIELD_ACCESSOR(bool, bool, Bool);
871 MESSAGE_FIELD_ACCESSOR(int, enum, Enum);
872 MESSAGE_FIELD_ACCESSOR(ArenaStringPtr, arena_string_ptr, ArenaStringPtr);
873 std::string GetString() const {
874 return reflection->GetString(*message, field);
875 }
876 void SetString(const std::string& v) {
877 reflection->SetString(message, field, v);
878 }
879 Message* GetMessage() const {
880 return reflection->ReleaseMessage(message, field);
881 }
882 void SetMessage(Message* v) {
883 reflection->SetAllocatedMessage(message, v, field);
884 }
885 Message* UnsafeGetMessage() const {
886 return reflection->UnsafeArenaReleaseMessage(message, field);
887 }
888 void UnsafeSetMessage(Message* v) {
889 reflection->UnsafeArenaSetAllocatedMessage(message, v, field);
890 }
891 void ClearOneofCase() {
892 *reflection->MutableOneofCase(message, field->containing_oneof()) = 0;
893 }
894
895 const Reflection* reflection;
896 Message* message;
897 const FieldDescriptor* field;
898 };
899
900 GOOGLE_DCHECK(!oneof_descriptor->is_synthetic());
901 uint32_t oneof_case_lhs = GetOneofCase(*lhs, oneof_descriptor);
902 uint32_t oneof_case_rhs = GetOneofCase(*rhs, oneof_descriptor);
903
904 LocalVarWrapper temp;
905 MessageWrapper lhs_wrapper, rhs_wrapper;
906 const FieldDescriptor* field_lhs = nullptr;
907 OneofFieldMover<unsafe_shallow_swap> mover;
908 // lhs --> temp
909 if (oneof_case_lhs > 0) {
910 field_lhs = descriptor_->FindFieldByNumber(oneof_case_lhs);
911 lhs_wrapper = {this, lhs, field_lhs};
912 mover(field_lhs, &lhs_wrapper, &temp);
913 }
914 // rhs --> lhs
915 if (oneof_case_rhs > 0) {
916 const FieldDescriptor* f = descriptor_->FindFieldByNumber(oneof_case_rhs);
917 lhs_wrapper = {this, lhs, f};
918 rhs_wrapper = {this, rhs, f};
919 mover(f, &rhs_wrapper, &lhs_wrapper);
920 } else if (!unsafe_shallow_swap) {
921 ClearOneof(lhs, oneof_descriptor);
922 }
923 // temp --> rhs
924 if (oneof_case_lhs > 0) {
925 rhs_wrapper = {this, rhs, field_lhs};
926 mover(field_lhs, &temp, &rhs_wrapper);
927 } else if (!unsafe_shallow_swap) {
928 ClearOneof(rhs, oneof_descriptor);
929 }
930
931 if (unsafe_shallow_swap) {
932 *MutableOneofCase(lhs, oneof_descriptor) = oneof_case_rhs;
933 *MutableOneofCase(rhs, oneof_descriptor) = oneof_case_lhs;
934 }
935 }
936
Swap(Message * message1,Message * message2) const937 void Reflection::Swap(Message* message1, Message* message2) const {
938 if (message1 == message2) return;
939
940 // TODO(kenton): Other Reflection methods should probably check this too.
941 GOOGLE_CHECK_EQ(message1->GetReflection(), this)
942 << "First argument to Swap() (of type \""
943 << message1->GetDescriptor()->full_name()
944 << "\") is not compatible with this reflection object (which is for type "
945 "\""
946 << descriptor_->full_name()
947 << "\"). Note that the exact same class is required; not just the same "
948 "descriptor.";
949 GOOGLE_CHECK_EQ(message2->GetReflection(), this)
950 << "Second argument to Swap() (of type \""
951 << message2->GetDescriptor()->full_name()
952 << "\") is not compatible with this reflection object (which is for type "
953 "\""
954 << descriptor_->full_name()
955 << "\"). Note that the exact same class is required; not just the same "
956 "descriptor.";
957
958 // Check that both messages are in the same arena (or both on the heap). We
959 // need to copy all data if not, due to ownership semantics.
960 #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
961 if (message1->GetOwningArena() == nullptr ||
962 message1->GetOwningArena() != message2->GetOwningArena()) {
963 #else // PROTOBUF_FORCE_COPY_IN_SWAP
964 if (message1->GetOwningArena() != message2->GetOwningArena()) {
965 #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
966 // One of the two is guaranteed to have an arena. Switch things around
967 // to guarantee that message1 has an arena.
968 Arena* arena = message1->GetOwningArena();
969 if (arena == nullptr) {
970 arena = message2->GetOwningArena();
971 std::swap(message1, message2); // Swapping names for pointers!
972 }
973
974 Message* temp = message1->New(arena);
975 temp->MergeFrom(*message2);
976 message2->CopyFrom(*message1);
977 #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
978 message1->CopyFrom(*temp);
979 if (arena == nullptr) delete temp;
980 #else // PROTOBUF_FORCE_COPY_IN_SWAP
981 Swap(message1, temp);
982 #endif // !PROTOBUF_FORCE_COPY_IN_SWAP
983 return;
984 }
985
986 GOOGLE_DCHECK_EQ(message1->GetOwningArena(), message2->GetOwningArena());
987
988 UnsafeArenaSwap(message1, message2);
989 }
990
991 template <bool unsafe_shallow_swap>
992 void Reflection::SwapFieldsImpl(
993 Message* message1, Message* message2,
994 const std::vector<const FieldDescriptor*>& fields) const {
995 if (message1 == message2) return;
996
997 // TODO(kenton): Other Reflection methods should probably check this too.
998 GOOGLE_CHECK_EQ(message1->GetReflection(), this)
999 << "First argument to SwapFields() (of type \""
1000 << message1->GetDescriptor()->full_name()
1001 << "\") is not compatible with this reflection object (which is for type "
1002 "\""
1003 << descriptor_->full_name()
1004 << "\"). Note that the exact same class is required; not just the same "
1005 "descriptor.";
1006 GOOGLE_CHECK_EQ(message2->GetReflection(), this)
1007 << "Second argument to SwapFields() (of type \""
1008 << message2->GetDescriptor()->full_name()
1009 << "\") is not compatible with this reflection object (which is for type "
1010 "\""
1011 << descriptor_->full_name()
1012 << "\"). Note that the exact same class is required; not just the same "
1013 "descriptor.";
1014
1015 std::set<int> swapped_oneof;
1016
1017 GOOGLE_DCHECK(!unsafe_shallow_swap || message1->GetArenaForAllocation() ==
1018 message2->GetArenaForAllocation());
1019
1020 const Message* prototype =
1021 message_factory_->GetPrototype(message1->GetDescriptor());
1022 for (const auto* field : fields) {
1023 CheckInvalidAccess(schema_, field);
1024 if (field->is_extension()) {
1025 if (unsafe_shallow_swap) {
1026 MutableExtensionSet(message1)->UnsafeShallowSwapExtension(
1027 MutableExtensionSet(message2), field->number());
1028 } else {
1029 MutableExtensionSet(message1)->SwapExtension(
1030 prototype, MutableExtensionSet(message2), field->number());
1031 }
1032 } else {
1033 if (schema_.InRealOneof(field)) {
1034 int oneof_index = field->containing_oneof()->index();
1035 // Only swap the oneof field once.
1036 if (swapped_oneof.find(oneof_index) != swapped_oneof.end()) {
1037 continue;
1038 }
1039 swapped_oneof.insert(oneof_index);
1040 SwapOneofField<unsafe_shallow_swap>(message1, message2,
1041 field->containing_oneof());
1042 } else {
1043 // Swap field.
1044 if (unsafe_shallow_swap) {
1045 UnsafeShallowSwapField(message1, message2, field);
1046 } else {
1047 SwapField(message1, message2, field);
1048 }
1049 // Swap has bit for non-repeated fields. We have already checked for
1050 // oneof already. This has to be done after SwapField, because SwapField
1051 // may depend on the information in has bits.
1052 if (!field->is_repeated()) {
1053 SwapBit(message1, message2, field);
1054 if (field->options().ctype() == FieldOptions::STRING &&
1055 IsInlined(field)) {
1056 GOOGLE_DCHECK(!unsafe_shallow_swap ||
1057 message1->GetArenaForAllocation() ==
1058 message2->GetArenaForAllocation());
1059 SwapInlinedStringDonated(message1, message2, field);
1060 }
1061 }
1062 }
1063 }
1064 }
1065 }
1066
1067 void Reflection::SwapFields(
1068 Message* message1, Message* message2,
1069 const std::vector<const FieldDescriptor*>& fields) const {
1070 SwapFieldsImpl<false>(message1, message2, fields);
1071 }
1072
1073 void Reflection::UnsafeShallowSwapFields(
1074 Message* message1, Message* message2,
1075 const std::vector<const FieldDescriptor*>& fields) const {
1076 SwapFieldsImpl<true>(message1, message2, fields);
1077 }
1078
1079 void Reflection::UnsafeArenaSwapFields(
1080 Message* lhs, Message* rhs,
1081 const std::vector<const FieldDescriptor*>& fields) const {
1082 GOOGLE_DCHECK_EQ(lhs->GetArenaForAllocation(), rhs->GetArenaForAllocation());
1083 UnsafeShallowSwapFields(lhs, rhs, fields);
1084 }
1085
1086 // -------------------------------------------------------------------
1087
1088 bool Reflection::HasField(const Message& message,
1089 const FieldDescriptor* field) const {
1090 USAGE_CHECK_MESSAGE_TYPE(HasField);
1091 USAGE_CHECK_SINGULAR(HasField);
1092 CheckInvalidAccess(schema_, field);
1093
1094 if (field->is_extension()) {
1095 return GetExtensionSet(message).Has(field->number());
1096 } else {
1097 if (schema_.InRealOneof(field)) {
1098 return HasOneofField(message, field);
1099 } else {
1100 return HasBit(message, field);
1101 }
1102 }
1103 }
1104
1105 void Reflection::UnsafeArenaSwap(Message* lhs, Message* rhs) const {
1106 if (lhs == rhs) return;
1107
1108 MutableInternalMetadata(lhs)->InternalSwap(MutableInternalMetadata(rhs));
1109
1110 for (int i = 0; i <= last_non_weak_field_index_; i++) {
1111 const FieldDescriptor* field = descriptor_->field(i);
1112 if (schema_.InRealOneof(field)) continue;
1113 if (schema_.IsFieldStripped(field)) continue;
1114 UnsafeShallowSwapField(lhs, rhs, field);
1115 }
1116 const int oneof_decl_count = descriptor_->oneof_decl_count();
1117 for (int i = 0; i < oneof_decl_count; i++) {
1118 const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
1119 if (!oneof->is_synthetic()) {
1120 SwapOneofField<true>(lhs, rhs, oneof);
1121 }
1122 }
1123
1124 // Swapping bits need to happen after swapping fields, because the latter may
1125 // depend on the has bit information.
1126 if (schema_.HasHasbits()) {
1127 uint32_t* lhs_has_bits = MutableHasBits(lhs);
1128 uint32_t* rhs_has_bits = MutableHasBits(rhs);
1129
1130 int fields_with_has_bits = 0;
1131 for (int i = 0; i < descriptor_->field_count(); i++) {
1132 const FieldDescriptor* field = descriptor_->field(i);
1133 if (field->is_repeated() || schema_.InRealOneof(field)) {
1134 continue;
1135 }
1136 fields_with_has_bits++;
1137 }
1138
1139 int has_bits_size = (fields_with_has_bits + 31) / 32;
1140
1141 for (int i = 0; i < has_bits_size; i++) {
1142 std::swap(lhs_has_bits[i], rhs_has_bits[i]);
1143 }
1144 }
1145
1146 if (schema_.HasInlinedString()) {
1147 uint32_t* lhs_donated_array = MutableInlinedStringDonatedArray(lhs);
1148 uint32_t* rhs_donated_array = MutableInlinedStringDonatedArray(rhs);
1149 int inlined_string_count = 0;
1150 for (int i = 0; i < descriptor_->field_count(); i++) {
1151 const FieldDescriptor* field = descriptor_->field(i);
1152 if (field->is_extension() || field->is_repeated() ||
1153 schema_.InRealOneof(field) ||
1154 field->options().ctype() != FieldOptions::STRING ||
1155 !IsInlined(field)) {
1156 continue;
1157 }
1158 inlined_string_count++;
1159 }
1160
1161 int donated_array_size = inlined_string_count == 0
1162 ? 0
1163 // One extra bit for the arena dtor tracking.
1164 : (inlined_string_count + 1 + 31) / 32;
1165 GOOGLE_CHECK_EQ((lhs_donated_array[0] & 0x1u) == 0,
1166 (rhs_donated_array[0] & 0x1u) == 0);
1167 for (int i = 0; i < donated_array_size; i++) {
1168 std::swap(lhs_donated_array[i], rhs_donated_array[i]);
1169 }
1170 }
1171
1172 if (schema_.HasExtensionSet()) {
1173 MutableExtensionSet(lhs)->InternalSwap(MutableExtensionSet(rhs));
1174 }
1175 }
1176
1177 int Reflection::FieldSize(const Message& message,
1178 const FieldDescriptor* field) const {
1179 USAGE_CHECK_MESSAGE_TYPE(FieldSize);
1180 USAGE_CHECK_REPEATED(FieldSize);
1181 CheckInvalidAccess(schema_, field);
1182
1183 if (field->is_extension()) {
1184 return GetExtensionSet(message).ExtensionSize(field->number());
1185 } else {
1186 switch (field->cpp_type()) {
1187 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
1188 case FieldDescriptor::CPPTYPE_##UPPERCASE: \
1189 return GetRaw<RepeatedField<LOWERCASE> >(message, field).size()
1190
1191 HANDLE_TYPE(INT32, int32_t);
1192 HANDLE_TYPE(INT64, int64_t);
1193 HANDLE_TYPE(UINT32, uint32_t);
1194 HANDLE_TYPE(UINT64, uint64_t);
1195 HANDLE_TYPE(DOUBLE, double);
1196 HANDLE_TYPE(FLOAT, float);
1197 HANDLE_TYPE(BOOL, bool);
1198 HANDLE_TYPE(ENUM, int);
1199 #undef HANDLE_TYPE
1200
1201 case FieldDescriptor::CPPTYPE_STRING:
1202 case FieldDescriptor::CPPTYPE_MESSAGE:
1203 if (IsMapFieldInApi(field)) {
1204 const internal::MapFieldBase& map =
1205 GetRaw<MapFieldBase>(message, field);
1206 if (map.IsRepeatedFieldValid()) {
1207 return map.GetRepeatedField().size();
1208 } else {
1209 // No need to materialize the repeated field if it is out of sync:
1210 // its size will be the same as the map's size.
1211 return map.size();
1212 }
1213 } else {
1214 return GetRaw<RepeatedPtrFieldBase>(message, field).size();
1215 }
1216 }
1217
1218 GOOGLE_LOG(FATAL) << "Can't get here.";
1219 return 0;
1220 }
1221 }
1222
1223 void Reflection::ClearField(Message* message,
1224 const FieldDescriptor* field) const {
1225 USAGE_CHECK_MESSAGE_TYPE(ClearField);
1226 CheckInvalidAccess(schema_, field);
1227
1228 if (field->is_extension()) {
1229 MutableExtensionSet(message)->ClearExtension(field->number());
1230 } else if (!field->is_repeated()) {
1231 if (schema_.InRealOneof(field)) {
1232 ClearOneofField(message, field);
1233 return;
1234 }
1235 if (HasBit(*message, field)) {
1236 ClearBit(message, field);
1237
1238 // We need to set the field back to its default value.
1239 switch (field->cpp_type()) {
1240 #define CLEAR_TYPE(CPPTYPE, TYPE) \
1241 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
1242 *MutableRaw<TYPE>(message, field) = field->default_value_##TYPE(); \
1243 break;
1244
1245 CLEAR_TYPE(INT32, int32_t);
1246 CLEAR_TYPE(INT64, int64_t);
1247 CLEAR_TYPE(UINT32, uint32_t);
1248 CLEAR_TYPE(UINT64, uint64_t);
1249 CLEAR_TYPE(FLOAT, float);
1250 CLEAR_TYPE(DOUBLE, double);
1251 CLEAR_TYPE(BOOL, bool);
1252 #undef CLEAR_TYPE
1253
1254 case FieldDescriptor::CPPTYPE_ENUM:
1255 *MutableRaw<int>(message, field) =
1256 field->default_value_enum()->number();
1257 break;
1258
1259 case FieldDescriptor::CPPTYPE_STRING: {
1260 switch (field->options().ctype()) {
1261 default: // TODO(kenton): Support other string reps.
1262 case FieldOptions::STRING:
1263 if (IsInlined(field)) {
1264 // Currently, string with default value can't be inlined. So we
1265 // don't have to handle default value here.
1266 MutableRaw<InlinedStringField>(message, field)->ClearToEmpty();
1267 } else {
1268 auto* str = MutableRaw<ArenaStringPtr>(message, field);
1269 str->Destroy();
1270 str->InitDefault();
1271 }
1272 break;
1273 }
1274 break;
1275 }
1276
1277 case FieldDescriptor::CPPTYPE_MESSAGE:
1278 if (schema_.HasBitIndex(field) == static_cast<uint32_t>(-1)) {
1279 // Proto3 does not have has-bits and we need to set a message field
1280 // to nullptr in order to indicate its un-presence.
1281 if (message->GetArenaForAllocation() == nullptr) {
1282 delete *MutableRaw<Message*>(message, field);
1283 }
1284 *MutableRaw<Message*>(message, field) = nullptr;
1285 } else {
1286 (*MutableRaw<Message*>(message, field))->Clear();
1287 }
1288 break;
1289 }
1290 }
1291 } else {
1292 switch (field->cpp_type()) {
1293 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
1294 case FieldDescriptor::CPPTYPE_##UPPERCASE: \
1295 MutableRaw<RepeatedField<LOWERCASE> >(message, field)->Clear(); \
1296 break
1297
1298 HANDLE_TYPE(INT32, int32_t);
1299 HANDLE_TYPE(INT64, int64_t);
1300 HANDLE_TYPE(UINT32, uint32_t);
1301 HANDLE_TYPE(UINT64, uint64_t);
1302 HANDLE_TYPE(DOUBLE, double);
1303 HANDLE_TYPE(FLOAT, float);
1304 HANDLE_TYPE(BOOL, bool);
1305 HANDLE_TYPE(ENUM, int);
1306 #undef HANDLE_TYPE
1307
1308 case FieldDescriptor::CPPTYPE_STRING: {
1309 switch (field->options().ctype()) {
1310 default: // TODO(kenton): Support other string reps.
1311 case FieldOptions::STRING:
1312 MutableRaw<RepeatedPtrField<std::string> >(message, field)->Clear();
1313 break;
1314 }
1315 break;
1316 }
1317
1318 case FieldDescriptor::CPPTYPE_MESSAGE: {
1319 if (IsMapFieldInApi(field)) {
1320 MutableRaw<MapFieldBase>(message, field)->Clear();
1321 } else {
1322 // We don't know which subclass of RepeatedPtrFieldBase the type is,
1323 // so we use RepeatedPtrFieldBase directly.
1324 MutableRaw<RepeatedPtrFieldBase>(message, field)
1325 ->Clear<GenericTypeHandler<Message> >();
1326 }
1327 break;
1328 }
1329 }
1330 }
1331 }
1332
1333 void Reflection::RemoveLast(Message* message,
1334 const FieldDescriptor* field) const {
1335 USAGE_CHECK_MESSAGE_TYPE(RemoveLast);
1336 USAGE_CHECK_REPEATED(RemoveLast);
1337 CheckInvalidAccess(schema_, field);
1338
1339 if (field->is_extension()) {
1340 MutableExtensionSet(message)->RemoveLast(field->number());
1341 } else {
1342 switch (field->cpp_type()) {
1343 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
1344 case FieldDescriptor::CPPTYPE_##UPPERCASE: \
1345 MutableRaw<RepeatedField<LOWERCASE> >(message, field)->RemoveLast(); \
1346 break
1347
1348 HANDLE_TYPE(INT32, int32_t);
1349 HANDLE_TYPE(INT64, int64_t);
1350 HANDLE_TYPE(UINT32, uint32_t);
1351 HANDLE_TYPE(UINT64, uint64_t);
1352 HANDLE_TYPE(DOUBLE, double);
1353 HANDLE_TYPE(FLOAT, float);
1354 HANDLE_TYPE(BOOL, bool);
1355 HANDLE_TYPE(ENUM, int);
1356 #undef HANDLE_TYPE
1357
1358 case FieldDescriptor::CPPTYPE_STRING:
1359 switch (field->options().ctype()) {
1360 default: // TODO(kenton): Support other string reps.
1361 case FieldOptions::STRING:
1362 MutableRaw<RepeatedPtrField<std::string> >(message, field)
1363 ->RemoveLast();
1364 break;
1365 }
1366 break;
1367
1368 case FieldDescriptor::CPPTYPE_MESSAGE:
1369 if (IsMapFieldInApi(field)) {
1370 MutableRaw<MapFieldBase>(message, field)
1371 ->MutableRepeatedField()
1372 ->RemoveLast<GenericTypeHandler<Message> >();
1373 } else {
1374 MutableRaw<RepeatedPtrFieldBase>(message, field)
1375 ->RemoveLast<GenericTypeHandler<Message> >();
1376 }
1377 break;
1378 }
1379 }
1380 }
1381
1382 Message* Reflection::ReleaseLast(Message* message,
1383 const FieldDescriptor* field) const {
1384 USAGE_CHECK_ALL(ReleaseLast, REPEATED, MESSAGE);
1385 CheckInvalidAccess(schema_, field);
1386
1387 Message* released;
1388 if (field->is_extension()) {
1389 released = static_cast<Message*>(
1390 MutableExtensionSet(message)->ReleaseLast(field->number()));
1391 } else {
1392 if (IsMapFieldInApi(field)) {
1393 released = MutableRaw<MapFieldBase>(message, field)
1394 ->MutableRepeatedField()
1395 ->ReleaseLast<GenericTypeHandler<Message>>();
1396 } else {
1397 released = MutableRaw<RepeatedPtrFieldBase>(message, field)
1398 ->ReleaseLast<GenericTypeHandler<Message>>();
1399 }
1400 }
1401 #ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
1402 return MaybeForceCopy(message->GetArenaForAllocation(), released);
1403 #else // PROTOBUF_FORCE_COPY_IN_RELEASE
1404 return released;
1405 #endif // !PROTOBUF_FORCE_COPY_IN_RELEASE
1406 }
1407
1408 Message* Reflection::UnsafeArenaReleaseLast(
1409 Message* message, const FieldDescriptor* field) const {
1410 USAGE_CHECK_ALL(UnsafeArenaReleaseLast, REPEATED, MESSAGE);
1411 CheckInvalidAccess(schema_, field);
1412
1413 if (field->is_extension()) {
1414 return static_cast<Message*>(
1415 MutableExtensionSet(message)->UnsafeArenaReleaseLast(field->number()));
1416 } else {
1417 if (IsMapFieldInApi(field)) {
1418 return MutableRaw<MapFieldBase>(message, field)
1419 ->MutableRepeatedField()
1420 ->UnsafeArenaReleaseLast<GenericTypeHandler<Message>>();
1421 } else {
1422 return MutableRaw<RepeatedPtrFieldBase>(message, field)
1423 ->UnsafeArenaReleaseLast<GenericTypeHandler<Message>>();
1424 }
1425 }
1426 }
1427
1428 void Reflection::SwapElements(Message* message, const FieldDescriptor* field,
1429 int index1, int index2) const {
1430 USAGE_CHECK_MESSAGE_TYPE(Swap);
1431 USAGE_CHECK_REPEATED(Swap);
1432 CheckInvalidAccess(schema_, field);
1433
1434 if (field->is_extension()) {
1435 MutableExtensionSet(message)->SwapElements(field->number(), index1, index2);
1436 } else {
1437 switch (field->cpp_type()) {
1438 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
1439 case FieldDescriptor::CPPTYPE_##UPPERCASE: \
1440 MutableRaw<RepeatedField<LOWERCASE> >(message, field) \
1441 ->SwapElements(index1, index2); \
1442 break
1443
1444 HANDLE_TYPE(INT32, int32_t);
1445 HANDLE_TYPE(INT64, int64_t);
1446 HANDLE_TYPE(UINT32, uint32_t);
1447 HANDLE_TYPE(UINT64, uint64_t);
1448 HANDLE_TYPE(DOUBLE, double);
1449 HANDLE_TYPE(FLOAT, float);
1450 HANDLE_TYPE(BOOL, bool);
1451 HANDLE_TYPE(ENUM, int);
1452 #undef HANDLE_TYPE
1453
1454 case FieldDescriptor::CPPTYPE_STRING:
1455 case FieldDescriptor::CPPTYPE_MESSAGE:
1456 if (IsMapFieldInApi(field)) {
1457 MutableRaw<MapFieldBase>(message, field)
1458 ->MutableRepeatedField()
1459 ->SwapElements(index1, index2);
1460 } else {
1461 MutableRaw<RepeatedPtrFieldBase>(message, field)
1462 ->SwapElements(index1, index2);
1463 }
1464 break;
1465 }
1466 }
1467 }
1468
1469 namespace {
1470 // Comparison functor for sorting FieldDescriptors by field number.
1471 struct FieldNumberSorter {
1472 bool operator()(const FieldDescriptor* left,
1473 const FieldDescriptor* right) const {
1474 return left->number() < right->number();
1475 }
1476 };
1477
1478 bool IsIndexInHasBitSet(const uint32_t* has_bit_set, uint32_t has_bit_index) {
1479 GOOGLE_DCHECK_NE(has_bit_index, ~0u);
1480 return ((has_bit_set[has_bit_index / 32] >> (has_bit_index % 32)) &
1481 static_cast<uint32_t>(1)) != 0;
1482 }
1483
1484 bool CreateUnknownEnumValues(const FileDescriptor* file) {
1485 return file->syntax() == FileDescriptor::SYNTAX_PROTO3;
1486 }
1487 } // namespace
1488
1489 namespace internal {
1490 bool CreateUnknownEnumValues(const FieldDescriptor* field) {
1491 bool open_enum = false;
1492 return field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 || open_enum;
1493 }
1494 } // namespace internal
1495 using internal::CreateUnknownEnumValues;
1496
1497 void Reflection::ListFieldsMayFailOnStripped(
1498 const Message& message, bool should_fail,
1499 std::vector<const FieldDescriptor*>* output) const {
1500 output->clear();
1501
1502 // Optimization: The default instance never has any fields set.
1503 if (schema_.IsDefaultInstance(message)) return;
1504
1505 // Optimization: Avoid calling GetHasBits() and HasOneofField() many times
1506 // within the field loop. We allow this violation of ReflectionSchema
1507 // encapsulation because this function takes a noticeable about of CPU
1508 // fleetwide and properly allowing this optimization through public interfaces
1509 // seems more trouble than it is worth.
1510 const uint32_t* const has_bits =
1511 schema_.HasHasbits() ? GetHasBits(message) : nullptr;
1512 const uint32_t* const has_bits_indices = schema_.has_bit_indices_;
1513 output->reserve(descriptor_->field_count());
1514 const int last_non_weak_field_index = last_non_weak_field_index_;
1515 for (int i = 0; i <= last_non_weak_field_index; i++) {
1516 const FieldDescriptor* field = descriptor_->field(i);
1517 if (!should_fail && schema_.IsFieldStripped(field)) {
1518 continue;
1519 }
1520 if (field->is_repeated()) {
1521 if (FieldSize(message, field) > 0) {
1522 output->push_back(field);
1523 }
1524 } else {
1525 const OneofDescriptor* containing_oneof = field->containing_oneof();
1526 if (schema_.InRealOneof(field)) {
1527 const uint32_t* const oneof_case_array =
1528 GetConstPointerAtOffset<uint32_t>(&message,
1529 schema_.oneof_case_offset_);
1530 // Equivalent to: HasOneofField(message, field)
1531 if (static_cast<int64_t>(oneof_case_array[containing_oneof->index()]) ==
1532 field->number()) {
1533 output->push_back(field);
1534 }
1535 } else if (has_bits && has_bits_indices[i] != static_cast<uint32_t>(-1)) {
1536 CheckInvalidAccess(schema_, field);
1537 // Equivalent to: HasBit(message, field)
1538 if (IsIndexInHasBitSet(has_bits, has_bits_indices[i])) {
1539 output->push_back(field);
1540 }
1541 } else if (HasBit(message, field)) { // Fall back on proto3-style HasBit.
1542 output->push_back(field);
1543 }
1544 }
1545 }
1546 if (schema_.HasExtensionSet()) {
1547 GetExtensionSet(message).AppendToList(descriptor_, descriptor_pool_,
1548 output);
1549 }
1550
1551 // ListFields() must sort output by field number.
1552 std::sort(output->begin(), output->end(), FieldNumberSorter());
1553 }
1554
1555 void Reflection::ListFields(const Message& message,
1556 std::vector<const FieldDescriptor*>* output) const {
1557 ListFieldsMayFailOnStripped(message, true, output);
1558 }
1559
1560 void Reflection::ListFieldsOmitStripped(
1561 const Message& message, std::vector<const FieldDescriptor*>* output) const {
1562 ListFieldsMayFailOnStripped(message, false, output);
1563 }
1564
1565 // -------------------------------------------------------------------
1566
1567 #undef DEFINE_PRIMITIVE_ACCESSORS
1568 #define DEFINE_PRIMITIVE_ACCESSORS(TYPENAME, TYPE, PASSTYPE, CPPTYPE) \
1569 PASSTYPE Reflection::Get##TYPENAME(const Message& message, \
1570 const FieldDescriptor* field) const { \
1571 USAGE_CHECK_ALL(Get##TYPENAME, SINGULAR, CPPTYPE); \
1572 if (field->is_extension()) { \
1573 return GetExtensionSet(message).Get##TYPENAME( \
1574 field->number(), field->default_value_##PASSTYPE()); \
1575 } else if (schema_.InRealOneof(field) && !HasOneofField(message, field)) { \
1576 return field->default_value_##PASSTYPE(); \
1577 } else { \
1578 return GetField<TYPE>(message, field); \
1579 } \
1580 } \
1581 \
1582 void Reflection::Set##TYPENAME( \
1583 Message* message, const FieldDescriptor* field, PASSTYPE value) const { \
1584 USAGE_CHECK_ALL(Set##TYPENAME, SINGULAR, CPPTYPE); \
1585 if (field->is_extension()) { \
1586 return MutableExtensionSet(message)->Set##TYPENAME( \
1587 field->number(), field->type(), value, field); \
1588 } else { \
1589 SetField<TYPE>(message, field, value); \
1590 } \
1591 } \
1592 \
1593 PASSTYPE Reflection::GetRepeated##TYPENAME( \
1594 const Message& message, const FieldDescriptor* field, int index) const { \
1595 USAGE_CHECK_ALL(GetRepeated##TYPENAME, REPEATED, CPPTYPE); \
1596 if (field->is_extension()) { \
1597 return GetExtensionSet(message).GetRepeated##TYPENAME(field->number(), \
1598 index); \
1599 } else { \
1600 return GetRepeatedField<TYPE>(message, field, index); \
1601 } \
1602 } \
1603 \
1604 void Reflection::SetRepeated##TYPENAME(Message* message, \
1605 const FieldDescriptor* field, \
1606 int index, PASSTYPE value) const { \
1607 USAGE_CHECK_ALL(SetRepeated##TYPENAME, REPEATED, CPPTYPE); \
1608 if (field->is_extension()) { \
1609 MutableExtensionSet(message)->SetRepeated##TYPENAME(field->number(), \
1610 index, value); \
1611 } else { \
1612 SetRepeatedField<TYPE>(message, field, index, value); \
1613 } \
1614 } \
1615 \
1616 void Reflection::Add##TYPENAME( \
1617 Message* message, const FieldDescriptor* field, PASSTYPE value) const { \
1618 USAGE_CHECK_ALL(Add##TYPENAME, REPEATED, CPPTYPE); \
1619 if (field->is_extension()) { \
1620 MutableExtensionSet(message)->Add##TYPENAME( \
1621 field->number(), field->type(), field->options().packed(), value, \
1622 field); \
1623 } else { \
1624 AddField<TYPE>(message, field, value); \
1625 } \
1626 }
1627
1628 DEFINE_PRIMITIVE_ACCESSORS(Int32, int32_t, int32_t, INT32)
1629 DEFINE_PRIMITIVE_ACCESSORS(Int64, int64_t, int64_t, INT64)
1630 DEFINE_PRIMITIVE_ACCESSORS(UInt32, uint32_t, uint32_t, UINT32)
1631 DEFINE_PRIMITIVE_ACCESSORS(UInt64, uint64_t, uint64_t, UINT64)
1632 DEFINE_PRIMITIVE_ACCESSORS(Float, float, float, FLOAT)
1633 DEFINE_PRIMITIVE_ACCESSORS(Double, double, double, DOUBLE)
1634 DEFINE_PRIMITIVE_ACCESSORS(Bool, bool, bool, BOOL)
1635 #undef DEFINE_PRIMITIVE_ACCESSORS
1636
1637 // -------------------------------------------------------------------
1638
1639 std::string Reflection::GetString(const Message& message,
1640 const FieldDescriptor* field) const {
1641 USAGE_CHECK_ALL(GetString, SINGULAR, STRING);
1642 if (field->is_extension()) {
1643 return GetExtensionSet(message).GetString(field->number(),
1644 field->default_value_string());
1645 } else {
1646 if (schema_.InRealOneof(field) && !HasOneofField(message, field)) {
1647 return field->default_value_string();
1648 }
1649 switch (field->options().ctype()) {
1650 default: // TODO(kenton): Support other string reps.
1651 case FieldOptions::STRING:
1652 if (IsInlined(field)) {
1653 return GetField<InlinedStringField>(message, field).GetNoArena();
1654 } else {
1655 const auto& str = GetField<ArenaStringPtr>(message, field);
1656 return str.IsDefault() ? field->default_value_string() : str.Get();
1657 }
1658 }
1659 }
1660 }
1661
1662 const std::string& Reflection::GetStringReference(const Message& message,
1663 const FieldDescriptor* field,
1664 std::string* scratch) const {
1665 (void)scratch; // Parameter is used by Google-internal code.
1666 USAGE_CHECK_ALL(GetStringReference, SINGULAR, STRING);
1667 if (field->is_extension()) {
1668 return GetExtensionSet(message).GetString(field->number(),
1669 field->default_value_string());
1670 } else {
1671 if (schema_.InRealOneof(field) && !HasOneofField(message, field)) {
1672 return field->default_value_string();
1673 }
1674 switch (field->options().ctype()) {
1675 default: // TODO(kenton): Support other string reps.
1676 case FieldOptions::STRING:
1677 if (IsInlined(field)) {
1678 return GetField<InlinedStringField>(message, field).GetNoArena();
1679 } else {
1680 const auto& str = GetField<ArenaStringPtr>(message, field);
1681 return str.IsDefault() ? field->default_value_string() : str.Get();
1682 }
1683 }
1684 }
1685 }
1686
1687
1688 void Reflection::SetString(Message* message, const FieldDescriptor* field,
1689 std::string value) const {
1690 USAGE_CHECK_ALL(SetString, SINGULAR, STRING);
1691 if (field->is_extension()) {
1692 return MutableExtensionSet(message)->SetString(
1693 field->number(), field->type(), std::move(value), field);
1694 } else {
1695 switch (field->options().ctype()) {
1696 default: // TODO(kenton): Support other string reps.
1697 case FieldOptions::STRING: {
1698 if (IsInlined(field)) {
1699 const uint32_t index = schema_.InlinedStringIndex(field);
1700 GOOGLE_DCHECK_GT(index, 0);
1701 uint32_t* states =
1702 &MutableInlinedStringDonatedArray(message)[index / 32];
1703 uint32_t mask = ~(static_cast<uint32_t>(1) << (index % 32));
1704 MutableField<InlinedStringField>(message, field)
1705 ->Set(value, message->GetArenaForAllocation(),
1706 IsInlinedStringDonated(*message, field), states, mask,
1707 message);
1708 break;
1709 }
1710
1711 // Oneof string fields are never set as a default instance.
1712 // We just need to pass some arbitrary default string to make it work.
1713 // This allows us to not have the real default accessible from
1714 // reflection.
1715 if (schema_.InRealOneof(field) && !HasOneofField(*message, field)) {
1716 ClearOneof(message, field->containing_oneof());
1717 MutableField<ArenaStringPtr>(message, field)->InitDefault();
1718 }
1719 MutableField<ArenaStringPtr>(message, field)
1720 ->Set(std::move(value), message->GetArenaForAllocation());
1721 break;
1722 }
1723 }
1724 }
1725 }
1726
1727
1728 std::string Reflection::GetRepeatedString(const Message& message,
1729 const FieldDescriptor* field,
1730 int index) const {
1731 USAGE_CHECK_ALL(GetRepeatedString, REPEATED, STRING);
1732 if (field->is_extension()) {
1733 return GetExtensionSet(message).GetRepeatedString(field->number(), index);
1734 } else {
1735 switch (field->options().ctype()) {
1736 default: // TODO(kenton): Support other string reps.
1737 case FieldOptions::STRING:
1738 return GetRepeatedPtrField<std::string>(message, field, index);
1739 }
1740 }
1741 }
1742
1743 const std::string& Reflection::GetRepeatedStringReference(
1744 const Message& message, const FieldDescriptor* field, int index,
1745 std::string* scratch) const {
1746 (void)scratch; // Parameter is used by Google-internal code.
1747 USAGE_CHECK_ALL(GetRepeatedStringReference, REPEATED, STRING);
1748 if (field->is_extension()) {
1749 return GetExtensionSet(message).GetRepeatedString(field->number(), index);
1750 } else {
1751 switch (field->options().ctype()) {
1752 default: // TODO(kenton): Support other string reps.
1753 case FieldOptions::STRING:
1754 return GetRepeatedPtrField<std::string>(message, field, index);
1755 }
1756 }
1757 }
1758
1759
1760 void Reflection::SetRepeatedString(Message* message,
1761 const FieldDescriptor* field, int index,
1762 std::string value) const {
1763 USAGE_CHECK_ALL(SetRepeatedString, REPEATED, STRING);
1764 if (field->is_extension()) {
1765 MutableExtensionSet(message)->SetRepeatedString(field->number(), index,
1766 std::move(value));
1767 } else {
1768 switch (field->options().ctype()) {
1769 default: // TODO(kenton): Support other string reps.
1770 case FieldOptions::STRING:
1771 MutableRepeatedField<std::string>(message, field, index)
1772 ->assign(std::move(value));
1773 break;
1774 }
1775 }
1776 }
1777
1778
1779 void Reflection::AddString(Message* message, const FieldDescriptor* field,
1780 std::string value) const {
1781 USAGE_CHECK_ALL(AddString, REPEATED, STRING);
1782 if (field->is_extension()) {
1783 MutableExtensionSet(message)->AddString(field->number(), field->type(),
1784 std::move(value), field);
1785 } else {
1786 switch (field->options().ctype()) {
1787 default: // TODO(kenton): Support other string reps.
1788 case FieldOptions::STRING:
1789 AddField<std::string>(message, field)->assign(std::move(value));
1790 break;
1791 }
1792 }
1793 }
1794
1795
1796 // -------------------------------------------------------------------
1797
1798 const EnumValueDescriptor* Reflection::GetEnum(
1799 const Message& message, const FieldDescriptor* field) const {
1800 // Usage checked by GetEnumValue.
1801 int value = GetEnumValue(message, field);
1802 return field->enum_type()->FindValueByNumberCreatingIfUnknown(value);
1803 }
1804
1805 int Reflection::GetEnumValue(const Message& message,
1806 const FieldDescriptor* field) const {
1807 USAGE_CHECK_ALL(GetEnumValue, SINGULAR, ENUM);
1808
1809 int32_t value;
1810 if (field->is_extension()) {
1811 value = GetExtensionSet(message).GetEnum(
1812 field->number(), field->default_value_enum()->number());
1813 } else if (schema_.InRealOneof(field) && !HasOneofField(message, field)) {
1814 value = field->default_value_enum()->number();
1815 } else {
1816 value = GetField<int>(message, field);
1817 }
1818 return value;
1819 }
1820
1821 void Reflection::SetEnum(Message* message, const FieldDescriptor* field,
1822 const EnumValueDescriptor* value) const {
1823 // Usage checked by SetEnumValue.
1824 USAGE_CHECK_ENUM_VALUE(SetEnum);
1825 SetEnumValueInternal(message, field, value->number());
1826 }
1827
1828 void Reflection::SetEnumValue(Message* message, const FieldDescriptor* field,
1829 int value) const {
1830 USAGE_CHECK_ALL(SetEnumValue, SINGULAR, ENUM);
1831 if (!CreateUnknownEnumValues(field)) {
1832 // Check that the value is valid if we don't support direct storage of
1833 // unknown enum values.
1834 const EnumValueDescriptor* value_desc =
1835 field->enum_type()->FindValueByNumber(value);
1836 if (value_desc == nullptr) {
1837 MutableUnknownFields(message)->AddVarint(field->number(), value);
1838 return;
1839 }
1840 }
1841 SetEnumValueInternal(message, field, value);
1842 }
1843
1844 void Reflection::SetEnumValueInternal(Message* message,
1845 const FieldDescriptor* field,
1846 int value) const {
1847 if (field->is_extension()) {
1848 MutableExtensionSet(message)->SetEnum(field->number(), field->type(), value,
1849 field);
1850 } else {
1851 SetField<int>(message, field, value);
1852 }
1853 }
1854
1855 const EnumValueDescriptor* Reflection::GetRepeatedEnum(
1856 const Message& message, const FieldDescriptor* field, int index) const {
1857 // Usage checked by GetRepeatedEnumValue.
1858 int value = GetRepeatedEnumValue(message, field, index);
1859 return field->enum_type()->FindValueByNumberCreatingIfUnknown(value);
1860 }
1861
1862 int Reflection::GetRepeatedEnumValue(const Message& message,
1863 const FieldDescriptor* field,
1864 int index) const {
1865 USAGE_CHECK_ALL(GetRepeatedEnumValue, REPEATED, ENUM);
1866
1867 int value;
1868 if (field->is_extension()) {
1869 value = GetExtensionSet(message).GetRepeatedEnum(field->number(), index);
1870 } else {
1871 value = GetRepeatedField<int>(message, field, index);
1872 }
1873 return value;
1874 }
1875
1876 void Reflection::SetRepeatedEnum(Message* message, const FieldDescriptor* field,
1877 int index,
1878 const EnumValueDescriptor* value) const {
1879 // Usage checked by SetRepeatedEnumValue.
1880 USAGE_CHECK_ENUM_VALUE(SetRepeatedEnum);
1881 SetRepeatedEnumValueInternal(message, field, index, value->number());
1882 }
1883
1884 void Reflection::SetRepeatedEnumValue(Message* message,
1885 const FieldDescriptor* field, int index,
1886 int value) const {
1887 USAGE_CHECK_ALL(SetRepeatedEnum, REPEATED, ENUM);
1888 if (!CreateUnknownEnumValues(field)) {
1889 // Check that the value is valid if we don't support direct storage of
1890 // unknown enum values.
1891 const EnumValueDescriptor* value_desc =
1892 field->enum_type()->FindValueByNumber(value);
1893 if (value_desc == nullptr) {
1894 MutableUnknownFields(message)->AddVarint(field->number(), value);
1895 return;
1896 }
1897 }
1898 SetRepeatedEnumValueInternal(message, field, index, value);
1899 }
1900
1901 void Reflection::SetRepeatedEnumValueInternal(Message* message,
1902 const FieldDescriptor* field,
1903 int index, int value) const {
1904 if (field->is_extension()) {
1905 MutableExtensionSet(message)->SetRepeatedEnum(field->number(), index,
1906 value);
1907 } else {
1908 SetRepeatedField<int>(message, field, index, value);
1909 }
1910 }
1911
1912 void Reflection::AddEnum(Message* message, const FieldDescriptor* field,
1913 const EnumValueDescriptor* value) const {
1914 // Usage checked by AddEnumValue.
1915 USAGE_CHECK_ENUM_VALUE(AddEnum);
1916 AddEnumValueInternal(message, field, value->number());
1917 }
1918
1919 void Reflection::AddEnumValue(Message* message, const FieldDescriptor* field,
1920 int value) const {
1921 USAGE_CHECK_ALL(AddEnum, REPEATED, ENUM);
1922 if (!CreateUnknownEnumValues(field)) {
1923 // Check that the value is valid if we don't support direct storage of
1924 // unknown enum values.
1925 const EnumValueDescriptor* value_desc =
1926 field->enum_type()->FindValueByNumber(value);
1927 if (value_desc == nullptr) {
1928 MutableUnknownFields(message)->AddVarint(field->number(), value);
1929 return;
1930 }
1931 }
1932 AddEnumValueInternal(message, field, value);
1933 }
1934
1935 void Reflection::AddEnumValueInternal(Message* message,
1936 const FieldDescriptor* field,
1937 int value) const {
1938 if (field->is_extension()) {
1939 MutableExtensionSet(message)->AddEnum(field->number(), field->type(),
1940 field->options().packed(), value,
1941 field);
1942 } else {
1943 AddField<int>(message, field, value);
1944 }
1945 }
1946
1947 // -------------------------------------------------------------------
1948
1949 const Message* Reflection::GetDefaultMessageInstance(
1950 const FieldDescriptor* field) const {
1951 // If we are using the generated factory, we cache the prototype in the field
1952 // descriptor for faster access.
1953 // The default instances of generated messages are not cross-linked, which
1954 // means they contain null pointers on their message fields and can't be used
1955 // to get the default of submessages.
1956 if (message_factory_ == MessageFactory::generated_factory()) {
1957 auto& ptr = field->default_generated_instance_;
1958 auto* res = ptr.load(std::memory_order_acquire);
1959 if (res == nullptr) {
1960 // First time asking for this field's default. Load it and cache it.
1961 res = message_factory_->GetPrototype(field->message_type());
1962 ptr.store(res, std::memory_order_release);
1963 }
1964 return res;
1965 }
1966
1967 // For other factories, we try the default's object field.
1968 // In particular, the DynamicMessageFactory will cross link the default
1969 // instances to allow for this. But only do this for real fields.
1970 // This is an optimization to avoid going to GetPrototype() below, as that
1971 // requires a lock and a map lookup.
1972 if (!field->is_extension() && !field->options().weak() &&
1973 !IsLazyField(field) && !schema_.InRealOneof(field)) {
1974 auto* res = DefaultRaw<const Message*>(field);
1975 if (res != nullptr) {
1976 return res;
1977 }
1978 }
1979 // Otherwise, just go to the factory.
1980 return message_factory_->GetPrototype(field->message_type());
1981 }
1982
1983 const Message& Reflection::GetMessage(const Message& message,
1984 const FieldDescriptor* field,
1985 MessageFactory* factory) const {
1986 USAGE_CHECK_ALL(GetMessage, SINGULAR, MESSAGE);
1987 CheckInvalidAccess(schema_, field);
1988
1989 if (factory == nullptr) factory = message_factory_;
1990
1991 if (field->is_extension()) {
1992 return static_cast<const Message&>(GetExtensionSet(message).GetMessage(
1993 field->number(), field->message_type(), factory));
1994 } else {
1995 if (schema_.InRealOneof(field) && !HasOneofField(message, field)) {
1996 return *GetDefaultMessageInstance(field);
1997 }
1998 const Message* result = GetRaw<const Message*>(message, field);
1999 if (result == nullptr) {
2000 result = GetDefaultMessageInstance(field);
2001 }
2002 return *result;
2003 }
2004 }
2005
2006 Message* Reflection::MutableMessage(Message* message,
2007 const FieldDescriptor* field,
2008 MessageFactory* factory) const {
2009 USAGE_CHECK_ALL(MutableMessage, SINGULAR, MESSAGE);
2010 CheckInvalidAccess(schema_, field);
2011
2012 if (factory == nullptr) factory = message_factory_;
2013
2014 if (field->is_extension()) {
2015 return static_cast<Message*>(
2016 MutableExtensionSet(message)->MutableMessage(field, factory));
2017 } else {
2018 Message* result;
2019
2020 Message** result_holder = MutableRaw<Message*>(message, field);
2021
2022 if (schema_.InRealOneof(field)) {
2023 if (!HasOneofField(*message, field)) {
2024 ClearOneof(message, field->containing_oneof());
2025 result_holder = MutableField<Message*>(message, field);
2026 const Message* default_message = GetDefaultMessageInstance(field);
2027 *result_holder = default_message->New(message->GetArenaForAllocation());
2028 }
2029 } else {
2030 SetBit(message, field);
2031 }
2032
2033 if (*result_holder == nullptr) {
2034 const Message* default_message = GetDefaultMessageInstance(field);
2035 *result_holder = default_message->New(message->GetArenaForAllocation());
2036 }
2037 result = *result_holder;
2038 return result;
2039 }
2040 }
2041
2042 void Reflection::UnsafeArenaSetAllocatedMessage(
2043 Message* message, Message* sub_message,
2044 const FieldDescriptor* field) const {
2045 USAGE_CHECK_ALL(SetAllocatedMessage, SINGULAR, MESSAGE);
2046 CheckInvalidAccess(schema_, field);
2047
2048
2049 if (field->is_extension()) {
2050 MutableExtensionSet(message)->UnsafeArenaSetAllocatedMessage(
2051 field->number(), field->type(), field, sub_message);
2052 } else {
2053 if (schema_.InRealOneof(field)) {
2054 if (sub_message == nullptr) {
2055 ClearOneof(message, field->containing_oneof());
2056 return;
2057 }
2058 ClearOneof(message, field->containing_oneof());
2059 *MutableRaw<Message*>(message, field) = sub_message;
2060 SetOneofCase(message, field);
2061 return;
2062 }
2063
2064 if (sub_message == nullptr) {
2065 ClearBit(message, field);
2066 } else {
2067 SetBit(message, field);
2068 }
2069 Message** sub_message_holder = MutableRaw<Message*>(message, field);
2070 if (message->GetArenaForAllocation() == nullptr) {
2071 delete *sub_message_holder;
2072 }
2073 *sub_message_holder = sub_message;
2074 }
2075 }
2076
2077 void Reflection::SetAllocatedMessage(Message* message, Message* sub_message,
2078 const FieldDescriptor* field) const {
2079 GOOGLE_DCHECK(sub_message == nullptr || sub_message->GetOwningArena() == nullptr ||
2080 sub_message->GetOwningArena() == message->GetArenaForAllocation());
2081 CheckInvalidAccess(schema_, field);
2082
2083 // If message and sub-message are in different memory ownership domains
2084 // (different arenas, or one is on heap and one is not), then we may need to
2085 // do a copy.
2086 if (sub_message != nullptr &&
2087 sub_message->GetOwningArena() != message->GetArenaForAllocation()) {
2088 if (sub_message->GetOwningArena() == nullptr &&
2089 message->GetArenaForAllocation() != nullptr) {
2090 // Case 1: parent is on an arena and child is heap-allocated. We can add
2091 // the child to the arena's Own() list to free on arena destruction, then
2092 // set our pointer.
2093 message->GetArenaForAllocation()->Own(sub_message);
2094 UnsafeArenaSetAllocatedMessage(message, sub_message, field);
2095 } else {
2096 // Case 2: all other cases. We need to make a copy. MutableMessage() will
2097 // either get the existing message object, or instantiate a new one as
2098 // appropriate w.r.t. our arena.
2099 Message* sub_message_copy = MutableMessage(message, field);
2100 sub_message_copy->CopyFrom(*sub_message);
2101 }
2102 } else {
2103 // Same memory ownership domains.
2104 UnsafeArenaSetAllocatedMessage(message, sub_message, field);
2105 }
2106 }
2107
2108 Message* Reflection::UnsafeArenaReleaseMessage(Message* message,
2109 const FieldDescriptor* field,
2110 MessageFactory* factory) const {
2111 USAGE_CHECK_ALL(ReleaseMessage, SINGULAR, MESSAGE);
2112 CheckInvalidAccess(schema_, field);
2113
2114 if (factory == nullptr) factory = message_factory_;
2115
2116 if (field->is_extension()) {
2117 return static_cast<Message*>(
2118 MutableExtensionSet(message)->UnsafeArenaReleaseMessage(field,
2119 factory));
2120 } else {
2121 if (!(field->is_repeated() || schema_.InRealOneof(field))) {
2122 ClearBit(message, field);
2123 }
2124 if (schema_.InRealOneof(field)) {
2125 if (HasOneofField(*message, field)) {
2126 *MutableOneofCase(message, field->containing_oneof()) = 0;
2127 } else {
2128 return nullptr;
2129 }
2130 }
2131 Message** result = MutableRaw<Message*>(message, field);
2132 Message* ret = *result;
2133 *result = nullptr;
2134 return ret;
2135 }
2136 }
2137
2138 Message* Reflection::ReleaseMessage(Message* message,
2139 const FieldDescriptor* field,
2140 MessageFactory* factory) const {
2141 CheckInvalidAccess(schema_, field);
2142
2143 Message* released = UnsafeArenaReleaseMessage(message, field, factory);
2144 #ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
2145 released = MaybeForceCopy(message->GetArenaForAllocation(), released);
2146 #endif // PROTOBUF_FORCE_COPY_IN_RELEASE
2147 if (message->GetArenaForAllocation() != nullptr && released != nullptr) {
2148 Message* copy_from_arena = released->New();
2149 copy_from_arena->CopyFrom(*released);
2150 released = copy_from_arena;
2151 }
2152 return released;
2153 }
2154
2155 const Message& Reflection::GetRepeatedMessage(const Message& message,
2156 const FieldDescriptor* field,
2157 int index) const {
2158 USAGE_CHECK_ALL(GetRepeatedMessage, REPEATED, MESSAGE);
2159 CheckInvalidAccess(schema_, field);
2160
2161 if (field->is_extension()) {
2162 return static_cast<const Message&>(
2163 GetExtensionSet(message).GetRepeatedMessage(field->number(), index));
2164 } else {
2165 if (IsMapFieldInApi(field)) {
2166 return GetRaw<MapFieldBase>(message, field)
2167 .GetRepeatedField()
2168 .Get<GenericTypeHandler<Message> >(index);
2169 } else {
2170 return GetRaw<RepeatedPtrFieldBase>(message, field)
2171 .Get<GenericTypeHandler<Message> >(index);
2172 }
2173 }
2174 }
2175
2176 Message* Reflection::MutableRepeatedMessage(Message* message,
2177 const FieldDescriptor* field,
2178 int index) const {
2179 USAGE_CHECK_ALL(MutableRepeatedMessage, REPEATED, MESSAGE);
2180 CheckInvalidAccess(schema_, field);
2181
2182 if (field->is_extension()) {
2183 return static_cast<Message*>(
2184 MutableExtensionSet(message)->MutableRepeatedMessage(field->number(),
2185 index));
2186 } else {
2187 if (IsMapFieldInApi(field)) {
2188 return MutableRaw<MapFieldBase>(message, field)
2189 ->MutableRepeatedField()
2190 ->Mutable<GenericTypeHandler<Message> >(index);
2191 } else {
2192 return MutableRaw<RepeatedPtrFieldBase>(message, field)
2193 ->Mutable<GenericTypeHandler<Message> >(index);
2194 }
2195 }
2196 }
2197
2198 Message* Reflection::AddMessage(Message* message, const FieldDescriptor* field,
2199 MessageFactory* factory) const {
2200 USAGE_CHECK_ALL(AddMessage, REPEATED, MESSAGE);
2201 CheckInvalidAccess(schema_, field);
2202
2203 if (factory == nullptr) factory = message_factory_;
2204
2205 if (field->is_extension()) {
2206 return static_cast<Message*>(
2207 MutableExtensionSet(message)->AddMessage(field, factory));
2208 } else {
2209 Message* result = nullptr;
2210
2211 // We can't use AddField<Message>() because RepeatedPtrFieldBase doesn't
2212 // know how to allocate one.
2213 RepeatedPtrFieldBase* repeated = nullptr;
2214 if (IsMapFieldInApi(field)) {
2215 repeated =
2216 MutableRaw<MapFieldBase>(message, field)->MutableRepeatedField();
2217 } else {
2218 repeated = MutableRaw<RepeatedPtrFieldBase>(message, field);
2219 }
2220 result = repeated->AddFromCleared<GenericTypeHandler<Message> >();
2221 if (result == nullptr) {
2222 // We must allocate a new object.
2223 const Message* prototype;
2224 if (repeated->size() == 0) {
2225 prototype = factory->GetPrototype(field->message_type());
2226 } else {
2227 prototype = &repeated->Get<GenericTypeHandler<Message> >(0);
2228 }
2229 result = prototype->New(message->GetArenaForAllocation());
2230 // We can guarantee here that repeated and result are either both heap
2231 // allocated or arena owned. So it is safe to call the unsafe version
2232 // of AddAllocated.
2233 repeated->UnsafeArenaAddAllocated<GenericTypeHandler<Message> >(result);
2234 }
2235
2236 return result;
2237 }
2238 }
2239
2240 void Reflection::AddAllocatedMessage(Message* message,
2241 const FieldDescriptor* field,
2242 Message* new_entry) const {
2243 USAGE_CHECK_ALL(AddAllocatedMessage, REPEATED, MESSAGE);
2244 CheckInvalidAccess(schema_, field);
2245
2246 if (field->is_extension()) {
2247 MutableExtensionSet(message)->AddAllocatedMessage(field, new_entry);
2248 } else {
2249 RepeatedPtrFieldBase* repeated = nullptr;
2250 if (IsMapFieldInApi(field)) {
2251 repeated =
2252 MutableRaw<MapFieldBase>(message, field)->MutableRepeatedField();
2253 } else {
2254 repeated = MutableRaw<RepeatedPtrFieldBase>(message, field);
2255 }
2256 repeated->AddAllocated<GenericTypeHandler<Message> >(new_entry);
2257 }
2258 }
2259
2260 void Reflection::UnsafeArenaAddAllocatedMessage(Message* message,
2261 const FieldDescriptor* field,
2262 Message* new_entry) const {
2263 USAGE_CHECK_ALL(UnsafeArenaAddAllocatedMessage, REPEATED, MESSAGE);
2264 CheckInvalidAccess(schema_, field);
2265
2266 if (field->is_extension()) {
2267 MutableExtensionSet(message)->UnsafeArenaAddAllocatedMessage(field,
2268 new_entry);
2269 } else {
2270 RepeatedPtrFieldBase* repeated = nullptr;
2271 if (IsMapFieldInApi(field)) {
2272 repeated =
2273 MutableRaw<MapFieldBase>(message, field)->MutableRepeatedField();
2274 } else {
2275 repeated = MutableRaw<RepeatedPtrFieldBase>(message, field);
2276 }
2277 repeated->UnsafeArenaAddAllocated<GenericTypeHandler<Message>>(new_entry);
2278 }
2279 }
2280
2281 void* Reflection::MutableRawRepeatedField(Message* message,
2282 const FieldDescriptor* field,
2283 FieldDescriptor::CppType cpptype,
2284 int ctype,
2285 const Descriptor* desc) const {
2286 (void)ctype; // Parameter is used by Google-internal code.
2287 USAGE_CHECK_REPEATED("MutableRawRepeatedField");
2288 CheckInvalidAccess(schema_, field);
2289
2290 if (field->cpp_type() != cpptype &&
2291 (field->cpp_type() != FieldDescriptor::CPPTYPE_ENUM ||
2292 cpptype != FieldDescriptor::CPPTYPE_INT32))
2293 ReportReflectionUsageTypeError(descriptor_, field,
2294 "MutableRawRepeatedField", cpptype);
2295 if (desc != nullptr)
2296 GOOGLE_CHECK_EQ(field->message_type(), desc) << "wrong submessage type";
2297 if (field->is_extension()) {
2298 return MutableExtensionSet(message)->MutableRawRepeatedField(
2299 field->number(), field->type(), field->is_packed(), field);
2300 } else {
2301 // Trigger transform for MapField
2302 if (IsMapFieldInApi(field)) {
2303 return MutableRawNonOneof<MapFieldBase>(message, field)
2304 ->MutableRepeatedField();
2305 }
2306 return MutableRawNonOneof<void>(message, field);
2307 }
2308 }
2309
2310 const void* Reflection::GetRawRepeatedField(const Message& message,
2311 const FieldDescriptor* field,
2312 FieldDescriptor::CppType cpptype,
2313 int ctype,
2314 const Descriptor* desc) const {
2315 USAGE_CHECK_REPEATED("GetRawRepeatedField");
2316 if (field->cpp_type() != cpptype)
2317 ReportReflectionUsageTypeError(descriptor_, field, "GetRawRepeatedField",
2318 cpptype);
2319 if (ctype >= 0)
2320 GOOGLE_CHECK_EQ(field->options().ctype(), ctype) << "subtype mismatch";
2321 if (desc != nullptr)
2322 GOOGLE_CHECK_EQ(field->message_type(), desc) << "wrong submessage type";
2323 if (field->is_extension()) {
2324 // Should use extension_set::GetRawRepeatedField. However, the required
2325 // parameter "default repeated value" is not very easy to get here.
2326 // Map is not supported in extensions, it is acceptable to use
2327 // extension_set::MutableRawRepeatedField which does not change the message.
2328 return MutableExtensionSet(const_cast<Message*>(&message))
2329 ->MutableRawRepeatedField(field->number(), field->type(),
2330 field->is_packed(), field);
2331 } else {
2332 // Trigger transform for MapField
2333 if (IsMapFieldInApi(field)) {
2334 return &(GetRawNonOneof<MapFieldBase>(message, field).GetRepeatedField());
2335 }
2336 return &GetRawNonOneof<char>(message, field);
2337 }
2338 }
2339
2340 const FieldDescriptor* Reflection::GetOneofFieldDescriptor(
2341 const Message& message, const OneofDescriptor* oneof_descriptor) const {
2342 if (oneof_descriptor->is_synthetic()) {
2343 const FieldDescriptor* field = oneof_descriptor->field(0);
2344 return HasField(message, field) ? field : nullptr;
2345 }
2346 uint32_t field_number = GetOneofCase(message, oneof_descriptor);
2347 if (field_number == 0) {
2348 return nullptr;
2349 }
2350 return descriptor_->FindFieldByNumber(field_number);
2351 }
2352
2353 bool Reflection::ContainsMapKey(const Message& message,
2354 const FieldDescriptor* field,
2355 const MapKey& key) const {
2356 USAGE_CHECK(IsMapFieldInApi(field), "LookupMapValue",
2357 "Field is not a map field.");
2358 return GetRaw<MapFieldBase>(message, field).ContainsMapKey(key);
2359 }
2360
2361 bool Reflection::InsertOrLookupMapValue(Message* message,
2362 const FieldDescriptor* field,
2363 const MapKey& key,
2364 MapValueRef* val) const {
2365 USAGE_CHECK(IsMapFieldInApi(field), "InsertOrLookupMapValue",
2366 "Field is not a map field.");
2367 val->SetType(field->message_type()->map_value()->cpp_type());
2368 return MutableRaw<MapFieldBase>(message, field)
2369 ->InsertOrLookupMapValue(key, val);
2370 }
2371
2372 bool Reflection::LookupMapValue(const Message& message,
2373 const FieldDescriptor* field, const MapKey& key,
2374 MapValueConstRef* val) const {
2375 USAGE_CHECK(IsMapFieldInApi(field), "LookupMapValue",
2376 "Field is not a map field.");
2377 val->SetType(field->message_type()->map_value()->cpp_type());
2378 return GetRaw<MapFieldBase>(message, field).LookupMapValue(key, val);
2379 }
2380
2381 bool Reflection::DeleteMapValue(Message* message, const FieldDescriptor* field,
2382 const MapKey& key) const {
2383 USAGE_CHECK(IsMapFieldInApi(field), "DeleteMapValue",
2384 "Field is not a map field.");
2385 return MutableRaw<MapFieldBase>(message, field)->DeleteMapValue(key);
2386 }
2387
2388 MapIterator Reflection::MapBegin(Message* message,
2389 const FieldDescriptor* field) const {
2390 USAGE_CHECK(IsMapFieldInApi(field), "MapBegin", "Field is not a map field.");
2391 MapIterator iter(message, field);
2392 GetRaw<MapFieldBase>(*message, field).MapBegin(&iter);
2393 return iter;
2394 }
2395
2396 MapIterator Reflection::MapEnd(Message* message,
2397 const FieldDescriptor* field) const {
2398 USAGE_CHECK(IsMapFieldInApi(field), "MapEnd", "Field is not a map field.");
2399 MapIterator iter(message, field);
2400 GetRaw<MapFieldBase>(*message, field).MapEnd(&iter);
2401 return iter;
2402 }
2403
2404 int Reflection::MapSize(const Message& message,
2405 const FieldDescriptor* field) const {
2406 USAGE_CHECK(IsMapFieldInApi(field), "MapSize", "Field is not a map field.");
2407 return GetRaw<MapFieldBase>(message, field).size();
2408 }
2409
2410 // -----------------------------------------------------------------------------
2411
2412 const FieldDescriptor* Reflection::FindKnownExtensionByName(
2413 const std::string& name) const {
2414 if (!schema_.HasExtensionSet()) return nullptr;
2415 return descriptor_pool_->FindExtensionByPrintableName(descriptor_, name);
2416 }
2417
2418 const FieldDescriptor* Reflection::FindKnownExtensionByNumber(
2419 int number) const {
2420 if (!schema_.HasExtensionSet()) return nullptr;
2421 return descriptor_pool_->FindExtensionByNumber(descriptor_, number);
2422 }
2423
2424 bool Reflection::SupportsUnknownEnumValues() const {
2425 return CreateUnknownEnumValues(descriptor_->file());
2426 }
2427
2428 // ===================================================================
2429 // Some private helpers.
2430
2431 // These simple template accessors obtain pointers (or references) to
2432 // the given field.
2433
2434 template <class Type>
2435 const Type& Reflection::GetRawNonOneof(const Message& message,
2436 const FieldDescriptor* field) const {
2437 return GetConstRefAtOffset<Type>(message,
2438 schema_.GetFieldOffsetNonOneof(field));
2439 }
2440
2441 template <class Type>
2442 Type* Reflection::MutableRawNonOneof(Message* message,
2443 const FieldDescriptor* field) const {
2444 return GetPointerAtOffset<Type>(message,
2445 schema_.GetFieldOffsetNonOneof(field));
2446 }
2447
2448 template <typename Type>
2449 Type* Reflection::MutableRaw(Message* message,
2450 const FieldDescriptor* field) const {
2451 return GetPointerAtOffset<Type>(message, schema_.GetFieldOffset(field));
2452 }
2453
2454 const uint32_t* Reflection::GetHasBits(const Message& message) const {
2455 GOOGLE_DCHECK(schema_.HasHasbits());
2456 return &GetConstRefAtOffset<uint32_t>(message, schema_.HasBitsOffset());
2457 }
2458
2459 uint32_t* Reflection::MutableHasBits(Message* message) const {
2460 GOOGLE_DCHECK(schema_.HasHasbits());
2461 return GetPointerAtOffset<uint32_t>(message, schema_.HasBitsOffset());
2462 }
2463
2464 uint32_t* Reflection::MutableOneofCase(
2465 Message* message, const OneofDescriptor* oneof_descriptor) const {
2466 GOOGLE_DCHECK(!oneof_descriptor->is_synthetic());
2467 return GetPointerAtOffset<uint32_t>(
2468 message, schema_.GetOneofCaseOffset(oneof_descriptor));
2469 }
2470
2471 const ExtensionSet& Reflection::GetExtensionSet(const Message& message) const {
2472 return GetConstRefAtOffset<ExtensionSet>(message,
2473 schema_.GetExtensionSetOffset());
2474 }
2475
2476 ExtensionSet* Reflection::MutableExtensionSet(Message* message) const {
2477 return GetPointerAtOffset<ExtensionSet>(message,
2478 schema_.GetExtensionSetOffset());
2479 }
2480
2481 const InternalMetadata& Reflection::GetInternalMetadata(
2482 const Message& message) const {
2483 return GetConstRefAtOffset<InternalMetadata>(message,
2484 schema_.GetMetadataOffset());
2485 }
2486
2487 InternalMetadata* Reflection::MutableInternalMetadata(Message* message) const {
2488 return GetPointerAtOffset<InternalMetadata>(message,
2489 schema_.GetMetadataOffset());
2490 }
2491
2492 const uint32_t* Reflection::GetInlinedStringDonatedArray(
2493 const Message& message) const {
2494 GOOGLE_DCHECK(schema_.HasInlinedString());
2495 return &GetConstRefAtOffset<uint32_t>(message,
2496 schema_.InlinedStringDonatedOffset());
2497 }
2498
2499 uint32_t* Reflection::MutableInlinedStringDonatedArray(Message* message) const {
2500 GOOGLE_DCHECK(schema_.HasInlinedString());
2501 return GetPointerAtOffset<uint32_t>(message,
2502 schema_.InlinedStringDonatedOffset());
2503 }
2504
2505 // Simple accessors for manipulating _inlined_string_donated_;
2506 bool Reflection::IsInlinedStringDonated(const Message& message,
2507 const FieldDescriptor* field) const {
2508 uint32_t index = schema_.InlinedStringIndex(field);
2509 GOOGLE_DCHECK_GT(index, 0);
2510 return IsIndexInHasBitSet(GetInlinedStringDonatedArray(message), index);
2511 }
2512
2513 inline void SetInlinedStringDonated(uint32_t index, uint32_t* array) {
2514 array[index / 32] |= (static_cast<uint32_t>(1) << (index % 32));
2515 }
2516
2517 inline void ClearInlinedStringDonated(uint32_t index, uint32_t* array) {
2518 array[index / 32] &= ~(static_cast<uint32_t>(1) << (index % 32));
2519 }
2520
2521 void Reflection::SwapInlinedStringDonated(Message* lhs, Message* rhs,
2522 const FieldDescriptor* field) const {
2523 Arena* lhs_arena = lhs->GetArenaForAllocation();
2524 Arena* rhs_arena = rhs->GetArenaForAllocation();
2525 // If arenas differ, inined string fields are swapped by copying values.
2526 // Donation status should not be swapped.
2527 if (lhs_arena != rhs_arena) {
2528 return;
2529 }
2530 bool lhs_donated = IsInlinedStringDonated(*lhs, field);
2531 bool rhs_donated = IsInlinedStringDonated(*rhs, field);
2532 if (lhs_donated == rhs_donated) {
2533 return;
2534 }
2535 // If one is undonated, both must have already registered ArenaDtor.
2536 uint32_t* lhs_array = MutableInlinedStringDonatedArray(lhs);
2537 uint32_t* rhs_array = MutableInlinedStringDonatedArray(rhs);
2538 GOOGLE_CHECK_EQ(lhs_array[0] & 0x1u, 0u);
2539 GOOGLE_CHECK_EQ(rhs_array[0] & 0x1u, 0u);
2540 // Swap donation status bit.
2541 uint32_t index = schema_.InlinedStringIndex(field);
2542 GOOGLE_DCHECK_GT(index, 0);
2543 if (rhs_donated) {
2544 SetInlinedStringDonated(index, lhs_array);
2545 ClearInlinedStringDonated(index, rhs_array);
2546 } else { // lhs_donated
2547 ClearInlinedStringDonated(index, lhs_array);
2548 SetInlinedStringDonated(index, rhs_array);
2549 }
2550 }
2551
2552 // Simple accessors for manipulating has_bits_.
2553 bool Reflection::HasBit(const Message& message,
2554 const FieldDescriptor* field) const {
2555 GOOGLE_DCHECK(!field->options().weak());
2556 if (schema_.HasBitIndex(field) != static_cast<uint32_t>(-1)) {
2557 return IsIndexInHasBitSet(GetHasBits(message), schema_.HasBitIndex(field));
2558 }
2559
2560 // Intentionally check here because HasBitIndex(field) != -1 means valid.
2561 CheckInvalidAccess(schema_, field);
2562
2563 // proto3: no has-bits. All fields present except messages, which are
2564 // present only if their message-field pointer is non-null.
2565 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
2566 return !schema_.IsDefaultInstance(message) &&
2567 GetRaw<const Message*>(message, field) != nullptr;
2568 } else {
2569 // Non-message field (and non-oneof, since that was handled in HasField()
2570 // before calling us), and singular (again, checked in HasField). So, this
2571 // field must be a scalar.
2572
2573 // Scalar primitive (numeric or string/bytes) fields are present if
2574 // their value is non-zero (numeric) or non-empty (string/bytes). N.B.:
2575 // we must use this definition here, rather than the "scalar fields
2576 // always present" in the proto3 docs, because MergeFrom() semantics
2577 // require presence as "present on wire", and reflection-based merge
2578 // (which uses HasField()) needs to be consistent with this.
2579 switch (field->cpp_type()) {
2580 case FieldDescriptor::CPPTYPE_STRING:
2581 switch (field->options().ctype()) {
2582 default: {
2583 if (IsInlined(field)) {
2584 return !GetField<InlinedStringField>(message, field)
2585 .GetNoArena()
2586 .empty();
2587 }
2588
2589 return GetField<ArenaStringPtr>(message, field).Get().size() > 0;
2590 }
2591 }
2592 return false;
2593 case FieldDescriptor::CPPTYPE_BOOL:
2594 return GetRaw<bool>(message, field) != false;
2595 case FieldDescriptor::CPPTYPE_INT32:
2596 return GetRaw<int32_t>(message, field) != 0;
2597 case FieldDescriptor::CPPTYPE_INT64:
2598 return GetRaw<int64_t>(message, field) != 0;
2599 case FieldDescriptor::CPPTYPE_UINT32:
2600 return GetRaw<uint32_t>(message, field) != 0;
2601 case FieldDescriptor::CPPTYPE_UINT64:
2602 return GetRaw<uint64_t>(message, field) != 0;
2603 case FieldDescriptor::CPPTYPE_FLOAT:
2604 static_assert(sizeof(uint32_t) == sizeof(float),
2605 "Code assumes uint32_t and float are the same size.");
2606 return GetRaw<uint32_t>(message, field) != 0;
2607 case FieldDescriptor::CPPTYPE_DOUBLE:
2608 static_assert(sizeof(uint64_t) == sizeof(double),
2609 "Code assumes uint64_t and double are the same size.");
2610 return GetRaw<uint64_t>(message, field) != 0;
2611 case FieldDescriptor::CPPTYPE_ENUM:
2612 return GetRaw<int>(message, field) != 0;
2613 case FieldDescriptor::CPPTYPE_MESSAGE:
2614 // handled above; avoid warning
2615 break;
2616 }
2617 GOOGLE_LOG(FATAL) << "Reached impossible case in HasBit().";
2618 return false;
2619 }
2620 }
2621
2622 void Reflection::SetBit(Message* message, const FieldDescriptor* field) const {
2623 GOOGLE_DCHECK(!field->options().weak());
2624 const uint32_t index = schema_.HasBitIndex(field);
2625 if (index == static_cast<uint32_t>(-1)) return;
2626 MutableHasBits(message)[index / 32] |=
2627 (static_cast<uint32_t>(1) << (index % 32));
2628 }
2629
2630 void Reflection::ClearBit(Message* message,
2631 const FieldDescriptor* field) const {
2632 GOOGLE_DCHECK(!field->options().weak());
2633 const uint32_t index = schema_.HasBitIndex(field);
2634 if (index == static_cast<uint32_t>(-1)) return;
2635 MutableHasBits(message)[index / 32] &=
2636 ~(static_cast<uint32_t>(1) << (index % 32));
2637 }
2638
2639 void Reflection::SwapBit(Message* message1, Message* message2,
2640 const FieldDescriptor* field) const {
2641 GOOGLE_DCHECK(!field->options().weak());
2642 if (!schema_.HasHasbits()) {
2643 return;
2644 }
2645 bool temp_has_bit = HasBit(*message1, field);
2646 if (HasBit(*message2, field)) {
2647 SetBit(message1, field);
2648 } else {
2649 ClearBit(message1, field);
2650 }
2651 if (temp_has_bit) {
2652 SetBit(message2, field);
2653 } else {
2654 ClearBit(message2, field);
2655 }
2656 }
2657
2658 bool Reflection::HasOneof(const Message& message,
2659 const OneofDescriptor* oneof_descriptor) const {
2660 if (oneof_descriptor->is_synthetic()) {
2661 return HasField(message, oneof_descriptor->field(0));
2662 }
2663 return (GetOneofCase(message, oneof_descriptor) > 0);
2664 }
2665
2666 void Reflection::SetOneofCase(Message* message,
2667 const FieldDescriptor* field) const {
2668 *MutableOneofCase(message, field->containing_oneof()) = field->number();
2669 }
2670
2671 void Reflection::ClearOneofField(Message* message,
2672 const FieldDescriptor* field) const {
2673 if (HasOneofField(*message, field)) {
2674 ClearOneof(message, field->containing_oneof());
2675 }
2676 }
2677
2678 void Reflection::ClearOneof(Message* message,
2679 const OneofDescriptor* oneof_descriptor) const {
2680 if (oneof_descriptor->is_synthetic()) {
2681 ClearField(message, oneof_descriptor->field(0));
2682 return;
2683 }
2684 // TODO(jieluo): Consider to cache the unused object instead of deleting
2685 // it. It will be much faster if an application switches a lot from
2686 // a few oneof fields. Time/space tradeoff
2687 uint32_t oneof_case = GetOneofCase(*message, oneof_descriptor);
2688 if (oneof_case > 0) {
2689 const FieldDescriptor* field = descriptor_->FindFieldByNumber(oneof_case);
2690 if (message->GetArenaForAllocation() == nullptr) {
2691 switch (field->cpp_type()) {
2692 case FieldDescriptor::CPPTYPE_STRING: {
2693 switch (field->options().ctype()) {
2694 default: // TODO(kenton): Support other string reps.
2695 case FieldOptions::STRING: {
2696 // Oneof string fields are never set as a default instance.
2697 // We just need to pass some arbitrary default string to make it
2698 // work. This allows us to not have the real default accessible
2699 // from reflection.
2700 MutableField<ArenaStringPtr>(message, field)->Destroy();
2701 break;
2702 }
2703 }
2704 break;
2705 }
2706
2707 case FieldDescriptor::CPPTYPE_MESSAGE:
2708 delete *MutableRaw<Message*>(message, field);
2709 break;
2710 default:
2711 break;
2712 }
2713 } else {
2714 }
2715
2716 *MutableOneofCase(message, oneof_descriptor) = 0;
2717 }
2718 }
2719
2720 #define HANDLE_TYPE(TYPE, CPPTYPE, CTYPE) \
2721 template <> \
2722 const RepeatedField<TYPE>& Reflection::GetRepeatedFieldInternal<TYPE>( \
2723 const Message& message, const FieldDescriptor* field) const { \
2724 return *static_cast<RepeatedField<TYPE>*>(MutableRawRepeatedField( \
2725 const_cast<Message*>(&message), field, CPPTYPE, CTYPE, nullptr)); \
2726 } \
2727 \
2728 template <> \
2729 RepeatedField<TYPE>* Reflection::MutableRepeatedFieldInternal<TYPE>( \
2730 Message * message, const FieldDescriptor* field) const { \
2731 return static_cast<RepeatedField<TYPE>*>( \
2732 MutableRawRepeatedField(message, field, CPPTYPE, CTYPE, nullptr)); \
2733 }
2734
2735 HANDLE_TYPE(int32_t, FieldDescriptor::CPPTYPE_INT32, -1);
2736 HANDLE_TYPE(int64_t, FieldDescriptor::CPPTYPE_INT64, -1);
2737 HANDLE_TYPE(uint32_t, FieldDescriptor::CPPTYPE_UINT32, -1);
2738 HANDLE_TYPE(uint64_t, FieldDescriptor::CPPTYPE_UINT64, -1);
2739 HANDLE_TYPE(float, FieldDescriptor::CPPTYPE_FLOAT, -1);
2740 HANDLE_TYPE(double, FieldDescriptor::CPPTYPE_DOUBLE, -1);
2741 HANDLE_TYPE(bool, FieldDescriptor::CPPTYPE_BOOL, -1);
2742
2743
2744 #undef HANDLE_TYPE
2745
2746 void* Reflection::MutableRawRepeatedString(Message* message,
2747 const FieldDescriptor* field,
2748 bool is_string) const {
2749 (void)is_string; // Parameter is used by Google-internal code.
2750 return MutableRawRepeatedField(message, field,
2751 FieldDescriptor::CPPTYPE_STRING,
2752 FieldOptions::STRING, nullptr);
2753 }
2754
2755 // Template implementations of basic accessors. Inline because each
2756 // template instance is only called from one location. These are
2757 // used for all types except messages.
2758 template <typename Type>
2759 const Type& Reflection::GetField(const Message& message,
2760 const FieldDescriptor* field) const {
2761 return GetRaw<Type>(message, field);
2762 }
2763
2764 template <typename Type>
2765 void Reflection::SetField(Message* message, const FieldDescriptor* field,
2766 const Type& value) const {
2767 bool real_oneof = schema_.InRealOneof(field);
2768 if (real_oneof && !HasOneofField(*message, field)) {
2769 ClearOneof(message, field->containing_oneof());
2770 }
2771 *MutableRaw<Type>(message, field) = value;
2772 real_oneof ? SetOneofCase(message, field) : SetBit(message, field);
2773 }
2774
2775 template <typename Type>
2776 Type* Reflection::MutableField(Message* message,
2777 const FieldDescriptor* field) const {
2778 schema_.InRealOneof(field) ? SetOneofCase(message, field)
2779 : SetBit(message, field);
2780 return MutableRaw<Type>(message, field);
2781 }
2782
2783 template <typename Type>
2784 const Type& Reflection::GetRepeatedField(const Message& message,
2785 const FieldDescriptor* field,
2786 int index) const {
2787 return GetRaw<RepeatedField<Type> >(message, field).Get(index);
2788 }
2789
2790 template <typename Type>
2791 const Type& Reflection::GetRepeatedPtrField(const Message& message,
2792 const FieldDescriptor* field,
2793 int index) const {
2794 return GetRaw<RepeatedPtrField<Type> >(message, field).Get(index);
2795 }
2796
2797 template <typename Type>
2798 void Reflection::SetRepeatedField(Message* message,
2799 const FieldDescriptor* field, int index,
2800 Type value) const {
2801 MutableRaw<RepeatedField<Type> >(message, field)->Set(index, value);
2802 }
2803
2804 template <typename Type>
2805 Type* Reflection::MutableRepeatedField(Message* message,
2806 const FieldDescriptor* field,
2807 int index) const {
2808 RepeatedPtrField<Type>* repeated =
2809 MutableRaw<RepeatedPtrField<Type> >(message, field);
2810 return repeated->Mutable(index);
2811 }
2812
2813 template <typename Type>
2814 void Reflection::AddField(Message* message, const FieldDescriptor* field,
2815 const Type& value) const {
2816 MutableRaw<RepeatedField<Type> >(message, field)->Add(value);
2817 }
2818
2819 template <typename Type>
2820 Type* Reflection::AddField(Message* message,
2821 const FieldDescriptor* field) const {
2822 RepeatedPtrField<Type>* repeated =
2823 MutableRaw<RepeatedPtrField<Type> >(message, field);
2824 return repeated->Add();
2825 }
2826
2827 MessageFactory* Reflection::GetMessageFactory() const {
2828 return message_factory_;
2829 }
2830
2831 void* Reflection::RepeatedFieldData(Message* message,
2832 const FieldDescriptor* field,
2833 FieldDescriptor::CppType cpp_type,
2834 const Descriptor* message_type) const {
2835 GOOGLE_CHECK(field->is_repeated());
2836 GOOGLE_CHECK(field->cpp_type() == cpp_type ||
2837 (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM &&
2838 cpp_type == FieldDescriptor::CPPTYPE_INT32))
2839 << "The type parameter T in RepeatedFieldRef<T> API doesn't match "
2840 << "the actual field type (for enums T should be the generated enum "
2841 << "type or int32_t).";
2842 if (message_type != nullptr) {
2843 GOOGLE_CHECK_EQ(message_type, field->message_type());
2844 }
2845 if (field->is_extension()) {
2846 return MutableExtensionSet(message)->MutableRawRepeatedField(
2847 field->number(), field->type(), field->is_packed(), field);
2848 } else {
2849 return MutableRawNonOneof<char>(message, field);
2850 }
2851 }
2852
2853 MapFieldBase* Reflection::MutableMapData(Message* message,
2854 const FieldDescriptor* field) const {
2855 USAGE_CHECK(IsMapFieldInApi(field), "GetMapData",
2856 "Field is not a map field.");
2857 return MutableRaw<MapFieldBase>(message, field);
2858 }
2859
2860 const MapFieldBase* Reflection::GetMapData(const Message& message,
2861 const FieldDescriptor* field) const {
2862 USAGE_CHECK(IsMapFieldInApi(field), "GetMapData",
2863 "Field is not a map field.");
2864 return &(GetRaw<MapFieldBase>(message, field));
2865 }
2866
2867 namespace {
2868
2869 // Helper function to transform migration schema into reflection schema.
2870 ReflectionSchema MigrationToReflectionSchema(
2871 const Message* const* default_instance, const uint32_t* offsets,
2872 MigrationSchema migration_schema) {
2873 ReflectionSchema result;
2874 result.default_instance_ = *default_instance;
2875 // First 7 offsets are offsets to the special fields. The following offsets
2876 // are the proto fields.
2877 result.offsets_ = offsets + migration_schema.offsets_index + 6;
2878 result.has_bit_indices_ = offsets + migration_schema.has_bit_indices_index;
2879 result.has_bits_offset_ = offsets[migration_schema.offsets_index + 0];
2880 result.metadata_offset_ = offsets[migration_schema.offsets_index + 1];
2881 result.extensions_offset_ = offsets[migration_schema.offsets_index + 2];
2882 result.oneof_case_offset_ = offsets[migration_schema.offsets_index + 3];
2883 result.object_size_ = migration_schema.object_size;
2884 result.weak_field_map_offset_ = offsets[migration_schema.offsets_index + 4];
2885 result.inlined_string_donated_offset_ =
2886 offsets[migration_schema.offsets_index + 5];
2887 result.inlined_string_indices_ =
2888 offsets + migration_schema.inlined_string_indices_index;
2889 return result;
2890 }
2891
2892 } // namespace
2893
2894 class AssignDescriptorsHelper {
2895 public:
2896 AssignDescriptorsHelper(MessageFactory* factory,
2897 Metadata* file_level_metadata,
2898 const EnumDescriptor** file_level_enum_descriptors,
2899 const MigrationSchema* schemas,
2900 const Message* const* default_instance_data,
2901 const uint32_t* offsets)
2902 : factory_(factory),
2903 file_level_metadata_(file_level_metadata),
2904 file_level_enum_descriptors_(file_level_enum_descriptors),
2905 schemas_(schemas),
2906 default_instance_data_(default_instance_data),
2907 offsets_(offsets) {}
2908
2909 void AssignMessageDescriptor(const Descriptor* descriptor) {
2910 for (int i = 0; i < descriptor->nested_type_count(); i++) {
2911 AssignMessageDescriptor(descriptor->nested_type(i));
2912 }
2913
2914 file_level_metadata_->descriptor = descriptor;
2915
2916 file_level_metadata_->reflection =
2917 new Reflection(descriptor,
2918 MigrationToReflectionSchema(default_instance_data_,
2919 offsets_, *schemas_),
2920 DescriptorPool::internal_generated_pool(), factory_);
2921 for (int i = 0; i < descriptor->enum_type_count(); i++) {
2922 AssignEnumDescriptor(descriptor->enum_type(i));
2923 }
2924 schemas_++;
2925 default_instance_data_++;
2926 file_level_metadata_++;
2927 }
2928
2929 void AssignEnumDescriptor(const EnumDescriptor* descriptor) {
2930 *file_level_enum_descriptors_ = descriptor;
2931 file_level_enum_descriptors_++;
2932 }
2933
2934 const Metadata* GetCurrentMetadataPtr() const { return file_level_metadata_; }
2935
2936 private:
2937 MessageFactory* factory_;
2938 Metadata* file_level_metadata_;
2939 const EnumDescriptor** file_level_enum_descriptors_;
2940 const MigrationSchema* schemas_;
2941 const Message* const* default_instance_data_;
2942 const uint32_t* offsets_;
2943 };
2944
2945 namespace {
2946
2947 // We have the routines that assign descriptors and build reflection
2948 // automatically delete the allocated reflection. MetadataOwner owns
2949 // all the allocated reflection instances.
2950 struct MetadataOwner {
2951 ~MetadataOwner() {
2952 for (auto range : metadata_arrays_) {
2953 for (const Metadata* m = range.first; m < range.second; m++) {
2954 delete m->reflection;
2955 }
2956 }
2957 }
2958
2959 void AddArray(const Metadata* begin, const Metadata* end) {
2960 mu_.Lock();
2961 metadata_arrays_.push_back(std::make_pair(begin, end));
2962 mu_.Unlock();
2963 }
2964
2965 static MetadataOwner* Instance() {
2966 static MetadataOwner* res = OnShutdownDelete(new MetadataOwner);
2967 return res;
2968 }
2969
2970 private:
2971 MetadataOwner() = default; // private because singleton
2972
2973 WrappedMutex mu_;
2974 std::vector<std::pair<const Metadata*, const Metadata*> > metadata_arrays_;
2975 };
2976
2977 void AddDescriptors(const DescriptorTable* table);
2978
2979 void AssignDescriptorsImpl(const DescriptorTable* table, bool eager) {
2980 // Ensure the file descriptor is added to the pool.
2981 {
2982 // This only happens once per proto file. So a global mutex to serialize
2983 // calls to AddDescriptors.
2984 static WrappedMutex mu{GOOGLE_PROTOBUF_LINKER_INITIALIZED};
2985 mu.Lock();
2986 AddDescriptors(table);
2987 mu.Unlock();
2988 }
2989 if (eager) {
2990 // Normally we do not want to eagerly build descriptors of our deps.
2991 // However if this proto is optimized for code size (ie using reflection)
2992 // and it has a message extending a custom option of a descriptor with that
2993 // message being optimized for code size as well. Building the descriptors
2994 // in this file requires parsing the serialized file descriptor, which now
2995 // requires parsing the message extension, which potentially requires
2996 // building the descriptor of the message extending one of the options.
2997 // However we are already updating descriptor pool under a lock. To prevent
2998 // this the compiler statically looks for this case and we just make sure we
2999 // first build the descriptors of all our dependencies, preventing the
3000 // deadlock.
3001 int num_deps = table->num_deps;
3002 for (int i = 0; i < num_deps; i++) {
3003 // In case of weak fields deps[i] could be null.
3004 if (table->deps[i]) AssignDescriptors(table->deps[i], true);
3005 }
3006 }
3007
3008 // Fill the arrays with pointers to descriptors and reflection classes.
3009 const FileDescriptor* file =
3010 DescriptorPool::internal_generated_pool()->FindFileByName(
3011 table->filename);
3012 GOOGLE_CHECK(file != nullptr);
3013
3014 MessageFactory* factory = MessageFactory::generated_factory();
3015
3016 AssignDescriptorsHelper helper(
3017 factory, table->file_level_metadata, table->file_level_enum_descriptors,
3018 table->schemas, table->default_instances, table->offsets);
3019
3020 for (int i = 0; i < file->message_type_count(); i++) {
3021 helper.AssignMessageDescriptor(file->message_type(i));
3022 }
3023
3024 for (int i = 0; i < file->enum_type_count(); i++) {
3025 helper.AssignEnumDescriptor(file->enum_type(i));
3026 }
3027 if (file->options().cc_generic_services()) {
3028 for (int i = 0; i < file->service_count(); i++) {
3029 table->file_level_service_descriptors[i] = file->service(i);
3030 }
3031 }
3032 MetadataOwner::Instance()->AddArray(table->file_level_metadata,
3033 helper.GetCurrentMetadataPtr());
3034 }
3035
3036 void AddDescriptorsImpl(const DescriptorTable* table) {
3037 // Reflection refers to the default fields so make sure they are initialized.
3038 internal::InitProtobufDefaults();
3039
3040 // Ensure all dependent descriptors are registered to the generated descriptor
3041 // pool and message factory.
3042 int num_deps = table->num_deps;
3043 for (int i = 0; i < num_deps; i++) {
3044 // In case of weak fields deps[i] could be null.
3045 if (table->deps[i]) AddDescriptors(table->deps[i]);
3046 }
3047
3048 // Register the descriptor of this file.
3049 DescriptorPool::InternalAddGeneratedFile(table->descriptor, table->size);
3050 MessageFactory::InternalRegisterGeneratedFile(table);
3051 }
3052
3053 void AddDescriptors(const DescriptorTable* table) {
3054 // AddDescriptors is not thread safe. Callers need to ensure calls are
3055 // properly serialized. This function is only called pre-main by global
3056 // descriptors and we can assume single threaded access or it's called
3057 // by AssignDescriptorImpl which uses a mutex to sequence calls.
3058 if (table->is_initialized) return;
3059 table->is_initialized = true;
3060 AddDescriptorsImpl(table);
3061 }
3062
3063 } // namespace
3064
3065 // Separate function because it needs to be a friend of
3066 // Reflection
3067 void RegisterAllTypesInternal(const Metadata* file_level_metadata, int size) {
3068 for (int i = 0; i < size; i++) {
3069 const Reflection* reflection = file_level_metadata[i].reflection;
3070 MessageFactory::InternalRegisterGeneratedMessage(
3071 file_level_metadata[i].descriptor,
3072 reflection->schema_.default_instance_);
3073 }
3074 }
3075
3076 namespace internal {
3077
3078 Metadata AssignDescriptors(const DescriptorTable* (*table)(),
3079 internal::once_flag* once,
3080 const Metadata& metadata) {
3081 call_once(*once, [=] {
3082 auto* t = table();
3083 AssignDescriptorsImpl(t, t->is_eager);
3084 });
3085
3086 return metadata;
3087 }
3088
3089 void AssignDescriptors(const DescriptorTable* table, bool eager) {
3090 if (!eager) eager = table->is_eager;
3091 call_once(*table->once, AssignDescriptorsImpl, table, eager);
3092 }
3093
3094 AddDescriptorsRunner::AddDescriptorsRunner(const DescriptorTable* table) {
3095 AddDescriptors(table);
3096 }
3097
3098 void RegisterFileLevelMetadata(const DescriptorTable* table) {
3099 AssignDescriptors(table);
3100 RegisterAllTypesInternal(table->file_level_metadata, table->num_messages);
3101 }
3102
3103 void UnknownFieldSetSerializer(const uint8_t* base, uint32_t offset,
3104 uint32_t /*tag*/, uint32_t /*has_offset*/,
3105 io::CodedOutputStream* output) {
3106 const void* ptr = base + offset;
3107 const InternalMetadata* metadata = static_cast<const InternalMetadata*>(ptr);
3108 if (metadata->have_unknown_fields()) {
3109 metadata->unknown_fields<UnknownFieldSet>(UnknownFieldSet::default_instance)
3110 .SerializeToCodedStream(output);
3111 }
3112 }
3113
3114 bool IsDescendant(Message& root, const Message& message) {
3115 const Reflection* reflection = root.GetReflection();
3116 std::vector<const FieldDescriptor*> fields;
3117 reflection->ListFieldsOmitStripped(root, &fields);
3118
3119 for (const auto* field : fields) {
3120 // Skip non-message fields.
3121 if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) continue;
3122
3123 // Optional messages.
3124 if (!field->is_repeated()) {
3125 Message* sub_message = reflection->MutableMessage(&root, field);
3126 if (sub_message == &message || IsDescendant(*sub_message, message)) {
3127 return true;
3128 }
3129 continue;
3130 }
3131
3132 // Repeated messages.
3133 if (!IsMapFieldInApi(field)) {
3134 int count = reflection->FieldSize(root, field);
3135 for (int i = 0; i < count; i++) {
3136 Message* sub_message =
3137 reflection->MutableRepeatedMessage(&root, field, i);
3138 if (sub_message == &message || IsDescendant(*sub_message, message)) {
3139 return true;
3140 }
3141 }
3142 continue;
3143 }
3144
3145 // Map field: if accessed as repeated fields, messages are *copied* and
3146 // matching pointer won't work. Must directly access map.
3147 constexpr int kValIdx = 1;
3148 const FieldDescriptor* val_field = field->message_type()->field(kValIdx);
3149 // Skip map fields whose value type is not message.
3150 if (val_field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) continue;
3151
3152 MapIterator end = reflection->MapEnd(&root, field);
3153 for (auto iter = reflection->MapBegin(&root, field); iter != end; ++iter) {
3154 Message* sub_message = iter.MutableValueRef()->MutableMessageValue();
3155 if (sub_message == &message || IsDescendant(*sub_message, message)) {
3156 return true;
3157 }
3158 }
3159 }
3160
3161 return false;
3162 }
3163
3164 } // namespace internal
3165 } // namespace protobuf
3166 } // namespace google
3167
3168 #include <google/protobuf/port_undef.inc>
3169