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/casts.h>
44 : #include <google/protobuf/stubs/common.h>
45 : // TODO(jasonh): Remove this once the compiler change to directly include this
46 : // is released to components.
47 : #include <google/protobuf/generated_enum_reflection.h>
48 : #include <google/protobuf/message.h>
49 : #include <google/protobuf/metadata.h>
50 : #include <google/protobuf/unknown_field_set.h>
51 :
52 :
53 : namespace google {
54 : namespace upb {
55 : namespace google_opensource {
56 : class GMR_Handlers;
57 : } // namespace google_opensource
58 : } // namespace upb
59 :
60 : namespace protobuf {
61 : class DescriptorPool;
62 : class MapKey;
63 : class MapValueRef;
64 : }
65 :
66 : namespace protobuf {
67 : namespace internal {
68 : class DefaultEmptyOneof;
69 :
70 : // Defined in this file.
71 : class GeneratedMessageReflection;
72 :
73 : // Defined in other files.
74 : class ExtensionSet; // extension_set.h
75 :
76 : // THIS CLASS IS NOT INTENDED FOR DIRECT USE. It is intended for use
77 : // by generated code. This class is just a big hack that reduces code
78 : // size.
79 : //
80 : // A GeneratedMessageReflection is an implementation of Reflection
81 : // which expects all fields to be backed by simple variables located in
82 : // memory. The locations are given using a base pointer and a set of
83 : // offsets.
84 : //
85 : // It is required that the user represents fields of each type in a standard
86 : // way, so that GeneratedMessageReflection can cast the void* pointer to
87 : // the appropriate type. For primitive fields and string fields, each field
88 : // should be represented using the obvious C++ primitive type. Enums and
89 : // Messages are different:
90 : // - Singular Message fields are stored as a pointer to a Message. These
91 : // should start out NULL, except for in the default instance where they
92 : // should start out pointing to other default instances.
93 : // - Enum fields are stored as an int. This int must always contain
94 : // a valid value, such that EnumDescriptor::FindValueByNumber() would
95 : // not return NULL.
96 : // - Repeated fields are stored as RepeatedFields or RepeatedPtrFields
97 : // of whatever type the individual field would be. Strings and
98 : // Messages use RepeatedPtrFields while everything else uses
99 : // RepeatedFields.
100 : class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection {
101 : public:
102 : // Constructs a GeneratedMessageReflection.
103 : // Parameters:
104 : // descriptor: The descriptor for the message type being implemented.
105 : // default_instance: The default instance of the message. This is only
106 : // used to obtain pointers to default instances of embedded
107 : // messages, which GetMessage() will return if the particular
108 : // sub-message has not been initialized yet. (Thus, all
109 : // embedded message fields *must* have non-NULL pointers
110 : // in the default instance.)
111 : // offsets: An array of ints giving the byte offsets, relative to
112 : // the start of the message object, of each field. These can
113 : // be computed at compile time using the
114 : // GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET() macro, defined
115 : // below.
116 : // has_bits_offset: Offset in the message of an array of uint32s of size
117 : // descriptor->field_count()/32, rounded up. This is a
118 : // bitfield where each bit indicates whether or not the
119 : // corresponding field of the message has been initialized.
120 : // The bit for field index i is obtained by the expression:
121 : // has_bits[i / 32] & (1 << (i % 32))
122 : // unknown_fields_offset: Offset in the message of the UnknownFieldSet for
123 : // the message.
124 : // extensions_offset: Offset in the message of the ExtensionSet for the
125 : // message, or -1 if the message type has no extension
126 : // ranges.
127 : // pool: DescriptorPool to search for extension definitions. Only
128 : // used by FindKnownExtensionByName() and
129 : // FindKnownExtensionByNumber().
130 : // factory: MessageFactory to use to construct extension messages.
131 : // object_size: The size of a message object of this type, as measured
132 : // by sizeof().
133 : GeneratedMessageReflection(const Descriptor* descriptor,
134 : const Message* default_instance,
135 : const int offsets[],
136 : int has_bits_offset,
137 : int unknown_fields_offset,
138 : int extensions_offset,
139 : const DescriptorPool* pool,
140 : MessageFactory* factory,
141 : int object_size,
142 : int arena_offset,
143 : int is_default_instance_offset = -1);
144 :
145 : // Similar with the construction above. Call this construction if the
146 : // message has oneof definition.
147 : // Parameters:
148 : // offsets: An array of ints giving the byte offsets.
149 : // For each oneof field, the offset is relative to the
150 : // default_oneof_instance. These can be computed at compile
151 : // time using the
152 : // PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET() macro.
153 : // For each none oneof field, the offset is related to
154 : // the start of the message object. These can be computed
155 : // at compile time using the
156 : // GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET() macro.
157 : // Besides offsets for all fields, this array also contains
158 : // offsets for oneof unions. The offset of the i-th oneof
159 : // union is offsets[descriptor->field_count() + i].
160 : // default_oneof_instance: The default instance of the oneofs. It is a
161 : // struct holding the default value of all oneof fields
162 : // for this message. It is only used to obtain pointers
163 : // to default instances of oneof fields, which Get
164 : // methods will return if the field is not set.
165 : // oneof_case_offset: Offset in the message of an array of uint32s of
166 : // size descriptor->oneof_decl_count(). Each uint32
167 : // indicates what field is set for each oneof.
168 : // other parameters are the same with the construction above.
169 : GeneratedMessageReflection(const Descriptor* descriptor,
170 : const Message* default_instance,
171 : const int offsets[],
172 : int has_bits_offset,
173 : int unknown_fields_offset,
174 : int extensions_offset,
175 : const void* default_oneof_instance,
176 : int oneof_case_offset,
177 : const DescriptorPool* pool,
178 : MessageFactory* factory,
179 : int object_size,
180 : int arena_offset,
181 : int is_default_instance_offset = -1);
182 : ~GeneratedMessageReflection();
183 :
184 : // Shorter-to-call helpers for the above two constructions that work if the
185 : // pool and factory are the usual, namely, DescriptorPool::generated_pool()
186 : // and MessageFactory::generated_factory().
187 :
188 : static GeneratedMessageReflection* NewGeneratedMessageReflection(
189 : const Descriptor* descriptor,
190 : const Message* default_instance,
191 : const int offsets[],
192 : int has_bits_offset,
193 : int unknown_fields_offset,
194 : int extensions_offset,
195 : const void* default_oneof_instance,
196 : int oneof_case_offset,
197 : int object_size,
198 : int arena_offset,
199 : int is_default_instance_offset = -1);
200 :
201 : static GeneratedMessageReflection* NewGeneratedMessageReflection(
202 : const Descriptor* descriptor,
203 : const Message* default_instance,
204 : const int offsets[],
205 : int has_bits_offset,
206 : int unknown_fields_offset,
207 : int extensions_offset,
208 : int object_size,
209 : int arena_offset,
210 : int is_default_instance_offset = -1);
211 :
212 : // implements Reflection -------------------------------------------
213 :
214 : const UnknownFieldSet& GetUnknownFields(const Message& message) const;
215 : UnknownFieldSet* MutableUnknownFields(Message* message) const;
216 :
217 : int SpaceUsed(const Message& message) const;
218 :
219 : bool HasField(const Message& message, const FieldDescriptor* field) const;
220 : int FieldSize(const Message& message, const FieldDescriptor* field) const;
221 : void ClearField(Message* message, const FieldDescriptor* field) const;
222 : bool HasOneof(const Message& message,
223 : const OneofDescriptor* oneof_descriptor) const;
224 : void ClearOneof(Message* message, const OneofDescriptor* field) const;
225 : void RemoveLast(Message* message, const FieldDescriptor* field) const;
226 : Message* ReleaseLast(Message* message, const FieldDescriptor* field) const;
227 : void Swap(Message* message1, Message* message2) const;
228 : void SwapFields(Message* message1, Message* message2,
229 : const vector<const FieldDescriptor*>& fields) const;
230 : void SwapElements(Message* message, const FieldDescriptor* field,
231 : int index1, int index2) const;
232 : void ListFields(const Message& message,
233 : vector<const FieldDescriptor*>* output) const;
234 :
235 : int32 GetInt32 (const Message& message,
236 : const FieldDescriptor* field) const;
237 : int64 GetInt64 (const Message& message,
238 : const FieldDescriptor* field) const;
239 : uint32 GetUInt32(const Message& message,
240 : const FieldDescriptor* field) const;
241 : uint64 GetUInt64(const Message& message,
242 : const FieldDescriptor* field) const;
243 : float GetFloat (const Message& message,
244 : const FieldDescriptor* field) const;
245 : double GetDouble(const Message& message,
246 : const FieldDescriptor* field) const;
247 : bool GetBool (const Message& message,
248 : const FieldDescriptor* field) const;
249 : string GetString(const Message& message,
250 : const FieldDescriptor* field) const;
251 : const string& GetStringReference(const Message& message,
252 : const FieldDescriptor* field,
253 : string* scratch) const;
254 : const EnumValueDescriptor* GetEnum(const Message& message,
255 : const FieldDescriptor* field) const;
256 : int GetEnumValue(const Message& message,
257 : const FieldDescriptor* field) const;
258 : const Message& GetMessage(const Message& message,
259 : const FieldDescriptor* field,
260 : MessageFactory* factory = NULL) const;
261 :
262 : const FieldDescriptor* GetOneofFieldDescriptor(
263 : const Message& message,
264 : const OneofDescriptor* oneof_descriptor) const;
265 :
266 : private:
267 : bool ContainsMapKey(const Message& message,
268 : const FieldDescriptor* field,
269 : const MapKey& key) const;
270 : bool InsertOrLookupMapValue(Message* message,
271 : const FieldDescriptor* field,
272 : const MapKey& key,
273 : MapValueRef* val) const;
274 : bool DeleteMapValue(Message* message,
275 : const FieldDescriptor* field,
276 : const MapKey& key) const;
277 : MapIterator MapBegin(
278 : Message* message,
279 : const FieldDescriptor* field) const;
280 : MapIterator MapEnd(
281 : Message* message,
282 : const FieldDescriptor* field) const;
283 : int MapSize(const Message& message, const FieldDescriptor* field) const;
284 :
285 : public:
286 : void SetInt32 (Message* message,
287 : const FieldDescriptor* field, int32 value) const;
288 : void SetInt64 (Message* message,
289 : const FieldDescriptor* field, int64 value) const;
290 : void SetUInt32(Message* message,
291 : const FieldDescriptor* field, uint32 value) const;
292 : void SetUInt64(Message* message,
293 : const FieldDescriptor* field, uint64 value) const;
294 : void SetFloat (Message* message,
295 : const FieldDescriptor* field, float value) const;
296 : void SetDouble(Message* message,
297 : const FieldDescriptor* field, double value) const;
298 : void SetBool (Message* message,
299 : const FieldDescriptor* field, bool value) const;
300 : void SetString(Message* message,
301 : const FieldDescriptor* field,
302 : const string& value) const;
303 : void SetEnum (Message* message, const FieldDescriptor* field,
304 : const EnumValueDescriptor* value) const;
305 : void SetEnumValue(Message* message, const FieldDescriptor* field,
306 : int value) const;
307 : Message* MutableMessage(Message* message, const FieldDescriptor* field,
308 : MessageFactory* factory = NULL) const;
309 : void SetAllocatedMessage(Message* message,
310 : Message* sub_message,
311 : const FieldDescriptor* field) const;
312 : Message* ReleaseMessage(Message* message, const FieldDescriptor* field,
313 : MessageFactory* factory = NULL) const;
314 :
315 : int32 GetRepeatedInt32 (const Message& message,
316 : const FieldDescriptor* field, int index) const;
317 : int64 GetRepeatedInt64 (const Message& message,
318 : const FieldDescriptor* field, int index) const;
319 : uint32 GetRepeatedUInt32(const Message& message,
320 : const FieldDescriptor* field, int index) const;
321 : uint64 GetRepeatedUInt64(const Message& message,
322 : const FieldDescriptor* field, int index) const;
323 : float GetRepeatedFloat (const Message& message,
324 : const FieldDescriptor* field, int index) const;
325 : double GetRepeatedDouble(const Message& message,
326 : const FieldDescriptor* field, int index) const;
327 : bool GetRepeatedBool (const Message& message,
328 : const FieldDescriptor* field, int index) const;
329 : string GetRepeatedString(const Message& message,
330 : const FieldDescriptor* field, int index) const;
331 : const string& GetRepeatedStringReference(const Message& message,
332 : const FieldDescriptor* field,
333 : int index, string* scratch) const;
334 : const EnumValueDescriptor* GetRepeatedEnum(const Message& message,
335 : const FieldDescriptor* field,
336 : int index) const;
337 : int GetRepeatedEnumValue(const Message& message,
338 : const FieldDescriptor* field,
339 : int index) const;
340 : const Message& GetRepeatedMessage(const Message& message,
341 : const FieldDescriptor* field,
342 : int index) const;
343 :
344 : // Set the value of a field.
345 : void SetRepeatedInt32 (Message* message,
346 : const FieldDescriptor* field, int index, int32 value) const;
347 : void SetRepeatedInt64 (Message* message,
348 : const FieldDescriptor* field, int index, int64 value) const;
349 : void SetRepeatedUInt32(Message* message,
350 : const FieldDescriptor* field, int index, uint32 value) const;
351 : void SetRepeatedUInt64(Message* message,
352 : const FieldDescriptor* field, int index, uint64 value) const;
353 : void SetRepeatedFloat (Message* message,
354 : const FieldDescriptor* field, int index, float value) const;
355 : void SetRepeatedDouble(Message* message,
356 : const FieldDescriptor* field, int index, double value) const;
357 : void SetRepeatedBool (Message* message,
358 : const FieldDescriptor* field, int index, bool value) const;
359 : void SetRepeatedString(Message* message,
360 : const FieldDescriptor* field, int index,
361 : const string& value) const;
362 : void SetRepeatedEnum(Message* message, const FieldDescriptor* field,
363 : int index, const EnumValueDescriptor* value) const;
364 : void SetRepeatedEnumValue(Message* message, const FieldDescriptor* field,
365 : int index, int value) const;
366 : // Get a mutable pointer to a field with a message type.
367 : Message* MutableRepeatedMessage(Message* message,
368 : const FieldDescriptor* field,
369 : int index) const;
370 :
371 : void AddInt32 (Message* message,
372 : const FieldDescriptor* field, int32 value) const;
373 : void AddInt64 (Message* message,
374 : const FieldDescriptor* field, int64 value) const;
375 : void AddUInt32(Message* message,
376 : const FieldDescriptor* field, uint32 value) const;
377 : void AddUInt64(Message* message,
378 : const FieldDescriptor* field, uint64 value) const;
379 : void AddFloat (Message* message,
380 : const FieldDescriptor* field, float value) const;
381 : void AddDouble(Message* message,
382 : const FieldDescriptor* field, double value) const;
383 : void AddBool (Message* message,
384 : const FieldDescriptor* field, bool value) const;
385 : void AddString(Message* message,
386 : const FieldDescriptor* field, const string& value) const;
387 : void AddEnum(Message* message,
388 : const FieldDescriptor* field,
389 : const EnumValueDescriptor* value) const;
390 : void AddEnumValue(Message* message,
391 : const FieldDescriptor* field,
392 : int value) const;
393 : Message* AddMessage(Message* message, const FieldDescriptor* field,
394 : MessageFactory* factory = NULL) const;
395 : void AddAllocatedMessage(
396 : Message* message, const FieldDescriptor* field,
397 : Message* new_entry) const;
398 :
399 : const FieldDescriptor* FindKnownExtensionByName(const string& name) const;
400 : const FieldDescriptor* FindKnownExtensionByNumber(int number) const;
401 :
402 : bool SupportsUnknownEnumValues() const;
403 :
404 : // This value for arena_offset_ indicates that there is no arena pointer in
405 : // this message (e.g., old generated code).
406 : static const int kNoArenaPointer = -1;
407 :
408 : // This value for unknown_field_offset_ indicates that there is no
409 : // UnknownFieldSet in this message, and that instead, we are using the
410 : // Zero-Overhead Arena Pointer trick. When this is the case, arena_offset_
411 : // actually indexes to an InternalMetadataWithArena instance, which can return
412 : // either an arena pointer or an UnknownFieldSet or both. It is never the case
413 : // that unknown_field_offset_ == kUnknownFieldSetInMetadata && arena_offset_
414 : // == kNoArenaPointer.
415 : static const int kUnknownFieldSetInMetadata = -1;
416 :
417 : protected:
418 : void* MutableRawRepeatedField(
419 : Message* message, const FieldDescriptor* field, FieldDescriptor::CppType,
420 : int ctype, const Descriptor* desc) const;
421 :
422 : const void* GetRawRepeatedField(
423 : const Message& message, const FieldDescriptor* field,
424 : FieldDescriptor::CppType, int ctype,
425 : const Descriptor* desc) const;
426 :
427 : virtual MessageFactory* GetMessageFactory() const;
428 :
429 : virtual void* RepeatedFieldData(
430 : Message* message, const FieldDescriptor* field,
431 : FieldDescriptor::CppType cpp_type,
432 : const Descriptor* message_type) const;
433 :
434 : private:
435 : friend class GeneratedMessage;
436 :
437 : // To parse directly into a proto2 generated class, the class GMR_Handlers
438 : // needs access to member offsets and hasbits.
439 : friend class upb::google_opensource::GMR_Handlers;
440 :
441 : const Descriptor* descriptor_;
442 : const Message* default_instance_;
443 : const void* default_oneof_instance_;
444 : const int* offsets_;
445 :
446 : int has_bits_offset_;
447 : int oneof_case_offset_;
448 : int unknown_fields_offset_;
449 : int extensions_offset_;
450 : int arena_offset_;
451 : int is_default_instance_offset_;
452 : int object_size_;
453 :
454 : static const int kHasNoDefaultInstanceField = -1;
455 :
456 : const DescriptorPool* descriptor_pool_;
457 : MessageFactory* message_factory_;
458 :
459 : template <typename Type>
460 : inline const Type& GetRaw(const Message& message,
461 2130 : const FieldDescriptor* field) const;
462 : template <typename Type>
463 : inline Type* MutableRaw(Message* message,
464 696 : const FieldDescriptor* field) const;
465 : template <typename Type>
466 13 : inline const Type& DefaultRaw(const FieldDescriptor* field) const;
467 : template <typename Type>
468 : inline const Type& DefaultOneofRaw(const FieldDescriptor* field) const;
469 :
470 : inline const uint32* GetHasBits(const Message& message) const;
471 : inline uint32* MutableHasBits(Message* message) const;
472 : inline uint32 GetOneofCase(
473 : const Message& message,
474 : const OneofDescriptor* oneof_descriptor) const;
475 : inline uint32* MutableOneofCase(
476 : Message* message,
477 : const OneofDescriptor* oneof_descriptor) const;
478 : inline const ExtensionSet& GetExtensionSet(const Message& message) const;
479 : inline ExtensionSet* MutableExtensionSet(Message* message) const;
480 : inline Arena* GetArena(Message* message) const;
481 : inline const internal::InternalMetadataWithArena&
482 : GetInternalMetadataWithArena(const Message& message) const;
483 : inline internal::InternalMetadataWithArena*
484 : MutableInternalMetadataWithArena(Message* message) const;
485 :
486 : inline bool GetIsDefaultInstance(const Message& message) const;
487 :
488 : inline bool HasBit(const Message& message,
489 : const FieldDescriptor* field) const;
490 : inline void SetBit(Message* message,
491 : const FieldDescriptor* field) const;
492 : inline void ClearBit(Message* message,
493 : const FieldDescriptor* field) const;
494 : inline void SwapBit(Message* message1,
495 : Message* message2,
496 : const FieldDescriptor* field) const;
497 :
498 : // This function only swaps the field. Should swap corresponding has_bit
499 : // before or after using this function.
500 : void SwapField(Message* message1,
501 : Message* message2,
502 : const FieldDescriptor* field) const;
503 :
504 : void SwapOneofField(Message* message1,
505 : Message* message2,
506 : const OneofDescriptor* oneof_descriptor) const;
507 :
508 : inline bool HasOneofField(const Message& message,
509 : const FieldDescriptor* field) const;
510 : inline void SetOneofCase(Message* message,
511 : const FieldDescriptor* field) const;
512 : inline void ClearOneofField(Message* message,
513 : const FieldDescriptor* field) const;
514 :
515 : template <typename Type>
516 : inline const Type& GetField(const Message& message,
517 : const FieldDescriptor* field) const;
518 : template <typename Type>
519 : inline void SetField(Message* message,
520 20 : const FieldDescriptor* field, const Type& value) const;
521 : template <typename Type>
522 : inline Type* MutableField(Message* message,
523 40 : const FieldDescriptor* field) const;
524 : template <typename Type>
525 : inline const Type& GetRepeatedField(const Message& message,
526 : const FieldDescriptor* field,
527 : int index) const;
528 : template <typename Type>
529 : inline const Type& GetRepeatedPtrField(const Message& message,
530 : const FieldDescriptor* field,
531 : int index) const;
532 : template <typename Type>
533 : inline void SetRepeatedField(Message* message,
534 : const FieldDescriptor* field, int index,
535 0 : Type value) const;
536 : template <typename Type>
537 : inline Type* MutableRepeatedField(Message* message,
538 : const FieldDescriptor* field,
539 0 : int index) const;
540 : template <typename Type>
541 : inline void AddField(Message* message,
542 0 : const FieldDescriptor* field, const Type& value) const;
543 : template <typename Type>
544 : inline Type* AddField(Message* message,
545 0 : const FieldDescriptor* field) const;
546 :
547 : int GetExtensionNumberOrDie(const Descriptor* type) const;
548 :
549 : // Internal versions of EnumValue API perform no checking. Called after checks
550 : // by public methods.
551 : void SetEnumValueInternal(Message* message,
552 : const FieldDescriptor* field,
553 : int value) const;
554 : void SetRepeatedEnumValueInternal(Message* message,
555 : const FieldDescriptor* field,
556 : int index,
557 : int value) const;
558 : void AddEnumValueInternal(Message* message,
559 : const FieldDescriptor* field,
560 : int value) const;
561 :
562 :
563 : Message* UnsafeArenaReleaseMessage(Message* message,
564 : const FieldDescriptor* field,
565 : MessageFactory* factory = NULL) const;
566 :
567 : void UnsafeArenaSetAllocatedMessage(Message* message,
568 : Message* sub_message,
569 : const FieldDescriptor* field) const;
570 :
571 : internal::MapFieldBase* MapData(
572 : Message* message, const FieldDescriptor* field) const;
573 :
574 : GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratedMessageReflection);
575 : };
576 :
577 : // Returns the offset of the given field within the given aggregate type.
578 : // This is equivalent to the ANSI C offsetof() macro. However, according
579 : // to the C++ standard, offsetof() only works on POD types, and GCC
580 : // enforces this requirement with a warning. In practice, this rule is
581 : // unnecessarily strict; there is probably no compiler or platform on
582 : // which the offsets of the direct fields of a class are non-constant.
583 : // Fields inherited from superclasses *can* have non-constant offsets,
584 : // but that's not what this macro will be used for.
585 : //
586 : // Note that we calculate relative to the pointer value 16 here since if we
587 : // just use zero, GCC complains about dereferencing a NULL pointer. We
588 : // choose 16 rather than some other number just in case the compiler would
589 : // be confused by an unaligned pointer.
590 : #define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD) \
591 : static_cast<int>( \
592 : reinterpret_cast<const char*>( \
593 : &reinterpret_cast<const TYPE*>(16)->FIELD) - \
594 : reinterpret_cast<const char*>(16))
595 :
596 : #define PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(ONEOF, FIELD) \
597 : static_cast<int>( \
598 : reinterpret_cast<const char*>(&(ONEOF->FIELD)) \
599 : - reinterpret_cast<const char*>(ONEOF))
600 :
601 : // There are some places in proto2 where dynamic_cast would be useful as an
602 : // optimization. For example, take Message::MergeFrom(const Message& other).
603 : // For a given generated message FooMessage, we generate these two methods:
604 : // void MergeFrom(const FooMessage& other);
605 : // void MergeFrom(const Message& other);
606 : // The former method can be implemented directly in terms of FooMessage's
607 : // inline accessors, but the latter method must work with the reflection
608 : // interface. However, if the parameter to the latter method is actually of
609 : // type FooMessage, then we'd like to be able to just call the other method
610 : // as an optimization. So, we use dynamic_cast to check this.
611 : //
612 : // That said, dynamic_cast requires RTTI, which many people like to disable
613 : // for performance and code size reasons. When RTTI is not available, we
614 : // still need to produce correct results. So, in this case we have to fall
615 : // back to using reflection, which is what we would have done anyway if the
616 : // objects were not of the exact same class.
617 : //
618 : // dynamic_cast_if_available() implements this logic. If RTTI is
619 : // enabled, it does a dynamic_cast. If RTTI is disabled, it just returns
620 : // NULL.
621 : //
622 : // If you need to compile without RTTI, simply #define GOOGLE_PROTOBUF_NO_RTTI.
623 : // On MSVC, this should be detected automatically.
624 : template<typename To, typename From>
625 : inline To dynamic_cast_if_available(From from) {
626 : #if defined(GOOGLE_PROTOBUF_NO_RTTI) || (defined(_MSC_VER)&&!defined(_CPPRTTI))
627 : return NULL;
628 : #else
629 : return dynamic_cast<To>(from);
630 : #endif
631 : }
632 :
633 : // Tries to downcast this message to a generated message type.
634 : // Returns NULL if this class is not an instance of T.
635 : //
636 : // This is like dynamic_cast_if_available, except it works even when
637 : // dynamic_cast is not available by using Reflection. However it only works
638 : // with Message objects.
639 : //
640 : // TODO(haberman): can we remove dynamic_cast_if_available in favor of this?
641 : template <typename T>
642 0 : T* DynamicCastToGenerated(const Message* from) {
643 : // Compile-time assert that T is a generated type that has a
644 : // default_instance() accessor, but avoid actually calling it.
645 0 : const T&(*get_default_instance)() = &T::default_instance;
646 : (void)get_default_instance;
647 :
648 : // Compile-time assert that T is a subclass of google::protobuf::Message.
649 0 : const Message* unused = static_cast<T*>(NULL);
650 : (void)unused;
651 :
652 : #if defined(GOOGLE_PROTOBUF_NO_RTTI) || \
653 : (defined(_MSC_VER) && !defined(_CPPRTTI))
654 : bool ok = &T::default_instance() ==
655 : from->GetReflection()->GetMessageFactory()->GetPrototype(
656 : from->GetDescriptor());
657 : return ok ? down_cast<T*>(from) : NULL;
658 : #else
659 0 : return dynamic_cast<T*>(from);
660 : #endif
661 : }
662 :
663 : template <typename T>
664 : T* DynamicCastToGenerated(Message* from) {
665 : const Message* message_const = from;
666 : return const_cast<T*>(DynamicCastToGenerated<const T>(message_const));
667 : }
668 :
669 : } // namespace internal
670 : } // namespace protobuf
671 :
672 : } // namespace google
673 : #endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
|