Line data Source code
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>
492 0 : inline To dynamic_cast_if_available(From from) {
493 : #if defined(GOOGLE_PROTOBUF_NO_RTTI) || (defined(_MSC_VER)&&!defined(_CPPRTTI))
494 0 : 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__
|