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