15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Protocol Buffers - Google's data interchange format
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2008 Google Inc.  All rights reserved.
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://code.google.com/p/protobuf/
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Redistribution and use in source and binary forms, with or without
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// modification, are permitted provided that the following conditions are
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// met:
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Redistributions of source code must retain the above copyright
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// notice, this list of conditions and the following disclaimer.
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Redistributions in binary form must reproduce the above
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// copyright notice, this list of conditions and the following disclaimer
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the documentation and/or other materials provided with the
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// distribution.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Neither the name of Google Inc. nor the names of its
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// contributors may be used to endorse or promote products derived from
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this software without specific prior written permission.
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Author: kenton@google.com (Kenton Varda)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  Based on original Protocol Buffers design by
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  Sanjay Ghemawat, Jeff Dean, and others.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This header is logically internal, but is made public because it is used
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// from protocol-compiler-generated code, which may reside in other components.
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
433d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch#include <google/protobuf/stubs/common.h>
443d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch// TODO(jasonh): Remove this once the compiler change to directly include this
453d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch// is released to components.
463d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch#include <google/protobuf/generated_enum_reflection.h>
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/message.h>
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/unknown_field_set.h>
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace google {
523d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdochnamespace upb {
533d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdochnamespace proto2_bridge_opensource {
543d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdochclass FieldAccessor;
553d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch}  // namespace protobuf_bridge_google3
563d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch}  // namespace upb
573d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace protobuf {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class DescriptorPool;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace protobuf {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Defined in this file.
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GeneratedMessageReflection;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Defined in other files.
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ExtensionSet;             // extension_set.h
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THIS CLASS IS NOT INTENDED FOR DIRECT USE.  It is intended for use
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// by generated code.  This class is just a big hack that reduces code
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// size.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A GeneratedMessageReflection is an implementation of Reflection
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// which expects all fields to be backed by simple variables located in
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// memory.  The locations are given using a base pointer and a set of
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// offsets.
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It is required that the user represents fields of each type in a standard
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// way, so that GeneratedMessageReflection can cast the void* pointer to
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the appropriate type.  For primitive fields and string fields, each field
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// should be represented using the obvious C++ primitive type.  Enums and
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Messages are different:
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  - Singular Message fields are stored as a pointer to a Message.  These
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    should start out NULL, except for in the default instance where they
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    should start out pointing to other default instances.
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  - Enum fields are stored as an int.  This int must always contain
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    a valid value, such that EnumDescriptor::FindValueByNumber() would
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    not return NULL.
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  - Repeated fields are stored as RepeatedFields or RepeatedPtrFields
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    of whatever type the individual field would be.  Strings and
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    Messages use RepeatedPtrFields while everything else uses
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    RepeatedFields.
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Constructs a GeneratedMessageReflection.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Parameters:
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   descriptor:    The descriptor for the message type being implemented.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   default_instance:  The default instance of the message.  This is only
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //                  used to obtain pointers to default instances of embedded
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //                  messages, which GetMessage() will return if the particular
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //                  sub-message has not been initialized yet.  (Thus, all
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //                  embedded message fields *must* have non-NULL pointers
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //                  in the default instance.)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   offsets:       An array of ints giving the byte offsets, relative to
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //                  the start of the message object, of each field.  These can
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //                  be computed at compile time using the
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //                  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET() macro, defined
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //                  below.
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   has_bits_offset:  Offset in the message of an array of uint32s of size
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //                  descriptor->field_count()/32, rounded up.  This is a
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //                  bitfield where each bit indicates whether or not the
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //                  corresponding field of the message has been initialized.
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //                  The bit for field index i is obtained by the expression:
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //                    has_bits[i / 32] & (1 << (i % 32))
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   unknown_fields_offset:  Offset in the message of the UnknownFieldSet for
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //                  the message.
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   extensions_offset:  Offset in the message of the ExtensionSet for the
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //                  message, or -1 if the message type has no extension
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //                  ranges.
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   pool:          DescriptorPool to search for extension definitions.  Only
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //                  used by FindKnownExtensionByName() and
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //                  FindKnownExtensionByNumber().
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   factory:       MessageFactory to use to construct extension messages.
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   object_size:   The size of a message object of this type, as measured
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //                  by sizeof().
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GeneratedMessageReflection(const Descriptor* descriptor,
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const Message* default_instance,
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const int offsets[],
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             int has_bits_offset,
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             int unknown_fields_offset,
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             int extensions_offset,
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const DescriptorPool* pool,
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             MessageFactory* factory,
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             int object_size);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~GeneratedMessageReflection();
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // implements Reflection -------------------------------------------
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const UnknownFieldSet& GetUnknownFields(const Message& message) const;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UnknownFieldSet* MutableUnknownFields(Message* message) const;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int SpaceUsed(const Message& message) const;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool HasField(const Message& message, const FieldDescriptor* field) const;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int FieldSize(const Message& message, const FieldDescriptor* field) const;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ClearField(Message* message, const FieldDescriptor* field) const;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RemoveLast(Message* message, const FieldDescriptor* field) const;
1503d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch  Message* ReleaseLast(Message* message, const FieldDescriptor* field) const;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Swap(Message* message1, Message* message2) const;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SwapElements(Message* message, const FieldDescriptor* field,
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            int index1, int index2) const;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ListFields(const Message& message,
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  vector<const FieldDescriptor*>* output) const;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32  GetInt32 (const Message& message,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   const FieldDescriptor* field) const;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64  GetInt64 (const Message& message,
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   const FieldDescriptor* field) const;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 GetUInt32(const Message& message,
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   const FieldDescriptor* field) const;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint64 GetUInt64(const Message& message,
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   const FieldDescriptor* field) const;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  float  GetFloat (const Message& message,
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   const FieldDescriptor* field) const;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  double GetDouble(const Message& message,
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   const FieldDescriptor* field) const;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool   GetBool  (const Message& message,
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   const FieldDescriptor* field) const;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string GetString(const Message& message,
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   const FieldDescriptor* field) const;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const string& GetStringReference(const Message& message,
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const FieldDescriptor* field,
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   string* scratch) const;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const EnumValueDescriptor* GetEnum(const Message& message,
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     const FieldDescriptor* field) const;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Message& GetMessage(const Message& message,
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const FieldDescriptor* field,
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            MessageFactory* factory = NULL) const;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetInt32 (Message* message,
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 const FieldDescriptor* field, int32  value) const;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetInt64 (Message* message,
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 const FieldDescriptor* field, int64  value) const;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetUInt32(Message* message,
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 const FieldDescriptor* field, uint32 value) const;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetUInt64(Message* message,
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 const FieldDescriptor* field, uint64 value) const;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetFloat (Message* message,
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 const FieldDescriptor* field, float  value) const;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetDouble(Message* message,
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 const FieldDescriptor* field, double value) const;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetBool  (Message* message,
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 const FieldDescriptor* field, bool   value) const;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetString(Message* message,
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 const FieldDescriptor* field,
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 const string& value) const;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetEnum  (Message* message, const FieldDescriptor* field,
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 const EnumValueDescriptor* value) const;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Message* MutableMessage(Message* message, const FieldDescriptor* field,
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          MessageFactory* factory = NULL) const;
2033d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch  Message* ReleaseMessage(Message* message, const FieldDescriptor* field,
2043d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch                          MessageFactory* factory = NULL) const;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32  GetRepeatedInt32 (const Message& message,
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const FieldDescriptor* field, int index) const;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64  GetRepeatedInt64 (const Message& message,
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const FieldDescriptor* field, int index) const;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 GetRepeatedUInt32(const Message& message,
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const FieldDescriptor* field, int index) const;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint64 GetRepeatedUInt64(const Message& message,
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const FieldDescriptor* field, int index) const;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  float  GetRepeatedFloat (const Message& message,
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const FieldDescriptor* field, int index) const;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  double GetRepeatedDouble(const Message& message,
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const FieldDescriptor* field, int index) const;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool   GetRepeatedBool  (const Message& message,
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const FieldDescriptor* field, int index) const;
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string GetRepeatedString(const Message& message,
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const FieldDescriptor* field, int index) const;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const string& GetRepeatedStringReference(const Message& message,
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           const FieldDescriptor* field,
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           int index, string* scratch) const;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const EnumValueDescriptor* GetRepeatedEnum(const Message& message,
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             const FieldDescriptor* field,
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             int index) const;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Message& GetRepeatedMessage(const Message& message,
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const FieldDescriptor* field,
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    int index) const;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set the value of a field.
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetRepeatedInt32 (Message* message,
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         const FieldDescriptor* field, int index, int32  value) const;
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetRepeatedInt64 (Message* message,
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         const FieldDescriptor* field, int index, int64  value) const;
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetRepeatedUInt32(Message* message,
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         const FieldDescriptor* field, int index, uint32 value) const;
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetRepeatedUInt64(Message* message,
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         const FieldDescriptor* field, int index, uint64 value) const;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetRepeatedFloat (Message* message,
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         const FieldDescriptor* field, int index, float  value) const;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetRepeatedDouble(Message* message,
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         const FieldDescriptor* field, int index, double value) const;
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetRepeatedBool  (Message* message,
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         const FieldDescriptor* field, int index, bool   value) const;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetRepeatedString(Message* message,
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         const FieldDescriptor* field, int index,
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         const string& value) const;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetRepeatedEnum(Message* message, const FieldDescriptor* field,
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       int index, const EnumValueDescriptor* value) const;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get a mutable pointer to a field with a message type.
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Message* MutableRepeatedMessage(Message* message,
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const FieldDescriptor* field,
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  int index) const;
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddInt32 (Message* message,
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 const FieldDescriptor* field, int32  value) const;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddInt64 (Message* message,
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 const FieldDescriptor* field, int64  value) const;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddUInt32(Message* message,
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 const FieldDescriptor* field, uint32 value) const;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddUInt64(Message* message,
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 const FieldDescriptor* field, uint64 value) const;
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddFloat (Message* message,
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 const FieldDescriptor* field, float  value) const;
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddDouble(Message* message,
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 const FieldDescriptor* field, double value) const;
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddBool  (Message* message,
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 const FieldDescriptor* field, bool   value) const;
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddString(Message* message,
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 const FieldDescriptor* field, const string& value) const;
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddEnum(Message* message,
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               const FieldDescriptor* field,
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               const EnumValueDescriptor* value) const;
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Message* AddMessage(Message* message, const FieldDescriptor* field,
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      MessageFactory* factory = NULL) const;
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FieldDescriptor* FindKnownExtensionByName(const string& name) const;
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FieldDescriptor* FindKnownExtensionByNumber(int number) const;
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2823d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch protected:
2833d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch  virtual void* MutableRawRepeatedField(
2843d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch      Message* message, const FieldDescriptor* field, FieldDescriptor::CppType,
2853d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch      int ctype, const Descriptor* desc) const;
2863d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class GeneratedMessage;
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2903d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch  // To parse directly into a proto2 generated class, FieldAccessor needs
2913d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch  // access to member offsets and hasbits.
2923d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch  friend class LIBPROTOBUF_EXPORT upb::proto2_bridge_opensource::FieldAccessor;
2933d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor* descriptor_;
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Message* default_instance_;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int* offsets_;
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int has_bits_offset_;
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int unknown_fields_offset_;
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int extensions_offset_;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int object_size_;
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const DescriptorPool* descriptor_pool_;
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageFactory* message_factory_;
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <typename Type>
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline const Type& GetRaw(const Message& message,
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const FieldDescriptor* field) const;
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <typename Type>
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline Type* MutableRaw(Message* message,
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const FieldDescriptor* field) const;
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <typename Type>
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline const Type& DefaultRaw(const FieldDescriptor* field) const;
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline const uint32* GetHasBits(const Message& message) const;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline uint32* MutableHasBits(Message* message) const;
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline const ExtensionSet& GetExtensionSet(const Message& message) const;
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline ExtensionSet* MutableExtensionSet(Message* message) const;
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline bool HasBit(const Message& message,
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const FieldDescriptor* field) const;
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void SetBit(Message* message,
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const FieldDescriptor* field) const;
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void ClearBit(Message* message,
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const FieldDescriptor* field) const;
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <typename Type>
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline const Type& GetField(const Message& message,
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              const FieldDescriptor* field) const;
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <typename Type>
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void SetField(Message* message,
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const FieldDescriptor* field, const Type& value) const;
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <typename Type>
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline Type* MutableField(Message* message,
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const FieldDescriptor* field) const;
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <typename Type>
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline const Type& GetRepeatedField(const Message& message,
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      const FieldDescriptor* field,
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      int index) const;
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <typename Type>
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline const Type& GetRepeatedPtrField(const Message& message,
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         const FieldDescriptor* field,
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         int index) const;
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <typename Type>
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void SetRepeatedField(Message* message,
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const FieldDescriptor* field, int index,
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               Type value) const;
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <typename Type>
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline Type* MutableRepeatedField(Message* message,
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const FieldDescriptor* field,
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    int index) const;
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <typename Type>
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void AddField(Message* message,
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const FieldDescriptor* field, const Type& value) const;
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <typename Type>
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline Type* AddField(Message* message,
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        const FieldDescriptor* field) const;
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int GetExtensionNumberOrDie(const Descriptor* type) const;
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratedMessageReflection);
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the offset of the given field within the given aggregate type.
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is equivalent to the ANSI C offsetof() macro.  However, according
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to the C++ standard, offsetof() only works on POD types, and GCC
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// enforces this requirement with a warning.  In practice, this rule is
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// unnecessarily strict; there is probably no compiler or platform on
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// which the offsets of the direct fields of a class are non-constant.
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Fields inherited from superclasses *can* have non-constant offsets,
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// but that's not what this macro will be used for.
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note that we calculate relative to the pointer value 16 here since if we
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// just use zero, GCC complains about dereferencing a NULL pointer.  We
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// choose 16 rather than some other number just in case the compiler would
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// be confused by an unaligned pointer.
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD)    \
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static_cast<int>(                                           \
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    reinterpret_cast<const char*>(                            \
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &reinterpret_cast<const TYPE*>(16)->FIELD) -            \
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    reinterpret_cast<const char*>(16))
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// There are some places in proto2 where dynamic_cast would be useful as an
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// optimization.  For example, take Message::MergeFrom(const Message& other).
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For a given generated message FooMessage, we generate these two methods:
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   void MergeFrom(const FooMessage& other);
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   void MergeFrom(const Message& other);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The former method can be implemented directly in terms of FooMessage's
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// inline accessors, but the latter method must work with the reflection
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// interface.  However, if the parameter to the latter method is actually of
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// type FooMessage, then we'd like to be able to just call the other method
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// as an optimization.  So, we use dynamic_cast to check this.
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// That said, dynamic_cast requires RTTI, which many people like to disable
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for performance and code size reasons.  When RTTI is not available, we
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// still need to produce correct results.  So, in this case we have to fall
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// back to using reflection, which is what we would have done anyway if the
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// objects were not of the exact same class.
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// dynamic_cast_if_available() implements this logic.  If RTTI is
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// enabled, it does a dynamic_cast.  If RTTI is disabled, it just returns
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NULL.
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If you need to compile without RTTI, simply #define GOOGLE_PROTOBUF_NO_RTTI.
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// On MSVC, this should be detected automatically.
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename To, typename From>
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline To dynamic_cast_if_available(From from) {
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(GOOGLE_PROTOBUF_NO_RTTI) || (defined(_MSC_VER)&&!defined(_CPPRTTI))
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return dynamic_cast<To>(from);
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace internal
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace protobuf
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace google
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
420