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