1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.
3 // http://code.google.com/p/protobuf/
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
17 // Author: kenton@google.com (Kenton Varda)
18 // Based on original Protocol Buffers design by
19 // Sanjay Ghemawat, Jeff Dean, and others.
21 // This header is logically internal, but is made public because it is used
22 // from protocol-compiler-generated code, which may reside in other components.
24 #ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
25 #define GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
29 #include <google/protobuf/message.h>
30 #include <google/protobuf/unknown_field_set.h>
33 // Generated code needs this to have been forward-declared. Easier to do it
34 // here than to print it inside every .pb.h file.
36 namespace protobuf
{ class EnumDescriptor
; }
41 // Defined in this file.
42 class GeneratedMessageReflection
;
44 // Defined in other files.
45 class ExtensionSet
; // extension_set.h
47 // THIS CLASS IS NOT INTENDED FOR DIRECT USE. It is intended for use
48 // by generated code. This class is just a big hack that reduces code
51 // A GeneratedMessageReflection is an implementation of Message::Reflection
52 // which expects all fields to be backed by simple variables located in
53 // memory. The locations are given using a base pointer and a set of
56 // It is required that the user represents fields of each type in a standard
57 // way, so that GeneratedMessageReflection can cast the void* pointer to
58 // the appropriate type. For primitive fields and string fields, each field
59 // should be represented using the obvious C++ primitive type. Enums and
60 // Messages are different:
61 // - Singular Message fields are stored as a pointer to a Message. These
62 // should start out NULL, except for in the default instance where they
63 // should start out pointing to other default instances.
64 // - Enum fields are stored as an int. This int must always contain
65 // a valid value, such that EnumDescriptor::FindValueByNumber() would
67 // - Repeated fields are stored as RepeatedFields or RepeatedPtrFields
68 // of whatever type the individual field would be. Strings and
69 // Messages use RepeatedPtrFields while everything else uses
71 class LIBPROTOBUF_EXPORT GeneratedMessageReflection
: public Message::Reflection
{
73 // Constructs a GeneratedMessageReflection.
75 // descriptor: The descriptor for the message type being implemented.
76 // base: Pointer to the location where the message object is
78 // default_base: Pointer to the location where the message's default
79 // instance is stored. This is only used to obtain
80 // pointers to default instances of embedded messages,
81 // which GetMessage() will return if the particular sub-
82 // message has not been initialized yet. (Thus, all
83 // embedded message fields *must* have non-NULL pointers
84 // in the default instance.)
85 // offsets: An array of bits giving the byte offsets, relative to
86 // "base" and "default_base", of each field. These can
87 // be computed at compile time using the
88 // GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET() macro, defined
90 // has_bits: An array of uint32s of size descriptor->field_count()/32,
91 // rounded up. This is a bitfield where each bit indicates
92 // whether or not the corresponding field of the message
93 // has been initialized. The bit for field index i is
94 // obtained by the expression:
95 // has_bits[i / 32] & (1 << (i % 32))
96 // extensions: The ExtensionSet for this message, or NULL if the
97 // message type has no extension ranges.
98 GeneratedMessageReflection(const Descriptor
* descriptor
,
99 void* base
, const void* default_base
,
100 const int offsets
[], uint32 has_bits
[],
101 ExtensionSet
* extensions
);
102 ~GeneratedMessageReflection();
104 inline const UnknownFieldSet
& unknown_fields() const {
105 return unknown_fields_
;
107 inline UnknownFieldSet
* mutable_unknown_fields() {
108 return &unknown_fields_
;
111 // implements Message::Reflection ----------------------------------
113 const UnknownFieldSet
& GetUnknownFields() const;
114 UnknownFieldSet
* MutableUnknownFields();
116 bool HasField(const FieldDescriptor
* field
) const;
117 int FieldSize(const FieldDescriptor
* field
) const;
118 void ClearField(const FieldDescriptor
* field
);
119 void ListFields(vector
<const FieldDescriptor
*>* output
) const;
121 int32
GetInt32 (const FieldDescriptor
* field
) const;
122 int64
GetInt64 (const FieldDescriptor
* field
) const;
123 uint32
GetUInt32(const FieldDescriptor
* field
) const;
124 uint64
GetUInt64(const FieldDescriptor
* field
) const;
125 float GetFloat (const FieldDescriptor
* field
) const;
126 double GetDouble(const FieldDescriptor
* field
) const;
127 bool GetBool (const FieldDescriptor
* field
) const;
128 string
GetString(const FieldDescriptor
* field
) const;
129 const string
& GetStringReference(const FieldDescriptor
* field
,
130 string
* scratch
) const;
131 const EnumValueDescriptor
* GetEnum(const FieldDescriptor
* field
) const;
132 const Message
& GetMessage(const FieldDescriptor
* field
) const;
134 void SetInt32 (const FieldDescriptor
* field
, int32 value
);
135 void SetInt64 (const FieldDescriptor
* field
, int64 value
);
136 void SetUInt32(const FieldDescriptor
* field
, uint32 value
);
137 void SetUInt64(const FieldDescriptor
* field
, uint64 value
);
138 void SetFloat (const FieldDescriptor
* field
, float value
);
139 void SetDouble(const FieldDescriptor
* field
, double value
);
140 void SetBool (const FieldDescriptor
* field
, bool value
);
141 void SetString(const FieldDescriptor
* field
,
142 const string
& value
);
143 void SetEnum (const FieldDescriptor
* field
,
144 const EnumValueDescriptor
* value
);
145 Message
* MutableMessage(const FieldDescriptor
* field
);
147 int32
GetRepeatedInt32 (const FieldDescriptor
* field
, int index
) const;
148 int64
GetRepeatedInt64 (const FieldDescriptor
* field
, int index
) const;
149 uint32
GetRepeatedUInt32(const FieldDescriptor
* field
, int index
) const;
150 uint64
GetRepeatedUInt64(const FieldDescriptor
* field
, int index
) const;
151 float GetRepeatedFloat (const FieldDescriptor
* field
, int index
) const;
152 double GetRepeatedDouble(const FieldDescriptor
* field
, int index
) const;
153 bool GetRepeatedBool (const FieldDescriptor
* field
, int index
) const;
154 string
GetRepeatedString(const FieldDescriptor
* field
, int index
) const;
155 const string
& GetRepeatedStringReference(const FieldDescriptor
* field
,
156 int index
, string
* scratch
) const;
157 const EnumValueDescriptor
* GetRepeatedEnum(const FieldDescriptor
* field
,
159 const Message
& GetRepeatedMessage(const FieldDescriptor
* field
,
162 // Set the value of a field.
163 void SetRepeatedInt32 (const FieldDescriptor
* field
, int index
, int32 value
);
164 void SetRepeatedInt64 (const FieldDescriptor
* field
, int index
, int64 value
);
165 void SetRepeatedUInt32(const FieldDescriptor
* field
, int index
, uint32 value
);
166 void SetRepeatedUInt64(const FieldDescriptor
* field
, int index
, uint64 value
);
167 void SetRepeatedFloat (const FieldDescriptor
* field
, int index
, float value
);
168 void SetRepeatedDouble(const FieldDescriptor
* field
, int index
, double value
);
169 void SetRepeatedBool (const FieldDescriptor
* field
, int index
, bool value
);
170 void SetRepeatedString(const FieldDescriptor
* field
, int index
,
171 const string
& value
);
172 void SetRepeatedEnum (const FieldDescriptor
* field
, int index
,
173 const EnumValueDescriptor
* value
);
174 // Get a mutable pointer to a field with a message type.
175 Message
* MutableRepeatedMessage(const FieldDescriptor
* field
, int index
);
177 void AddInt32 (const FieldDescriptor
* field
, int32 value
);
178 void AddInt64 (const FieldDescriptor
* field
, int64 value
);
179 void AddUInt32(const FieldDescriptor
* field
, uint32 value
);
180 void AddUInt64(const FieldDescriptor
* field
, uint64 value
);
181 void AddFloat (const FieldDescriptor
* field
, float value
);
182 void AddDouble(const FieldDescriptor
* field
, double value
);
183 void AddBool (const FieldDescriptor
* field
, bool value
);
184 void AddString(const FieldDescriptor
* field
, const string
& value
);
185 void AddEnum(const FieldDescriptor
* field
, const EnumValueDescriptor
* value
);
186 Message
* AddMessage(const FieldDescriptor
* field
);
188 const FieldDescriptor
* FindKnownExtensionByName(const string
& name
) const;
189 const FieldDescriptor
* FindKnownExtensionByNumber(int number
) const;
192 friend class GeneratedMessage
;
194 const Descriptor
* descriptor_
;
196 const void* default_base_
;
199 // TODO(kenton): These two pointers just point back into the message object.
200 // We could save space by removing them and using offsets instead.
202 ExtensionSet
* extensions_
;
204 // We put this directly in the GeneratedMessageReflection because every
205 // message class needs it, and if we don't find any unknown fields, it
206 // takes up only one pointer of space.
207 UnknownFieldSet unknown_fields_
;
209 template <typename Type
>
210 inline const Type
& GetRaw(const FieldDescriptor
* field
) const;
211 template <typename Type
>
212 inline Type
* MutableRaw(const FieldDescriptor
* field
);
213 template <typename Type
>
214 inline const Type
& DefaultRaw(const FieldDescriptor
* field
) const;
215 inline const Message
* GetMessagePrototype(const FieldDescriptor
* field
) const;
217 inline bool HasBit(const FieldDescriptor
* field
) const;
218 inline void SetBit(const FieldDescriptor
* field
);
219 inline void ClearBit(const FieldDescriptor
* field
);
221 template <typename Type
>
222 inline const Type
& GetField(const FieldDescriptor
* field
) const;
223 template <typename Type
>
224 inline void SetField(const FieldDescriptor
* field
, const Type
& value
);
225 template <typename Type
>
226 inline Type
* MutableField(const FieldDescriptor
* field
);
227 template <typename Type
>
228 inline const Type
& GetRepeatedField(const FieldDescriptor
* field
,
230 template <typename Type
>
231 inline void SetRepeatedField(const FieldDescriptor
* field
, int index
,
233 template <typename Type
>
234 inline Type
* MutableRepeatedField(const FieldDescriptor
* field
, int index
);
235 template <typename Type
>
236 inline void AddField(const FieldDescriptor
* field
, const Type
& value
);
237 template <typename Type
>
238 inline Type
* AddField(const FieldDescriptor
* field
);
240 int GetExtensionNumberOrDie(const Descriptor
* type
) const;
242 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratedMessageReflection
);
245 // Returns the offset of the given field within the given aggregate type.
246 // This is equivalent to the ANSI C offsetof() macro. However, according
247 // to the C++ standard, offsetof() only works on POD types, and GCC
248 // enforces this requirement with a warning. In practice, this rule is
249 // unnecessarily strict; there is probably no compiler or platform on
250 // which the offsets of the direct fields of a class are non-constant.
251 // Fields inherited from superclasses *can* have non-constant offsets,
252 // but that's not what this macro will be used for.
254 // Note that we calculate relative to the pointer value 16 here since if we
255 // just use zero, GCC complains about dereferencing a NULL pointer. We
256 // choose 16 rather than some other number just in case the compiler would
257 // be confused by an unaligned pointer.
258 #define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD) \
259 (reinterpret_cast<const char*>( \
260 &reinterpret_cast<const TYPE*>(16)->FIELD) - \
261 reinterpret_cast<const char*>(16))
263 // There are some places in proto2 where dynamic_cast would be useful as an
264 // optimization. For example, take Message::MergeFrom(const Message& other).
265 // For a given generated message FooMessage, we generate these two methods:
266 // void MergeFrom(const FooMessage& other);
267 // void MergeFrom(const Message& other);
268 // The former method can be implemented directly in terms of FooMessage's
269 // inline accessors, but the latter method must work with the reflection
270 // interface. However, if the parameter to the latter method is actually of
271 // type FooMessage, then we'd like to be able to just call the other method
272 // as an optimization. So, we use dynamic_cast to check this.
274 // That said, dynamic_cast requires RTTI, which many people like to disable
275 // for performance and code size reasons. When RTTI is not available, we
276 // still need to produce correct results. So, in this case we have to fall
277 // back to using reflection, which is what we would have done anyway if the
278 // objects were not of the exact same class.
280 // dynamic_cast_if_available() implements this logic. If RTTI is
281 // enabled, it does a dynamic_cast. If RTTI is disabled, it just returns
284 // If you need to compile without RTTI, simply #define GOOGLE_PROTOBUF_NO_RTTI.
285 // On MSVC, this should be detected automatically.
286 template<typename To
, typename From
>
287 inline To
dynamic_cast_if_available(From from
) {
288 #if defined(GOOGLE_PROTOBUF_NO_RTTI) || (defined(_MSC_VER)&&!defined(_CPPRTTI))
291 return dynamic_cast<To
>(from
);
296 } // namespace internal
297 } // namespace protobuf
299 } // namespace google
300 #endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__