generated_message_reflection.h revision d0332953cda33fb4f8e24ebff9c49159b69c43d6
1bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// Protocol Buffers - Google's data interchange format 2bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// Copyright 2008 Google Inc. All rights reserved. 3f5256e16dfc425c1d466f6308d4026d529ce9e0bHoward Hinnant// http://code.google.com/p/protobuf/ 4bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// 5b64f8b07c104c6cc986570ac8ee0ed16a9f23976Howard Hinnant// Redistribution and use in source and binary forms, with or without 6b64f8b07c104c6cc986570ac8ee0ed16a9f23976Howard Hinnant// modification, are permitted provided that the following conditions are 7bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// met: 8bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// 9bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// * Redistributions of source code must retain the above copyright 10bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// notice, this list of conditions and the following disclaimer. 11bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// * Redistributions in binary form must reproduce the above 12bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// copyright notice, this list of conditions and the following disclaimer 13bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// in the documentation and/or other materials provided with the 14bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// distribution. 15bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// * Neither the name of Google Inc. nor the names of its 16bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// contributors may be used to endorse or promote products derived from 17bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// this software without specific prior written permission. 1883e2c4d877fe2d7793868b1c6a5d9525a7c4d431Marshall Clow// 19c0d0cbad9ed434267a7af9531bdeeae52eb6d706Howard Hinnant// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 31bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// Author: kenton@google.com (Kenton Varda) 32bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// Based on original Protocol Buffers design by 33bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// Sanjay Ghemawat, Jeff Dean, and others. 34bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// 35bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// This header is logically internal, but is made public because it is used 36bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// from protocol-compiler-generated code, which may reside in other components. 37bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 38bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__ 39bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__ 40bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 41bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include <string> 42bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include <vector> 43bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include <google/protobuf/message.h> 44bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant#include <google/protobuf/unknown_field_set.h> 45bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 46bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 47bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantnamespace google { 48bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantnamespace protobuf { 49bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant class DescriptorPool; 50bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant // Generated code needs these to have been forward-declared. Easier to do it 51bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant // here than to print them inside every .pb.h file. 52bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant class FileDescriptor; 53bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant class EnumDescriptor; 54bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant} 55bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 56bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantnamespace protobuf { 57bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantnamespace internal { 58bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 59bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// Defined in this file. 60bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantclass GeneratedMessageReflection; 61bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 62bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// Defined in other files. 63bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantclass ExtensionSet; // extension_set.h 64bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant 65bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// THIS CLASS IS NOT INTENDED FOR DIRECT USE. It is intended for use 66bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// by generated code. This class is just a big hack that reduces code 67bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// size. 68bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// 69bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// A GeneratedMessageReflection is an implementation of Reflection 70bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// which expects all fields to be backed by simple variables located in 71bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// memory. The locations are given using a base pointer and a set of 72c0d0cbad9ed434267a7af9531bdeeae52eb6d706Howard Hinnant// offsets. 73bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// 74c0d0cbad9ed434267a7af9531bdeeae52eb6d706Howard Hinnant// It is required that the user represents fields of each type in a standard 75bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// way, so that GeneratedMessageReflection can cast the void* pointer to 76bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// the appropriate type. For primitive fields and string fields, each field 77bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// should be represented using the obvious C++ primitive type. Enums and 78bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant// Messages are different: 79// - Singular Message fields are stored as a pointer to a Message. These 80// should start out NULL, except for in the default instance where they 81// should start out pointing to other default instances. 82// - Enum fields are stored as an int. This int must always contain 83// a valid value, such that EnumDescriptor::FindValueByNumber() would 84// not return NULL. 85// - Repeated fields are stored as RepeatedFields or RepeatedPtrFields 86// of whatever type the individual field would be. Strings and 87// Messages use RepeatedPtrFields while everything else uses 88// RepeatedFields. 89class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection { 90 public: 91 // Constructs a GeneratedMessageReflection. 92 // Parameters: 93 // descriptor: The descriptor for the message type being implemented. 94 // default_instance: The default instance of the message. This is only 95 // used to obtain pointers to default instances of embedded 96 // messages, which GetMessage() will return if the particular 97 // sub-message has not been initialized yet. (Thus, all 98 // embedded message fields *must* have non-NULL pointers 99 // in the default instance.) 100 // offsets: An array of ints giving the byte offsets, relative to 101 // the start of the message object, of each field. These can 102 // be computed at compile time using the 103 // GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET() macro, defined 104 // below. 105 // has_bits_offset: Offset in the message of an array of uint32s of size 106 // descriptor->field_count()/32, rounded up. This is a 107 // bitfield where each bit indicates whether or not the 108 // corresponding field of the message has been initialized. 109 // The bit for field index i is obtained by the expression: 110 // has_bits[i / 32] & (1 << (i % 32)) 111 // unknown_fields_offset: Offset in the message of the UnknownFieldSet for 112 // the message. 113 // extensions_offset: Offset in the message of the ExtensionSet for the 114 // message, or -1 if the message type has no extension 115 // ranges. 116 // pool: DescriptorPool to search for extension definitions. Only 117 // used by FindKnownExtensionByName() and 118 // FindKnownExtensionByNumber(). 119 // factory: MessageFactory to use to construct extension messages. 120 // object_size: The size of a message object of this type, as measured 121 // by sizeof(). 122 GeneratedMessageReflection(const Descriptor* descriptor, 123 const Message* default_instance, 124 const int offsets[], 125 int has_bits_offset, 126 int unknown_fields_offset, 127 int extensions_offset, 128 const DescriptorPool* pool, 129 MessageFactory* factory, 130 int object_size); 131 ~GeneratedMessageReflection(); 132 133 // implements Reflection ------------------------------------------- 134 135 const UnknownFieldSet& GetUnknownFields(const Message& message) const; 136 UnknownFieldSet* MutableUnknownFields(Message* message) const; 137 138 int SpaceUsed(const Message& message) const; 139 140 bool HasField(const Message& message, const FieldDescriptor* field) const; 141 int FieldSize(const Message& message, const FieldDescriptor* field) const; 142 void ClearField(Message* message, const FieldDescriptor* field) const; 143 void RemoveLast(Message* message, const FieldDescriptor* field) const; 144 void Swap(Message* message1, Message* message2) const; 145 void SwapElements(Message* message, const FieldDescriptor* field, 146 int index1, int index2) const; 147 void ListFields(const Message& message, 148 vector<const FieldDescriptor*>* output) const; 149 150 int32 GetInt32 (const Message& message, 151 const FieldDescriptor* field) const; 152 int64 GetInt64 (const Message& message, 153 const FieldDescriptor* field) const; 154 uint32 GetUInt32(const Message& message, 155 const FieldDescriptor* field) const; 156 uint64 GetUInt64(const Message& message, 157 const FieldDescriptor* field) const; 158 float GetFloat (const Message& message, 159 const FieldDescriptor* field) const; 160 double GetDouble(const Message& message, 161 const FieldDescriptor* field) const; 162 bool GetBool (const Message& message, 163 const FieldDescriptor* field) const; 164 string GetString(const Message& message, 165 const FieldDescriptor* field) const; 166 const string& GetStringReference(const Message& message, 167 const FieldDescriptor* field, 168 string* scratch) const; 169 const EnumValueDescriptor* GetEnum(const Message& message, 170 const FieldDescriptor* field) const; 171 const Message& GetMessage(const Message& message, 172 const FieldDescriptor* field, 173 MessageFactory* factory = NULL) const; 174 175 void SetInt32 (Message* message, 176 const FieldDescriptor* field, int32 value) const; 177 void SetInt64 (Message* message, 178 const FieldDescriptor* field, int64 value) const; 179 void SetUInt32(Message* message, 180 const FieldDescriptor* field, uint32 value) const; 181 void SetUInt64(Message* message, 182 const FieldDescriptor* field, uint64 value) const; 183 void SetFloat (Message* message, 184 const FieldDescriptor* field, float value) const; 185 void SetDouble(Message* message, 186 const FieldDescriptor* field, double value) const; 187 void SetBool (Message* message, 188 const FieldDescriptor* field, bool value) const; 189 void SetString(Message* message, 190 const FieldDescriptor* field, 191 const string& value) const; 192 void SetEnum (Message* message, const FieldDescriptor* field, 193 const EnumValueDescriptor* value) const; 194 Message* MutableMessage(Message* message, const FieldDescriptor* field, 195 MessageFactory* factory = NULL) const; 196 197 int32 GetRepeatedInt32 (const Message& message, 198 const FieldDescriptor* field, int index) const; 199 int64 GetRepeatedInt64 (const Message& message, 200 const FieldDescriptor* field, int index) const; 201 uint32 GetRepeatedUInt32(const Message& message, 202 const FieldDescriptor* field, int index) const; 203 uint64 GetRepeatedUInt64(const Message& message, 204 const FieldDescriptor* field, int index) const; 205 float GetRepeatedFloat (const Message& message, 206 const FieldDescriptor* field, int index) const; 207 double GetRepeatedDouble(const Message& message, 208 const FieldDescriptor* field, int index) const; 209 bool GetRepeatedBool (const Message& message, 210 const FieldDescriptor* field, int index) const; 211 string GetRepeatedString(const Message& message, 212 const FieldDescriptor* field, int index) const; 213 const string& GetRepeatedStringReference(const Message& message, 214 const FieldDescriptor* field, 215 int index, string* scratch) const; 216 const EnumValueDescriptor* GetRepeatedEnum(const Message& message, 217 const FieldDescriptor* field, 218 int index) const; 219 const Message& GetRepeatedMessage(const Message& message, 220 const FieldDescriptor* field, 221 int index) const; 222 223 // Set the value of a field. 224 void SetRepeatedInt32 (Message* message, 225 const FieldDescriptor* field, int index, int32 value) const; 226 void SetRepeatedInt64 (Message* message, 227 const FieldDescriptor* field, int index, int64 value) const; 228 void SetRepeatedUInt32(Message* message, 229 const FieldDescriptor* field, int index, uint32 value) const; 230 void SetRepeatedUInt64(Message* message, 231 const FieldDescriptor* field, int index, uint64 value) const; 232 void SetRepeatedFloat (Message* message, 233 const FieldDescriptor* field, int index, float value) const; 234 void SetRepeatedDouble(Message* message, 235 const FieldDescriptor* field, int index, double value) const; 236 void SetRepeatedBool (Message* message, 237 const FieldDescriptor* field, int index, bool value) const; 238 void SetRepeatedString(Message* message, 239 const FieldDescriptor* field, int index, 240 const string& value) const; 241 void SetRepeatedEnum(Message* message, const FieldDescriptor* field, 242 int index, const EnumValueDescriptor* value) const; 243 // Get a mutable pointer to a field with a message type. 244 Message* MutableRepeatedMessage(Message* message, 245 const FieldDescriptor* field, 246 int index) const; 247 248 void AddInt32 (Message* message, 249 const FieldDescriptor* field, int32 value) const; 250 void AddInt64 (Message* message, 251 const FieldDescriptor* field, int64 value) const; 252 void AddUInt32(Message* message, 253 const FieldDescriptor* field, uint32 value) const; 254 void AddUInt64(Message* message, 255 const FieldDescriptor* field, uint64 value) const; 256 void AddFloat (Message* message, 257 const FieldDescriptor* field, float value) const; 258 void AddDouble(Message* message, 259 const FieldDescriptor* field, double value) const; 260 void AddBool (Message* message, 261 const FieldDescriptor* field, bool value) const; 262 void AddString(Message* message, 263 const FieldDescriptor* field, const string& value) const; 264 void AddEnum(Message* message, 265 const FieldDescriptor* field, 266 const EnumValueDescriptor* value) const; 267 Message* AddMessage(Message* message, const FieldDescriptor* field, 268 MessageFactory* factory = NULL) const; 269 270 const FieldDescriptor* FindKnownExtensionByName(const string& name) const; 271 const FieldDescriptor* FindKnownExtensionByNumber(int number) const; 272 273 private: 274 friend class GeneratedMessage; 275 276 const Descriptor* descriptor_; 277 const Message* default_instance_; 278 const int* offsets_; 279 280 int has_bits_offset_; 281 int unknown_fields_offset_; 282 int extensions_offset_; 283 int object_size_; 284 285 const DescriptorPool* descriptor_pool_; 286 MessageFactory* message_factory_; 287 288 template <typename Type> 289 inline const Type& GetRaw(const Message& message, 290 const FieldDescriptor* field) const; 291 template <typename Type> 292 inline Type* MutableRaw(Message* message, 293 const FieldDescriptor* field) const; 294 template <typename Type> 295 inline const Type& DefaultRaw(const FieldDescriptor* field) const; 296 inline const Message* GetMessagePrototype(const FieldDescriptor* field) const; 297 298 inline const uint32* GetHasBits(const Message& message) const; 299 inline uint32* MutableHasBits(Message* message) const; 300 inline const ExtensionSet& GetExtensionSet(const Message& message) const; 301 inline ExtensionSet* MutableExtensionSet(Message* message) const; 302 303 inline bool HasBit(const Message& message, 304 const FieldDescriptor* field) const; 305 inline void SetBit(Message* message, 306 const FieldDescriptor* field) const; 307 inline void ClearBit(Message* message, 308 const FieldDescriptor* field) const; 309 310 template <typename Type> 311 inline const Type& GetField(const Message& message, 312 const FieldDescriptor* field) const; 313 template <typename Type> 314 inline void SetField(Message* message, 315 const FieldDescriptor* field, const Type& value) const; 316 template <typename Type> 317 inline Type* MutableField(Message* message, 318 const FieldDescriptor* field) const; 319 template <typename Type> 320 inline const Type& GetRepeatedField(const Message& message, 321 const FieldDescriptor* field, 322 int index) const; 323 template <typename Type> 324 inline const Type& GetRepeatedPtrField(const Message& message, 325 const FieldDescriptor* field, 326 int index) const; 327 template <typename Type> 328 inline void SetRepeatedField(Message* message, 329 const FieldDescriptor* field, int index, 330 Type value) const; 331 template <typename Type> 332 inline Type* MutableRepeatedField(Message* message, 333 const FieldDescriptor* field, 334 int index) const; 335 template <typename Type> 336 inline void AddField(Message* message, 337 const FieldDescriptor* field, const Type& value) const; 338 template <typename Type> 339 inline Type* AddField(Message* message, 340 const FieldDescriptor* field) const; 341 342 int GetExtensionNumberOrDie(const Descriptor* type) const; 343 344 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratedMessageReflection); 345}; 346 347// Returns the offset of the given field within the given aggregate type. 348// This is equivalent to the ANSI C offsetof() macro. However, according 349// to the C++ standard, offsetof() only works on POD types, and GCC 350// enforces this requirement with a warning. In practice, this rule is 351// unnecessarily strict; there is probably no compiler or platform on 352// which the offsets of the direct fields of a class are non-constant. 353// Fields inherited from superclasses *can* have non-constant offsets, 354// but that's not what this macro will be used for. 355// 356// Note that we calculate relative to the pointer value 16 here since if we 357// just use zero, GCC complains about dereferencing a NULL pointer. We 358// choose 16 rather than some other number just in case the compiler would 359// be confused by an unaligned pointer. 360#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD) \ 361 static_cast<int>( \ 362 reinterpret_cast<const char*>( \ 363 &reinterpret_cast<const TYPE*>(16)->FIELD) - \ 364 reinterpret_cast<const char*>(16)) 365 366// There are some places in proto2 where dynamic_cast would be useful as an 367// optimization. For example, take Message::MergeFrom(const Message& other). 368// For a given generated message FooMessage, we generate these two methods: 369// void MergeFrom(const FooMessage& other); 370// void MergeFrom(const Message& other); 371// The former method can be implemented directly in terms of FooMessage's 372// inline accessors, but the latter method must work with the reflection 373// interface. However, if the parameter to the latter method is actually of 374// type FooMessage, then we'd like to be able to just call the other method 375// as an optimization. So, we use dynamic_cast to check this. 376// 377// That said, dynamic_cast requires RTTI, which many people like to disable 378// for performance and code size reasons. When RTTI is not available, we 379// still need to produce correct results. So, in this case we have to fall 380// back to using reflection, which is what we would have done anyway if the 381// objects were not of the exact same class. 382// 383// dynamic_cast_if_available() implements this logic. If RTTI is 384// enabled, it does a dynamic_cast. If RTTI is disabled, it just returns 385// NULL. 386// 387// If you need to compile without RTTI, simply #define GOOGLE_PROTOBUF_NO_RTTI. 388// On MSVC, this should be detected automatically. 389template<typename To, typename From> 390inline To dynamic_cast_if_available(From from) { 391#if defined(GOOGLE_PROTOBUF_NO_RTTI) || (defined(_MSC_VER)&&!defined(_CPPRTTI)) 392 return NULL; 393#else 394 return dynamic_cast<To>(from); 395#endif 396} 397 398// Helper for EnumType_Parse functions: try to parse the string 'name' as an 399// enum name of the given type, returning true and filling in value on success, 400// or returning false and leaving value unchanged on failure. 401LIBPROTOBUF_EXPORT bool ParseNamedEnum(const EnumDescriptor* descriptor, 402 const string& name, 403 int* value); 404 405template<typename EnumType> 406bool ParseNamedEnum(const EnumDescriptor* descriptor, 407 const string& name, 408 EnumType* value) { 409 int tmp; 410 if (!ParseNamedEnum(descriptor, name, &tmp)) return false; 411 *value = static_cast<EnumType>(tmp); 412 return true; 413} 414 415// Just a wrapper around printing the name of a value. The main point of this 416// function is not to be inlined, so that you can do this without including 417// descriptor.h. 418LIBPROTOBUF_EXPORT const string& NameOfEnum(const EnumDescriptor* descriptor, int value); 419 420} // namespace internal 421} // namespace protobuf 422 423} // namespace google 424#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__ 425