blob: 412c48a1e664fe315de7e257e70039e774c22dcb [file] [log] [blame]
temporal40ee5512008-07-10 02:12:20 +00001// Protocol Buffers - Google's data interchange format
kenton@google.com24bf56f2008-09-24 20:31:01 +00002// Copyright 2008 Google Inc. All rights reserved.
Feng Xiaoe4288622014-10-01 16:26:23 -07003// https://developers.google.com/protocol-buffers/
temporal40ee5512008-07-10 02:12:20 +00004//
kenton@google.com24bf56f2008-09-24 20:31:01 +00005// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are
7// met:
temporal40ee5512008-07-10 02:12:20 +00008//
kenton@google.com24bf56f2008-09-24 20:31:01 +00009// * 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.
temporal40ee5512008-07-10 02:12:20 +000018//
kenton@google.com24bf56f2008-09-24 20:31:01 +000019// 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.
temporal40ee5512008-07-10 02:12:20 +000030
31// Author: kenton@google.com (Kenton Varda)
32// Based on original Protocol Buffers design by
33// Sanjay Ghemawat, Jeff Dean, and others.
34
35#include <algorithm>
jieluo@google.com4de8f552014-07-18 00:47:59 +000036#include <set>
Feng Xiaof157a562014-11-14 11:50:31 -080037
temporal40ee5512008-07-10 02:12:20 +000038#include <google/protobuf/stubs/common.h>
Feng Xiaof157a562014-11-14 11:50:31 -080039#include <google/protobuf/descriptor.pb.h>
40#include <google/protobuf/descriptor.h>
41#include <google/protobuf/extension_set.h>
42#include <google/protobuf/generated_message_reflection.h>
43#include <google/protobuf/generated_message_util.h>
44#include <google/protobuf/map_field.h>
45#include <google/protobuf/repeated_field.h>
46
temporal40ee5512008-07-10 02:12:20 +000047
jieluo@google.com4de8f552014-07-18 00:47:59 +000048#define GOOGLE_PROTOBUF_HAS_ONEOF
49
temporal40ee5512008-07-10 02:12:20 +000050namespace google {
51namespace protobuf {
52namespace internal {
53
Feng Xiaof157a562014-11-14 11:50:31 -080054namespace {
55bool IsMapFieldInApi(const FieldDescriptor* field) {
56 return field->is_map();
57}
58} // anonymous namespace
59
kenton@google.com26bd9ee2008-11-21 00:06:27 +000060int StringSpaceUsedExcludingSelf(const string& str) {
61 const void* start = &str;
62 const void* end = &str + 1;
63
jieluo@google.com4de8f552014-07-18 00:47:59 +000064 if (start <= str.data() && str.data() < end) {
kenton@google.com26bd9ee2008-11-21 00:06:27 +000065 // The string's data is stored inside the string object itself.
66 return 0;
67 } else {
68 return str.capacity();
69 }
70}
71
kenton@google.comd37d46d2009-04-25 02:53:47 +000072bool ParseNamedEnum(const EnumDescriptor* descriptor,
73 const string& name,
74 int* value) {
75 const EnumValueDescriptor* d = descriptor->FindValueByName(name);
76 if (d == NULL) return false;
77 *value = d->number();
78 return true;
79}
80
81const string& NameOfEnum(const EnumDescriptor* descriptor, int value) {
kenton@google.comd37d46d2009-04-25 02:53:47 +000082 const EnumValueDescriptor* d = descriptor->FindValueByNumber(value);
xiaofeng@google.com37c74262014-02-13 22:09:48 +000083 return (d == NULL ? GetEmptyString() : d->name());
kenton@google.comd37d46d2009-04-25 02:53:47 +000084}
85
Feng Xiao6ef984a2014-11-10 17:34:54 -080086namespace {
87inline bool SupportsArenas(const Descriptor* descriptor) {
Feng Xiaof157a562014-11-14 11:50:31 -080088 return descriptor->file()->options().cc_enable_arenas();
Feng Xiao6ef984a2014-11-10 17:34:54 -080089}
90} // anonymous namespace
91
temporal40ee5512008-07-10 02:12:20 +000092// ===================================================================
93// Helpers for reporting usage errors (e.g. trying to use GetInt32() on
94// a string field).
95
96namespace {
97
98void ReportReflectionUsageError(
99 const Descriptor* descriptor, const FieldDescriptor* field,
100 const char* method, const char* description) {
101 GOOGLE_LOG(FATAL)
102 << "Protocol Buffer reflection usage error:\n"
temporal779f61c2008-08-13 03:15:00 +0000103 " Method : google::protobuf::Reflection::" << method << "\n"
temporal40ee5512008-07-10 02:12:20 +0000104 " Message type: " << descriptor->full_name() << "\n"
105 " Field : " << field->full_name() << "\n"
106 " Problem : " << description;
107}
108
109const char* cpptype_names_[FieldDescriptor::MAX_CPPTYPE + 1] = {
110 "INVALID_CPPTYPE",
111 "CPPTYPE_INT32",
112 "CPPTYPE_INT64",
113 "CPPTYPE_UINT32",
114 "CPPTYPE_UINT64",
115 "CPPTYPE_DOUBLE",
116 "CPPTYPE_FLOAT",
117 "CPPTYPE_BOOL",
118 "CPPTYPE_ENUM",
119 "CPPTYPE_STRING",
120 "CPPTYPE_MESSAGE"
121};
122
123static void ReportReflectionUsageTypeError(
124 const Descriptor* descriptor, const FieldDescriptor* field,
125 const char* method,
126 FieldDescriptor::CppType expected_type) {
127 GOOGLE_LOG(FATAL)
128 << "Protocol Buffer reflection usage error:\n"
temporal779f61c2008-08-13 03:15:00 +0000129 " Method : google::protobuf::Reflection::" << method << "\n"
temporal40ee5512008-07-10 02:12:20 +0000130 " Message type: " << descriptor->full_name() << "\n"
131 " Field : " << field->full_name() << "\n"
132 " Problem : Field is not the right type for this message:\n"
133 " Expected : " << cpptype_names_[expected_type] << "\n"
134 " Field type: " << cpptype_names_[field->cpp_type()];
135}
136
137static void ReportReflectionUsageEnumTypeError(
138 const Descriptor* descriptor, const FieldDescriptor* field,
139 const char* method, const EnumValueDescriptor* value) {
140 GOOGLE_LOG(FATAL)
141 << "Protocol Buffer reflection usage error:\n"
temporal779f61c2008-08-13 03:15:00 +0000142 " Method : google::protobuf::Reflection::" << method << "\n"
temporal40ee5512008-07-10 02:12:20 +0000143 " Message type: " << descriptor->full_name() << "\n"
144 " Field : " << field->full_name() << "\n"
145 " Problem : Enum value did not match field type:\n"
146 " Expected : " << field->enum_type()->full_name() << "\n"
147 " Actual : " << value->full_name();
148}
149
150#define USAGE_CHECK(CONDITION, METHOD, ERROR_DESCRIPTION) \
151 if (!(CONDITION)) \
152 ReportReflectionUsageError(descriptor_, field, #METHOD, ERROR_DESCRIPTION)
153#define USAGE_CHECK_EQ(A, B, METHOD, ERROR_DESCRIPTION) \
154 USAGE_CHECK((A) == (B), METHOD, ERROR_DESCRIPTION)
155#define USAGE_CHECK_NE(A, B, METHOD, ERROR_DESCRIPTION) \
156 USAGE_CHECK((A) != (B), METHOD, ERROR_DESCRIPTION)
157
158#define USAGE_CHECK_TYPE(METHOD, CPPTYPE) \
159 if (field->cpp_type() != FieldDescriptor::CPPTYPE_##CPPTYPE) \
160 ReportReflectionUsageTypeError(descriptor_, field, #METHOD, \
161 FieldDescriptor::CPPTYPE_##CPPTYPE)
162
163#define USAGE_CHECK_ENUM_VALUE(METHOD) \
164 if (value->type() != field->enum_type()) \
165 ReportReflectionUsageEnumTypeError(descriptor_, field, #METHOD, value)
166
167#define USAGE_CHECK_MESSAGE_TYPE(METHOD) \
168 USAGE_CHECK_EQ(field->containing_type(), descriptor_, \
169 METHOD, "Field does not match message type.");
170#define USAGE_CHECK_SINGULAR(METHOD) \
171 USAGE_CHECK_NE(field->label(), FieldDescriptor::LABEL_REPEATED, METHOD, \
172 "Field is repeated; the method requires a singular field.")
173#define USAGE_CHECK_REPEATED(METHOD) \
174 USAGE_CHECK_EQ(field->label(), FieldDescriptor::LABEL_REPEATED, METHOD, \
175 "Field is singular; the method requires a repeated field.")
176
177#define USAGE_CHECK_ALL(METHOD, LABEL, CPPTYPE) \
178 USAGE_CHECK_MESSAGE_TYPE(METHOD); \
179 USAGE_CHECK_##LABEL(METHOD); \
180 USAGE_CHECK_TYPE(METHOD, CPPTYPE)
181
182} // namespace
183
184// ===================================================================
185
186GeneratedMessageReflection::GeneratedMessageReflection(
187 const Descriptor* descriptor,
temporal779f61c2008-08-13 03:15:00 +0000188 const Message* default_instance,
189 const int offsets[],
190 int has_bits_offset,
191 int unknown_fields_offset,
192 int extensions_offset,
kenton@google.com26bd9ee2008-11-21 00:06:27 +0000193 const DescriptorPool* descriptor_pool,
kenton@google.comd37d46d2009-04-25 02:53:47 +0000194 MessageFactory* factory,
Feng Xiao6ef984a2014-11-10 17:34:54 -0800195 int object_size,
Feng Xiaoc25d9fe2014-11-26 16:15:29 -0800196 int arena_offset,
197 int is_default_instance_offset)
temporal779f61c2008-08-13 03:15:00 +0000198 : descriptor_ (descriptor),
199 default_instance_ (default_instance),
200 offsets_ (offsets),
201 has_bits_offset_ (has_bits_offset),
202 unknown_fields_offset_(unknown_fields_offset),
203 extensions_offset_(extensions_offset),
Feng Xiao6ef984a2014-11-10 17:34:54 -0800204 arena_offset_ (arena_offset),
Feng Xiaoc25d9fe2014-11-26 16:15:29 -0800205 is_default_instance_offset_(is_default_instance_offset),
kenton@google.com26bd9ee2008-11-21 00:06:27 +0000206 object_size_ (object_size),
temporal779f61c2008-08-13 03:15:00 +0000207 descriptor_pool_ ((descriptor_pool == NULL) ?
208 DescriptorPool::generated_pool() :
kenton@google.comd37d46d2009-04-25 02:53:47 +0000209 descriptor_pool),
210 message_factory_ (factory) {
temporal40ee5512008-07-10 02:12:20 +0000211}
212
jieluo@google.com4de8f552014-07-18 00:47:59 +0000213GeneratedMessageReflection::GeneratedMessageReflection(
214 const Descriptor* descriptor,
215 const Message* default_instance,
216 const int offsets[],
217 int has_bits_offset,
218 int unknown_fields_offset,
219 int extensions_offset,
220 const void* default_oneof_instance,
221 int oneof_case_offset,
222 const DescriptorPool* descriptor_pool,
223 MessageFactory* factory,
Feng Xiao6ef984a2014-11-10 17:34:54 -0800224 int object_size,
Feng Xiaoc25d9fe2014-11-26 16:15:29 -0800225 int arena_offset,
226 int is_default_instance_offset)
jieluo@google.com4de8f552014-07-18 00:47:59 +0000227 : descriptor_ (descriptor),
228 default_instance_ (default_instance),
229 default_oneof_instance_ (default_oneof_instance),
230 offsets_ (offsets),
231 has_bits_offset_ (has_bits_offset),
232 oneof_case_offset_(oneof_case_offset),
233 unknown_fields_offset_(unknown_fields_offset),
234 extensions_offset_(extensions_offset),
Feng Xiao6ef984a2014-11-10 17:34:54 -0800235 arena_offset_ (arena_offset),
Feng Xiaoc25d9fe2014-11-26 16:15:29 -0800236 is_default_instance_offset_(is_default_instance_offset),
jieluo@google.com4de8f552014-07-18 00:47:59 +0000237 object_size_ (object_size),
238 descriptor_pool_ ((descriptor_pool == NULL) ?
239 DescriptorPool::generated_pool() :
240 descriptor_pool),
241 message_factory_ (factory) {
242}
243
temporal40ee5512008-07-10 02:12:20 +0000244GeneratedMessageReflection::~GeneratedMessageReflection() {}
245
Feng Xiao6ef984a2014-11-10 17:34:54 -0800246namespace {
247UnknownFieldSet* empty_unknown_field_set_ = NULL;
248GOOGLE_PROTOBUF_DECLARE_ONCE(empty_unknown_field_set_once_);
249
Jisi Liu7a00a1e2015-02-21 17:28:51 -0800250void DeleteEmptyUnknownFieldSet() {
251 delete empty_unknown_field_set_;
252 empty_unknown_field_set_ = NULL;
253}
254
Feng Xiao6ef984a2014-11-10 17:34:54 -0800255void InitEmptyUnknownFieldSet() {
256 empty_unknown_field_set_ = new UnknownFieldSet;
Jisi Liu7a00a1e2015-02-21 17:28:51 -0800257 internal::OnShutdown(&DeleteEmptyUnknownFieldSet);
Feng Xiao6ef984a2014-11-10 17:34:54 -0800258}
259
260const UnknownFieldSet& GetEmptyUnknownFieldSet() {
261 ::google::protobuf::GoogleOnceInit(&empty_unknown_field_set_once_, &InitEmptyUnknownFieldSet);
262 return *empty_unknown_field_set_;
263}
264} // namespace
265
temporal779f61c2008-08-13 03:15:00 +0000266const UnknownFieldSet& GeneratedMessageReflection::GetUnknownFields(
267 const Message& message) const {
Feng Xiao6ef984a2014-11-10 17:34:54 -0800268 if (descriptor_->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) {
269 return GetEmptyUnknownFieldSet();
270 }
271 if (unknown_fields_offset_ == kUnknownFieldSetInMetadata) {
272 return GetInternalMetadataWithArena(message).unknown_fields();
273 }
temporal779f61c2008-08-13 03:15:00 +0000274 const void* ptr = reinterpret_cast<const uint8*>(&message) +
275 unknown_fields_offset_;
276 return *reinterpret_cast<const UnknownFieldSet*>(ptr);
temporal40ee5512008-07-10 02:12:20 +0000277}
Feng Xiao6ef984a2014-11-10 17:34:54 -0800278
temporal779f61c2008-08-13 03:15:00 +0000279UnknownFieldSet* GeneratedMessageReflection::MutableUnknownFields(
280 Message* message) const {
Feng Xiao6ef984a2014-11-10 17:34:54 -0800281 if (unknown_fields_offset_ == kUnknownFieldSetInMetadata) {
282 return MutableInternalMetadataWithArena(message)->
283 mutable_unknown_fields();
284 }
temporal779f61c2008-08-13 03:15:00 +0000285 void* ptr = reinterpret_cast<uint8*>(message) + unknown_fields_offset_;
286 return reinterpret_cast<UnknownFieldSet*>(ptr);
temporal40ee5512008-07-10 02:12:20 +0000287}
288
kenton@google.com26bd9ee2008-11-21 00:06:27 +0000289int GeneratedMessageReflection::SpaceUsed(const Message& message) const {
290 // object_size_ already includes the in-memory representation of each field
291 // in the message, so we only need to account for additional memory used by
292 // the fields.
293 int total_size = object_size_;
294
295 total_size += GetUnknownFields(message).SpaceUsedExcludingSelf();
296
297 if (extensions_offset_ != -1) {
298 total_size += GetExtensionSet(message).SpaceUsedExcludingSelf();
299 }
300
301 for (int i = 0; i < descriptor_->field_count(); i++) {
302 const FieldDescriptor* field = descriptor_->field(i);
303
304 if (field->is_repeated()) {
kenton@google.com80b1d622009-07-29 01:13:20 +0000305 switch (field->cpp_type()) {
306#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
307 case FieldDescriptor::CPPTYPE_##UPPERCASE : \
308 total_size += GetRaw<RepeatedField<LOWERCASE> >(message, field) \
309 .SpaceUsedExcludingSelf(); \
310 break
311
312 HANDLE_TYPE( INT32, int32);
313 HANDLE_TYPE( INT64, int64);
314 HANDLE_TYPE(UINT32, uint32);
315 HANDLE_TYPE(UINT64, uint64);
316 HANDLE_TYPE(DOUBLE, double);
317 HANDLE_TYPE( FLOAT, float);
318 HANDLE_TYPE( BOOL, bool);
319 HANDLE_TYPE( ENUM, int);
320#undef HANDLE_TYPE
321
322 case FieldDescriptor::CPPTYPE_STRING:
kenton@google.comfccb1462009-12-18 02:11:36 +0000323 switch (field->options().ctype()) {
324 default: // TODO(kenton): Support other string reps.
325 case FieldOptions::STRING:
326 total_size += GetRaw<RepeatedPtrField<string> >(message, field)
327 .SpaceUsedExcludingSelf();
328 break;
329 }
kenton@google.com80b1d622009-07-29 01:13:20 +0000330 break;
331
332 case FieldDescriptor::CPPTYPE_MESSAGE:
Feng Xiaof157a562014-11-14 11:50:31 -0800333 if (IsMapFieldInApi(field)) {
334 total_size +=
335 GetRaw<MapFieldBase>(message, field).SpaceUsedExcludingSelf();
336 } else {
337 // We don't know which subclass of RepeatedPtrFieldBase the type is,
338 // so we use RepeatedPtrFieldBase directly.
339 total_size +=
340 GetRaw<RepeatedPtrFieldBase>(message, field)
341 .SpaceUsedExcludingSelf<GenericTypeHandler<Message> >();
342 }
343
kenton@google.com80b1d622009-07-29 01:13:20 +0000344 break;
345 }
kenton@google.com26bd9ee2008-11-21 00:06:27 +0000346 } else {
jieluo@google.com4de8f552014-07-18 00:47:59 +0000347 if (field->containing_oneof() && !HasOneofField(message, field)) {
348 continue;
349 }
kenton@google.com26bd9ee2008-11-21 00:06:27 +0000350 switch (field->cpp_type()) {
351 case FieldDescriptor::CPPTYPE_INT32 :
352 case FieldDescriptor::CPPTYPE_INT64 :
353 case FieldDescriptor::CPPTYPE_UINT32:
354 case FieldDescriptor::CPPTYPE_UINT64:
355 case FieldDescriptor::CPPTYPE_DOUBLE:
356 case FieldDescriptor::CPPTYPE_FLOAT :
357 case FieldDescriptor::CPPTYPE_BOOL :
358 case FieldDescriptor::CPPTYPE_ENUM :
359 // Field is inline, so we've already counted it.
360 break;
361
362 case FieldDescriptor::CPPTYPE_STRING: {
kenton@google.comfccb1462009-12-18 02:11:36 +0000363 switch (field->options().ctype()) {
364 default: // TODO(kenton): Support other string reps.
365 case FieldOptions::STRING: {
kenton@google.comfccb1462009-12-18 02:11:36 +0000366 // Initially, the string points to the default value stored in
367 // the prototype. Only count the string if it has been changed
368 // from the default value.
Feng Xiao6ef984a2014-11-10 17:34:54 -0800369 const string* default_ptr =
370 &DefaultRaw<ArenaStringPtr>(field).Get(NULL);
371 const string* ptr =
372 &GetField<ArenaStringPtr>(message, field).Get(default_ptr);
kenton@google.com26bd9ee2008-11-21 00:06:27 +0000373
kenton@google.comfccb1462009-12-18 02:11:36 +0000374 if (ptr != default_ptr) {
375 // string fields are represented by just a pointer, so also
376 // include sizeof(string) as well.
377 total_size += sizeof(*ptr) + StringSpaceUsedExcludingSelf(*ptr);
378 }
379 break;
kenton@google.com26bd9ee2008-11-21 00:06:27 +0000380 }
kenton@google.comfccb1462009-12-18 02:11:36 +0000381 }
kenton@google.com26bd9ee2008-11-21 00:06:27 +0000382 break;
383 }
384
385 case FieldDescriptor::CPPTYPE_MESSAGE:
386 if (&message == default_instance_) {
387 // For singular fields, the prototype just stores a pointer to the
388 // external type's prototype, so there is no extra memory usage.
389 } else {
390 const Message* sub_message = GetRaw<const Message*>(message, field);
391 if (sub_message != NULL) {
392 total_size += sub_message->SpaceUsed();
393 }
394 }
395 break;
396 }
397 }
398 }
399
400 return total_size;
401}
402
jieluo@google.com4de8f552014-07-18 00:47:59 +0000403void GeneratedMessageReflection::SwapField(
404 Message* message1,
405 Message* message2,
406 const FieldDescriptor* field) const {
407 if (field->is_repeated()) {
408 switch (field->cpp_type()) {
409#define SWAP_ARRAYS(CPPTYPE, TYPE) \
410 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
411 MutableRaw<RepeatedField<TYPE> >(message1, field)->Swap( \
412 MutableRaw<RepeatedField<TYPE> >(message2, field)); \
413 break;
414
415 SWAP_ARRAYS(INT32 , int32 );
416 SWAP_ARRAYS(INT64 , int64 );
417 SWAP_ARRAYS(UINT32, uint32);
418 SWAP_ARRAYS(UINT64, uint64);
419 SWAP_ARRAYS(FLOAT , float );
420 SWAP_ARRAYS(DOUBLE, double);
421 SWAP_ARRAYS(BOOL , bool );
422 SWAP_ARRAYS(ENUM , int );
423#undef SWAP_ARRAYS
424
425 case FieldDescriptor::CPPTYPE_STRING:
426 case FieldDescriptor::CPPTYPE_MESSAGE:
Feng Xiaof157a562014-11-14 11:50:31 -0800427 if (IsMapFieldInApi(field)) {
428 MutableRaw<MapFieldBase>(message1, field)->
429 MutableRepeatedField()->
430 Swap<GenericTypeHandler<google::protobuf::Message> >(
431 MutableRaw<MapFieldBase>(message2, field)->
432 MutableRepeatedField());
433 } else {
434 MutableRaw<RepeatedPtrFieldBase>(message1, field)->
Feng Xiao6ef984a2014-11-10 17:34:54 -0800435 Swap<GenericTypeHandler<google::protobuf::Message> >(
436 MutableRaw<RepeatedPtrFieldBase>(message2, field));
Feng Xiaof157a562014-11-14 11:50:31 -0800437 }
jieluo@google.com4de8f552014-07-18 00:47:59 +0000438 break;
439
440 default:
441 GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
442 }
443 } else {
444 switch (field->cpp_type()) {
445#define SWAP_VALUES(CPPTYPE, TYPE) \
446 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
447 std::swap(*MutableRaw<TYPE>(message1, field), \
448 *MutableRaw<TYPE>(message2, field)); \
449 break;
450
451 SWAP_VALUES(INT32 , int32 );
452 SWAP_VALUES(INT64 , int64 );
453 SWAP_VALUES(UINT32, uint32);
454 SWAP_VALUES(UINT64, uint64);
455 SWAP_VALUES(FLOAT , float );
456 SWAP_VALUES(DOUBLE, double);
457 SWAP_VALUES(BOOL , bool );
458 SWAP_VALUES(ENUM , int );
459#undef SWAP_VALUES
460 case FieldDescriptor::CPPTYPE_MESSAGE:
461 std::swap(*MutableRaw<Message*>(message1, field),
462 *MutableRaw<Message*>(message2, field));
463 break;
464
465 case FieldDescriptor::CPPTYPE_STRING:
466 switch (field->options().ctype()) {
467 default: // TODO(kenton): Support other string reps.
468 case FieldOptions::STRING:
Feng Xiao6ef984a2014-11-10 17:34:54 -0800469 MutableRaw<ArenaStringPtr>(message1, field)->Swap(
470 MutableRaw<ArenaStringPtr>(message2, field));
jieluo@google.com4de8f552014-07-18 00:47:59 +0000471 break;
472 }
473 break;
474
475 default:
476 GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
477 }
478 }
479}
480
481void GeneratedMessageReflection::SwapOneofField(
482 Message* message1,
483 Message* message2,
484 const OneofDescriptor* oneof_descriptor) const {
485 uint32 oneof_case1 = GetOneofCase(*message1, oneof_descriptor);
486 uint32 oneof_case2 = GetOneofCase(*message2, oneof_descriptor);
487
488 int32 temp_int32;
489 int64 temp_int64;
490 uint32 temp_uint32;
491 uint64 temp_uint64;
492 float temp_float;
493 double temp_double;
494 bool temp_bool;
495 int temp_int;
Feng Xiao9173ba22014-12-02 15:28:11 -0800496 Message* temp_message = NULL;
jieluo@google.com4de8f552014-07-18 00:47:59 +0000497 string temp_string;
498
499 // Stores message1's oneof field to a temp variable.
Feng Xiao9173ba22014-12-02 15:28:11 -0800500 const FieldDescriptor* field1 = NULL;
jieluo@google.com4de8f552014-07-18 00:47:59 +0000501 if (oneof_case1 > 0) {
502 field1 = descriptor_->FindFieldByNumber(oneof_case1);
503 //oneof_descriptor->field(oneof_case1);
504 switch (field1->cpp_type()) {
505#define GET_TEMP_VALUE(CPPTYPE, TYPE) \
506 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
507 temp_##TYPE = GetField<TYPE>(*message1, field1); \
508 break;
509
510 GET_TEMP_VALUE(INT32 , int32 );
511 GET_TEMP_VALUE(INT64 , int64 );
512 GET_TEMP_VALUE(UINT32, uint32);
513 GET_TEMP_VALUE(UINT64, uint64);
514 GET_TEMP_VALUE(FLOAT , float );
515 GET_TEMP_VALUE(DOUBLE, double);
516 GET_TEMP_VALUE(BOOL , bool );
517 GET_TEMP_VALUE(ENUM , int );
518#undef GET_TEMP_VALUE
519 case FieldDescriptor::CPPTYPE_MESSAGE:
520 temp_message = ReleaseMessage(message1, field1);
521 break;
522
523 case FieldDescriptor::CPPTYPE_STRING:
524 temp_string = GetString(*message1, field1);
525 break;
526
527 default:
528 GOOGLE_LOG(FATAL) << "Unimplemented type: " << field1->cpp_type();
529 }
530 }
531
532 // Sets message1's oneof field from the message2's oneof field.
533 if (oneof_case2 > 0) {
534 const FieldDescriptor* field2 =
535 descriptor_->FindFieldByNumber(oneof_case2);
536 switch (field2->cpp_type()) {
537#define SET_ONEOF_VALUE1(CPPTYPE, TYPE) \
538 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
539 SetField<TYPE>(message1, field2, GetField<TYPE>(*message2, field2)); \
540 break;
541
542 SET_ONEOF_VALUE1(INT32 , int32 );
543 SET_ONEOF_VALUE1(INT64 , int64 );
544 SET_ONEOF_VALUE1(UINT32, uint32);
545 SET_ONEOF_VALUE1(UINT64, uint64);
546 SET_ONEOF_VALUE1(FLOAT , float );
547 SET_ONEOF_VALUE1(DOUBLE, double);
548 SET_ONEOF_VALUE1(BOOL , bool );
549 SET_ONEOF_VALUE1(ENUM , int );
550#undef SET_ONEOF_VALUE1
551 case FieldDescriptor::CPPTYPE_MESSAGE:
552 SetAllocatedMessage(message1,
553 ReleaseMessage(message2, field2),
554 field2);
555 break;
556
557 case FieldDescriptor::CPPTYPE_STRING:
558 SetString(message1, field2, GetString(*message2, field2));
559 break;
560
561 default:
562 GOOGLE_LOG(FATAL) << "Unimplemented type: " << field2->cpp_type();
563 }
564 } else {
565 ClearOneof(message1, oneof_descriptor);
566 }
567
568 // Sets message2's oneof field from the temp variable.
569 if (oneof_case1 > 0) {
570 switch (field1->cpp_type()) {
571#define SET_ONEOF_VALUE2(CPPTYPE, TYPE) \
572 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
573 SetField<TYPE>(message2, field1, temp_##TYPE); \
574 break;
575
576 SET_ONEOF_VALUE2(INT32 , int32 );
577 SET_ONEOF_VALUE2(INT64 , int64 );
578 SET_ONEOF_VALUE2(UINT32, uint32);
579 SET_ONEOF_VALUE2(UINT64, uint64);
580 SET_ONEOF_VALUE2(FLOAT , float );
581 SET_ONEOF_VALUE2(DOUBLE, double);
582 SET_ONEOF_VALUE2(BOOL , bool );
583 SET_ONEOF_VALUE2(ENUM , int );
584#undef SET_ONEOF_VALUE2
585 case FieldDescriptor::CPPTYPE_MESSAGE:
586 SetAllocatedMessage(message2, temp_message, field1);
587 break;
588
589 case FieldDescriptor::CPPTYPE_STRING:
590 SetString(message2, field1, temp_string);
591 break;
592
593 default:
594 GOOGLE_LOG(FATAL) << "Unimplemented type: " << field1->cpp_type();
595 }
596 } else {
597 ClearOneof(message2, oneof_descriptor);
598 }
599}
600
kenton@google.comceb561d2009-06-25 19:05:36 +0000601void GeneratedMessageReflection::Swap(
602 Message* message1,
603 Message* message2) const {
604 if (message1 == message2) return;
605
kenton@google.com80b1d622009-07-29 01:13:20 +0000606 // TODO(kenton): Other Reflection methods should probably check this too.
kenton@google.comceb561d2009-06-25 19:05:36 +0000607 GOOGLE_CHECK_EQ(message1->GetReflection(), this)
kenton@google.com80b1d622009-07-29 01:13:20 +0000608 << "First argument to Swap() (of type \""
609 << message1->GetDescriptor()->full_name()
610 << "\") is not compatible with this reflection object (which is for type \""
611 << descriptor_->full_name()
612 << "\"). Note that the exact same class is required; not just the same "
613 "descriptor.";
kenton@google.comceb561d2009-06-25 19:05:36 +0000614 GOOGLE_CHECK_EQ(message2->GetReflection(), this)
kenton@google.com80b1d622009-07-29 01:13:20 +0000615 << "Second argument to Swap() (of type \""
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000616 << message2->GetDescriptor()->full_name()
kenton@google.com80b1d622009-07-29 01:13:20 +0000617 << "\") is not compatible with this reflection object (which is for type \""
618 << descriptor_->full_name()
619 << "\"). Note that the exact same class is required; not just the same "
620 "descriptor.";
kenton@google.comceb561d2009-06-25 19:05:36 +0000621
Feng Xiao6ef984a2014-11-10 17:34:54 -0800622 // Check that both messages are in the same arena (or both on the heap). We
623 // need to copy all data if not, due to ownership semantics.
624 if (GetArena(message1) != GetArena(message2)) {
625 // Slow copy path.
626 // Use our arena as temp space, if available.
627 Message* temp = message1->New(GetArena(message1));
628 temp->MergeFrom(*message1);
629 message1->CopyFrom(*message2);
630 message2->CopyFrom(*temp);
631 if (GetArena(message1) == NULL) {
632 delete temp;
633 }
634 return;
635 }
kenton@google.comceb561d2009-06-25 19:05:36 +0000636
Feng Xiao6ef984a2014-11-10 17:34:54 -0800637 if (has_bits_offset_ != -1) {
638 uint32* has_bits1 = MutableHasBits(message1);
639 uint32* has_bits2 = MutableHasBits(message2);
640 int has_bits_size = (descriptor_->field_count() + 31) / 32;
641
642 for (int i = 0; i < has_bits_size; i++) {
643 std::swap(has_bits1[i], has_bits2[i]);
644 }
kenton@google.comceb561d2009-06-25 19:05:36 +0000645 }
646
647 for (int i = 0; i < descriptor_->field_count(); i++) {
648 const FieldDescriptor* field = descriptor_->field(i);
jieluo@google.com4de8f552014-07-18 00:47:59 +0000649 if (!field->containing_oneof()) {
650 SwapField(message1, message2, field);
kenton@google.comceb561d2009-06-25 19:05:36 +0000651 }
652 }
653
jieluo@google.com4de8f552014-07-18 00:47:59 +0000654 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
655 SwapOneofField(message1, message2, descriptor_->oneof_decl(i));
656 }
657
kenton@google.comceb561d2009-06-25 19:05:36 +0000658 if (extensions_offset_ != -1) {
659 MutableExtensionSet(message1)->Swap(MutableExtensionSet(message2));
660 }
661
662 MutableUnknownFields(message1)->Swap(MutableUnknownFields(message2));
663}
664
jieluo@google.com4de8f552014-07-18 00:47:59 +0000665void GeneratedMessageReflection::SwapFields(
666 Message* message1,
667 Message* message2,
668 const vector<const FieldDescriptor*>& fields) const {
669 if (message1 == message2) return;
670
671 // TODO(kenton): Other Reflection methods should probably check this too.
672 GOOGLE_CHECK_EQ(message1->GetReflection(), this)
673 << "First argument to SwapFields() (of type \""
674 << message1->GetDescriptor()->full_name()
675 << "\") is not compatible with this reflection object (which is for type \""
676 << descriptor_->full_name()
677 << "\"). Note that the exact same class is required; not just the same "
678 "descriptor.";
679 GOOGLE_CHECK_EQ(message2->GetReflection(), this)
680 << "Second argument to SwapFields() (of type \""
681 << message2->GetDescriptor()->full_name()
682 << "\") is not compatible with this reflection object (which is for type \""
683 << descriptor_->full_name()
684 << "\"). Note that the exact same class is required; not just the same "
685 "descriptor.";
686
687 std::set<int> swapped_oneof;
688
689 for (int i = 0; i < fields.size(); i++) {
690 const FieldDescriptor* field = fields[i];
691 if (field->is_extension()) {
692 MutableExtensionSet(message1)->SwapExtension(
693 MutableExtensionSet(message2),
694 field->number());
695 } else {
696 if (field->containing_oneof()) {
697 int oneof_index = field->containing_oneof()->index();
698 // Only swap the oneof field once.
699 if (swapped_oneof.find(oneof_index) != swapped_oneof.end()) {
700 continue;
701 }
702 swapped_oneof.insert(oneof_index);
703 SwapOneofField(message1, message2, field->containing_oneof());
704 } else {
705 // Swap has bit.
706 SwapBit(message1, message2, field);
707 // Swap field.
708 SwapField(message1, message2, field);
709 }
710 }
711 }
712}
713
temporal40ee5512008-07-10 02:12:20 +0000714// -------------------------------------------------------------------
715
temporal779f61c2008-08-13 03:15:00 +0000716bool GeneratedMessageReflection::HasField(const Message& message,
717 const FieldDescriptor* field) const {
temporal40ee5512008-07-10 02:12:20 +0000718 USAGE_CHECK_MESSAGE_TYPE(HasField);
719 USAGE_CHECK_SINGULAR(HasField);
720
721 if (field->is_extension()) {
temporal779f61c2008-08-13 03:15:00 +0000722 return GetExtensionSet(message).Has(field->number());
temporal40ee5512008-07-10 02:12:20 +0000723 } else {
jieluo@google.com4de8f552014-07-18 00:47:59 +0000724 if (field->containing_oneof()) {
725 return HasOneofField(message, field);
726 } else {
727 return HasBit(message, field);
728 }
temporal40ee5512008-07-10 02:12:20 +0000729 }
730}
731
temporal779f61c2008-08-13 03:15:00 +0000732int GeneratedMessageReflection::FieldSize(const Message& message,
733 const FieldDescriptor* field) const {
kenton@google.comceb561d2009-06-25 19:05:36 +0000734 USAGE_CHECK_MESSAGE_TYPE(FieldSize);
735 USAGE_CHECK_REPEATED(FieldSize);
temporal40ee5512008-07-10 02:12:20 +0000736
737 if (field->is_extension()) {
temporal779f61c2008-08-13 03:15:00 +0000738 return GetExtensionSet(message).ExtensionSize(field->number());
temporal40ee5512008-07-10 02:12:20 +0000739 } else {
kenton@google.com80b1d622009-07-29 01:13:20 +0000740 switch (field->cpp_type()) {
741#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
742 case FieldDescriptor::CPPTYPE_##UPPERCASE : \
743 return GetRaw<RepeatedField<LOWERCASE> >(message, field).size()
744
745 HANDLE_TYPE( INT32, int32);
746 HANDLE_TYPE( INT64, int64);
747 HANDLE_TYPE(UINT32, uint32);
748 HANDLE_TYPE(UINT64, uint64);
749 HANDLE_TYPE(DOUBLE, double);
750 HANDLE_TYPE( FLOAT, float);
751 HANDLE_TYPE( BOOL, bool);
752 HANDLE_TYPE( ENUM, int);
753#undef HANDLE_TYPE
754
755 case FieldDescriptor::CPPTYPE_STRING:
756 case FieldDescriptor::CPPTYPE_MESSAGE:
Feng Xiaof157a562014-11-14 11:50:31 -0800757 if (IsMapFieldInApi(field)) {
758 return GetRaw<MapFieldBase>(message, field).GetRepeatedField().size();
759 } else {
760 return GetRaw<RepeatedPtrFieldBase>(message, field).size();
761 }
kenton@google.com80b1d622009-07-29 01:13:20 +0000762 }
763
764 GOOGLE_LOG(FATAL) << "Can't get here.";
765 return 0;
temporal40ee5512008-07-10 02:12:20 +0000766 }
767}
768
temporal779f61c2008-08-13 03:15:00 +0000769void GeneratedMessageReflection::ClearField(
770 Message* message, const FieldDescriptor* field) const {
temporal40ee5512008-07-10 02:12:20 +0000771 USAGE_CHECK_MESSAGE_TYPE(ClearField);
772
773 if (field->is_extension()) {
temporal779f61c2008-08-13 03:15:00 +0000774 MutableExtensionSet(message)->ClearExtension(field->number());
temporal40ee5512008-07-10 02:12:20 +0000775 } else if (!field->is_repeated()) {
jieluo@google.com4de8f552014-07-18 00:47:59 +0000776 if (field->containing_oneof()) {
777 ClearOneofField(message, field);
778 return;
779 }
780
temporal779f61c2008-08-13 03:15:00 +0000781 if (HasBit(*message, field)) {
782 ClearBit(message, field);
temporal40ee5512008-07-10 02:12:20 +0000783
784 // We need to set the field back to its default value.
785 switch (field->cpp_type()) {
786#define CLEAR_TYPE(CPPTYPE, TYPE) \
787 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
temporal779f61c2008-08-13 03:15:00 +0000788 *MutableRaw<TYPE>(message, field) = \
789 field->default_value_##TYPE(); \
temporal40ee5512008-07-10 02:12:20 +0000790 break;
791
792 CLEAR_TYPE(INT32 , int32 );
793 CLEAR_TYPE(INT64 , int64 );
794 CLEAR_TYPE(UINT32, uint32);
795 CLEAR_TYPE(UINT64, uint64);
796 CLEAR_TYPE(FLOAT , float );
797 CLEAR_TYPE(DOUBLE, double);
798 CLEAR_TYPE(BOOL , bool );
799#undef CLEAR_TYPE
800
801 case FieldDescriptor::CPPTYPE_ENUM:
temporal779f61c2008-08-13 03:15:00 +0000802 *MutableRaw<int>(message, field) =
803 field->default_value_enum()->number();
temporal40ee5512008-07-10 02:12:20 +0000804 break;
805
806 case FieldDescriptor::CPPTYPE_STRING: {
kenton@google.comfccb1462009-12-18 02:11:36 +0000807 switch (field->options().ctype()) {
808 default: // TODO(kenton): Support other string reps.
Feng Xiao6ef984a2014-11-10 17:34:54 -0800809 case FieldOptions::STRING: {
810 const string* default_ptr =
811 &DefaultRaw<ArenaStringPtr>(field).Get(NULL);
812 MutableRaw<ArenaStringPtr>(message, field)->Destroy(default_ptr,
813 GetArena(message));
kenton@google.comfccb1462009-12-18 02:11:36 +0000814 break;
Feng Xiao6ef984a2014-11-10 17:34:54 -0800815 }
kenton@google.comfccb1462009-12-18 02:11:36 +0000816 }
temporal40ee5512008-07-10 02:12:20 +0000817 break;
818 }
819
820 case FieldDescriptor::CPPTYPE_MESSAGE:
temporal779f61c2008-08-13 03:15:00 +0000821 (*MutableRaw<Message*>(message, field))->Clear();
temporal40ee5512008-07-10 02:12:20 +0000822 break;
823 }
824 }
825 } else {
kenton@google.com80b1d622009-07-29 01:13:20 +0000826 switch (field->cpp_type()) {
827#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
828 case FieldDescriptor::CPPTYPE_##UPPERCASE : \
829 MutableRaw<RepeatedField<LOWERCASE> >(message, field)->Clear(); \
830 break
831
832 HANDLE_TYPE( INT32, int32);
833 HANDLE_TYPE( INT64, int64);
834 HANDLE_TYPE(UINT32, uint32);
835 HANDLE_TYPE(UINT64, uint64);
836 HANDLE_TYPE(DOUBLE, double);
837 HANDLE_TYPE( FLOAT, float);
838 HANDLE_TYPE( BOOL, bool);
839 HANDLE_TYPE( ENUM, int);
840#undef HANDLE_TYPE
841
842 case FieldDescriptor::CPPTYPE_STRING: {
kenton@google.comfccb1462009-12-18 02:11:36 +0000843 switch (field->options().ctype()) {
844 default: // TODO(kenton): Support other string reps.
845 case FieldOptions::STRING:
846 MutableRaw<RepeatedPtrField<string> >(message, field)->Clear();
847 break;
848 }
kenton@google.com80b1d622009-07-29 01:13:20 +0000849 break;
850 }
851
852 case FieldDescriptor::CPPTYPE_MESSAGE: {
Feng Xiaof157a562014-11-14 11:50:31 -0800853 if (IsMapFieldInApi(field)) {
854 MutableRaw<MapFieldBase>(message, field)
855 ->MutableRepeatedField()
856 ->Clear<GenericTypeHandler<Message> >();
857 } else {
858 // We don't know which subclass of RepeatedPtrFieldBase the type is,
859 // so we use RepeatedPtrFieldBase directly.
860 MutableRaw<RepeatedPtrFieldBase>(message, field)
861 ->Clear<GenericTypeHandler<Message> >();
862 }
kenton@google.com80b1d622009-07-29 01:13:20 +0000863 break;
864 }
865 }
temporal40ee5512008-07-10 02:12:20 +0000866 }
867}
868
kenton@google.comceb561d2009-06-25 19:05:36 +0000869void GeneratedMessageReflection::RemoveLast(
870 Message* message,
871 const FieldDescriptor* field) const {
872 USAGE_CHECK_MESSAGE_TYPE(RemoveLast);
873 USAGE_CHECK_REPEATED(RemoveLast);
874
875 if (field->is_extension()) {
876 MutableExtensionSet(message)->RemoveLast(field->number());
877 } else {
kenton@google.com80b1d622009-07-29 01:13:20 +0000878 switch (field->cpp_type()) {
879#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
880 case FieldDescriptor::CPPTYPE_##UPPERCASE : \
881 MutableRaw<RepeatedField<LOWERCASE> >(message, field)->RemoveLast(); \
882 break
883
884 HANDLE_TYPE( INT32, int32);
885 HANDLE_TYPE( INT64, int64);
886 HANDLE_TYPE(UINT32, uint32);
887 HANDLE_TYPE(UINT64, uint64);
888 HANDLE_TYPE(DOUBLE, double);
889 HANDLE_TYPE( FLOAT, float);
890 HANDLE_TYPE( BOOL, bool);
891 HANDLE_TYPE( ENUM, int);
892#undef HANDLE_TYPE
893
894 case FieldDescriptor::CPPTYPE_STRING:
kenton@google.comfccb1462009-12-18 02:11:36 +0000895 switch (field->options().ctype()) {
896 default: // TODO(kenton): Support other string reps.
897 case FieldOptions::STRING:
898 MutableRaw<RepeatedPtrField<string> >(message, field)->RemoveLast();
899 break;
900 }
kenton@google.com80b1d622009-07-29 01:13:20 +0000901 break;
902
903 case FieldDescriptor::CPPTYPE_MESSAGE:
Feng Xiaof157a562014-11-14 11:50:31 -0800904 if (IsMapFieldInApi(field)) {
905 MutableRaw<MapFieldBase>(message, field)
906 ->MutableRepeatedField()
907 ->RemoveLast<GenericTypeHandler<Message> >();
908 } else {
909 MutableRaw<RepeatedPtrFieldBase>(message, field)
kenton@google.com80b1d622009-07-29 01:13:20 +0000910 ->RemoveLast<GenericTypeHandler<Message> >();
Feng Xiaof157a562014-11-14 11:50:31 -0800911 }
kenton@google.com80b1d622009-07-29 01:13:20 +0000912 break;
913 }
kenton@google.comceb561d2009-06-25 19:05:36 +0000914 }
915}
916
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000917Message* GeneratedMessageReflection::ReleaseLast(
918 Message* message,
919 const FieldDescriptor* field) const {
920 USAGE_CHECK_ALL(ReleaseLast, REPEATED, MESSAGE);
921
922 if (field->is_extension()) {
923 return static_cast<Message*>(
924 MutableExtensionSet(message)->ReleaseLast(field->number()));
925 } else {
Feng Xiaof157a562014-11-14 11:50:31 -0800926 if (IsMapFieldInApi(field)) {
927 return MutableRaw<MapFieldBase>(message, field)
928 ->MutableRepeatedField()
929 ->ReleaseLast<GenericTypeHandler<Message> >();
930 } else {
931 return MutableRaw<RepeatedPtrFieldBase>(message, field)
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000932 ->ReleaseLast<GenericTypeHandler<Message> >();
Feng Xiaof157a562014-11-14 11:50:31 -0800933 }
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000934 }
935}
936
kenton@google.comceb561d2009-06-25 19:05:36 +0000937void GeneratedMessageReflection::SwapElements(
938 Message* message,
939 const FieldDescriptor* field,
940 int index1,
941 int index2) const {
942 USAGE_CHECK_MESSAGE_TYPE(Swap);
943 USAGE_CHECK_REPEATED(Swap);
944
945 if (field->is_extension()) {
kenton@google.com80b1d622009-07-29 01:13:20 +0000946 MutableExtensionSet(message)->SwapElements(field->number(), index1, index2);
kenton@google.comceb561d2009-06-25 19:05:36 +0000947 } else {
kenton@google.com80b1d622009-07-29 01:13:20 +0000948 switch (field->cpp_type()) {
949#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
950 case FieldDescriptor::CPPTYPE_##UPPERCASE : \
951 MutableRaw<RepeatedField<LOWERCASE> >(message, field) \
952 ->SwapElements(index1, index2); \
953 break
954
955 HANDLE_TYPE( INT32, int32);
956 HANDLE_TYPE( INT64, int64);
957 HANDLE_TYPE(UINT32, uint32);
958 HANDLE_TYPE(UINT64, uint64);
959 HANDLE_TYPE(DOUBLE, double);
960 HANDLE_TYPE( FLOAT, float);
961 HANDLE_TYPE( BOOL, bool);
962 HANDLE_TYPE( ENUM, int);
963#undef HANDLE_TYPE
964
965 case FieldDescriptor::CPPTYPE_STRING:
966 case FieldDescriptor::CPPTYPE_MESSAGE:
Feng Xiaof157a562014-11-14 11:50:31 -0800967 if (IsMapFieldInApi(field)) {
968 MutableRaw<MapFieldBase>(message, field)
969 ->MutableRepeatedField()
970 ->SwapElements(index1, index2);
971 } else {
972 MutableRaw<RepeatedPtrFieldBase>(message, field)
kenton@google.com80b1d622009-07-29 01:13:20 +0000973 ->SwapElements(index1, index2);
Feng Xiaof157a562014-11-14 11:50:31 -0800974 }
kenton@google.com80b1d622009-07-29 01:13:20 +0000975 break;
976 }
kenton@google.comceb561d2009-06-25 19:05:36 +0000977 }
978}
979
temporal40ee5512008-07-10 02:12:20 +0000980namespace {
981// Comparison functor for sorting FieldDescriptors by field number.
982struct FieldNumberSorter {
983 bool operator()(const FieldDescriptor* left,
984 const FieldDescriptor* right) const {
985 return left->number() < right->number();
986 }
987};
988} // namespace
989
990void GeneratedMessageReflection::ListFields(
temporal779f61c2008-08-13 03:15:00 +0000991 const Message& message,
temporal40ee5512008-07-10 02:12:20 +0000992 vector<const FieldDescriptor*>* output) const {
993 output->clear();
994
995 // Optimization: The default instance never has any fields set.
temporal779f61c2008-08-13 03:15:00 +0000996 if (&message == default_instance_) return;
temporal40ee5512008-07-10 02:12:20 +0000997
Jisi Liu885b6122015-02-28 14:51:22 -0800998 output->reserve(descriptor_->field_count());
temporal40ee5512008-07-10 02:12:20 +0000999 for (int i = 0; i < descriptor_->field_count(); i++) {
1000 const FieldDescriptor* field = descriptor_->field(i);
1001 if (field->is_repeated()) {
kenton@google.com80b1d622009-07-29 01:13:20 +00001002 if (FieldSize(message, field) > 0) {
temporal40ee5512008-07-10 02:12:20 +00001003 output->push_back(field);
1004 }
1005 } else {
jieluo@google.com4de8f552014-07-18 00:47:59 +00001006 if (field->containing_oneof()) {
1007 if (HasOneofField(message, field)) {
1008 output->push_back(field);
1009 }
1010 } else if (HasBit(message, field)) {
temporal40ee5512008-07-10 02:12:20 +00001011 output->push_back(field);
1012 }
1013 }
1014 }
1015
temporal779f61c2008-08-13 03:15:00 +00001016 if (extensions_offset_ != -1) {
kenton@google.comd37d46d2009-04-25 02:53:47 +00001017 GetExtensionSet(message).AppendToList(descriptor_, descriptor_pool_,
1018 output);
temporal40ee5512008-07-10 02:12:20 +00001019 }
1020
1021 // ListFields() must sort output by field number.
Jisi Liu885b6122015-02-28 14:51:22 -08001022 std::sort(output->begin(), output->end(), FieldNumberSorter());
temporal40ee5512008-07-10 02:12:20 +00001023}
1024
1025// -------------------------------------------------------------------
1026
1027#undef DEFINE_PRIMITIVE_ACCESSORS
1028#define DEFINE_PRIMITIVE_ACCESSORS(TYPENAME, TYPE, PASSTYPE, CPPTYPE) \
1029 PASSTYPE GeneratedMessageReflection::Get##TYPENAME( \
temporal779f61c2008-08-13 03:15:00 +00001030 const Message& message, const FieldDescriptor* field) const { \
temporal40ee5512008-07-10 02:12:20 +00001031 USAGE_CHECK_ALL(Get##TYPENAME, SINGULAR, CPPTYPE); \
1032 if (field->is_extension()) { \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001033 return GetExtensionSet(message).Get##TYPENAME( \
1034 field->number(), field->default_value_##PASSTYPE()); \
temporal40ee5512008-07-10 02:12:20 +00001035 } else { \
temporal779f61c2008-08-13 03:15:00 +00001036 return GetField<TYPE>(message, field); \
temporal40ee5512008-07-10 02:12:20 +00001037 } \
1038 } \
1039 \
1040 void GeneratedMessageReflection::Set##TYPENAME( \
temporal779f61c2008-08-13 03:15:00 +00001041 Message* message, const FieldDescriptor* field, \
1042 PASSTYPE value) const { \
temporal40ee5512008-07-10 02:12:20 +00001043 USAGE_CHECK_ALL(Set##TYPENAME, SINGULAR, CPPTYPE); \
1044 if (field->is_extension()) { \
temporal779f61c2008-08-13 03:15:00 +00001045 return MutableExtensionSet(message)->Set##TYPENAME( \
kenton@google.comfccb1462009-12-18 02:11:36 +00001046 field->number(), field->type(), value, field); \
temporal40ee5512008-07-10 02:12:20 +00001047 } else { \
temporal779f61c2008-08-13 03:15:00 +00001048 SetField<TYPE>(message, field, value); \
temporal40ee5512008-07-10 02:12:20 +00001049 } \
1050 } \
1051 \
1052 PASSTYPE GeneratedMessageReflection::GetRepeated##TYPENAME( \
temporal779f61c2008-08-13 03:15:00 +00001053 const Message& message, \
temporal40ee5512008-07-10 02:12:20 +00001054 const FieldDescriptor* field, int index) const { \
1055 USAGE_CHECK_ALL(GetRepeated##TYPENAME, REPEATED, CPPTYPE); \
1056 if (field->is_extension()) { \
temporal779f61c2008-08-13 03:15:00 +00001057 return GetExtensionSet(message).GetRepeated##TYPENAME( \
1058 field->number(), index); \
temporal40ee5512008-07-10 02:12:20 +00001059 } else { \
temporal779f61c2008-08-13 03:15:00 +00001060 return GetRepeatedField<TYPE>(message, field, index); \
temporal40ee5512008-07-10 02:12:20 +00001061 } \
1062 } \
1063 \
1064 void GeneratedMessageReflection::SetRepeated##TYPENAME( \
temporal779f61c2008-08-13 03:15:00 +00001065 Message* message, const FieldDescriptor* field, \
1066 int index, PASSTYPE value) const { \
temporal40ee5512008-07-10 02:12:20 +00001067 USAGE_CHECK_ALL(SetRepeated##TYPENAME, REPEATED, CPPTYPE); \
1068 if (field->is_extension()) { \
temporal779f61c2008-08-13 03:15:00 +00001069 MutableExtensionSet(message)->SetRepeated##TYPENAME( \
1070 field->number(), index, value); \
temporal40ee5512008-07-10 02:12:20 +00001071 } else { \
temporal779f61c2008-08-13 03:15:00 +00001072 SetRepeatedField<TYPE>(message, field, index, value); \
temporal40ee5512008-07-10 02:12:20 +00001073 } \
1074 } \
1075 \
1076 void GeneratedMessageReflection::Add##TYPENAME( \
temporal779f61c2008-08-13 03:15:00 +00001077 Message* message, const FieldDescriptor* field, \
1078 PASSTYPE value) const { \
temporal40ee5512008-07-10 02:12:20 +00001079 USAGE_CHECK_ALL(Add##TYPENAME, REPEATED, CPPTYPE); \
1080 if (field->is_extension()) { \
kenton@google.comd37d46d2009-04-25 02:53:47 +00001081 MutableExtensionSet(message)->Add##TYPENAME( \
kenton@google.comfccb1462009-12-18 02:11:36 +00001082 field->number(), field->type(), field->options().packed(), value, \
1083 field); \
temporal40ee5512008-07-10 02:12:20 +00001084 } else { \
temporal779f61c2008-08-13 03:15:00 +00001085 AddField<TYPE>(message, field, value); \
temporal40ee5512008-07-10 02:12:20 +00001086 } \
1087 }
1088
1089DEFINE_PRIMITIVE_ACCESSORS(Int32 , int32 , int32 , INT32 )
1090DEFINE_PRIMITIVE_ACCESSORS(Int64 , int64 , int64 , INT64 )
1091DEFINE_PRIMITIVE_ACCESSORS(UInt32, uint32, uint32, UINT32)
1092DEFINE_PRIMITIVE_ACCESSORS(UInt64, uint64, uint64, UINT64)
1093DEFINE_PRIMITIVE_ACCESSORS(Float , float , float , FLOAT )
1094DEFINE_PRIMITIVE_ACCESSORS(Double, double, double, DOUBLE)
1095DEFINE_PRIMITIVE_ACCESSORS(Bool , bool , bool , BOOL )
1096#undef DEFINE_PRIMITIVE_ACCESSORS
1097
1098// -------------------------------------------------------------------
1099
1100string GeneratedMessageReflection::GetString(
temporal779f61c2008-08-13 03:15:00 +00001101 const Message& message, const FieldDescriptor* field) const {
temporal40ee5512008-07-10 02:12:20 +00001102 USAGE_CHECK_ALL(GetString, SINGULAR, STRING);
1103 if (field->is_extension()) {
kenton@google.comd37d46d2009-04-25 02:53:47 +00001104 return GetExtensionSet(message).GetString(field->number(),
1105 field->default_value_string());
temporal40ee5512008-07-10 02:12:20 +00001106 } else {
kenton@google.comfccb1462009-12-18 02:11:36 +00001107 switch (field->options().ctype()) {
1108 default: // TODO(kenton): Support other string reps.
Feng Xiao6ef984a2014-11-10 17:34:54 -08001109 case FieldOptions::STRING: {
1110 const string* default_ptr =
1111 &DefaultRaw<ArenaStringPtr>(field).Get(NULL);
1112 return GetField<ArenaStringPtr>(message, field).Get(default_ptr);
1113 }
kenton@google.comfccb1462009-12-18 02:11:36 +00001114 }
1115
1116 GOOGLE_LOG(FATAL) << "Can't get here.";
xiaofeng@google.com37c74262014-02-13 22:09:48 +00001117 return GetEmptyString(); // Make compiler happy.
temporal40ee5512008-07-10 02:12:20 +00001118 }
1119}
1120
1121const string& GeneratedMessageReflection::GetStringReference(
temporal779f61c2008-08-13 03:15:00 +00001122 const Message& message,
jieluo@google.com4de8f552014-07-18 00:47:59 +00001123 const FieldDescriptor* field, string* scratch) const {
temporal40ee5512008-07-10 02:12:20 +00001124 USAGE_CHECK_ALL(GetStringReference, SINGULAR, STRING);
1125 if (field->is_extension()) {
kenton@google.comd37d46d2009-04-25 02:53:47 +00001126 return GetExtensionSet(message).GetString(field->number(),
1127 field->default_value_string());
temporal40ee5512008-07-10 02:12:20 +00001128 } else {
kenton@google.comfccb1462009-12-18 02:11:36 +00001129 switch (field->options().ctype()) {
1130 default: // TODO(kenton): Support other string reps.
Feng Xiao6ef984a2014-11-10 17:34:54 -08001131 case FieldOptions::STRING: {
1132 const string* default_ptr =
1133 &DefaultRaw<ArenaStringPtr>(field).Get(NULL);
1134 return GetField<ArenaStringPtr>(message, field).Get(default_ptr);
1135 }
kenton@google.comfccb1462009-12-18 02:11:36 +00001136 }
1137
1138 GOOGLE_LOG(FATAL) << "Can't get here.";
xiaofeng@google.com37c74262014-02-13 22:09:48 +00001139 return GetEmptyString(); // Make compiler happy.
temporal40ee5512008-07-10 02:12:20 +00001140 }
1141}
1142
1143
1144void GeneratedMessageReflection::SetString(
temporal779f61c2008-08-13 03:15:00 +00001145 Message* message, const FieldDescriptor* field,
1146 const string& value) const {
temporal40ee5512008-07-10 02:12:20 +00001147 USAGE_CHECK_ALL(SetString, SINGULAR, STRING);
1148 if (field->is_extension()) {
kenton@google.comd37d46d2009-04-25 02:53:47 +00001149 return MutableExtensionSet(message)->SetString(field->number(),
kenton@google.comfccb1462009-12-18 02:11:36 +00001150 field->type(), value, field);
temporal40ee5512008-07-10 02:12:20 +00001151 } else {
kenton@google.comfccb1462009-12-18 02:11:36 +00001152 switch (field->options().ctype()) {
1153 default: // TODO(kenton): Support other string reps.
1154 case FieldOptions::STRING: {
Feng Xiao6ef984a2014-11-10 17:34:54 -08001155 const string* default_ptr =
1156 &DefaultRaw<ArenaStringPtr>(field).Get(NULL);
jieluo@google.com4de8f552014-07-18 00:47:59 +00001157 if (field->containing_oneof() && !HasOneofField(*message, field)) {
1158 ClearOneof(message, field->containing_oneof());
Feng Xiao6ef984a2014-11-10 17:34:54 -08001159 MutableField<ArenaStringPtr>(message, field)->UnsafeSetDefault(
1160 default_ptr);
jieluo@google.com4de8f552014-07-18 00:47:59 +00001161 }
Feng Xiao6ef984a2014-11-10 17:34:54 -08001162 MutableField<ArenaStringPtr>(message, field)->Set(default_ptr,
1163 value, GetArena(message));
kenton@google.comfccb1462009-12-18 02:11:36 +00001164 break;
1165 }
temporal40ee5512008-07-10 02:12:20 +00001166 }
1167 }
1168}
1169
1170
1171string GeneratedMessageReflection::GetRepeatedString(
temporal779f61c2008-08-13 03:15:00 +00001172 const Message& message, const FieldDescriptor* field, int index) const {
temporal40ee5512008-07-10 02:12:20 +00001173 USAGE_CHECK_ALL(GetRepeatedString, REPEATED, STRING);
1174 if (field->is_extension()) {
temporal779f61c2008-08-13 03:15:00 +00001175 return GetExtensionSet(message).GetRepeatedString(field->number(), index);
temporal40ee5512008-07-10 02:12:20 +00001176 } else {
kenton@google.comfccb1462009-12-18 02:11:36 +00001177 switch (field->options().ctype()) {
1178 default: // TODO(kenton): Support other string reps.
1179 case FieldOptions::STRING:
1180 return GetRepeatedPtrField<string>(message, field, index);
1181 }
1182
1183 GOOGLE_LOG(FATAL) << "Can't get here.";
xiaofeng@google.com37c74262014-02-13 22:09:48 +00001184 return GetEmptyString(); // Make compiler happy.
temporal40ee5512008-07-10 02:12:20 +00001185 }
1186}
1187
1188const string& GeneratedMessageReflection::GetRepeatedStringReference(
temporal779f61c2008-08-13 03:15:00 +00001189 const Message& message, const FieldDescriptor* field,
jieluo@google.com4de8f552014-07-18 00:47:59 +00001190 int index, string* scratch) const {
temporal40ee5512008-07-10 02:12:20 +00001191 USAGE_CHECK_ALL(GetRepeatedStringReference, REPEATED, STRING);
1192 if (field->is_extension()) {
temporal779f61c2008-08-13 03:15:00 +00001193 return GetExtensionSet(message).GetRepeatedString(field->number(), index);
temporal40ee5512008-07-10 02:12:20 +00001194 } else {
kenton@google.comfccb1462009-12-18 02:11:36 +00001195 switch (field->options().ctype()) {
1196 default: // TODO(kenton): Support other string reps.
1197 case FieldOptions::STRING:
1198 return GetRepeatedPtrField<string>(message, field, index);
1199 }
1200
1201 GOOGLE_LOG(FATAL) << "Can't get here.";
xiaofeng@google.com37c74262014-02-13 22:09:48 +00001202 return GetEmptyString(); // Make compiler happy.
temporal40ee5512008-07-10 02:12:20 +00001203 }
1204}
1205
1206
1207void GeneratedMessageReflection::SetRepeatedString(
temporal779f61c2008-08-13 03:15:00 +00001208 Message* message, const FieldDescriptor* field,
1209 int index, const string& value) const {
temporal40ee5512008-07-10 02:12:20 +00001210 USAGE_CHECK_ALL(SetRepeatedString, REPEATED, STRING);
1211 if (field->is_extension()) {
temporal779f61c2008-08-13 03:15:00 +00001212 MutableExtensionSet(message)->SetRepeatedString(
1213 field->number(), index, value);
temporal40ee5512008-07-10 02:12:20 +00001214 } else {
kenton@google.comfccb1462009-12-18 02:11:36 +00001215 switch (field->options().ctype()) {
1216 default: // TODO(kenton): Support other string reps.
1217 case FieldOptions::STRING:
1218 *MutableRepeatedField<string>(message, field, index) = value;
1219 break;
1220 }
temporal40ee5512008-07-10 02:12:20 +00001221 }
1222}
1223
1224
1225void GeneratedMessageReflection::AddString(
temporal779f61c2008-08-13 03:15:00 +00001226 Message* message, const FieldDescriptor* field,
1227 const string& value) const {
temporal40ee5512008-07-10 02:12:20 +00001228 USAGE_CHECK_ALL(AddString, REPEATED, STRING);
1229 if (field->is_extension()) {
kenton@google.comd37d46d2009-04-25 02:53:47 +00001230 MutableExtensionSet(message)->AddString(field->number(),
kenton@google.comfccb1462009-12-18 02:11:36 +00001231 field->type(), value, field);
temporal40ee5512008-07-10 02:12:20 +00001232 } else {
kenton@google.comfccb1462009-12-18 02:11:36 +00001233 switch (field->options().ctype()) {
1234 default: // TODO(kenton): Support other string reps.
1235 case FieldOptions::STRING:
1236 *AddField<string>(message, field) = value;
1237 break;
1238 }
temporal40ee5512008-07-10 02:12:20 +00001239 }
1240}
1241
1242
1243// -------------------------------------------------------------------
1244
Feng Xiao6ef984a2014-11-10 17:34:54 -08001245inline bool CreateUnknownEnumValues(const FileDescriptor* file) {
1246 return file->syntax() == FileDescriptor::SYNTAX_PROTO3;
1247}
1248
temporal40ee5512008-07-10 02:12:20 +00001249const EnumValueDescriptor* GeneratedMessageReflection::GetEnum(
temporal779f61c2008-08-13 03:15:00 +00001250 const Message& message, const FieldDescriptor* field) const {
Feng Xiao6ef984a2014-11-10 17:34:54 -08001251 // Usage checked by GetEnumValue.
1252 int value = GetEnumValue(message, field);
1253 return field->enum_type()->FindValueByNumberCreatingIfUnknown(value);
1254}
temporal40ee5512008-07-10 02:12:20 +00001255
Feng Xiao6ef984a2014-11-10 17:34:54 -08001256int GeneratedMessageReflection::GetEnumValue(
1257 const Message& message, const FieldDescriptor* field) const {
1258 USAGE_CHECK_ALL(GetEnumValue, SINGULAR, ENUM);
1259
1260 int32 value;
temporal40ee5512008-07-10 02:12:20 +00001261 if (field->is_extension()) {
kenton@google.comd37d46d2009-04-25 02:53:47 +00001262 value = GetExtensionSet(message).GetEnum(
1263 field->number(), field->default_value_enum()->number());
temporal40ee5512008-07-10 02:12:20 +00001264 } else {
temporal779f61c2008-08-13 03:15:00 +00001265 value = GetField<int>(message, field);
temporal40ee5512008-07-10 02:12:20 +00001266 }
Feng Xiao6ef984a2014-11-10 17:34:54 -08001267 return value;
temporal40ee5512008-07-10 02:12:20 +00001268}
1269
temporal779f61c2008-08-13 03:15:00 +00001270void GeneratedMessageReflection::SetEnum(
1271 Message* message, const FieldDescriptor* field,
1272 const EnumValueDescriptor* value) const {
Feng Xiao6ef984a2014-11-10 17:34:54 -08001273 // Usage checked by SetEnumValue.
temporal40ee5512008-07-10 02:12:20 +00001274 USAGE_CHECK_ENUM_VALUE(SetEnum);
Feng Xiao6ef984a2014-11-10 17:34:54 -08001275 SetEnumValueInternal(message, field, value->number());
1276}
temporal40ee5512008-07-10 02:12:20 +00001277
Feng Xiao6ef984a2014-11-10 17:34:54 -08001278void GeneratedMessageReflection::SetEnumValue(
1279 Message* message, const FieldDescriptor* field,
1280 int value) const {
1281 USAGE_CHECK_ALL(SetEnumValue, SINGULAR, ENUM);
1282 if (!CreateUnknownEnumValues(descriptor_->file())) {
1283 // Check that the value is valid if we don't support direct storage of
1284 // unknown enum values.
1285 const EnumValueDescriptor* value_desc =
1286 field->enum_type()->FindValueByNumber(value);
1287 if (value_desc == NULL) {
1288 GOOGLE_LOG(DFATAL) << "SetEnumValue accepts only valid integer values: value "
1289 << value << " unexpected for field " << field->full_name();
1290 // In production builds, DFATAL will not terminate the program, so we have
1291 // to do something reasonable: just set the default value.
1292 value = field->default_value_enum()->number();
1293 }
1294 }
1295 SetEnumValueInternal(message, field, value);
1296}
1297
1298void GeneratedMessageReflection::SetEnumValueInternal(
1299 Message* message, const FieldDescriptor* field,
1300 int value) const {
temporal40ee5512008-07-10 02:12:20 +00001301 if (field->is_extension()) {
kenton@google.comd37d46d2009-04-25 02:53:47 +00001302 MutableExtensionSet(message)->SetEnum(field->number(), field->type(),
Feng Xiao6ef984a2014-11-10 17:34:54 -08001303 value, field);
temporal40ee5512008-07-10 02:12:20 +00001304 } else {
Feng Xiao6ef984a2014-11-10 17:34:54 -08001305 SetField<int>(message, field, value);
temporal40ee5512008-07-10 02:12:20 +00001306 }
1307}
1308
1309const EnumValueDescriptor* GeneratedMessageReflection::GetRepeatedEnum(
temporal779f61c2008-08-13 03:15:00 +00001310 const Message& message, const FieldDescriptor* field, int index) const {
Feng Xiao6ef984a2014-11-10 17:34:54 -08001311 // Usage checked by GetRepeatedEnumValue.
1312 int value = GetRepeatedEnumValue(message, field, index);
1313 return field->enum_type()->FindValueByNumberCreatingIfUnknown(value);
1314}
1315
1316int GeneratedMessageReflection::GetRepeatedEnumValue(
1317 const Message& message, const FieldDescriptor* field, int index) const {
1318 USAGE_CHECK_ALL(GetRepeatedEnumValue, REPEATED, ENUM);
temporal40ee5512008-07-10 02:12:20 +00001319
1320 int value;
1321 if (field->is_extension()) {
temporal779f61c2008-08-13 03:15:00 +00001322 value = GetExtensionSet(message).GetRepeatedEnum(field->number(), index);
temporal40ee5512008-07-10 02:12:20 +00001323 } else {
temporal779f61c2008-08-13 03:15:00 +00001324 value = GetRepeatedField<int>(message, field, index);
temporal40ee5512008-07-10 02:12:20 +00001325 }
Feng Xiao6ef984a2014-11-10 17:34:54 -08001326 return value;
temporal40ee5512008-07-10 02:12:20 +00001327}
1328
1329void GeneratedMessageReflection::SetRepeatedEnum(
temporal779f61c2008-08-13 03:15:00 +00001330 Message* message,
temporal40ee5512008-07-10 02:12:20 +00001331 const FieldDescriptor* field, int index,
temporal779f61c2008-08-13 03:15:00 +00001332 const EnumValueDescriptor* value) const {
Feng Xiao6ef984a2014-11-10 17:34:54 -08001333 // Usage checked by SetRepeatedEnumValue.
temporal40ee5512008-07-10 02:12:20 +00001334 USAGE_CHECK_ENUM_VALUE(SetRepeatedEnum);
Feng Xiao6ef984a2014-11-10 17:34:54 -08001335 SetRepeatedEnumValueInternal(message, field, index, value->number());
1336}
temporal40ee5512008-07-10 02:12:20 +00001337
Feng Xiao6ef984a2014-11-10 17:34:54 -08001338void GeneratedMessageReflection::SetRepeatedEnumValue(
1339 Message* message,
1340 const FieldDescriptor* field, int index,
1341 int value) const {
1342 USAGE_CHECK_ALL(SetRepeatedEnum, REPEATED, ENUM);
1343 if (!CreateUnknownEnumValues(descriptor_->file())) {
1344 // Check that the value is valid if we don't support direct storage of
1345 // unknown enum values.
1346 const EnumValueDescriptor* value_desc =
1347 field->enum_type()->FindValueByNumber(value);
1348 if (value_desc == NULL) {
1349 GOOGLE_LOG(DFATAL) << "SetRepeatedEnumValue accepts only valid integer values: "
1350 << "value " << value << " unexpected for field "
1351 << field->full_name();
1352 // In production builds, DFATAL will not terminate the program, so we have
1353 // to do something reasonable: just set the default value.
1354 value = field->default_value_enum()->number();
1355 }
1356 }
1357 SetRepeatedEnumValueInternal(message, field, index, value);
1358}
1359
1360void GeneratedMessageReflection::SetRepeatedEnumValueInternal(
1361 Message* message,
1362 const FieldDescriptor* field, int index,
1363 int value) const {
temporal40ee5512008-07-10 02:12:20 +00001364 if (field->is_extension()) {
temporal779f61c2008-08-13 03:15:00 +00001365 MutableExtensionSet(message)->SetRepeatedEnum(
Feng Xiao6ef984a2014-11-10 17:34:54 -08001366 field->number(), index, value);
temporal40ee5512008-07-10 02:12:20 +00001367 } else {
Feng Xiao6ef984a2014-11-10 17:34:54 -08001368 SetRepeatedField<int>(message, field, index, value);
temporal40ee5512008-07-10 02:12:20 +00001369 }
1370}
1371
temporal779f61c2008-08-13 03:15:00 +00001372void GeneratedMessageReflection::AddEnum(
1373 Message* message, const FieldDescriptor* field,
1374 const EnumValueDescriptor* value) const {
Feng Xiao6ef984a2014-11-10 17:34:54 -08001375 // Usage checked by AddEnumValue.
temporal40ee5512008-07-10 02:12:20 +00001376 USAGE_CHECK_ENUM_VALUE(AddEnum);
Feng Xiao6ef984a2014-11-10 17:34:54 -08001377 AddEnumValueInternal(message, field, value->number());
1378}
temporal40ee5512008-07-10 02:12:20 +00001379
Feng Xiao6ef984a2014-11-10 17:34:54 -08001380void GeneratedMessageReflection::AddEnumValue(
1381 Message* message, const FieldDescriptor* field,
1382 int value) const {
1383 USAGE_CHECK_ALL(AddEnum, REPEATED, ENUM);
1384 if (!CreateUnknownEnumValues(descriptor_->file())) {
1385 // Check that the value is valid if we don't support direct storage of
1386 // unknown enum values.
1387 const EnumValueDescriptor* value_desc =
1388 field->enum_type()->FindValueByNumber(value);
1389 if (value_desc == NULL) {
1390 GOOGLE_LOG(DFATAL) << "AddEnumValue accepts only valid integer values: value "
1391 << value << " unexpected for field " << field->full_name();
1392 // In production builds, DFATAL will not terminate the program, so we have
1393 // to do something reasonable: just set the default value.
1394 value = field->default_value_enum()->number();
1395 }
1396 }
1397 AddEnumValueInternal(message, field, value);
1398}
1399
1400void GeneratedMessageReflection::AddEnumValueInternal(
1401 Message* message, const FieldDescriptor* field,
1402 int value) const {
temporal40ee5512008-07-10 02:12:20 +00001403 if (field->is_extension()) {
kenton@google.comd37d46d2009-04-25 02:53:47 +00001404 MutableExtensionSet(message)->AddEnum(field->number(), field->type(),
1405 field->options().packed(),
Feng Xiao6ef984a2014-11-10 17:34:54 -08001406 value, field);
temporal40ee5512008-07-10 02:12:20 +00001407 } else {
Feng Xiao6ef984a2014-11-10 17:34:54 -08001408 AddField<int>(message, field, value);
temporal40ee5512008-07-10 02:12:20 +00001409 }
1410}
1411
1412// -------------------------------------------------------------------
1413
1414const Message& GeneratedMessageReflection::GetMessage(
kenton@google.comfccb1462009-12-18 02:11:36 +00001415 const Message& message, const FieldDescriptor* field,
1416 MessageFactory* factory) const {
temporal40ee5512008-07-10 02:12:20 +00001417 USAGE_CHECK_ALL(GetMessage, SINGULAR, MESSAGE);
1418
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001419 if (factory == NULL) factory = message_factory_;
1420
temporal40ee5512008-07-10 02:12:20 +00001421 if (field->is_extension()) {
kenton@google.com80b1d622009-07-29 01:13:20 +00001422 return static_cast<const Message&>(
kenton@google.comfccb1462009-12-18 02:11:36 +00001423 GetExtensionSet(message).GetMessage(
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001424 field->number(), field->message_type(), factory));
temporal40ee5512008-07-10 02:12:20 +00001425 } else {
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001426 const Message* result;
1427 result = GetRaw<const Message*>(message, field);
temporal40ee5512008-07-10 02:12:20 +00001428 if (result == NULL) {
1429 result = DefaultRaw<const Message*>(field);
1430 }
1431 return *result;
1432 }
1433}
1434
1435Message* GeneratedMessageReflection::MutableMessage(
kenton@google.comfccb1462009-12-18 02:11:36 +00001436 Message* message, const FieldDescriptor* field,
1437 MessageFactory* factory) const {
Jisi Liu885b6122015-02-28 14:51:22 -08001438 USAGE_CHECK_ALL(MutableMessage, SINGULAR, MESSAGE);
1439
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001440 if (factory == NULL) factory = message_factory_;
1441
temporal40ee5512008-07-10 02:12:20 +00001442 if (field->is_extension()) {
kenton@google.com80b1d622009-07-29 01:13:20 +00001443 return static_cast<Message*>(
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001444 MutableExtensionSet(message)->MutableMessage(field, factory));
temporal40ee5512008-07-10 02:12:20 +00001445 } else {
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001446 Message* result;
jieluo@google.com4de8f552014-07-18 00:47:59 +00001447 Message** result_holder = MutableRaw<Message*>(message, field);
1448
1449 if (field->containing_oneof()) {
1450 if (!HasOneofField(*message, field)) {
1451 ClearOneof(message, field->containing_oneof());
1452 result_holder = MutableField<Message*>(message, field);
1453 const Message* default_message = DefaultRaw<const Message*>(field);
Feng Xiao6ef984a2014-11-10 17:34:54 -08001454 *result_holder = default_message->New(message->GetArena());
jieluo@google.com4de8f552014-07-18 00:47:59 +00001455 }
1456 } else {
1457 SetBit(message, field);
1458 }
1459
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001460 if (*result_holder == NULL) {
temporal40ee5512008-07-10 02:12:20 +00001461 const Message* default_message = DefaultRaw<const Message*>(field);
Feng Xiao6ef984a2014-11-10 17:34:54 -08001462 *result_holder = default_message->New(message->GetArena());
temporal40ee5512008-07-10 02:12:20 +00001463 }
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001464 result = *result_holder;
1465 return result;
1466 }
1467}
1468
Feng Xiao6ef984a2014-11-10 17:34:54 -08001469void GeneratedMessageReflection::UnsafeArenaSetAllocatedMessage(
jieluo@google.com4de8f552014-07-18 00:47:59 +00001470 Message* message,
1471 Message* sub_message,
1472 const FieldDescriptor* field) const {
1473 USAGE_CHECK_ALL(SetAllocatedMessage, SINGULAR, MESSAGE);
1474
1475 if (field->is_extension()) {
1476 MutableExtensionSet(message)->SetAllocatedMessage(
1477 field->number(), field->type(), field, sub_message);
1478 } else {
1479 if (field->containing_oneof()) {
1480 if (sub_message == NULL) {
1481 ClearOneof(message, field->containing_oneof());
1482 return;
1483 }
1484 ClearOneof(message, field->containing_oneof());
1485 *MutableRaw<Message*>(message, field) = sub_message;
1486 SetOneofCase(message, field);
1487 return;
1488 }
1489
1490 if (sub_message == NULL) {
1491 ClearBit(message, field);
1492 } else {
1493 SetBit(message, field);
1494 }
1495 Message** sub_message_holder = MutableRaw<Message*>(message, field);
Feng Xiao6ef984a2014-11-10 17:34:54 -08001496 if (GetArena(message) == NULL) {
1497 delete *sub_message_holder;
1498 }
jieluo@google.com4de8f552014-07-18 00:47:59 +00001499 *sub_message_holder = sub_message;
1500 }
1501}
1502
Feng Xiao6ef984a2014-11-10 17:34:54 -08001503void GeneratedMessageReflection::SetAllocatedMessage(
1504 Message* message,
1505 Message* sub_message,
1506 const FieldDescriptor* field) const {
1507 // If message and sub-message are in different memory ownership domains
1508 // (different arenas, or one is on heap and one is not), then we may need to
1509 // do a copy.
1510 if (sub_message != NULL &&
1511 sub_message->GetArena() != message->GetArena()) {
1512 if (sub_message->GetArena() == NULL && message->GetArena() != NULL) {
1513 // Case 1: parent is on an arena and child is heap-allocated. We can add
1514 // the child to the arena's Own() list to free on arena destruction, then
1515 // set our pointer.
1516 message->GetArena()->Own(sub_message);
1517 UnsafeArenaSetAllocatedMessage(message, sub_message, field);
1518 } else {
1519 // Case 2: all other cases. We need to make a copy. MutableMessage() will
1520 // either get the existing message object, or instantiate a new one as
1521 // appropriate w.r.t. our arena.
1522 Message* sub_message_copy = MutableMessage(message, field);
1523 sub_message_copy->CopyFrom(*sub_message);
1524 }
1525 } else {
1526 // Same memory ownership domains.
1527 UnsafeArenaSetAllocatedMessage(message, sub_message, field);
1528 }
1529}
1530
1531Message* GeneratedMessageReflection::UnsafeArenaReleaseMessage(
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001532 Message* message,
1533 const FieldDescriptor* field,
1534 MessageFactory* factory) const {
1535 USAGE_CHECK_ALL(ReleaseMessage, SINGULAR, MESSAGE);
1536
1537 if (factory == NULL) factory = message_factory_;
1538
1539 if (field->is_extension()) {
1540 return static_cast<Message*>(
1541 MutableExtensionSet(message)->ReleaseMessage(field, factory));
1542 } else {
1543 ClearBit(message, field);
jieluo@google.com4de8f552014-07-18 00:47:59 +00001544 if (field->containing_oneof()) {
1545 if (HasOneofField(*message, field)) {
1546 *MutableOneofCase(message, field->containing_oneof()) = 0;
1547 } else {
1548 return NULL;
1549 }
1550 }
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001551 Message** result = MutableRaw<Message*>(message, field);
1552 Message* ret = *result;
1553 *result = NULL;
1554 return ret;
temporal40ee5512008-07-10 02:12:20 +00001555 }
1556}
1557
Feng Xiao6ef984a2014-11-10 17:34:54 -08001558Message* GeneratedMessageReflection::ReleaseMessage(
1559 Message* message,
1560 const FieldDescriptor* field,
1561 MessageFactory* factory) const {
1562 Message* released = UnsafeArenaReleaseMessage(message, field, factory);
1563 if (GetArena(message) != NULL && released != NULL) {
1564 Message* copy_from_arena = released->New();
1565 copy_from_arena->CopyFrom(*released);
1566 released = copy_from_arena;
1567 }
1568 return released;
1569}
1570
temporal40ee5512008-07-10 02:12:20 +00001571const Message& GeneratedMessageReflection::GetRepeatedMessage(
temporal779f61c2008-08-13 03:15:00 +00001572 const Message& message, const FieldDescriptor* field, int index) const {
temporal40ee5512008-07-10 02:12:20 +00001573 USAGE_CHECK_ALL(GetRepeatedMessage, REPEATED, MESSAGE);
1574
1575 if (field->is_extension()) {
kenton@google.com80b1d622009-07-29 01:13:20 +00001576 return static_cast<const Message&>(
1577 GetExtensionSet(message).GetRepeatedMessage(field->number(), index));
temporal40ee5512008-07-10 02:12:20 +00001578 } else {
Feng Xiaof157a562014-11-14 11:50:31 -08001579 if (IsMapFieldInApi(field)) {
1580 return GetRaw<MapFieldBase>(message, field)
1581 .GetRepeatedField()
1582 .Get<GenericTypeHandler<Message> >(index);
1583 } else {
1584 return GetRaw<RepeatedPtrFieldBase>(message, field)
1585 .Get<GenericTypeHandler<Message> >(index);
1586 }
temporal40ee5512008-07-10 02:12:20 +00001587 }
1588}
1589
1590Message* GeneratedMessageReflection::MutableRepeatedMessage(
temporal779f61c2008-08-13 03:15:00 +00001591 Message* message, const FieldDescriptor* field, int index) const {
temporal40ee5512008-07-10 02:12:20 +00001592 USAGE_CHECK_ALL(MutableRepeatedMessage, REPEATED, MESSAGE);
1593
1594 if (field->is_extension()) {
kenton@google.com80b1d622009-07-29 01:13:20 +00001595 return static_cast<Message*>(
1596 MutableExtensionSet(message)->MutableRepeatedMessage(
1597 field->number(), index));
temporal40ee5512008-07-10 02:12:20 +00001598 } else {
Feng Xiaof157a562014-11-14 11:50:31 -08001599 if (IsMapFieldInApi(field)) {
1600 return MutableRaw<MapFieldBase>(message, field)
1601 ->MutableRepeatedField()
1602 ->Mutable<GenericTypeHandler<Message> >(index);
1603 } else {
1604 return MutableRaw<RepeatedPtrFieldBase>(message, field)
kenton@google.com80b1d622009-07-29 01:13:20 +00001605 ->Mutable<GenericTypeHandler<Message> >(index);
Feng Xiaof157a562014-11-14 11:50:31 -08001606 }
temporal40ee5512008-07-10 02:12:20 +00001607 }
1608}
1609
temporal779f61c2008-08-13 03:15:00 +00001610Message* GeneratedMessageReflection::AddMessage(
kenton@google.comfccb1462009-12-18 02:11:36 +00001611 Message* message, const FieldDescriptor* field,
1612 MessageFactory* factory) const {
temporal40ee5512008-07-10 02:12:20 +00001613 USAGE_CHECK_ALL(AddMessage, REPEATED, MESSAGE);
1614
kenton@google.comfccb1462009-12-18 02:11:36 +00001615 if (factory == NULL) factory = message_factory_;
1616
temporal40ee5512008-07-10 02:12:20 +00001617 if (field->is_extension()) {
kenton@google.com80b1d622009-07-29 01:13:20 +00001618 return static_cast<Message*>(
kenton@google.comfccb1462009-12-18 02:11:36 +00001619 MutableExtensionSet(message)->AddMessage(field, factory));
temporal40ee5512008-07-10 02:12:20 +00001620 } else {
Feng Xiaof157a562014-11-14 11:50:31 -08001621 Message* result = NULL;
1622
kenton@google.com80b1d622009-07-29 01:13:20 +00001623 // We can't use AddField<Message>() because RepeatedPtrFieldBase doesn't
1624 // know how to allocate one.
Feng Xiaof157a562014-11-14 11:50:31 -08001625 RepeatedPtrFieldBase* repeated = NULL;
1626 if (IsMapFieldInApi(field)) {
1627 repeated =
1628 MutableRaw<MapFieldBase>(message, field)->MutableRepeatedField();
1629 } else {
1630 repeated = MutableRaw<RepeatedPtrFieldBase>(message, field);
1631 }
1632 result = repeated->AddFromCleared<GenericTypeHandler<Message> >();
kenton@google.com80b1d622009-07-29 01:13:20 +00001633 if (result == NULL) {
1634 // We must allocate a new object.
1635 const Message* prototype;
1636 if (repeated->size() == 0) {
kenton@google.comfccb1462009-12-18 02:11:36 +00001637 prototype = factory->GetPrototype(field->message_type());
kenton@google.com80b1d622009-07-29 01:13:20 +00001638 } else {
1639 prototype = &repeated->Get<GenericTypeHandler<Message> >(0);
1640 }
Feng Xiao6ef984a2014-11-10 17:34:54 -08001641 result = prototype->New(message->GetArena());
1642 // We can guarantee here that repeated and result are either both heap
1643 // allocated or arena owned. So it is safe to call the unsafe version
1644 // of AddAllocated.
1645 repeated->UnsafeArenaAddAllocated<GenericTypeHandler<Message> >(result);
kenton@google.com80b1d622009-07-29 01:13:20 +00001646 }
Feng Xiaof157a562014-11-14 11:50:31 -08001647
kenton@google.com80b1d622009-07-29 01:13:20 +00001648 return result;
temporal40ee5512008-07-10 02:12:20 +00001649 }
1650}
1651
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001652void* GeneratedMessageReflection::MutableRawRepeatedField(
1653 Message* message, const FieldDescriptor* field,
1654 FieldDescriptor::CppType cpptype,
1655 int ctype, const Descriptor* desc) const {
1656 USAGE_CHECK_REPEATED("MutableRawRepeatedField");
1657 if (field->cpp_type() != cpptype)
1658 ReportReflectionUsageTypeError(descriptor_,
1659 field, "MutableRawRepeatedField", cpptype);
1660 if (ctype >= 0)
1661 GOOGLE_CHECK_EQ(field->options().ctype(), ctype) << "subtype mismatch";
1662 if (desc != NULL)
1663 GOOGLE_CHECK_EQ(field->message_type(), desc) << "wrong submessage type";
Feng Xiaof157a562014-11-14 11:50:31 -08001664 if (field->is_extension()) {
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001665 return MutableExtensionSet(message)->MutableRawRepeatedField(
jieluo@google.com4de8f552014-07-18 00:47:59 +00001666 field->number(), field->type(), field->is_packed(), field);
Feng Xiaof157a562014-11-14 11:50:31 -08001667 } else {
1668 // Trigger transform for MapField
1669 if (IsMapFieldInApi(field)) {
1670 return reinterpret_cast<MapFieldBase*>(reinterpret_cast<uint8*>(message) +
1671 offsets_[field->index()])
1672 ->MutableRepeatedField();
1673 }
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001674 return reinterpret_cast<uint8*>(message) + offsets_[field->index()];
Feng Xiaof157a562014-11-14 11:50:31 -08001675 }
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001676}
1677
jieluo@google.com4de8f552014-07-18 00:47:59 +00001678const FieldDescriptor* GeneratedMessageReflection::GetOneofFieldDescriptor(
1679 const Message& message,
1680 const OneofDescriptor* oneof_descriptor) const {
1681 uint32 field_number = GetOneofCase(message, oneof_descriptor);
1682 if (field_number == 0) {
1683 return NULL;
1684 }
1685 return descriptor_->FindFieldByNumber(field_number);
1686}
1687
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +00001688// -----------------------------------------------------------------------------
temporal40ee5512008-07-10 02:12:20 +00001689
1690const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByName(
1691 const string& name) const {
temporal779f61c2008-08-13 03:15:00 +00001692 if (extensions_offset_ == -1) return NULL;
1693
1694 const FieldDescriptor* result = descriptor_pool_->FindExtensionByName(name);
1695 if (result != NULL && result->containing_type() == descriptor_) {
1696 return result;
1697 }
1698
1699 if (descriptor_->options().message_set_wire_format()) {
1700 // MessageSet extensions may be identified by type name.
1701 const Descriptor* type = descriptor_pool_->FindMessageTypeByName(name);
1702 if (type != NULL) {
1703 // Look for a matching extension in the foreign type's scope.
1704 for (int i = 0; i < type->extension_count(); i++) {
1705 const FieldDescriptor* extension = type->extension(i);
1706 if (extension->containing_type() == descriptor_ &&
1707 extension->type() == FieldDescriptor::TYPE_MESSAGE &&
1708 extension->is_optional() &&
1709 extension->message_type() == type) {
1710 // Found it.
1711 return extension;
1712 }
1713 }
1714 }
1715 }
1716
1717 return NULL;
temporal40ee5512008-07-10 02:12:20 +00001718}
1719
1720const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByNumber(
1721 int number) const {
temporal779f61c2008-08-13 03:15:00 +00001722 if (extensions_offset_ == -1) return NULL;
1723 return descriptor_pool_->FindExtensionByNumber(descriptor_, number);
temporal40ee5512008-07-10 02:12:20 +00001724}
1725
Feng Xiao6ef984a2014-11-10 17:34:54 -08001726bool GeneratedMessageReflection::SupportsUnknownEnumValues() const {
1727 return CreateUnknownEnumValues(descriptor_->file());
1728}
1729
temporal40ee5512008-07-10 02:12:20 +00001730// ===================================================================
1731// Some private helpers.
1732
1733// These simple template accessors obtain pointers (or references) to
1734// the given field.
1735template <typename Type>
1736inline const Type& GeneratedMessageReflection::GetRaw(
temporal779f61c2008-08-13 03:15:00 +00001737 const Message& message, const FieldDescriptor* field) const {
jieluo@google.com4de8f552014-07-18 00:47:59 +00001738 if (field->containing_oneof() && !HasOneofField(message, field)) {
1739 return DefaultRaw<Type>(field);
1740 }
1741 int index = field->containing_oneof() ?
1742 descriptor_->field_count() + field->containing_oneof()->index() :
1743 field->index();
temporal779f61c2008-08-13 03:15:00 +00001744 const void* ptr = reinterpret_cast<const uint8*>(&message) +
jieluo@google.com4de8f552014-07-18 00:47:59 +00001745 offsets_[index];
temporal40ee5512008-07-10 02:12:20 +00001746 return *reinterpret_cast<const Type*>(ptr);
1747}
1748
1749template <typename Type>
1750inline Type* GeneratedMessageReflection::MutableRaw(
temporal779f61c2008-08-13 03:15:00 +00001751 Message* message, const FieldDescriptor* field) const {
jieluo@google.com4de8f552014-07-18 00:47:59 +00001752 int index = field->containing_oneof() ?
1753 descriptor_->field_count() + field->containing_oneof()->index() :
1754 field->index();
1755 void* ptr = reinterpret_cast<uint8*>(message) + offsets_[index];
temporal40ee5512008-07-10 02:12:20 +00001756 return reinterpret_cast<Type*>(ptr);
1757}
1758
1759template <typename Type>
1760inline const Type& GeneratedMessageReflection::DefaultRaw(
1761 const FieldDescriptor* field) const {
jieluo@google.com4de8f552014-07-18 00:47:59 +00001762 const void* ptr = field->containing_oneof() ?
1763 reinterpret_cast<const uint8*>(default_oneof_instance_) +
1764 offsets_[field->index()] :
1765 reinterpret_cast<const uint8*>(default_instance_) +
1766 offsets_[field->index()];
temporal40ee5512008-07-10 02:12:20 +00001767 return *reinterpret_cast<const Type*>(ptr);
1768}
1769
temporal779f61c2008-08-13 03:15:00 +00001770inline const uint32* GeneratedMessageReflection::GetHasBits(
1771 const Message& message) const {
Feng Xiao6ef984a2014-11-10 17:34:54 -08001772 if (has_bits_offset_ == -1) { // proto3 with no has-bits.
1773 return NULL;
1774 }
temporal779f61c2008-08-13 03:15:00 +00001775 const void* ptr = reinterpret_cast<const uint8*>(&message) + has_bits_offset_;
1776 return reinterpret_cast<const uint32*>(ptr);
1777}
1778inline uint32* GeneratedMessageReflection::MutableHasBits(
1779 Message* message) const {
Feng Xiao6ef984a2014-11-10 17:34:54 -08001780 if (has_bits_offset_ == -1) {
1781 return NULL;
1782 }
temporal779f61c2008-08-13 03:15:00 +00001783 void* ptr = reinterpret_cast<uint8*>(message) + has_bits_offset_;
1784 return reinterpret_cast<uint32*>(ptr);
1785}
1786
huahangc871fb92014-09-04 10:51:57 +08001787inline uint32 GeneratedMessageReflection::GetOneofCase(
jieluo@google.com4de8f552014-07-18 00:47:59 +00001788 const Message& message,
1789 const OneofDescriptor* oneof_descriptor) const {
1790 const void* ptr = reinterpret_cast<const uint8*>(&message)
1791 + oneof_case_offset_;
1792 return reinterpret_cast<const uint32*>(ptr)[oneof_descriptor->index()];
1793}
1794
1795inline uint32* GeneratedMessageReflection::MutableOneofCase(
1796 Message* message,
1797 const OneofDescriptor* oneof_descriptor) const {
1798 void* ptr = reinterpret_cast<uint8*>(message) + oneof_case_offset_;
1799 return &(reinterpret_cast<uint32*>(ptr)[oneof_descriptor->index()]);
1800}
1801
temporal779f61c2008-08-13 03:15:00 +00001802inline const ExtensionSet& GeneratedMessageReflection::GetExtensionSet(
1803 const Message& message) const {
1804 GOOGLE_DCHECK_NE(extensions_offset_, -1);
1805 const void* ptr = reinterpret_cast<const uint8*>(&message) +
1806 extensions_offset_;
1807 return *reinterpret_cast<const ExtensionSet*>(ptr);
1808}
1809inline ExtensionSet* GeneratedMessageReflection::MutableExtensionSet(
1810 Message* message) const {
1811 GOOGLE_DCHECK_NE(extensions_offset_, -1);
1812 void* ptr = reinterpret_cast<uint8*>(message) + extensions_offset_;
1813 return reinterpret_cast<ExtensionSet*>(ptr);
1814}
1815
Feng Xiao6ef984a2014-11-10 17:34:54 -08001816inline Arena* GeneratedMessageReflection::GetArena(Message* message) const {
1817 if (arena_offset_ == kNoArenaPointer) {
1818 return NULL;
1819 }
1820
1821 if (unknown_fields_offset_ == kUnknownFieldSetInMetadata) {
1822 // zero-overhead arena pointer overloading UnknownFields
1823 return GetInternalMetadataWithArena(*message).arena();
1824 }
1825
1826 // Baseline case: message class has a dedicated arena pointer.
1827 void* ptr = reinterpret_cast<uint8*>(message) + arena_offset_;
1828 return *reinterpret_cast<Arena**>(ptr);
1829}
1830
1831inline const InternalMetadataWithArena&
1832GeneratedMessageReflection::GetInternalMetadataWithArena(
1833 const Message& message) const {
1834 const void* ptr = reinterpret_cast<const uint8*>(&message) + arena_offset_;
1835 return *reinterpret_cast<const InternalMetadataWithArena*>(ptr);
1836}
1837
1838inline InternalMetadataWithArena*
1839GeneratedMessageReflection::MutableInternalMetadataWithArena(
1840 Message* message) const {
1841 void* ptr = reinterpret_cast<uint8*>(message) + arena_offset_;
1842 return reinterpret_cast<InternalMetadataWithArena*>(ptr);
1843}
1844
Feng Xiaoc25d9fe2014-11-26 16:15:29 -08001845inline bool
1846GeneratedMessageReflection::GetIsDefaultInstance(
1847 const Message& message) const {
1848 if (is_default_instance_offset_ == kHasNoDefaultInstanceField) {
1849 return false;
1850 }
1851 const void* ptr = reinterpret_cast<const uint8*>(&message) +
1852 is_default_instance_offset_;
1853 return *reinterpret_cast<const bool*>(ptr);
1854}
1855
temporal40ee5512008-07-10 02:12:20 +00001856// Simple accessors for manipulating has_bits_.
1857inline bool GeneratedMessageReflection::HasBit(
temporal779f61c2008-08-13 03:15:00 +00001858 const Message& message, const FieldDescriptor* field) const {
Feng Xiao6ef984a2014-11-10 17:34:54 -08001859 if (has_bits_offset_ == -1) {
1860 // proto3: no has-bits. All fields present except messages, which are
1861 // present only if their message-field pointer is non-NULL.
1862 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
Feng Xiaoc25d9fe2014-11-26 16:15:29 -08001863 return !GetIsDefaultInstance(message) &&
1864 GetRaw<const Message*>(message, field) != NULL;
Feng Xiao6ef984a2014-11-10 17:34:54 -08001865 } else {
1866 // Non-message field (and non-oneof, since that was handled in HasField()
1867 // before calling us), and singular (again, checked in HasField). So, this
1868 // field must be a scalar.
1869
1870 // Scalar primitive (numeric or string/bytes) fields are present if
1871 // their value is non-zero (numeric) or non-empty (string/bytes). N.B.:
1872 // we must use this definition here, rather than the "scalar fields
1873 // always present" in the proto3 docs, because MergeFrom() semantics
1874 // require presence as "present on wire", and reflection-based merge
1875 // (which uses HasField()) needs to be consistent with this.
1876 switch (field->cpp_type()) {
1877 case FieldDescriptor::CPPTYPE_STRING:
1878 switch (field->options().ctype()) {
1879 default: {
1880 const string* default_ptr =
1881 &DefaultRaw<ArenaStringPtr>(field).Get(NULL);
1882 return GetField<ArenaStringPtr>(message, field).Get(
1883 default_ptr).size() > 0;
1884 }
1885 }
1886 return false;
1887 case FieldDescriptor::CPPTYPE_BOOL:
1888 return GetRaw<bool>(message, field) != false;
1889 case FieldDescriptor::CPPTYPE_INT32:
1890 return GetRaw<int32>(message, field) != 0;
1891 case FieldDescriptor::CPPTYPE_INT64:
1892 return GetRaw<int64>(message, field) != 0;
1893 case FieldDescriptor::CPPTYPE_UINT32:
1894 return GetRaw<uint32>(message, field) != 0;
1895 case FieldDescriptor::CPPTYPE_UINT64:
1896 return GetRaw<uint64>(message, field) != 0;
1897 case FieldDescriptor::CPPTYPE_FLOAT:
1898 return GetRaw<float>(message, field) != 0.0;
1899 case FieldDescriptor::CPPTYPE_DOUBLE:
1900 return GetRaw<double>(message, field) != 0.0;
1901 case FieldDescriptor::CPPTYPE_ENUM:
1902 return GetRaw<int>(message, field) != 0;
1903 case FieldDescriptor::CPPTYPE_MESSAGE:
1904 // handled above; avoid warning
1905 GOOGLE_LOG(FATAL) << "Reached impossible case in HasBit().";
1906 break;
1907 }
1908 }
1909 }
temporal779f61c2008-08-13 03:15:00 +00001910 return GetHasBits(message)[field->index() / 32] &
1911 (1 << (field->index() % 32));
temporal40ee5512008-07-10 02:12:20 +00001912}
1913
1914inline void GeneratedMessageReflection::SetBit(
temporal779f61c2008-08-13 03:15:00 +00001915 Message* message, const FieldDescriptor* field) const {
Feng Xiao6ef984a2014-11-10 17:34:54 -08001916 if (has_bits_offset_ == -1) {
1917 return;
1918 }
temporal779f61c2008-08-13 03:15:00 +00001919 MutableHasBits(message)[field->index() / 32] |= (1 << (field->index() % 32));
temporal40ee5512008-07-10 02:12:20 +00001920}
1921
1922inline void GeneratedMessageReflection::ClearBit(
temporal779f61c2008-08-13 03:15:00 +00001923 Message* message, const FieldDescriptor* field) const {
Feng Xiao6ef984a2014-11-10 17:34:54 -08001924 if (has_bits_offset_ == -1) {
1925 return;
1926 }
temporal779f61c2008-08-13 03:15:00 +00001927 MutableHasBits(message)[field->index() / 32] &= ~(1 << (field->index() % 32));
temporal40ee5512008-07-10 02:12:20 +00001928}
1929
jieluo@google.com4de8f552014-07-18 00:47:59 +00001930inline void GeneratedMessageReflection::SwapBit(
1931 Message* message1, Message* message2, const FieldDescriptor* field) const {
Feng Xiao6ef984a2014-11-10 17:34:54 -08001932 if (has_bits_offset_ == -1) {
1933 return;
1934 }
jieluo@google.com4de8f552014-07-18 00:47:59 +00001935 bool temp_has_bit = HasBit(*message1, field);
1936 if (HasBit(*message2, field)) {
1937 SetBit(message1, field);
1938 } else {
1939 ClearBit(message1, field);
1940 }
1941 if (temp_has_bit) {
1942 SetBit(message2, field);
1943 } else {
1944 ClearBit(message2, field);
1945 }
1946}
1947
1948inline bool GeneratedMessageReflection::HasOneof(
1949 const Message& message, const OneofDescriptor* oneof_descriptor) const {
1950 return (GetOneofCase(message, oneof_descriptor) > 0);
1951}
1952
1953inline bool GeneratedMessageReflection::HasOneofField(
1954 const Message& message, const FieldDescriptor* field) const {
1955 return (GetOneofCase(message, field->containing_oneof()) == field->number());
1956}
1957
1958inline void GeneratedMessageReflection::SetOneofCase(
1959 Message* message, const FieldDescriptor* field) const {
1960 *MutableOneofCase(message, field->containing_oneof()) = field->number();
1961}
1962
1963inline void GeneratedMessageReflection::ClearOneofField(
1964 Message* message, const FieldDescriptor* field) const {
1965 if (HasOneofField(*message, field)) {
1966 ClearOneof(message, field->containing_oneof());
1967 }
1968}
1969
1970inline void GeneratedMessageReflection::ClearOneof(
1971 Message* message, const OneofDescriptor* oneof_descriptor) const {
1972 // TODO(jieluo): Consider to cache the unused object instead of deleting
1973 // it. It will be much faster if an aplication switches a lot from
1974 // a few oneof fields. Time/space tradeoff
1975 uint32 oneof_case = GetOneofCase(*message, oneof_descriptor);
1976 if (oneof_case > 0) {
1977 const FieldDescriptor* field = descriptor_->FindFieldByNumber(oneof_case);
Jisi Liu885b6122015-02-28 14:51:22 -08001978 if (GetArena(message) == NULL) {
1979 switch (field->cpp_type()) {
1980 case FieldDescriptor::CPPTYPE_STRING: {
1981 switch (field->options().ctype()) {
1982 default: // TODO(kenton): Support other string reps.
1983 case FieldOptions::STRING: {
1984 const string* default_ptr =
1985 &DefaultRaw<ArenaStringPtr>(field).Get(NULL);
1986 MutableField<ArenaStringPtr>(message, field)->
1987 Destroy(default_ptr, GetArena(message));
1988 break;
1989 }
Feng Xiao6ef984a2014-11-10 17:34:54 -08001990 }
Jisi Liu885b6122015-02-28 14:51:22 -08001991 break;
jieluo@google.com4de8f552014-07-18 00:47:59 +00001992 }
jieluo@google.com4de8f552014-07-18 00:47:59 +00001993
Jisi Liu885b6122015-02-28 14:51:22 -08001994 case FieldDescriptor::CPPTYPE_MESSAGE:
1995 delete *MutableRaw<Message*>(message, field);
1996 break;
1997 default:
1998 break;
1999 }
jieluo@google.com4de8f552014-07-18 00:47:59 +00002000 }
2001
2002 *MutableOneofCase(message, oneof_descriptor) = 0;
2003 }
2004}
2005
temporal40ee5512008-07-10 02:12:20 +00002006// Template implementations of basic accessors. Inline because each
2007// template instance is only called from one location. These are
2008// used for all types except messages.
2009template <typename Type>
2010inline const Type& GeneratedMessageReflection::GetField(
temporal779f61c2008-08-13 03:15:00 +00002011 const Message& message, const FieldDescriptor* field) const {
2012 return GetRaw<Type>(message, field);
temporal40ee5512008-07-10 02:12:20 +00002013}
2014
2015template <typename Type>
2016inline void GeneratedMessageReflection::SetField(
temporal779f61c2008-08-13 03:15:00 +00002017 Message* message, const FieldDescriptor* field, const Type& value) const {
jieluo@google.com4de8f552014-07-18 00:47:59 +00002018 if (field->containing_oneof() && !HasOneofField(*message, field)) {
2019 ClearOneof(message, field->containing_oneof());
2020 }
temporal779f61c2008-08-13 03:15:00 +00002021 *MutableRaw<Type>(message, field) = value;
jieluo@google.com4de8f552014-07-18 00:47:59 +00002022 field->containing_oneof() ?
2023 SetOneofCase(message, field) : SetBit(message, field);
temporal40ee5512008-07-10 02:12:20 +00002024}
2025
2026template <typename Type>
2027inline Type* GeneratedMessageReflection::MutableField(
temporal779f61c2008-08-13 03:15:00 +00002028 Message* message, const FieldDescriptor* field) const {
jieluo@google.com4de8f552014-07-18 00:47:59 +00002029 field->containing_oneof() ?
2030 SetOneofCase(message, field) : SetBit(message, field);
temporal779f61c2008-08-13 03:15:00 +00002031 return MutableRaw<Type>(message, field);
temporal40ee5512008-07-10 02:12:20 +00002032}
2033
2034template <typename Type>
kenton@google.comfccb1462009-12-18 02:11:36 +00002035inline const Type& GeneratedMessageReflection::GetRepeatedField(
temporal779f61c2008-08-13 03:15:00 +00002036 const Message& message, const FieldDescriptor* field, int index) const {
kenton@google.com80b1d622009-07-29 01:13:20 +00002037 return GetRaw<RepeatedField<Type> >(message, field).Get(index);
2038}
2039
2040template <typename Type>
2041inline const Type& GeneratedMessageReflection::GetRepeatedPtrField(
2042 const Message& message, const FieldDescriptor* field, int index) const {
2043 return GetRaw<RepeatedPtrField<Type> >(message, field).Get(index);
temporal40ee5512008-07-10 02:12:20 +00002044}
2045
2046template <typename Type>
2047inline void GeneratedMessageReflection::SetRepeatedField(
temporal779f61c2008-08-13 03:15:00 +00002048 Message* message, const FieldDescriptor* field,
kenton@google.com80b1d622009-07-29 01:13:20 +00002049 int index, Type value) const {
2050 MutableRaw<RepeatedField<Type> >(message, field)->Set(index, value);
temporal40ee5512008-07-10 02:12:20 +00002051}
2052
2053template <typename Type>
2054inline Type* GeneratedMessageReflection::MutableRepeatedField(
temporal779f61c2008-08-13 03:15:00 +00002055 Message* message, const FieldDescriptor* field, int index) const {
kenton@google.com80b1d622009-07-29 01:13:20 +00002056 RepeatedPtrField<Type>* repeated =
2057 MutableRaw<RepeatedPtrField<Type> >(message, field);
2058 return repeated->Mutable(index);
temporal40ee5512008-07-10 02:12:20 +00002059}
2060
2061template <typename Type>
2062inline void GeneratedMessageReflection::AddField(
kenton@google.comfccb1462009-12-18 02:11:36 +00002063 Message* message, const FieldDescriptor* field, const Type& value) const {
kenton@google.com80b1d622009-07-29 01:13:20 +00002064 MutableRaw<RepeatedField<Type> >(message, field)->Add(value);
temporal40ee5512008-07-10 02:12:20 +00002065}
2066
2067template <typename Type>
2068inline Type* GeneratedMessageReflection::AddField(
temporal779f61c2008-08-13 03:15:00 +00002069 Message* message, const FieldDescriptor* field) const {
kenton@google.com80b1d622009-07-29 01:13:20 +00002070 RepeatedPtrField<Type>* repeated =
2071 MutableRaw<RepeatedPtrField<Type> >(message, field);
2072 return repeated->Add();
temporal40ee5512008-07-10 02:12:20 +00002073}
2074
Feng Xiao6ef984a2014-11-10 17:34:54 -08002075MessageFactory* GeneratedMessageReflection::GetMessageFactory() const {
2076 return message_factory_;
2077}
2078
2079void* GeneratedMessageReflection::RepeatedFieldData(
2080 Message* message, const FieldDescriptor* field,
2081 FieldDescriptor::CppType cpp_type,
2082 const Descriptor* message_type) const {
2083 GOOGLE_CHECK(field->is_repeated());
2084 GOOGLE_CHECK(field->cpp_type() == cpp_type ||
2085 (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM &&
2086 cpp_type == FieldDescriptor::CPPTYPE_INT32))
2087 << "The type parameter T in RepeatedFieldRef<T> API doesn't match "
2088 << "the actual field type (for enums T should be the generated enum "
2089 << "type or int32).";
2090 if (message_type != NULL) {
2091 GOOGLE_CHECK_EQ(message_type, field->message_type());
2092 }
2093 if (field->is_extension()) {
2094 return MutableExtensionSet(message)->MutableRawRepeatedField(
2095 field->number(), field->type(), field->is_packed(), field);
2096 } else {
2097 return reinterpret_cast<uint8*>(message) + offsets_[field->index()];
2098 }
2099}
2100
Feng Xiaof157a562014-11-14 11:50:31 -08002101GeneratedMessageReflection*
2102GeneratedMessageReflection::NewGeneratedMessageReflection(
2103 const Descriptor* descriptor,
2104 const Message* default_instance,
2105 const int offsets[],
2106 int has_bits_offset,
2107 int unknown_fields_offset,
2108 int extensions_offset,
2109 const void* default_oneof_instance,
2110 int oneof_case_offset,
2111 int object_size,
Feng Xiaoc25d9fe2014-11-26 16:15:29 -08002112 int arena_offset,
2113 int is_default_instance_offset) {
Feng Xiaof157a562014-11-14 11:50:31 -08002114 return new GeneratedMessageReflection(descriptor,
2115 default_instance,
2116 offsets,
2117 has_bits_offset,
2118 unknown_fields_offset,
2119 extensions_offset,
2120 default_oneof_instance,
2121 oneof_case_offset,
2122 DescriptorPool::generated_pool(),
2123 MessageFactory::generated_factory(),
2124 object_size,
Feng Xiaoc25d9fe2014-11-26 16:15:29 -08002125 arena_offset,
2126 is_default_instance_offset);
Feng Xiaof157a562014-11-14 11:50:31 -08002127}
2128
2129GeneratedMessageReflection*
2130GeneratedMessageReflection::NewGeneratedMessageReflection(
2131 const Descriptor* descriptor,
2132 const Message* default_instance,
2133 const int offsets[],
2134 int has_bits_offset,
2135 int unknown_fields_offset,
2136 int extensions_offset,
2137 int object_size,
Feng Xiaoc25d9fe2014-11-26 16:15:29 -08002138 int arena_offset,
2139 int is_default_instance_offset) {
Feng Xiaof157a562014-11-14 11:50:31 -08002140 return new GeneratedMessageReflection(descriptor,
2141 default_instance,
2142 offsets,
2143 has_bits_offset,
2144 unknown_fields_offset,
2145 extensions_offset,
2146 DescriptorPool::generated_pool(),
2147 MessageFactory::generated_factory(),
2148 object_size,
Feng Xiaoc25d9fe2014-11-26 16:15:29 -08002149 arena_offset,
2150 is_default_instance_offset);
Feng Xiaof157a562014-11-14 11:50:31 -08002151}
2152
temporal40ee5512008-07-10 02:12:20 +00002153} // namespace internal
2154} // namespace protobuf
2155} // namespace google