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