1// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc.  All rights reserved.
3// http://code.google.com/p/protobuf/
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/message.h>
44#include <google/protobuf/unknown_field_set.h>
45
46
47namespace google {
48namespace protobuf {
49  class DescriptorPool;
50  // Generated code needs these to have been forward-declared.  Easier to do it
51  // here than to print them inside every .pb.h file.
52  class FileDescriptor;
53  class EnumDescriptor;
54}
55
56namespace protobuf {
57namespace internal {
58
59// Defined in this file.
60class GeneratedMessageReflection;
61
62// Defined in other files.
63class ExtensionSet;             // extension_set.h
64
65// THIS CLASS IS NOT INTENDED FOR DIRECT USE.  It is intended for use
66// by generated code.  This class is just a big hack that reduces code
67// size.
68//
69// A GeneratedMessageReflection is an implementation of Reflection
70// which expects all fields to be backed by simple variables located in
71// memory.  The locations are given using a base pointer and a set of
72// offsets.
73//
74// It is required that the user represents fields of each type in a standard
75// way, so that GeneratedMessageReflection can cast the void* pointer to
76// the appropriate type.  For primitive fields and string fields, each field
77// should be represented using the obvious C++ primitive type.  Enums and
78// Messages are different:
79//  - Singular Message fields are stored as a pointer to a Message.  These
80//    should start out NULL, except for in the default instance where they
81//    should start out pointing to other default instances.
82//  - Enum fields are stored as an int.  This int must always contain
83//    a valid value, such that EnumDescriptor::FindValueByNumber() would
84//    not return NULL.
85//  - Repeated fields are stored as RepeatedFields or RepeatedPtrFields
86//    of whatever type the individual field would be.  Strings and
87//    Messages use RepeatedPtrFields while everything else uses
88//    RepeatedFields.
89class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection {
90 public:
91  // Constructs a GeneratedMessageReflection.
92  // Parameters:
93  //   descriptor:    The descriptor for the message type being implemented.
94  //   default_instance:  The default instance of the message.  This is only
95  //                  used to obtain pointers to default instances of embedded
96  //                  messages, which GetMessage() will return if the particular
97  //                  sub-message has not been initialized yet.  (Thus, all
98  //                  embedded message fields *must* have non-NULL pointers
99  //                  in the default instance.)
100  //   offsets:       An array of ints giving the byte offsets, relative to
101  //                  the start of the message object, of each field.  These can
102  //                  be computed at compile time using the
103  //                  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET() macro, defined
104  //                  below.
105  //   has_bits_offset:  Offset in the message of an array of uint32s of size
106  //                  descriptor->field_count()/32, rounded up.  This is a
107  //                  bitfield where each bit indicates whether or not the
108  //                  corresponding field of the message has been initialized.
109  //                  The bit for field index i is obtained by the expression:
110  //                    has_bits[i / 32] & (1 << (i % 32))
111  //   unknown_fields_offset:  Offset in the message of the UnknownFieldSet for
112  //                  the message.
113  //   extensions_offset:  Offset in the message of the ExtensionSet for the
114  //                  message, or -1 if the message type has no extension
115  //                  ranges.
116  //   pool:          DescriptorPool to search for extension definitions.  Only
117  //                  used by FindKnownExtensionByName() and
118  //                  FindKnownExtensionByNumber().
119  //   factory:       MessageFactory to use to construct extension messages.
120  //   object_size:   The size of a message object of this type, as measured
121  //                  by sizeof().
122  GeneratedMessageReflection(const Descriptor* descriptor,
123                             const Message* default_instance,
124                             const int offsets[],
125                             int has_bits_offset,
126                             int unknown_fields_offset,
127                             int extensions_offset,
128                             const DescriptorPool* pool,
129                             MessageFactory* factory,
130                             int object_size);
131  ~GeneratedMessageReflection();
132
133  // implements Reflection -------------------------------------------
134
135  const UnknownFieldSet& GetUnknownFields(const Message& message) const;
136  UnknownFieldSet* MutableUnknownFields(Message* message) const;
137
138  int SpaceUsed(const Message& message) const;
139
140  bool HasField(const Message& message, const FieldDescriptor* field) const;
141  int FieldSize(const Message& message, const FieldDescriptor* field) const;
142  void ClearField(Message* message, const FieldDescriptor* field) const;
143  void RemoveLast(Message* message, const FieldDescriptor* field) const;
144  void Swap(Message* message1, Message* message2) const;
145  void SwapElements(Message* message, const FieldDescriptor* field,
146            int index1, int index2) const;
147  void ListFields(const Message& message,
148                  vector<const FieldDescriptor*>* output) const;
149
150  int32  GetInt32 (const Message& message,
151                   const FieldDescriptor* field) const;
152  int64  GetInt64 (const Message& message,
153                   const FieldDescriptor* field) const;
154  uint32 GetUInt32(const Message& message,
155                   const FieldDescriptor* field) const;
156  uint64 GetUInt64(const Message& message,
157                   const FieldDescriptor* field) const;
158  float  GetFloat (const Message& message,
159                   const FieldDescriptor* field) const;
160  double GetDouble(const Message& message,
161                   const FieldDescriptor* field) const;
162  bool   GetBool  (const Message& message,
163                   const FieldDescriptor* field) const;
164  string GetString(const Message& message,
165                   const FieldDescriptor* field) const;
166  const string& GetStringReference(const Message& message,
167                                   const FieldDescriptor* field,
168                                   string* scratch) const;
169  const EnumValueDescriptor* GetEnum(const Message& message,
170                                     const FieldDescriptor* field) const;
171  const Message& GetMessage(const Message& message,
172                            const FieldDescriptor* field,
173                            MessageFactory* factory = NULL) const;
174
175  void SetInt32 (Message* message,
176                 const FieldDescriptor* field, int32  value) const;
177  void SetInt64 (Message* message,
178                 const FieldDescriptor* field, int64  value) const;
179  void SetUInt32(Message* message,
180                 const FieldDescriptor* field, uint32 value) const;
181  void SetUInt64(Message* message,
182                 const FieldDescriptor* field, uint64 value) const;
183  void SetFloat (Message* message,
184                 const FieldDescriptor* field, float  value) const;
185  void SetDouble(Message* message,
186                 const FieldDescriptor* field, double value) const;
187  void SetBool  (Message* message,
188                 const FieldDescriptor* field, bool   value) const;
189  void SetString(Message* message,
190                 const FieldDescriptor* field,
191                 const string& value) const;
192  void SetEnum  (Message* message, const FieldDescriptor* field,
193                 const EnumValueDescriptor* value) const;
194  Message* MutableMessage(Message* message, const FieldDescriptor* field,
195                          MessageFactory* factory = NULL) const;
196
197  int32  GetRepeatedInt32 (const Message& message,
198                           const FieldDescriptor* field, int index) const;
199  int64  GetRepeatedInt64 (const Message& message,
200                           const FieldDescriptor* field, int index) const;
201  uint32 GetRepeatedUInt32(const Message& message,
202                           const FieldDescriptor* field, int index) const;
203  uint64 GetRepeatedUInt64(const Message& message,
204                           const FieldDescriptor* field, int index) const;
205  float  GetRepeatedFloat (const Message& message,
206                           const FieldDescriptor* field, int index) const;
207  double GetRepeatedDouble(const Message& message,
208                           const FieldDescriptor* field, int index) const;
209  bool   GetRepeatedBool  (const Message& message,
210                           const FieldDescriptor* field, int index) const;
211  string GetRepeatedString(const Message& message,
212                           const FieldDescriptor* field, int index) const;
213  const string& GetRepeatedStringReference(const Message& message,
214                                           const FieldDescriptor* field,
215                                           int index, string* scratch) const;
216  const EnumValueDescriptor* GetRepeatedEnum(const Message& message,
217                                             const FieldDescriptor* field,
218                                             int index) const;
219  const Message& GetRepeatedMessage(const Message& message,
220                                    const FieldDescriptor* field,
221                                    int index) const;
222
223  // Set the value of a field.
224  void SetRepeatedInt32 (Message* message,
225                         const FieldDescriptor* field, int index, int32  value) const;
226  void SetRepeatedInt64 (Message* message,
227                         const FieldDescriptor* field, int index, int64  value) const;
228  void SetRepeatedUInt32(Message* message,
229                         const FieldDescriptor* field, int index, uint32 value) const;
230  void SetRepeatedUInt64(Message* message,
231                         const FieldDescriptor* field, int index, uint64 value) const;
232  void SetRepeatedFloat (Message* message,
233                         const FieldDescriptor* field, int index, float  value) const;
234  void SetRepeatedDouble(Message* message,
235                         const FieldDescriptor* field, int index, double value) const;
236  void SetRepeatedBool  (Message* message,
237                         const FieldDescriptor* field, int index, bool   value) const;
238  void SetRepeatedString(Message* message,
239                         const FieldDescriptor* field, int index,
240                         const string& value) const;
241  void SetRepeatedEnum(Message* message, const FieldDescriptor* field,
242                       int index, const EnumValueDescriptor* value) const;
243  // Get a mutable pointer to a field with a message type.
244  Message* MutableRepeatedMessage(Message* message,
245                                  const FieldDescriptor* field,
246                                  int index) const;
247
248  void AddInt32 (Message* message,
249                 const FieldDescriptor* field, int32  value) const;
250  void AddInt64 (Message* message,
251                 const FieldDescriptor* field, int64  value) const;
252  void AddUInt32(Message* message,
253                 const FieldDescriptor* field, uint32 value) const;
254  void AddUInt64(Message* message,
255                 const FieldDescriptor* field, uint64 value) const;
256  void AddFloat (Message* message,
257                 const FieldDescriptor* field, float  value) const;
258  void AddDouble(Message* message,
259                 const FieldDescriptor* field, double value) const;
260  void AddBool  (Message* message,
261                 const FieldDescriptor* field, bool   value) const;
262  void AddString(Message* message,
263                 const FieldDescriptor* field, const string& value) const;
264  void AddEnum(Message* message,
265               const FieldDescriptor* field,
266               const EnumValueDescriptor* value) const;
267  Message* AddMessage(Message* message, const FieldDescriptor* field,
268                      MessageFactory* factory = NULL) const;
269
270  const FieldDescriptor* FindKnownExtensionByName(const string& name) const;
271  const FieldDescriptor* FindKnownExtensionByNumber(int number) const;
272
273 private:
274  friend class GeneratedMessage;
275
276  const Descriptor* descriptor_;
277  const Message* default_instance_;
278  const int* offsets_;
279
280  int has_bits_offset_;
281  int unknown_fields_offset_;
282  int extensions_offset_;
283  int object_size_;
284
285  const DescriptorPool* descriptor_pool_;
286  MessageFactory* message_factory_;
287
288  template <typename Type>
289  inline const Type& GetRaw(const Message& message,
290                            const FieldDescriptor* field) const;
291  template <typename Type>
292  inline Type* MutableRaw(Message* message,
293                          const FieldDescriptor* field) const;
294  template <typename Type>
295  inline const Type& DefaultRaw(const FieldDescriptor* field) const;
296  inline const Message* GetMessagePrototype(const FieldDescriptor* field) const;
297
298  inline const uint32* GetHasBits(const Message& message) const;
299  inline uint32* MutableHasBits(Message* message) const;
300  inline const ExtensionSet& GetExtensionSet(const Message& message) const;
301  inline ExtensionSet* MutableExtensionSet(Message* message) const;
302
303  inline bool HasBit(const Message& message,
304                     const FieldDescriptor* field) const;
305  inline void SetBit(Message* message,
306                     const FieldDescriptor* field) const;
307  inline void ClearBit(Message* message,
308                       const FieldDescriptor* field) const;
309
310  template <typename Type>
311  inline const Type& GetField(const Message& message,
312                              const FieldDescriptor* field) const;
313  template <typename Type>
314  inline void SetField(Message* message,
315                       const FieldDescriptor* field, const Type& value) const;
316  template <typename Type>
317  inline Type* MutableField(Message* message,
318                            const FieldDescriptor* field) const;
319  template <typename Type>
320  inline const Type& GetRepeatedField(const Message& message,
321                                      const FieldDescriptor* field,
322                                      int index) const;
323  template <typename Type>
324  inline const Type& GetRepeatedPtrField(const Message& message,
325                                         const FieldDescriptor* field,
326                                         int index) const;
327  template <typename Type>
328  inline void SetRepeatedField(Message* message,
329                               const FieldDescriptor* field, int index,
330                               Type value) const;
331  template <typename Type>
332  inline Type* MutableRepeatedField(Message* message,
333                                    const FieldDescriptor* field,
334                                    int index) const;
335  template <typename Type>
336  inline void AddField(Message* message,
337                       const FieldDescriptor* field, const Type& value) const;
338  template <typename Type>
339  inline Type* AddField(Message* message,
340                        const FieldDescriptor* field) const;
341
342  int GetExtensionNumberOrDie(const Descriptor* type) const;
343
344  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratedMessageReflection);
345};
346
347// Returns the offset of the given field within the given aggregate type.
348// This is equivalent to the ANSI C offsetof() macro.  However, according
349// to the C++ standard, offsetof() only works on POD types, and GCC
350// enforces this requirement with a warning.  In practice, this rule is
351// unnecessarily strict; there is probably no compiler or platform on
352// which the offsets of the direct fields of a class are non-constant.
353// Fields inherited from superclasses *can* have non-constant offsets,
354// but that's not what this macro will be used for.
355//
356// Note that we calculate relative to the pointer value 16 here since if we
357// just use zero, GCC complains about dereferencing a NULL pointer.  We
358// choose 16 rather than some other number just in case the compiler would
359// be confused by an unaligned pointer.
360#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD)    \
361  static_cast<int>(                                           \
362    reinterpret_cast<const char*>(                            \
363      &reinterpret_cast<const TYPE*>(16)->FIELD) -            \
364    reinterpret_cast<const char*>(16))
365
366// There are some places in proto2 where dynamic_cast would be useful as an
367// optimization.  For example, take Message::MergeFrom(const Message& other).
368// For a given generated message FooMessage, we generate these two methods:
369//   void MergeFrom(const FooMessage& other);
370//   void MergeFrom(const Message& other);
371// The former method can be implemented directly in terms of FooMessage's
372// inline accessors, but the latter method must work with the reflection
373// interface.  However, if the parameter to the latter method is actually of
374// type FooMessage, then we'd like to be able to just call the other method
375// as an optimization.  So, we use dynamic_cast to check this.
376//
377// That said, dynamic_cast requires RTTI, which many people like to disable
378// for performance and code size reasons.  When RTTI is not available, we
379// still need to produce correct results.  So, in this case we have to fall
380// back to using reflection, which is what we would have done anyway if the
381// objects were not of the exact same class.
382//
383// dynamic_cast_if_available() implements this logic.  If RTTI is
384// enabled, it does a dynamic_cast.  If RTTI is disabled, it just returns
385// NULL.
386//
387// If you need to compile without RTTI, simply #define GOOGLE_PROTOBUF_NO_RTTI.
388// On MSVC, this should be detected automatically.
389template<typename To, typename From>
390inline To dynamic_cast_if_available(From from) {
391#if defined(GOOGLE_PROTOBUF_NO_RTTI) || (defined(_MSC_VER)&&!defined(_CPPRTTI))
392  return NULL;
393#else
394  return dynamic_cast<To>(from);
395#endif
396}
397
398// Helper for EnumType_Parse functions: try to parse the string 'name' as an
399// enum name of the given type, returning true and filling in value on success,
400// or returning false and leaving value unchanged on failure.
401LIBPROTOBUF_EXPORT bool ParseNamedEnum(const EnumDescriptor* descriptor,
402                    const string& name,
403                    int* value);
404
405template<typename EnumType>
406bool ParseNamedEnum(const EnumDescriptor* descriptor,
407                    const string& name,
408                    EnumType* value) {
409  int tmp;
410  if (!ParseNamedEnum(descriptor, name, &tmp)) return false;
411  *value = static_cast<EnumType>(tmp);
412  return true;
413}
414
415// Just a wrapper around printing the name of a value. The main point of this
416// function is not to be inlined, so that you can do this without including
417// descriptor.h.
418LIBPROTOBUF_EXPORT const string& NameOfEnum(const EnumDescriptor* descriptor, int value);
419
420}  // namespace internal
421}  // namespace protobuf
422
423}  // namespace google
424#endif  // GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
425