blob: 31f249b6b448ed3d4d6fe7af053ebd802206ec08 [file] [log] [blame]
Brian Silverman9c614bc2016-02-15 20:20:02 -05001// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc. All rights reserved.
3// https://developers.google.com/protocol-buffers/
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are
7// met:
8//
9// * Redistributions of source code must retain the above copyright
10// notice, this list of conditions and the following disclaimer.
11// * Redistributions in binary form must reproduce the above
12// copyright notice, this list of conditions and the following disclaimer
13// in the documentation and/or other materials provided with the
14// distribution.
15// * Neither the name of Google Inc. nor the names of its
16// contributors may be used to endorse or promote products derived from
17// this software without specific prior written permission.
18//
19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31// Author: kenton@google.com (Kenton Varda)
32// Based on original Protocol Buffers design by
33// Sanjay Ghemawat, Jeff Dean, and others.
34//
35// This header is logically internal, but is made public because it is used
36// from protocol-compiler-generated code, which may reside in other components.
37
38#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
39#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
40
41#include <string>
42#include <vector>
43#include <google/protobuf/stubs/casts.h>
44#include <google/protobuf/stubs/common.h>
45// TODO(jasonh): Remove this once the compiler change to directly include this
46// is released to components.
47#include <google/protobuf/generated_enum_reflection.h>
48#include <google/protobuf/message.h>
49#include <google/protobuf/metadata.h>
50#include <google/protobuf/unknown_field_set.h>
51
52
53namespace google {
54namespace upb {
55namespace google_opensource {
56class GMR_Handlers;
57} // namespace google_opensource
58} // namespace upb
59
60namespace protobuf {
61class DescriptorPool;
62class MapKey;
63class MapValueRef;
Austin Schuh40c16522018-10-28 20:27:54 -070064} // namespace protobuf
65
66
67namespace protobuf {
68namespace flat {
69class MetadataBuilder;
70} // namespace flat
71} // namespace protobuf
72
Brian Silverman9c614bc2016-02-15 20:20:02 -050073
74namespace protobuf {
75namespace internal {
76class DefaultEmptyOneof;
77
78// Defined in this file.
79class GeneratedMessageReflection;
80
81// Defined in other files.
82class ExtensionSet; // extension_set.h
Austin Schuh40c16522018-10-28 20:27:54 -070083class WeakFieldMap; // weak_field_map.h
84
85// This struct describes the internal layout of the message, hence this is
86// used to act on the message reflectively.
87// default_instance: The default instance of the message. This is only
88// used to obtain pointers to default instances of embedded
89// messages, which GetMessage() will return if the particular
90// sub-message has not been initialized yet. (Thus, all
91// embedded message fields *must* have non-NULL pointers
92// in the default instance.)
93// offsets: An array of ints giving the byte offsets.
94// For each oneof or weak field, the offset is relative to the
95// default_instance. These can be computed at compile time
96// using the
97// PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET()
98// macro. For each none oneof field, the offset is related to
99// the start of the message object. These can be computed at
100// compile time using the
101// GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET() macro.
102// Besides offsets for all fields, this array also contains
103// offsets for oneof unions. The offset of the i-th oneof union
104// is offsets[descriptor->field_count() + i].
105// has_bit_indices: Mapping from field indexes to their index in the has
106// bit array.
107// has_bits_offset: Offset in the message of an array of uint32s of size
108// descriptor->field_count()/32, rounded up. This is a
109// bitfield where each bit indicates whether or not the
110// corresponding field of the message has been initialized.
111// The bit for field index i is obtained by the expression:
112// has_bits[i / 32] & (1 << (i % 32))
113// unknown_fields_offset: Offset in the message of the UnknownFieldSet for
114// the message.
115// extensions_offset: Offset in the message of the ExtensionSet for the
116// message, or -1 if the message type has no extension
117// ranges.
118// oneof_case_offset: Offset in the message of an array of uint32s of
119// size descriptor->oneof_decl_count(). Each uint32
120// indicates what field is set for each oneof.
121// object_size: The size of a message object of this type, as measured
122// by sizeof().
123// arena_offset: If a message doesn't have a unknown_field_set that stores
124// the arena, it must have a direct pointer to the arena.
125// weak_field_map_offset: If the message proto has weak fields, this is the
126// offset of _weak_field_map_ in the generated proto. Otherwise
127// -1.
128struct ReflectionSchema {
129 public:
130 // Size of a google::protobuf::Message object of this type.
131 uint32 GetObjectSize() const { return static_cast<uint32>(object_size_); }
132
133 // Offset of a non-oneof field. Getting a field offset is slightly more
134 // efficient when we know statically that it is not a oneof field.
135 uint32 GetFieldOffsetNonOneof(const FieldDescriptor* field) const {
136 GOOGLE_DCHECK(!field->containing_oneof());
137 return OffsetValue(offsets_[field->index()], field->type());
138 }
139
140 // Offset of any field.
141 uint32 GetFieldOffset(const FieldDescriptor* field) const {
142 if (field->containing_oneof()) {
143 size_t offset =
144 static_cast<size_t>(field->containing_type()->field_count() +
145 field->containing_oneof()->index());
146 return OffsetValue(offsets_[offset], field->type());
147 } else {
148 return GetFieldOffsetNonOneof(field);
149 }
150 }
151
152 bool IsFieldInlined(const FieldDescriptor* field) const {
153 if (field->containing_oneof()) {
154 size_t offset =
155 static_cast<size_t>(field->containing_type()->field_count() +
156 field->containing_oneof()->index());
157 return Inlined(offsets_[offset], field->type());
158 } else {
159 return Inlined(offsets_[field->index()], field->type());
160 }
161 }
162
163 uint32 GetOneofCaseOffset(const OneofDescriptor* oneof_descriptor) const {
164 return static_cast<uint32>(oneof_case_offset_) +
165 static_cast<uint32>(
166 static_cast<size_t>(oneof_descriptor->index()) * sizeof(uint32));
167 }
168
169 bool HasHasbits() const { return has_bits_offset_ != -1; }
170
171 // Bit index within the bit array of hasbits. Bit order is low-to-high.
172 uint32 HasBitIndex(const FieldDescriptor* field) const {
173 GOOGLE_DCHECK(HasHasbits());
174 return has_bit_indices_[field->index()];
175 }
176
177 // Byte offset of the hasbits array.
178 uint32 HasBitsOffset() const {
179 GOOGLE_DCHECK(HasHasbits());
180 return static_cast<uint32>(has_bits_offset_);
181 }
182
183 // The offset of the InternalMetadataWithArena member.
184 // For Lite this will actually be an InternalMetadataWithArenaLite.
185 // The schema doesn't contain enough information to distinguish between
186 // these two cases.
187 uint32 GetMetadataOffset() const {
188 return static_cast<uint32>(metadata_offset_);
189 }
190
191 // Whether this message has an ExtensionSet.
192 bool HasExtensionSet() const { return extensions_offset_ != -1; }
193
194 // The offset of the ExtensionSet in this message.
195 uint32 GetExtensionSetOffset() const {
196 GOOGLE_DCHECK(HasExtensionSet());
197 return static_cast<uint32>(extensions_offset_);
198 }
199
200 // The off set of WeakFieldMap when the message contains weak fields.
201 // The default is 0 for now.
202 int GetWeakFieldMapOffset() const { return weak_field_map_offset_; }
203
204 bool IsDefaultInstance(const Message& message) const {
205 return &message == default_instance_;
206 }
207
208 // Returns a pointer to the default value for this field. The size and type
209 // of the underlying data depends on the field's type.
210 const void *GetFieldDefault(const FieldDescriptor* field) const {
211 return reinterpret_cast<const uint8*>(default_instance_) +
212 OffsetValue(offsets_[field->index()], field->type());
213 }
214
215
216 bool HasWeakFields() const { return weak_field_map_offset_ > 0; }
217
218 // These members are intended to be private, but we cannot actually make them
219 // private because this prevents us from using aggregate initialization of
220 // them, ie.
221 //
222 // ReflectionSchema schema = {a, b, c, d, e, ...};
223 // private:
224 const Message* default_instance_;
225 const uint32* offsets_;
226 const uint32* has_bit_indices_;
227 int has_bits_offset_;
228 int metadata_offset_;
229 int extensions_offset_;
230 int oneof_case_offset_;
231 int object_size_;
232 int weak_field_map_offset_;
233
234 // We tag offset values to provide additional data about fields (such as
235 // inlined).
236 static uint32 OffsetValue(uint32 v, FieldDescriptor::Type type) {
237 if (type == FieldDescriptor::TYPE_STRING ||
238 type == FieldDescriptor::TYPE_BYTES) {
239 return v & ~1u;
240 } else {
241 return v;
242 }
243 }
244
245 static bool Inlined(uint32 v, FieldDescriptor::Type type) {
246 if (type == FieldDescriptor::TYPE_STRING ||
247 type == FieldDescriptor::TYPE_BYTES) {
248 return v & 1u;
249 } else {
250 // Non string/byte fields are not inlined.
251 return false;
252 }
253 }
254};
255
256// Structs that the code generator emits directly to describe a message.
257// These should never used directly except to build a ReflectionSchema
258// object.
259//
260// EXPERIMENTAL: these are changing rapidly, and may completely disappear
261// or merge with ReflectionSchema.
262struct MigrationSchema {
263 int32 offsets_index;
264 int32 has_bit_indices_index;
265 int object_size;
266};
Brian Silverman9c614bc2016-02-15 20:20:02 -0500267
268// THIS CLASS IS NOT INTENDED FOR DIRECT USE. It is intended for use
269// by generated code. This class is just a big hack that reduces code
270// size.
271//
272// A GeneratedMessageReflection is an implementation of Reflection
273// which expects all fields to be backed by simple variables located in
274// memory. The locations are given using a base pointer and a set of
275// offsets.
276//
277// It is required that the user represents fields of each type in a standard
278// way, so that GeneratedMessageReflection can cast the void* pointer to
279// the appropriate type. For primitive fields and string fields, each field
280// should be represented using the obvious C++ primitive type. Enums and
281// Messages are different:
282// - Singular Message fields are stored as a pointer to a Message. These
283// should start out NULL, except for in the default instance where they
284// should start out pointing to other default instances.
285// - Enum fields are stored as an int. This int must always contain
286// a valid value, such that EnumDescriptor::FindValueByNumber() would
287// not return NULL.
288// - Repeated fields are stored as RepeatedFields or RepeatedPtrFields
289// of whatever type the individual field would be. Strings and
290// Messages use RepeatedPtrFields while everything else uses
291// RepeatedFields.
Austin Schuh40c16522018-10-28 20:27:54 -0700292class GeneratedMessageReflection final : public Reflection {
Brian Silverman9c614bc2016-02-15 20:20:02 -0500293 public:
294 // Constructs a GeneratedMessageReflection.
295 // Parameters:
296 // descriptor: The descriptor for the message type being implemented.
Austin Schuh40c16522018-10-28 20:27:54 -0700297 // schema: The description of the internal guts of the message.
Brian Silverman9c614bc2016-02-15 20:20:02 -0500298 // pool: DescriptorPool to search for extension definitions. Only
299 // used by FindKnownExtensionByName() and
300 // FindKnownExtensionByNumber().
301 // factory: MessageFactory to use to construct extension messages.
Brian Silverman9c614bc2016-02-15 20:20:02 -0500302 GeneratedMessageReflection(const Descriptor* descriptor,
Austin Schuh40c16522018-10-28 20:27:54 -0700303 const ReflectionSchema& schema,
Brian Silverman9c614bc2016-02-15 20:20:02 -0500304 const DescriptorPool* pool,
Austin Schuh40c16522018-10-28 20:27:54 -0700305 MessageFactory* factory);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500306
Brian Silverman9c614bc2016-02-15 20:20:02 -0500307 ~GeneratedMessageReflection();
308
Brian Silverman9c614bc2016-02-15 20:20:02 -0500309 // implements Reflection -------------------------------------------
310
311 const UnknownFieldSet& GetUnknownFields(const Message& message) const;
312 UnknownFieldSet* MutableUnknownFields(Message* message) const;
313
Austin Schuh40c16522018-10-28 20:27:54 -0700314 size_t SpaceUsedLong(const Message& message) const;
Brian Silverman9c614bc2016-02-15 20:20:02 -0500315
316 bool HasField(const Message& message, const FieldDescriptor* field) const;
317 int FieldSize(const Message& message, const FieldDescriptor* field) const;
318 void ClearField(Message* message, const FieldDescriptor* field) const;
319 bool HasOneof(const Message& message,
320 const OneofDescriptor* oneof_descriptor) const;
321 void ClearOneof(Message* message, const OneofDescriptor* field) const;
322 void RemoveLast(Message* message, const FieldDescriptor* field) const;
323 Message* ReleaseLast(Message* message, const FieldDescriptor* field) const;
324 void Swap(Message* message1, Message* message2) const;
325 void SwapFields(Message* message1, Message* message2,
Austin Schuh40c16522018-10-28 20:27:54 -0700326 const std::vector<const FieldDescriptor*>& fields) const;
Brian Silverman9c614bc2016-02-15 20:20:02 -0500327 void SwapElements(Message* message, const FieldDescriptor* field,
328 int index1, int index2) const;
329 void ListFields(const Message& message,
Austin Schuh40c16522018-10-28 20:27:54 -0700330 std::vector<const FieldDescriptor*>* output) const;
Brian Silverman9c614bc2016-02-15 20:20:02 -0500331
332 int32 GetInt32 (const Message& message,
333 const FieldDescriptor* field) const;
334 int64 GetInt64 (const Message& message,
335 const FieldDescriptor* field) const;
336 uint32 GetUInt32(const Message& message,
337 const FieldDescriptor* field) const;
338 uint64 GetUInt64(const Message& message,
339 const FieldDescriptor* field) const;
340 float GetFloat (const Message& message,
341 const FieldDescriptor* field) const;
342 double GetDouble(const Message& message,
343 const FieldDescriptor* field) const;
344 bool GetBool (const Message& message,
345 const FieldDescriptor* field) const;
346 string GetString(const Message& message,
347 const FieldDescriptor* field) const;
348 const string& GetStringReference(const Message& message,
349 const FieldDescriptor* field,
350 string* scratch) const;
351 const EnumValueDescriptor* GetEnum(const Message& message,
352 const FieldDescriptor* field) const;
353 int GetEnumValue(const Message& message,
354 const FieldDescriptor* field) const;
355 const Message& GetMessage(const Message& message,
356 const FieldDescriptor* field,
357 MessageFactory* factory = NULL) const;
358
359 const FieldDescriptor* GetOneofFieldDescriptor(
360 const Message& message,
361 const OneofDescriptor* oneof_descriptor) const;
362
363 private:
364 bool ContainsMapKey(const Message& message,
365 const FieldDescriptor* field,
366 const MapKey& key) const;
367 bool InsertOrLookupMapValue(Message* message,
368 const FieldDescriptor* field,
369 const MapKey& key,
370 MapValueRef* val) const;
371 bool DeleteMapValue(Message* message,
372 const FieldDescriptor* field,
373 const MapKey& key) const;
374 MapIterator MapBegin(
375 Message* message,
376 const FieldDescriptor* field) const;
377 MapIterator MapEnd(
378 Message* message,
379 const FieldDescriptor* field) const;
380 int MapSize(const Message& message, const FieldDescriptor* field) const;
381
382 public:
383 void SetInt32 (Message* message,
384 const FieldDescriptor* field, int32 value) const;
385 void SetInt64 (Message* message,
386 const FieldDescriptor* field, int64 value) const;
387 void SetUInt32(Message* message,
388 const FieldDescriptor* field, uint32 value) const;
389 void SetUInt64(Message* message,
390 const FieldDescriptor* field, uint64 value) const;
391 void SetFloat (Message* message,
392 const FieldDescriptor* field, float value) const;
393 void SetDouble(Message* message,
394 const FieldDescriptor* field, double value) const;
395 void SetBool (Message* message,
396 const FieldDescriptor* field, bool value) const;
397 void SetString(Message* message,
398 const FieldDescriptor* field,
399 const string& value) const;
400 void SetEnum (Message* message, const FieldDescriptor* field,
401 const EnumValueDescriptor* value) const;
402 void SetEnumValue(Message* message, const FieldDescriptor* field,
403 int value) const;
404 Message* MutableMessage(Message* message, const FieldDescriptor* field,
405 MessageFactory* factory = NULL) const;
406 void SetAllocatedMessage(Message* message,
407 Message* sub_message,
408 const FieldDescriptor* field) const;
409 Message* ReleaseMessage(Message* message, const FieldDescriptor* field,
410 MessageFactory* factory = NULL) const;
411
412 int32 GetRepeatedInt32 (const Message& message,
413 const FieldDescriptor* field, int index) const;
414 int64 GetRepeatedInt64 (const Message& message,
415 const FieldDescriptor* field, int index) const;
416 uint32 GetRepeatedUInt32(const Message& message,
417 const FieldDescriptor* field, int index) const;
418 uint64 GetRepeatedUInt64(const Message& message,
419 const FieldDescriptor* field, int index) const;
420 float GetRepeatedFloat (const Message& message,
421 const FieldDescriptor* field, int index) const;
422 double GetRepeatedDouble(const Message& message,
423 const FieldDescriptor* field, int index) const;
424 bool GetRepeatedBool (const Message& message,
425 const FieldDescriptor* field, int index) const;
426 string GetRepeatedString(const Message& message,
427 const FieldDescriptor* field, int index) const;
428 const string& GetRepeatedStringReference(const Message& message,
429 const FieldDescriptor* field,
430 int index, string* scratch) const;
431 const EnumValueDescriptor* GetRepeatedEnum(const Message& message,
432 const FieldDescriptor* field,
433 int index) const;
434 int GetRepeatedEnumValue(const Message& message,
435 const FieldDescriptor* field,
436 int index) const;
437 const Message& GetRepeatedMessage(const Message& message,
438 const FieldDescriptor* field,
439 int index) const;
440
441 // Set the value of a field.
442 void SetRepeatedInt32 (Message* message,
443 const FieldDescriptor* field, int index, int32 value) const;
444 void SetRepeatedInt64 (Message* message,
445 const FieldDescriptor* field, int index, int64 value) const;
446 void SetRepeatedUInt32(Message* message,
447 const FieldDescriptor* field, int index, uint32 value) const;
448 void SetRepeatedUInt64(Message* message,
449 const FieldDescriptor* field, int index, uint64 value) const;
450 void SetRepeatedFloat (Message* message,
451 const FieldDescriptor* field, int index, float value) const;
452 void SetRepeatedDouble(Message* message,
453 const FieldDescriptor* field, int index, double value) const;
454 void SetRepeatedBool (Message* message,
455 const FieldDescriptor* field, int index, bool value) const;
456 void SetRepeatedString(Message* message,
457 const FieldDescriptor* field, int index,
458 const string& value) const;
459 void SetRepeatedEnum(Message* message, const FieldDescriptor* field,
460 int index, const EnumValueDescriptor* value) const;
461 void SetRepeatedEnumValue(Message* message, const FieldDescriptor* field,
462 int index, int value) const;
463 // Get a mutable pointer to a field with a message type.
464 Message* MutableRepeatedMessage(Message* message,
465 const FieldDescriptor* field,
466 int index) const;
467
468 void AddInt32 (Message* message,
469 const FieldDescriptor* field, int32 value) const;
470 void AddInt64 (Message* message,
471 const FieldDescriptor* field, int64 value) const;
472 void AddUInt32(Message* message,
473 const FieldDescriptor* field, uint32 value) const;
474 void AddUInt64(Message* message,
475 const FieldDescriptor* field, uint64 value) const;
476 void AddFloat (Message* message,
477 const FieldDescriptor* field, float value) const;
478 void AddDouble(Message* message,
479 const FieldDescriptor* field, double value) const;
480 void AddBool (Message* message,
481 const FieldDescriptor* field, bool value) const;
482 void AddString(Message* message,
483 const FieldDescriptor* field, const string& value) const;
484 void AddEnum(Message* message,
485 const FieldDescriptor* field,
486 const EnumValueDescriptor* value) const;
487 void AddEnumValue(Message* message,
488 const FieldDescriptor* field,
489 int value) const;
490 Message* AddMessage(Message* message, const FieldDescriptor* field,
491 MessageFactory* factory = NULL) const;
492 void AddAllocatedMessage(
493 Message* message, const FieldDescriptor* field,
494 Message* new_entry) const;
495
496 const FieldDescriptor* FindKnownExtensionByName(const string& name) const;
497 const FieldDescriptor* FindKnownExtensionByNumber(int number) const;
498
499 bool SupportsUnknownEnumValues() const;
500
501 // This value for arena_offset_ indicates that there is no arena pointer in
502 // this message (e.g., old generated code).
503 static const int kNoArenaPointer = -1;
504
505 // This value for unknown_field_offset_ indicates that there is no
506 // UnknownFieldSet in this message, and that instead, we are using the
507 // Zero-Overhead Arena Pointer trick. When this is the case, arena_offset_
508 // actually indexes to an InternalMetadataWithArena instance, which can return
509 // either an arena pointer or an UnknownFieldSet or both. It is never the case
510 // that unknown_field_offset_ == kUnknownFieldSetInMetadata && arena_offset_
511 // == kNoArenaPointer.
512 static const int kUnknownFieldSetInMetadata = -1;
513
514 protected:
515 void* MutableRawRepeatedField(
516 Message* message, const FieldDescriptor* field, FieldDescriptor::CppType,
517 int ctype, const Descriptor* desc) const;
518
519 const void* GetRawRepeatedField(
520 const Message& message, const FieldDescriptor* field,
521 FieldDescriptor::CppType, int ctype,
522 const Descriptor* desc) const;
523
524 virtual MessageFactory* GetMessageFactory() const;
525
526 virtual void* RepeatedFieldData(
527 Message* message, const FieldDescriptor* field,
528 FieldDescriptor::CppType cpp_type,
529 const Descriptor* message_type) const;
530
531 private:
Austin Schuh40c16522018-10-28 20:27:54 -0700532 friend class google::protobuf::flat::MetadataBuilder;
Brian Silverman9c614bc2016-02-15 20:20:02 -0500533 friend class upb::google_opensource::GMR_Handlers;
534
Austin Schuh40c16522018-10-28 20:27:54 -0700535 const Descriptor* const descriptor_;
536 const ReflectionSchema schema_;
537 const DescriptorPool* const descriptor_pool_;
538 MessageFactory* const message_factory_;
Brian Silverman9c614bc2016-02-15 20:20:02 -0500539
Austin Schuh40c16522018-10-28 20:27:54 -0700540 // Last non weak field index. This is an optimization when most weak fields
541 // are at the end of the containing message. If a message proto doesn't
542 // contain weak fields, then this field equals descriptor_->field_count().
543 int last_non_weak_field_index_;
Brian Silverman9c614bc2016-02-15 20:20:02 -0500544
Austin Schuh40c16522018-10-28 20:27:54 -0700545 template <class T>
546 const T& GetRawNonOneof(const Message& message,
547 const FieldDescriptor* field) const;
548 template <class T>
549 T* MutableRawNonOneof(Message* message, const FieldDescriptor* field) const;
Brian Silverman9c614bc2016-02-15 20:20:02 -0500550
551 template <typename Type>
Austin Schuh40c16522018-10-28 20:27:54 -0700552 const Type& GetRaw(const Message& message,
Brian Silverman9c614bc2016-02-15 20:20:02 -0500553 const FieldDescriptor* field) const;
554 template <typename Type>
555 inline Type* MutableRaw(Message* message,
556 const FieldDescriptor* field) const;
557 template <typename Type>
558 inline const Type& DefaultRaw(const FieldDescriptor* field) const;
Brian Silverman9c614bc2016-02-15 20:20:02 -0500559
560 inline const uint32* GetHasBits(const Message& message) const;
561 inline uint32* MutableHasBits(Message* message) const;
562 inline uint32 GetOneofCase(
563 const Message& message,
564 const OneofDescriptor* oneof_descriptor) const;
565 inline uint32* MutableOneofCase(
566 Message* message,
567 const OneofDescriptor* oneof_descriptor) const;
568 inline const ExtensionSet& GetExtensionSet(const Message& message) const;
569 inline ExtensionSet* MutableExtensionSet(Message* message) const;
570 inline Arena* GetArena(Message* message) const;
Austin Schuh40c16522018-10-28 20:27:54 -0700571
572 inline const InternalMetadataWithArena& GetInternalMetadataWithArena(
573 const Message& message) const;
574
575 inline InternalMetadataWithArena*
Brian Silverman9c614bc2016-02-15 20:20:02 -0500576 MutableInternalMetadataWithArena(Message* message) const;
577
Austin Schuh40c16522018-10-28 20:27:54 -0700578 inline bool IsInlined(const FieldDescriptor* field) const;
Brian Silverman9c614bc2016-02-15 20:20:02 -0500579
580 inline bool HasBit(const Message& message,
581 const FieldDescriptor* field) const;
582 inline void SetBit(Message* message,
583 const FieldDescriptor* field) const;
584 inline void ClearBit(Message* message,
585 const FieldDescriptor* field) const;
586 inline void SwapBit(Message* message1,
587 Message* message2,
588 const FieldDescriptor* field) const;
589
590 // This function only swaps the field. Should swap corresponding has_bit
591 // before or after using this function.
592 void SwapField(Message* message1,
593 Message* message2,
594 const FieldDescriptor* field) const;
595
596 void SwapOneofField(Message* message1,
597 Message* message2,
598 const OneofDescriptor* oneof_descriptor) const;
599
600 inline bool HasOneofField(const Message& message,
601 const FieldDescriptor* field) const;
602 inline void SetOneofCase(Message* message,
603 const FieldDescriptor* field) const;
604 inline void ClearOneofField(Message* message,
605 const FieldDescriptor* field) const;
606
607 template <typename Type>
608 inline const Type& GetField(const Message& message,
609 const FieldDescriptor* field) const;
610 template <typename Type>
611 inline void SetField(Message* message,
612 const FieldDescriptor* field, const Type& value) const;
613 template <typename Type>
614 inline Type* MutableField(Message* message,
615 const FieldDescriptor* field) const;
616 template <typename Type>
617 inline const Type& GetRepeatedField(const Message& message,
618 const FieldDescriptor* field,
619 int index) const;
620 template <typename Type>
621 inline const Type& GetRepeatedPtrField(const Message& message,
622 const FieldDescriptor* field,
623 int index) const;
624 template <typename Type>
625 inline void SetRepeatedField(Message* message,
626 const FieldDescriptor* field, int index,
627 Type value) const;
628 template <typename Type>
629 inline Type* MutableRepeatedField(Message* message,
630 const FieldDescriptor* field,
631 int index) const;
632 template <typename Type>
633 inline void AddField(Message* message,
634 const FieldDescriptor* field, const Type& value) const;
635 template <typename Type>
636 inline Type* AddField(Message* message,
637 const FieldDescriptor* field) const;
638
639 int GetExtensionNumberOrDie(const Descriptor* type) const;
640
641 // Internal versions of EnumValue API perform no checking. Called after checks
642 // by public methods.
643 void SetEnumValueInternal(Message* message,
644 const FieldDescriptor* field,
645 int value) const;
646 void SetRepeatedEnumValueInternal(Message* message,
647 const FieldDescriptor* field,
648 int index,
649 int value) const;
650 void AddEnumValueInternal(Message* message,
651 const FieldDescriptor* field,
652 int value) const;
653
654
655 Message* UnsafeArenaReleaseMessage(Message* message,
656 const FieldDescriptor* field,
657 MessageFactory* factory = NULL) const;
658
659 void UnsafeArenaSetAllocatedMessage(Message* message,
660 Message* sub_message,
661 const FieldDescriptor* field) const;
662
663 internal::MapFieldBase* MapData(
664 Message* message, const FieldDescriptor* field) const;
665
Austin Schuh40c16522018-10-28 20:27:54 -0700666 friend inline // inline so nobody can call this function.
667 void
668 RegisterAllTypesInternal(const Metadata* file_level_metadata, int size);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500669 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratedMessageReflection);
670};
671
Brian Silverman9c614bc2016-02-15 20:20:02 -0500672// There are some places in proto2 where dynamic_cast would be useful as an
673// optimization. For example, take Message::MergeFrom(const Message& other).
674// For a given generated message FooMessage, we generate these two methods:
675// void MergeFrom(const FooMessage& other);
676// void MergeFrom(const Message& other);
677// The former method can be implemented directly in terms of FooMessage's
678// inline accessors, but the latter method must work with the reflection
679// interface. However, if the parameter to the latter method is actually of
680// type FooMessage, then we'd like to be able to just call the other method
681// as an optimization. So, we use dynamic_cast to check this.
682//
683// That said, dynamic_cast requires RTTI, which many people like to disable
684// for performance and code size reasons. When RTTI is not available, we
685// still need to produce correct results. So, in this case we have to fall
686// back to using reflection, which is what we would have done anyway if the
687// objects were not of the exact same class.
688//
689// dynamic_cast_if_available() implements this logic. If RTTI is
690// enabled, it does a dynamic_cast. If RTTI is disabled, it just returns
691// NULL.
Brian Silverman9c614bc2016-02-15 20:20:02 -0500692template<typename To, typename From>
693inline To dynamic_cast_if_available(From from) {
Austin Schuh40c16522018-10-28 20:27:54 -0700694#ifdef GOOGLE_PROTOBUF_NO_RTTI
695 // Avoid the compiler warning about unused variables.
696 (void)from;
Brian Silverman9c614bc2016-02-15 20:20:02 -0500697 return NULL;
698#else
699 return dynamic_cast<To>(from);
700#endif
701}
702
703// Tries to downcast this message to a generated message type.
704// Returns NULL if this class is not an instance of T.
705//
706// This is like dynamic_cast_if_available, except it works even when
707// dynamic_cast is not available by using Reflection. However it only works
708// with Message objects.
709//
710// TODO(haberman): can we remove dynamic_cast_if_available in favor of this?
711template <typename T>
712T* DynamicCastToGenerated(const Message* from) {
713 // Compile-time assert that T is a generated type that has a
714 // default_instance() accessor, but avoid actually calling it.
715 const T&(*get_default_instance)() = &T::default_instance;
716 (void)get_default_instance;
717
718 // Compile-time assert that T is a subclass of google::protobuf::Message.
719 const Message* unused = static_cast<T*>(NULL);
720 (void)unused;
721
Austin Schuh40c16522018-10-28 20:27:54 -0700722#ifdef GOOGLE_PROTOBUF_NO_RTTI
Brian Silverman9c614bc2016-02-15 20:20:02 -0500723 bool ok = &T::default_instance() ==
724 from->GetReflection()->GetMessageFactory()->GetPrototype(
725 from->GetDescriptor());
726 return ok ? down_cast<T*>(from) : NULL;
727#else
728 return dynamic_cast<T*>(from);
729#endif
730}
731
732template <typename T>
733T* DynamicCastToGenerated(Message* from) {
734 const Message* message_const = from;
735 return const_cast<T*>(DynamicCastToGenerated<const T>(message_const));
736}
737
Austin Schuh40c16522018-10-28 20:27:54 -0700738LIBPROTOBUF_EXPORT void AssignDescriptors(
739 const string& filename, const MigrationSchema* schemas,
740 const Message* const* default_instances_, const uint32* offsets,
741 // update the following descriptor arrays.
742 Metadata* file_level_metadata,
743 const EnumDescriptor** file_level_enum_descriptors,
744 const ServiceDescriptor** file_level_service_descriptors);
745
746LIBPROTOBUF_EXPORT void RegisterAllTypes(const Metadata* file_level_metadata, int size);
747
748// These cannot be in lite so we put them in the reflection.
749LIBPROTOBUF_EXPORT void UnknownFieldSetSerializer(const uint8* base, uint32 offset, uint32 tag,
750 uint32 has_offset,
751 ::google::protobuf::io::CodedOutputStream* output);
752
Brian Silverman9c614bc2016-02-15 20:20:02 -0500753} // namespace internal
754} // namespace protobuf
755
756} // namespace google
757#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__