Initial import of v2.0.0beta
[protobuf.git] / src / google / protobuf / generated_message_reflection.h
blob579d6abe1ae5a789cf576836e0988645a341e42e
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.
3 // http://code.google.com/p/protobuf/
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
17 // Author: kenton@google.com (Kenton Varda)
18 // Based on original Protocol Buffers design by
19 // Sanjay Ghemawat, Jeff Dean, and others.
21 // This header is logically internal, but is made public because it is used
22 // from protocol-compiler-generated code, which may reside in other components.
24 #ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
25 #define GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
27 #include <string>
28 #include <vector>
29 #include <google/protobuf/message.h>
30 #include <google/protobuf/unknown_field_set.h>
33 // Generated code needs this to have been forward-declared. Easier to do it
34 // here than to print it inside every .pb.h file.
35 namespace google {
36 namespace protobuf { class EnumDescriptor; }
38 namespace protobuf {
39 namespace internal {
41 // Defined in this file.
42 class GeneratedMessageReflection;
44 // Defined in other files.
45 class ExtensionSet; // extension_set.h
47 // THIS CLASS IS NOT INTENDED FOR DIRECT USE. It is intended for use
48 // by generated code. This class is just a big hack that reduces code
49 // size.
51 // A GeneratedMessageReflection is an implementation of Message::Reflection
52 // which expects all fields to be backed by simple variables located in
53 // memory. The locations are given using a base pointer and a set of
54 // offsets.
56 // It is required that the user represents fields of each type in a standard
57 // way, so that GeneratedMessageReflection can cast the void* pointer to
58 // the appropriate type. For primitive fields and string fields, each field
59 // should be represented using the obvious C++ primitive type. Enums and
60 // Messages are different:
61 // - Singular Message fields are stored as a pointer to a Message. These
62 // should start out NULL, except for in the default instance where they
63 // should start out pointing to other default instances.
64 // - Enum fields are stored as an int. This int must always contain
65 // a valid value, such that EnumDescriptor::FindValueByNumber() would
66 // not return NULL.
67 // - Repeated fields are stored as RepeatedFields or RepeatedPtrFields
68 // of whatever type the individual field would be. Strings and
69 // Messages use RepeatedPtrFields while everything else uses
70 // RepeatedFields.
71 class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Message::Reflection {
72 public:
73 // Constructs a GeneratedMessageReflection.
74 // Parameters:
75 // descriptor: The descriptor for the message type being implemented.
76 // base: Pointer to the location where the message object is
77 // stored.
78 // default_base: Pointer to the location where the message's default
79 // instance is stored. This is only used to obtain
80 // pointers to default instances of embedded messages,
81 // which GetMessage() will return if the particular sub-
82 // message has not been initialized yet. (Thus, all
83 // embedded message fields *must* have non-NULL pointers
84 // in the default instance.)
85 // offsets: An array of bits giving the byte offsets, relative to
86 // "base" and "default_base", of each field. These can
87 // be computed at compile time using the
88 // GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET() macro, defined
89 // below.
90 // has_bits: An array of uint32s of size descriptor->field_count()/32,
91 // rounded up. This is a bitfield where each bit indicates
92 // whether or not the corresponding field of the message
93 // has been initialized. The bit for field index i is
94 // obtained by the expression:
95 // has_bits[i / 32] & (1 << (i % 32))
96 // extensions: The ExtensionSet for this message, or NULL if the
97 // message type has no extension ranges.
98 GeneratedMessageReflection(const Descriptor* descriptor,
99 void* base, const void* default_base,
100 const int offsets[], uint32 has_bits[],
101 ExtensionSet* extensions);
102 ~GeneratedMessageReflection();
104 inline const UnknownFieldSet& unknown_fields() const {
105 return unknown_fields_;
107 inline UnknownFieldSet* mutable_unknown_fields() {
108 return &unknown_fields_;
111 // implements Message::Reflection ----------------------------------
113 const UnknownFieldSet& GetUnknownFields() const;
114 UnknownFieldSet* MutableUnknownFields();
116 bool HasField(const FieldDescriptor* field) const;
117 int FieldSize(const FieldDescriptor* field) const;
118 void ClearField(const FieldDescriptor* field);
119 void ListFields(vector<const FieldDescriptor*>* output) const;
121 int32 GetInt32 (const FieldDescriptor* field) const;
122 int64 GetInt64 (const FieldDescriptor* field) const;
123 uint32 GetUInt32(const FieldDescriptor* field) const;
124 uint64 GetUInt64(const FieldDescriptor* field) const;
125 float GetFloat (const FieldDescriptor* field) const;
126 double GetDouble(const FieldDescriptor* field) const;
127 bool GetBool (const FieldDescriptor* field) const;
128 string GetString(const FieldDescriptor* field) const;
129 const string& GetStringReference(const FieldDescriptor* field,
130 string* scratch) const;
131 const EnumValueDescriptor* GetEnum(const FieldDescriptor* field) const;
132 const Message& GetMessage(const FieldDescriptor* field) const;
134 void SetInt32 (const FieldDescriptor* field, int32 value);
135 void SetInt64 (const FieldDescriptor* field, int64 value);
136 void SetUInt32(const FieldDescriptor* field, uint32 value);
137 void SetUInt64(const FieldDescriptor* field, uint64 value);
138 void SetFloat (const FieldDescriptor* field, float value);
139 void SetDouble(const FieldDescriptor* field, double value);
140 void SetBool (const FieldDescriptor* field, bool value);
141 void SetString(const FieldDescriptor* field,
142 const string& value);
143 void SetEnum (const FieldDescriptor* field,
144 const EnumValueDescriptor* value);
145 Message* MutableMessage(const FieldDescriptor* field);
147 int32 GetRepeatedInt32 (const FieldDescriptor* field, int index) const;
148 int64 GetRepeatedInt64 (const FieldDescriptor* field, int index) const;
149 uint32 GetRepeatedUInt32(const FieldDescriptor* field, int index) const;
150 uint64 GetRepeatedUInt64(const FieldDescriptor* field, int index) const;
151 float GetRepeatedFloat (const FieldDescriptor* field, int index) const;
152 double GetRepeatedDouble(const FieldDescriptor* field, int index) const;
153 bool GetRepeatedBool (const FieldDescriptor* field, int index) const;
154 string GetRepeatedString(const FieldDescriptor* field, int index) const;
155 const string& GetRepeatedStringReference(const FieldDescriptor* field,
156 int index, string* scratch) const;
157 const EnumValueDescriptor* GetRepeatedEnum(const FieldDescriptor* field,
158 int index) const;
159 const Message& GetRepeatedMessage(const FieldDescriptor* field,
160 int index) const;
162 // Set the value of a field.
163 void SetRepeatedInt32 (const FieldDescriptor* field, int index, int32 value);
164 void SetRepeatedInt64 (const FieldDescriptor* field, int index, int64 value);
165 void SetRepeatedUInt32(const FieldDescriptor* field, int index, uint32 value);
166 void SetRepeatedUInt64(const FieldDescriptor* field, int index, uint64 value);
167 void SetRepeatedFloat (const FieldDescriptor* field, int index, float value);
168 void SetRepeatedDouble(const FieldDescriptor* field, int index, double value);
169 void SetRepeatedBool (const FieldDescriptor* field, int index, bool value);
170 void SetRepeatedString(const FieldDescriptor* field, int index,
171 const string& value);
172 void SetRepeatedEnum (const FieldDescriptor* field, int index,
173 const EnumValueDescriptor* value);
174 // Get a mutable pointer to a field with a message type.
175 Message* MutableRepeatedMessage(const FieldDescriptor* field, int index);
177 void AddInt32 (const FieldDescriptor* field, int32 value);
178 void AddInt64 (const FieldDescriptor* field, int64 value);
179 void AddUInt32(const FieldDescriptor* field, uint32 value);
180 void AddUInt64(const FieldDescriptor* field, uint64 value);
181 void AddFloat (const FieldDescriptor* field, float value);
182 void AddDouble(const FieldDescriptor* field, double value);
183 void AddBool (const FieldDescriptor* field, bool value);
184 void AddString(const FieldDescriptor* field, const string& value);
185 void AddEnum(const FieldDescriptor* field, const EnumValueDescriptor* value);
186 Message* AddMessage(const FieldDescriptor* field);
188 const FieldDescriptor* FindKnownExtensionByName(const string& name) const;
189 const FieldDescriptor* FindKnownExtensionByNumber(int number) const;
191 private:
192 friend class GeneratedMessage;
194 const Descriptor* descriptor_;
195 void* base_;
196 const void* default_base_;
197 const int* offsets_;
199 // TODO(kenton): These two pointers just point back into the message object.
200 // We could save space by removing them and using offsets instead.
201 uint32* has_bits_;
202 ExtensionSet* extensions_;
204 // We put this directly in the GeneratedMessageReflection because every
205 // message class needs it, and if we don't find any unknown fields, it
206 // takes up only one pointer of space.
207 UnknownFieldSet unknown_fields_;
209 template <typename Type>
210 inline const Type& GetRaw(const FieldDescriptor* field) const;
211 template <typename Type>
212 inline Type* MutableRaw(const FieldDescriptor* field);
213 template <typename Type>
214 inline const Type& DefaultRaw(const FieldDescriptor* field) const;
215 inline const Message* GetMessagePrototype(const FieldDescriptor* field) const;
217 inline bool HasBit(const FieldDescriptor* field) const;
218 inline void SetBit(const FieldDescriptor* field);
219 inline void ClearBit(const FieldDescriptor* field);
221 template <typename Type>
222 inline const Type& GetField(const FieldDescriptor* field) const;
223 template <typename Type>
224 inline void SetField(const FieldDescriptor* field, const Type& value);
225 template <typename Type>
226 inline Type* MutableField(const FieldDescriptor* field);
227 template <typename Type>
228 inline const Type& GetRepeatedField(const FieldDescriptor* field,
229 int index) const;
230 template <typename Type>
231 inline void SetRepeatedField(const FieldDescriptor* field, int index,
232 const Type& value);
233 template <typename Type>
234 inline Type* MutableRepeatedField(const FieldDescriptor* field, int index);
235 template <typename Type>
236 inline void AddField(const FieldDescriptor* field, const Type& value);
237 template <typename Type>
238 inline Type* AddField(const FieldDescriptor* field);
240 int GetExtensionNumberOrDie(const Descriptor* type) const;
242 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratedMessageReflection);
245 // Returns the offset of the given field within the given aggregate type.
246 // This is equivalent to the ANSI C offsetof() macro. However, according
247 // to the C++ standard, offsetof() only works on POD types, and GCC
248 // enforces this requirement with a warning. In practice, this rule is
249 // unnecessarily strict; there is probably no compiler or platform on
250 // which the offsets of the direct fields of a class are non-constant.
251 // Fields inherited from superclasses *can* have non-constant offsets,
252 // but that's not what this macro will be used for.
254 // Note that we calculate relative to the pointer value 16 here since if we
255 // just use zero, GCC complains about dereferencing a NULL pointer. We
256 // choose 16 rather than some other number just in case the compiler would
257 // be confused by an unaligned pointer.
258 #define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD) \
259 (reinterpret_cast<const char*>( \
260 &reinterpret_cast<const TYPE*>(16)->FIELD) - \
261 reinterpret_cast<const char*>(16))
263 // There are some places in proto2 where dynamic_cast would be useful as an
264 // optimization. For example, take Message::MergeFrom(const Message& other).
265 // For a given generated message FooMessage, we generate these two methods:
266 // void MergeFrom(const FooMessage& other);
267 // void MergeFrom(const Message& other);
268 // The former method can be implemented directly in terms of FooMessage's
269 // inline accessors, but the latter method must work with the reflection
270 // interface. However, if the parameter to the latter method is actually of
271 // type FooMessage, then we'd like to be able to just call the other method
272 // as an optimization. So, we use dynamic_cast to check this.
274 // That said, dynamic_cast requires RTTI, which many people like to disable
275 // for performance and code size reasons. When RTTI is not available, we
276 // still need to produce correct results. So, in this case we have to fall
277 // back to using reflection, which is what we would have done anyway if the
278 // objects were not of the exact same class.
280 // dynamic_cast_if_available() implements this logic. If RTTI is
281 // enabled, it does a dynamic_cast. If RTTI is disabled, it just returns
282 // NULL.
284 // If you need to compile without RTTI, simply #define GOOGLE_PROTOBUF_NO_RTTI.
285 // On MSVC, this should be detected automatically.
286 template<typename To, typename From>
287 inline To dynamic_cast_if_available(From from) {
288 #if defined(GOOGLE_PROTOBUF_NO_RTTI) || (defined(_MSC_VER)&&!defined(_CPPRTTI))
289 return NULL;
290 #else
291 return dynamic_cast<To>(from);
292 #endif
296 } // namespace internal
297 } // namespace protobuf
299 } // namespace google
300 #endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__