BWAPI
|
00001 // Protocol Buffers - Google's data interchange format 00002 // Copyright 2008 Google Inc. All rights reserved. 00003 // http://code.google.com/p/protobuf/ 00004 // 00005 // Redistribution and use in source and binary forms, with or without 00006 // modification, are permitted provided that the following conditions are 00007 // met: 00008 // 00009 // * Redistributions of source code must retain the above copyright 00010 // notice, this list of conditions and the following disclaimer. 00011 // * Redistributions in binary form must reproduce the above 00012 // copyright notice, this list of conditions and the following disclaimer 00013 // in the documentation and/or other materials provided with the 00014 // distribution. 00015 // * Neither the name of Google Inc. nor the names of its 00016 // contributors may be used to endorse or promote products derived from 00017 // this software without specific prior written permission. 00018 // 00019 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00020 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00021 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00022 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00023 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00024 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00025 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00026 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00027 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00028 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00029 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00030 00031 // Author: kenton@google.com (Kenton Varda) 00032 // Based on original Protocol Buffers design by 00033 // Sanjay Ghemawat, Jeff Dean, and others. 00034 // 00035 // This header is logically internal, but is made public because it is used 00036 // from protocol-compiler-generated code, which may reside in other components. 00037 00038 #ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__ 00039 #define GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__ 00040 00041 #include <string> 00042 #include <vector> 00043 #include <google/protobuf/message.h> 00044 #include <google/protobuf/unknown_field_set.h> 00045 00046 00047 namespace google { 00048 namespace protobuf { 00049 class DescriptorPool; 00050 // Generated code needs these to have been forward-declared. Easier to do it 00051 // here than to print them inside every .pb.h file. 00052 class FileDescriptor; 00053 class EnumDescriptor; 00054 } 00055 00056 namespace protobuf { 00057 namespace internal { 00058 00059 // Defined in this file. 00060 class GeneratedMessageReflection; 00061 00062 // Defined in other files. 00063 class ExtensionSet; // extension_set.h 00064 00065 // THIS CLASS IS NOT INTENDED FOR DIRECT USE. It is intended for use 00066 // by generated code. This class is just a big hack that reduces code 00067 // size. 00068 // 00069 // A GeneratedMessageReflection is an implementation of Reflection 00070 // which expects all fields to be backed by simple variables located in 00071 // memory. The locations are given using a base pointer and a set of 00072 // offsets. 00073 // 00074 // It is required that the user represents fields of each type in a standard 00075 // way, so that GeneratedMessageReflection can cast the void* pointer to 00076 // the appropriate type. For primitive fields and string fields, each field 00077 // should be represented using the obvious C++ primitive type. Enums and 00078 // Messages are different: 00079 // - Singular Message fields are stored as a pointer to a Message. These 00080 // should start out NULL, except for in the default instance where they 00081 // should start out pointing to other default instances. 00082 // - Enum fields are stored as an int. This int must always contain 00083 // a valid value, such that EnumDescriptor::FindValueByNumber() would 00084 // not return NULL. 00085 // - Repeated fields are stored as RepeatedFields or RepeatedPtrFields 00086 // of whatever type the individual field would be. Strings and 00087 // Messages use RepeatedPtrFields while everything else uses 00088 // RepeatedFields. 00089 class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection { 00090 public: 00091 // Constructs a GeneratedMessageReflection. 00092 // Parameters: 00093 // descriptor: The descriptor for the message type being implemented. 00094 // default_instance: The default instance of the message. This is only 00095 // used to obtain pointers to default instances of embedded 00096 // messages, which GetMessage() will return if the particular 00097 // sub-message has not been initialized yet. (Thus, all 00098 // embedded message fields *must* have non-NULL pointers 00099 // in the default instance.) 00100 // offsets: An array of ints giving the byte offsets, relative to 00101 // the start of the message object, of each field. These can 00102 // be computed at compile time using the 00103 // GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET() macro, defined 00104 // below. 00105 // has_bits_offset: Offset in the message of an array of uint32s of size 00106 // descriptor->field_count()/32, rounded up. This is a 00107 // bitfield where each bit indicates whether or not the 00108 // corresponding field of the message has been initialized. 00109 // The bit for field index i is obtained by the expression: 00110 // has_bits[i / 32] & (1 << (i % 32)) 00111 // unknown_fields_offset: Offset in the message of the UnknownFieldSet for 00112 // the message. 00113 // extensions_offset: Offset in the message of the ExtensionSet for the 00114 // message, or -1 if the message type has no extension 00115 // ranges. 00116 // pool: DescriptorPool to search for extension definitions. Only 00117 // used by FindKnownExtensionByName() and 00118 // FindKnownExtensionByNumber(). 00119 // factory: MessageFactory to use to construct extension messages. 00120 // object_size: The size of a message object of this type, as measured 00121 // by sizeof(). 00122 GeneratedMessageReflection(const Descriptor* descriptor, 00123 const Message* default_instance, 00124 const int offsets[], 00125 int has_bits_offset, 00126 int unknown_fields_offset, 00127 int extensions_offset, 00128 const DescriptorPool* pool, 00129 MessageFactory* factory, 00130 int object_size); 00131 ~GeneratedMessageReflection(); 00132 00133 // implements Reflection ------------------------------------------- 00134 00135 const UnknownFieldSet& GetUnknownFields(const Message& message) const; 00136 UnknownFieldSet* MutableUnknownFields(Message* message) const; 00137 00138 int SpaceUsed(const Message& message) const; 00139 00140 bool HasField(const Message& message, const FieldDescriptor* field) const; 00141 int FieldSize(const Message& message, const FieldDescriptor* field) const; 00142 void ClearField(Message* message, const FieldDescriptor* field) const; 00143 void RemoveLast(Message* message, const FieldDescriptor* field) const; 00144 void Swap(Message* message1, Message* message2) const; 00145 void SwapElements(Message* message, const FieldDescriptor* field, 00146 int index1, int index2) const; 00147 void ListFields(const Message& message, 00148 vector<const FieldDescriptor*>* output) const; 00149 00150 int32 GetInt32 (const Message& message, 00151 const FieldDescriptor* field) const; 00152 int64 GetInt64 (const Message& message, 00153 const FieldDescriptor* field) const; 00154 uint32 GetUInt32(const Message& message, 00155 const FieldDescriptor* field) const; 00156 uint64 GetUInt64(const Message& message, 00157 const FieldDescriptor* field) const; 00158 float GetFloat (const Message& message, 00159 const FieldDescriptor* field) const; 00160 double GetDouble(const Message& message, 00161 const FieldDescriptor* field) const; 00162 bool GetBool (const Message& message, 00163 const FieldDescriptor* field) const; 00164 string GetString(const Message& message, 00165 const FieldDescriptor* field) const; 00166 const string& GetStringReference(const Message& message, 00167 const FieldDescriptor* field, 00168 string* scratch) const; 00169 const EnumValueDescriptor* GetEnum(const Message& message, 00170 const FieldDescriptor* field) const; 00171 const Message& GetMessage(const Message& message, 00172 const FieldDescriptor* field, 00173 MessageFactory* factory = NULL) const; 00174 00175 void SetInt32 (Message* message, 00176 const FieldDescriptor* field, int32 value) const; 00177 void SetInt64 (Message* message, 00178 const FieldDescriptor* field, int64 value) const; 00179 void SetUInt32(Message* message, 00180 const FieldDescriptor* field, uint32 value) const; 00181 void SetUInt64(Message* message, 00182 const FieldDescriptor* field, uint64 value) const; 00183 void SetFloat (Message* message, 00184 const FieldDescriptor* field, float value) const; 00185 void SetDouble(Message* message, 00186 const FieldDescriptor* field, double value) const; 00187 void SetBool (Message* message, 00188 const FieldDescriptor* field, bool value) const; 00189 void SetString(Message* message, 00190 const FieldDescriptor* field, 00191 const string& value) const; 00192 void SetEnum (Message* message, const FieldDescriptor* field, 00193 const EnumValueDescriptor* value) const; 00194 Message* MutableMessage(Message* message, const FieldDescriptor* field, 00195 MessageFactory* factory = NULL) const; 00196 00197 int32 GetRepeatedInt32 (const Message& message, 00198 const FieldDescriptor* field, int index) const; 00199 int64 GetRepeatedInt64 (const Message& message, 00200 const FieldDescriptor* field, int index) const; 00201 uint32 GetRepeatedUInt32(const Message& message, 00202 const FieldDescriptor* field, int index) const; 00203 uint64 GetRepeatedUInt64(const Message& message, 00204 const FieldDescriptor* field, int index) const; 00205 float GetRepeatedFloat (const Message& message, 00206 const FieldDescriptor* field, int index) const; 00207 double GetRepeatedDouble(const Message& message, 00208 const FieldDescriptor* field, int index) const; 00209 bool GetRepeatedBool (const Message& message, 00210 const FieldDescriptor* field, int index) const; 00211 string GetRepeatedString(const Message& message, 00212 const FieldDescriptor* field, int index) const; 00213 const string& GetRepeatedStringReference(const Message& message, 00214 const FieldDescriptor* field, 00215 int index, string* scratch) const; 00216 const EnumValueDescriptor* GetRepeatedEnum(const Message& message, 00217 const FieldDescriptor* field, 00218 int index) const; 00219 const Message& GetRepeatedMessage(const Message& message, 00220 const FieldDescriptor* field, 00221 int index) const; 00222 00223 // Set the value of a field. 00224 void SetRepeatedInt32 (Message* message, 00225 const FieldDescriptor* field, int index, int32 value) const; 00226 void SetRepeatedInt64 (Message* message, 00227 const FieldDescriptor* field, int index, int64 value) const; 00228 void SetRepeatedUInt32(Message* message, 00229 const FieldDescriptor* field, int index, uint32 value) const; 00230 void SetRepeatedUInt64(Message* message, 00231 const FieldDescriptor* field, int index, uint64 value) const; 00232 void SetRepeatedFloat (Message* message, 00233 const FieldDescriptor* field, int index, float value) const; 00234 void SetRepeatedDouble(Message* message, 00235 const FieldDescriptor* field, int index, double value) const; 00236 void SetRepeatedBool (Message* message, 00237 const FieldDescriptor* field, int index, bool value) const; 00238 void SetRepeatedString(Message* message, 00239 const FieldDescriptor* field, int index, 00240 const string& value) const; 00241 void SetRepeatedEnum(Message* message, const FieldDescriptor* field, 00242 int index, const EnumValueDescriptor* value) const; 00243 // Get a mutable pointer to a field with a message type. 00244 Message* MutableRepeatedMessage(Message* message, 00245 const FieldDescriptor* field, 00246 int index) const; 00247 00248 void AddInt32 (Message* message, 00249 const FieldDescriptor* field, int32 value) const; 00250 void AddInt64 (Message* message, 00251 const FieldDescriptor* field, int64 value) const; 00252 void AddUInt32(Message* message, 00253 const FieldDescriptor* field, uint32 value) const; 00254 void AddUInt64(Message* message, 00255 const FieldDescriptor* field, uint64 value) const; 00256 void AddFloat (Message* message, 00257 const FieldDescriptor* field, float value) const; 00258 void AddDouble(Message* message, 00259 const FieldDescriptor* field, double value) const; 00260 void AddBool (Message* message, 00261 const FieldDescriptor* field, bool value) const; 00262 void AddString(Message* message, 00263 const FieldDescriptor* field, const string& value) const; 00264 void AddEnum(Message* message, 00265 const FieldDescriptor* field, 00266 const EnumValueDescriptor* value) const; 00267 Message* AddMessage(Message* message, const FieldDescriptor* field, 00268 MessageFactory* factory = NULL) const; 00269 00270 const FieldDescriptor* FindKnownExtensionByName(const string& name) const; 00271 const FieldDescriptor* FindKnownExtensionByNumber(int number) const; 00272 00273 private: 00274 friend class GeneratedMessage; 00275 00276 const Descriptor* descriptor_; 00277 const Message* default_instance_; 00278 const int* offsets_; 00279 00280 int has_bits_offset_; 00281 int unknown_fields_offset_; 00282 int extensions_offset_; 00283 int object_size_; 00284 00285 const DescriptorPool* descriptor_pool_; 00286 MessageFactory* message_factory_; 00287 00288 template <typename Type> 00289 inline const Type& GetRaw(const Message& message, 00290 const FieldDescriptor* field) const; 00291 template <typename Type> 00292 inline Type* MutableRaw(Message* message, 00293 const FieldDescriptor* field) const; 00294 template <typename Type> 00295 inline const Type& DefaultRaw(const FieldDescriptor* field) const; 00296 inline const Message* GetMessagePrototype(const FieldDescriptor* field) const; 00297 00298 inline const uint32* GetHasBits(const Message& message) const; 00299 inline uint32* MutableHasBits(Message* message) const; 00300 inline const ExtensionSet& GetExtensionSet(const Message& message) const; 00301 inline ExtensionSet* MutableExtensionSet(Message* message) const; 00302 00303 inline bool HasBit(const Message& message, 00304 const FieldDescriptor* field) const; 00305 inline void SetBit(Message* message, 00306 const FieldDescriptor* field) const; 00307 inline void ClearBit(Message* message, 00308 const FieldDescriptor* field) const; 00309 00310 template <typename Type> 00311 inline const Type& GetField(const Message& message, 00312 const FieldDescriptor* field) const; 00313 template <typename Type> 00314 inline void SetField(Message* message, 00315 const FieldDescriptor* field, const Type& value) const; 00316 template <typename Type> 00317 inline Type* MutableField(Message* message, 00318 const FieldDescriptor* field) const; 00319 template <typename Type> 00320 inline const Type& GetRepeatedField(const Message& message, 00321 const FieldDescriptor* field, 00322 int index) const; 00323 template <typename Type> 00324 inline const Type& GetRepeatedPtrField(const Message& message, 00325 const FieldDescriptor* field, 00326 int index) const; 00327 template <typename Type> 00328 inline void SetRepeatedField(Message* message, 00329 const FieldDescriptor* field, int index, 00330 Type value) const; 00331 template <typename Type> 00332 inline Type* MutableRepeatedField(Message* message, 00333 const FieldDescriptor* field, 00334 int index) const; 00335 template <typename Type> 00336 inline void AddField(Message* message, 00337 const FieldDescriptor* field, const Type& value) const; 00338 template <typename Type> 00339 inline Type* AddField(Message* message, 00340 const FieldDescriptor* field) const; 00341 00342 int GetExtensionNumberOrDie(const Descriptor* type) const; 00343 00344 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratedMessageReflection); 00345 }; 00346 00347 // Returns the offset of the given field within the given aggregate type. 00348 // This is equivalent to the ANSI C offsetof() macro. However, according 00349 // to the C++ standard, offsetof() only works on POD types, and GCC 00350 // enforces this requirement with a warning. In practice, this rule is 00351 // unnecessarily strict; there is probably no compiler or platform on 00352 // which the offsets of the direct fields of a class are non-constant. 00353 // Fields inherited from superclasses *can* have non-constant offsets, 00354 // but that's not what this macro will be used for. 00355 // 00356 // Note that we calculate relative to the pointer value 16 here since if we 00357 // just use zero, GCC complains about dereferencing a NULL pointer. We 00358 // choose 16 rather than some other number just in case the compiler would 00359 // be confused by an unaligned pointer. 00360 #define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD) \ 00361 static_cast<int>( \ 00362 reinterpret_cast<const char*>( \ 00363 &reinterpret_cast<const TYPE*>(16)->FIELD) - \ 00364 reinterpret_cast<const char*>(16)) 00365 00366 // There are some places in proto2 where dynamic_cast would be useful as an 00367 // optimization. For example, take Message::MergeFrom(const Message& other). 00368 // For a given generated message FooMessage, we generate these two methods: 00369 // void MergeFrom(const FooMessage& other); 00370 // void MergeFrom(const Message& other); 00371 // The former method can be implemented directly in terms of FooMessage's 00372 // inline accessors, but the latter method must work with the reflection 00373 // interface. However, if the parameter to the latter method is actually of 00374 // type FooMessage, then we'd like to be able to just call the other method 00375 // as an optimization. So, we use dynamic_cast to check this. 00376 // 00377 // That said, dynamic_cast requires RTTI, which many people like to disable 00378 // for performance and code size reasons. When RTTI is not available, we 00379 // still need to produce correct results. So, in this case we have to fall 00380 // back to using reflection, which is what we would have done anyway if the 00381 // objects were not of the exact same class. 00382 // 00383 // dynamic_cast_if_available() implements this logic. If RTTI is 00384 // enabled, it does a dynamic_cast. If RTTI is disabled, it just returns 00385 // NULL. 00386 // 00387 // If you need to compile without RTTI, simply #define GOOGLE_PROTOBUF_NO_RTTI. 00388 // On MSVC, this should be detected automatically. 00389 template<typename To, typename From> 00390 inline To dynamic_cast_if_available(From from) { 00391 #if defined(GOOGLE_PROTOBUF_NO_RTTI) || (defined(_MSC_VER)&&!defined(_CPPRTTI)) 00392 return NULL; 00393 #else 00394 return dynamic_cast<To>(from); 00395 #endif 00396 } 00397 00398 // Helper for EnumType_Parse functions: try to parse the string 'name' as an 00399 // enum name of the given type, returning true and filling in value on success, 00400 // or returning false and leaving value unchanged on failure. 00401 LIBPROTOBUF_EXPORT bool ParseNamedEnum(const EnumDescriptor* descriptor, 00402 const string& name, 00403 int* value); 00404 00405 template<typename EnumType> 00406 bool ParseNamedEnum(const EnumDescriptor* descriptor, 00407 const string& name, 00408 EnumType* value) { 00409 int tmp; 00410 if (!ParseNamedEnum(descriptor, name, &tmp)) return false; 00411 *value = static_cast<EnumType>(tmp); 00412 return true; 00413 } 00414 00415 // Just a wrapper around printing the name of a value. The main point of this 00416 // function is not to be inlined, so that you can do this without including 00417 // descriptor.h. 00418 LIBPROTOBUF_EXPORT const string& NameOfEnum(const EnumDescriptor* descriptor, int value); 00419 00420 } // namespace internal 00421 } // namespace protobuf 00422 00423 } // namespace google 00424 #endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__