| // Protocol Buffers - Google's data interchange format |
| // Copyright 2008 Google Inc. |
| // http://code.google.com/p/protobuf/ |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| // Author: kenton@google.com (Kenton Varda) |
| // Based on original Protocol Buffers design by |
| // Sanjay Ghemawat, Jeff Dean, and others. |
| // |
| // This file contains the abstract interface for all protocol messages. |
| // Although it's possible to implement this interface manually, most users |
| // will use the protocol compiler to generate implementations. |
| // |
| // Example usage: |
| // |
| // Say you have a message defined as: |
| // |
| // message Foo { |
| // optional string text = 1; |
| // repeated int32 numbers = 2; |
| // } |
| // |
| // Then, if you used the protocol compiler to generate a class from the above |
| // definition, you could use it like so: |
| // |
| // string data; // Will store a serialized version of the message. |
| // |
| // { |
| // // Create a message and serialize it. |
| // Foo foo; |
| // foo.set_text("Hello World!"); |
| // foo.add_numbers(1); |
| // foo.add_numbers(5); |
| // foo.add_numbers(42); |
| // |
| // foo.SerializeToString(&data); |
| // } |
| // |
| // { |
| // // Parse the serialized message and check that it contains the |
| // // correct data. |
| // Foo foo; |
| // foo.ParseFromString(data); |
| // |
| // assert(foo.text() == "Hello World!"); |
| // assert(foo.numbers_size() == 3); |
| // assert(foo.numbers(0) == 1); |
| // assert(foo.numbers(1) == 5); |
| // assert(foo.numbers(2) == 42); |
| // } |
| // |
| // { |
| // // Same as the last block, but do it dynamically via the Message |
| // // reflection interface. |
| // Message* foo = new Foo; |
| // Descriptor* descriptor = foo->GetDescriptor(); |
| // |
| // // Get the descriptors for the fields we're interested in and verify |
| // // their types. |
| // FieldDescriptor* text_field = descriptor->FindFieldByName("text"); |
| // assert(text_field != NULL); |
| // assert(text_field->type() == FieldDescriptor::TYPE_STRING); |
| // assert(text_field->label() == FieldDescriptor::TYPE_OPTIONAL); |
| // FieldDescriptor* numbers_field = descriptor->FindFieldByName("numbers"); |
| // assert(numbers_field != NULL); |
| // assert(numbers_field->type() == FieldDescriptor::TYPE_INT32); |
| // assert(numbers_field->label() == FieldDescriptor::TYPE_REPEATED); |
| // |
| // // Parse the message. |
| // foo->ParseFromString(data); |
| // |
| // // Use the reflection interface to examine the contents. |
| // Message::Reflection* reflection = foo->GetReflection(); |
| // assert(reflection->GetString(text_field) == "Hello World!"); |
| // assert(reflection->CountField(numbers_field) == 3); |
| // assert(reflection->GetInt32(numbers_field, 0) == 1); |
| // assert(reflection->GetInt32(numbers_field, 1) == 5); |
| // assert(reflection->GetInt32(numbers_field, 2) == 42); |
| // |
| // delete foo; |
| // } |
| |
| #ifndef GOOGLE_PROTOBUF_MESSAGE_H__ |
| #define GOOGLE_PROTOBUF_MESSAGE_H__ |
| |
| #include <vector> |
| #include <string> |
| #include <iosfwd> |
| #include <google/protobuf/stubs/common.h> |
| |
| namespace google { |
| |
| namespace protobuf { |
| |
| // Defined in this file. |
| class Message; |
| |
| // Defined in other files. |
| class Descriptor; // descriptor.h |
| class FieldDescriptor; // descriptor.h |
| class EnumValueDescriptor; // descriptor.h |
| namespace io { |
| class ZeroCopyInputStream; // zero_copy_stream.h |
| class ZeroCopyOutputStream; // zero_copy_stream.h |
| class CodedInputStream; // coded_stream.h |
| class CodedOutputStream; // coded_stream.h |
| } |
| class UnknownFieldSet; // unknown_field_set.h |
| |
| // Abstract interface for protocol messages. |
| // |
| // The methods of this class that are virtual but not pure-virtual have |
| // default implementations based on reflection. Message classes which are |
| // optimized for speed will want to override these with faster implementations, |
| // but classes optimized for code size may be happy with keeping them. See |
| // the optimize_for option in descriptor.proto. |
| class LIBPROTOBUF_EXPORT Message { |
| public: |
| inline Message() {} |
| virtual ~Message(); |
| |
| // Basic Operations ------------------------------------------------ |
| |
| // Construct a new instance of the same type. Ownership is passed to the |
| // caller. |
| virtual Message* New() const = 0; |
| |
| // Make this message into a copy of the given message. The given message |
| // must have the same descriptor, but need not necessarily be the same class. |
| // By default this is just implemented as "Clear(); MergeFrom(from);". |
| virtual void CopyFrom(const Message& from); |
| |
| // Merge the fields from the given message into this message. Singular |
| // fields will be overwritten, except for embedded messages which will |
| // be merged. Repeated fields will be concatenated. The given message |
| // must be of the same type as this message (i.e. the exact same class). |
| virtual void MergeFrom(const Message& from); |
| |
| // Clear all fields of the message and set them to their default values. |
| // Clear() avoids freeing memory, assuming that any memory allocated |
| // to hold parts of the message will be needed again to hold the next |
| // message. If you actually want to free the memory used by a Message, |
| // you must delete it. |
| virtual void Clear(); |
| |
| // Quickly check if all required fields have values set. |
| virtual bool IsInitialized() const; |
| |
| // Verifies that IsInitialized() returns true. GOOGLE_CHECK-fails otherwise, with |
| // a nice error message. |
| void CheckInitialized() const; |
| |
| // Slowly build a list of all required fields that are not set. |
| // This is much, much slower than IsInitialized() as it is implemented |
| // purely via reflection. Generally, you should not call this unless you |
| // have already determined that an error exists by calling IsInitialized(). |
| void FindInitializationErrors(vector<string>* errors) const; |
| |
| // Like FindInitializationErrors, but joins all the strings, delimited by |
| // commas, and returns them. |
| string InitializationErrorString() const; |
| |
| // Clears all unknown fields from this message and all embedded messages. |
| // Normally, if unknown tag numbers are encountered when parsing a message, |
| // the tag and value are stored in the message's UnknownFieldSet and |
| // then written back out when the message is serialized. This allows servers |
| // which simply route messages to other servers to pass through messages |
| // that have new field definitions which they don't yet know about. However, |
| // this behavior can have security implications. To avoid it, call this |
| // method after parsing. |
| // |
| // See Reflection::GetUnknownFields() for more on unknown fields. |
| virtual void DiscardUnknownFields(); |
| |
| // Debugging ------------------------------------------------------- |
| |
| // Generates a human readable form of this message, useful for debugging |
| // and other purposes. |
| string DebugString() const; |
| // Like DebugString(), but with less whitespace. |
| string ShortDebugString() const; |
| // Convenience function useful in GDB. Prints DebugString() to stdout. |
| void PrintDebugString() const; |
| |
| // Parsing --------------------------------------------------------- |
| // Methods for parsing in protocol buffer format. Most of these are |
| // just simple wrappers around MergeFromCodedStream(). |
| |
| // Fill the message with a protocol buffer parsed from the given input |
| // stream. Returns false on a read error or if the input is in the |
| // wrong format. |
| bool ParseFromCodedStream(io::CodedInputStream* input); |
| // Like ParseFromCodedStream(), but accepts messages that are missing |
| // required fields. |
| bool ParsePartialFromCodedStream(io::CodedInputStream* input); |
| // Read a protocol buffer from the given zero-copy input stream. If |
| // successful, the entire input will be consumed. |
| bool ParseFromZeroCopyStream(io::ZeroCopyInputStream* input); |
| // Like ParseFromZeroCopyStream(), but accepts messages that are missing |
| // required fields. |
| bool ParsePartialFromZeroCopyStream(io::ZeroCopyInputStream* input); |
| // Parse a protocol buffer contained in a string. |
| bool ParseFromString(const string& data); |
| // Like ParseFromString(), but accepts messages that are missing |
| // required fields. |
| bool ParsePartialFromString(const string& data); |
| // Parse a protocol buffer contained in an array of bytes. |
| bool ParseFromArray(const void* data, int size); |
| // Like ParseFromArray(), but accepts messages that are missing |
| // required fields. |
| bool ParsePartialFromArray(const void* data, int size); |
| |
| // Parse a protocol buffer from a file descriptor. If successful, the entire |
| // input will be consumed. |
| bool ParseFromFileDescriptor(int file_descriptor); |
| // Like ParseFromFileDescriptor(), but accepts messages that are missing |
| // required fields. |
| bool ParsePartialFromFileDescriptor(int file_descriptor); |
| // Parse a protocol buffer from a C++ istream. If successful, the entire |
| // input will be consumed. |
| bool ParseFromIstream(istream* input); |
| // Like ParseFromIstream(), but accepts messages that are missing |
| // required fields. |
| bool ParsePartialFromIstream(istream* input); |
| |
| |
| // Reads a protocol buffer from the stream and merges it into this |
| // Message. Singular fields read from the input overwrite what is |
| // already in the Message and repeated fields are appended to those |
| // already present. |
| // |
| // It is the responsibility of the caller to call input->LastTagWas() |
| // (for groups) or input->ConsumedEntireMessage() (for non-groups) after |
| // this returns to verify that the message's end was delimited correctly. |
| // |
| // ParsefromCodedStream() is implemented as Clear() followed by |
| // MergeFromCodedStream(). |
| bool MergeFromCodedStream(io::CodedInputStream* input); |
| |
| // Like MergeFromCodedStream(), but succeeds even if required fields are |
| // missing in the input. |
| // |
| // MergeFromCodedStream() is just implemented as MergePartialFromCodedStream() |
| // followed by IsInitialized(). |
| virtual bool MergePartialFromCodedStream(io::CodedInputStream* input); |
| |
| // Serialization --------------------------------------------------- |
| // Methods for serializing in protocol buffer format. Most of these |
| // are just simple wrappers around ByteSize() and SerializeWithCachedSizes(). |
| |
| // Write a protocol buffer of this message to the given output. Returns |
| // false on a write error. If the message is missing required fields, |
| // this may GOOGLE_CHECK-fail. |
| bool SerializeToCodedStream(io::CodedOutputStream* output) const; |
| // Like SerializeToCodedStream(), but allows missing required fields. |
| bool SerializePartialToCodedStream(io::CodedOutputStream* output) const; |
| // Write the message to the given zero-copy output stream. All required |
| // fields must be set. |
| bool SerializeToZeroCopyStream(io::ZeroCopyOutputStream* output) const; |
| // Like SerializeToZeroCopyStream(), but allows missing required fields. |
| bool SerializePartialToZeroCopyStream(io::ZeroCopyOutputStream* output) const; |
| // Serialize the message and store it in the given string. All required |
| // fields must be set. |
| bool SerializeToString(string* output) const; |
| // Like SerializeToString(), but allows missing required fields. |
| bool SerializePartialToString(string* output) const; |
| // Serialize the message and store it in the given byte array. All required |
| // fields must be set. |
| bool SerializeToArray(void* data, int size) const; |
| // Like SerializeToArray(), but allows missing required fields. |
| bool SerializePartialToArray(void* data, int size) const; |
| |
| // Serialize the message and write it to the given file descriptor. All |
| // required fields must be set. |
| bool SerializeToFileDescriptor(int file_descriptor) const; |
| // Like SerializeToFileDescriptor(), but allows missing required fields. |
| bool SerializePartialToFileDescriptor(int file_descriptor) const; |
| // Serialize the message and write it to the given C++ ostream. All |
| // required fields must be set. |
| bool SerializeToOstream(ostream* output) const; |
| // Like SerializeToOstream(), but allows missing required fields. |
| bool SerializePartialToOstream(ostream* output) const; |
| |
| |
| // Like SerializeToString(), but appends to the data to the string's existing |
| // contents. All required fields must be set. |
| bool AppendToString(string* output) const; |
| // Like AppendToString(), but allows missing required fields. |
| bool AppendPartialToString(string* output) const; |
| |
| // Computes the serialized size of the message. This recursively calls |
| // ByteSize() on all embedded messages. If a subclass does not override |
| // this, it MUST override SetCachedSize(). |
| virtual int ByteSize() const; |
| |
| // Serializes the message without recomputing the size. The message must |
| // not have changed since the last call to ByteSize(); if it has, the results |
| // are undefined. |
| virtual bool SerializeWithCachedSizes(io::CodedOutputStream* output) const; |
| |
| // Returns the result of the last call to ByteSize(). An embedded message's |
| // size is needed both to serialize it (because embedded messages are |
| // length-delimited) and to compute the outer message's size. Caching |
| // the size avoids computing it multiple times. |
| // |
| // ByteSize() does not automatically use the cached size when available |
| // because this would require invalidating it every time the message was |
| // modified, which would be too hard and expensive. (E.g. if a deeply-nested |
| // sub-message is changed, all of its parents' cached sizes would need to be |
| // invalidated, which is too much work for an otherwise inlined setter |
| // method.) |
| virtual int GetCachedSize() const = 0; |
| |
| private: |
| // This is called only by the default implementation of ByteSize(), to |
| // update the cached size. If you override ByteSize(), you do not need |
| // to override this. If you do not override ByteSize(), you MUST override |
| // this; the default implementation will crash. |
| // |
| // The method is private because subclasses should never call it; only |
| // override it. Yes, C++ lets you do that. Crazy, huh? |
| virtual void SetCachedSize(int size) const; |
| |
| public: |
| |
| // Introspection --------------------------------------------------- |
| |
| class Reflection; // Defined below. |
| |
| // Get a Descriptor for this message's type. This describes what |
| // fields the message contains, the types of those fields, etc. |
| virtual const Descriptor* GetDescriptor() const = 0; |
| |
| // Get the Reflection interface for this Message, which can be used to |
| // read and modify the fields of the Message dynamically (in other words, |
| // without knowing the message type at compile time). This object remains |
| // property of the Message. |
| virtual const Reflection* GetReflection() const = 0; |
| |
| // Get the Reflection interface for this Message, which can be used to |
| // read and modify the fields of the Message dynamically (in other words, |
| // without knowing the message type at compile time). This object remains |
| // property of the Message. |
| virtual Reflection* GetReflection() = 0; |
| |
| private: |
| GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Message); |
| }; |
| |
| // This interface contains methods that can be used to dynamically access |
| // and modify the fields of a protocol message. Their semantics are |
| // similar to the accessors the protocol compiler generates. |
| // |
| // To get the Reflection for a given Message, call Message::GetReflection(). |
| // |
| // This interface is separate from Message only for efficiency reasons; |
| // the vast majority of implementations of Message will share the same |
| // implementation of Reflection (GeneratedMessageReflection, |
| // defined in generated_message.h). |
| // |
| // There are several ways that these methods can be used incorrectly. For |
| // example, any of the following conditions will lead to undefined |
| // results (probably assertion failures): |
| // - The FieldDescriptor is not a field of this message type. |
| // - The method called is not appropriate for the field's type. For |
| // each field type in FieldDescriptor::TYPE_*, there is only one |
| // Get*() method, one Set*() method, and one Add*() method that is |
| // valid for that type. It should be obvious which (except maybe |
| // for TYPE_BYTES, which are represented using strings in C++). |
| // - A Get*() or Set*() method for singular fields is called on a repeated |
| // field. |
| // - GetRepeated*(), SetRepeated*(), or Add*() is called on a non-repeated |
| // field. |
| // |
| // You might wonder why there is not any abstract representation for a field |
| // of arbitrary type. E.g., why isn't there just a "GetField()" method that |
| // returns "const Field&", where "Field" is some class with accessors like |
| // "GetInt32Value()". The problem is that someone would have to deal with |
| // allocating these Field objects. For generated message classes, having to |
| // allocate space for an additional object to wrap every field would at least |
| // double the message's memory footprint, probably worse. Allocating the |
| // objects on-demand, on the other hand, would be expensive and prone to |
| // memory leaks. So, instead we ended up with this flat interface. |
| // |
| // TODO(kenton): Create a utility class which callers can use to read and |
| // write fields from a Reflection without paying attention to the type. |
| class LIBPROTOBUF_EXPORT Message::Reflection { |
| public: |
| inline Reflection() {} |
| virtual ~Reflection(); |
| |
| // Get the UnknownFieldSet for the message. This contains fields which |
| // were seen when the Message was parsed but were not recognized according |
| // to the Message's definition. |
| virtual const UnknownFieldSet& GetUnknownFields() const = 0; |
| // Get a mutable pointer to the UnknownFieldSet for the message. This |
| // contains fields which were seen when the Message was parsed but were not |
| // recognized according to the Message's definition. |
| virtual UnknownFieldSet* MutableUnknownFields() = 0; |
| |
| // Check if the given non-repeated field is set. |
| virtual bool HasField(const FieldDescriptor* field) const = 0; |
| |
| // Get the number of elements of a repeated field. |
| virtual int FieldSize(const FieldDescriptor* field) const = 0; |
| |
| // Clear the value of a field, so that HasField() returns false or |
| // FieldSize() returns zero. |
| virtual void ClearField(const FieldDescriptor* field) = 0; |
| |
| // List all fields of the message which are currently set. This includes |
| // extensions. Singular fields will only be listed if HasField(field) would |
| // return true and repeated fields will only be listed if FieldSize(field) |
| // would return non-zero. Fields (both normal fields and extension fields) |
| // will be listed ordered by field number. |
| virtual void ListFields(vector<const FieldDescriptor*>* output) const = 0; |
| |
| // Singular field getters ------------------------------------------ |
| // These get the value of a non-repeated field. They return the default |
| // value for fields that aren't set. |
| |
| virtual int32 GetInt32 (const FieldDescriptor* field) const = 0; |
| virtual int64 GetInt64 (const FieldDescriptor* field) const = 0; |
| virtual uint32 GetUInt32(const FieldDescriptor* field) const = 0; |
| virtual uint64 GetUInt64(const FieldDescriptor* field) const = 0; |
| virtual float GetFloat (const FieldDescriptor* field) const = 0; |
| virtual double GetDouble(const FieldDescriptor* field) const = 0; |
| virtual bool GetBool (const FieldDescriptor* field) const = 0; |
| virtual string GetString(const FieldDescriptor* field) const = 0; |
| virtual const EnumValueDescriptor* GetEnum( |
| const FieldDescriptor* field) const = 0; |
| virtual const Message& GetMessage(const FieldDescriptor* field) const = 0; |
| |
| // Get a string value without copying, if possible. |
| // |
| // GetString() necessarily returns a copy of the string. This can be |
| // inefficient when the string is already stored in a string object in the |
| // underlying message. GetStringReference() will return a reference to the |
| // underlying string in this case. Otherwise, it will copy the string into |
| // *scratch and return that. |
| // |
| // Note: It is perfectly reasonable and useful to write code like: |
| // str = reflection->GetStringReference(field, &str); |
| // This line would ensure that only one copy of the string is made |
| // regardless of the field's underlying representation. When initializing |
| // a newly-constructed string, though, it's just as fast and more readable |
| // to use code like: |
| // string str = reflection->GetString(field); |
| virtual const string& GetStringReference(const FieldDescriptor* field, |
| string* scratch) const = 0; |
| |
| |
| // Singular field mutators ----------------------------------------- |
| // These mutate the value of a non-repeated field. |
| |
| virtual void SetInt32 (const FieldDescriptor* field, int32 value) = 0; |
| virtual void SetInt64 (const FieldDescriptor* field, int64 value) = 0; |
| virtual void SetUInt32(const FieldDescriptor* field, uint32 value) = 0; |
| virtual void SetUInt64(const FieldDescriptor* field, uint64 value) = 0; |
| virtual void SetFloat (const FieldDescriptor* field, float value) = 0; |
| virtual void SetDouble(const FieldDescriptor* field, double value) = 0; |
| virtual void SetBool (const FieldDescriptor* field, bool value) = 0; |
| virtual void SetString(const FieldDescriptor* field, const string& value) = 0; |
| virtual void SetEnum (const FieldDescriptor* field, |
| const EnumValueDescriptor* value) = 0; |
| // Get a mutable pointer to a field with a message type. |
| virtual Message* MutableMessage(const FieldDescriptor* field) = 0; |
| |
| |
| // Repeated field getters ------------------------------------------ |
| // These get the value of one element of a repeated field. |
| |
| virtual int32 GetRepeatedInt32 (const FieldDescriptor* field, |
| int index) const = 0; |
| virtual int64 GetRepeatedInt64 (const FieldDescriptor* field, |
| int index) const = 0; |
| virtual uint32 GetRepeatedUInt32(const FieldDescriptor* field, |
| int index) const = 0; |
| virtual uint64 GetRepeatedUInt64(const FieldDescriptor* field, |
| int index) const = 0; |
| virtual float GetRepeatedFloat (const FieldDescriptor* field, |
| int index) const = 0; |
| virtual double GetRepeatedDouble(const FieldDescriptor* field, |
| int index) const = 0; |
| virtual bool GetRepeatedBool (const FieldDescriptor* field, |
| int index) const = 0; |
| virtual string GetRepeatedString(const FieldDescriptor* field, |
| int index) const = 0; |
| virtual const EnumValueDescriptor* GetRepeatedEnum( |
| const FieldDescriptor* field, int index) const = 0; |
| virtual const Message& GetRepeatedMessage( |
| const FieldDescriptor* field, int index) const = 0; |
| |
| // See GetStringReference(), above. |
| virtual const string& GetRepeatedStringReference( |
| const FieldDescriptor* field, int index, |
| string* scratch) const = 0; |
| |
| |
| // Repeated field mutators ----------------------------------------- |
| // These mutate the value of one element of a repeated field. |
| |
| virtual void SetRepeatedInt32 (const FieldDescriptor* field, |
| int index, int32 value) = 0; |
| virtual void SetRepeatedInt64 (const FieldDescriptor* field, |
| int index, int64 value) = 0; |
| virtual void SetRepeatedUInt32(const FieldDescriptor* field, |
| int index, uint32 value) = 0; |
| virtual void SetRepeatedUInt64(const FieldDescriptor* field, |
| int index, uint64 value) = 0; |
| virtual void SetRepeatedFloat (const FieldDescriptor* field, |
| int index, float value) = 0; |
| virtual void SetRepeatedDouble(const FieldDescriptor* field, |
| int index, double value) = 0; |
| virtual void SetRepeatedBool (const FieldDescriptor* field, |
| int index, bool value) = 0; |
| virtual void SetRepeatedString(const FieldDescriptor* field, |
| int index, const string& value) = 0; |
| virtual void SetRepeatedEnum(const FieldDescriptor* field, |
| int index, const EnumValueDescriptor* value) = 0; |
| // Get a mutable pointer to an element of a repeated field with a message |
| // type. |
| virtual Message* MutableRepeatedMessage( |
| const FieldDescriptor* field, int index) = 0; |
| |
| |
| // Repeated field adders ------------------------------------------- |
| // These add an element to a repeated field. |
| |
| virtual void AddInt32 (const FieldDescriptor* field, int32 value) = 0; |
| virtual void AddInt64 (const FieldDescriptor* field, int64 value) = 0; |
| virtual void AddUInt32(const FieldDescriptor* field, uint32 value) = 0; |
| virtual void AddUInt64(const FieldDescriptor* field, uint64 value) = 0; |
| virtual void AddFloat (const FieldDescriptor* field, float value) = 0; |
| virtual void AddDouble(const FieldDescriptor* field, double value) = 0; |
| virtual void AddBool (const FieldDescriptor* field, bool value) = 0; |
| virtual void AddString(const FieldDescriptor* field, const string& value) = 0; |
| virtual void AddEnum (const FieldDescriptor* field, |
| const EnumValueDescriptor* value) = 0; |
| virtual Message* AddMessage(const FieldDescriptor* field) = 0; |
| |
| |
| // Extensions ------------------------------------------------------ |
| |
| // Try to find an extension of this message type by fully-qualified field |
| // name. Returns NULL if no extension is known for this name or number. |
| virtual const FieldDescriptor* FindKnownExtensionByName( |
| const string& name) const = 0; |
| |
| // Try to find an extension of this message type by field number. |
| // Returns NULL if no extension is known for this name or number. |
| virtual const FieldDescriptor* FindKnownExtensionByNumber( |
| int number) const = 0; |
| |
| private: |
| GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Reflection); |
| }; |
| |
| // Abstract interface for a factory for message objects. |
| class LIBPROTOBUF_EXPORT MessageFactory { |
| public: |
| inline MessageFactory() {} |
| virtual ~MessageFactory(); |
| |
| // Given a Descriptor, gets or constructs the default (prototype) Message |
| // of that type. You can then call that message's New() method to construct |
| // a mutable message of that type. |
| // |
| // Calling this method twice with the same Descriptor returns the same |
| // object. The returned object remains property of the factory. Also, any |
| // objects created by calling the prototype's New() method share some data |
| // with the prototype, so these must be destoyed before the MessageFactory |
| // is destroyed. |
| // |
| // The given descriptor must outlive the returned message, and hence must |
| // outlive the MessageFactory. |
| // |
| // Some implementations do not support all types. GetPrototype() will |
| // return NULL if the descriptor passed in is not supported. |
| // |
| // This method may or may not be thread-safe depending on the implementation. |
| // Each implementation should document its own degree thread-safety. |
| virtual const Message* GetPrototype(const Descriptor* type) = 0; |
| |
| // Gets a MessageFactory which supports all generated, compiled-in messages. |
| // In other words, for any compiled-in type FooMessage, the following is true: |
| // MessageFactory::generated_factory()->GetPrototype( |
| // FooMessage::descriptor()) == FooMessage::default_instance() |
| // This factory supports all types which are found in |
| // DescriptorPool::generated_pool(). If given a descriptor from any other |
| // pool, GetPrototype() will return NULL. (You can also check if a |
| // descriptor is for a generated message by checking if |
| // descriptor->file()->pool() == DescriptorPool::generated_pool().) |
| // |
| // This factory is 100% thread-safe; calling GetPrototype() does not modify |
| // any shared data. |
| // |
| // This factory is a singleton. The caller must not delete the object. |
| static MessageFactory* generated_factory(); |
| |
| // For internal use only: Registers a message type at static initialization |
| // time, to be placed in generated_factory(). |
| static void InternalRegisterGeneratedMessage(const Descriptor* descriptor, |
| const Message* prototype); |
| |
| private: |
| GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFactory); |
| }; |
| |
| } // namespace protobuf |
| |
| } // namespace google |
| #endif // GOOGLE_PROTOBUF_MESSAGE_H__ |