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
47 namespace google {
48 namespace 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
56 namespace protobuf {
57 namespace internal {
58
59 // Defined in this file.
60 class GeneratedMessageReflection;
61
62 // Defined in other files.
63 class 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.
89 class 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.
389 template<typename To, typename From>
dynamic_cast_if_available(From from)390 inline 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.
401 LIBPROTOBUF_EXPORT bool ParseNamedEnum(const EnumDescriptor* descriptor,
402 const string& name,
403 int* value);
404
405 template<typename EnumType>
ParseNamedEnum(const EnumDescriptor * descriptor,const string & name,EnumType * value)406 bool 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.
418 LIBPROTOBUF_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