diff options
Diffstat (limited to 'src/google/protobuf/message.h')
-rw-r--r-- | src/google/protobuf/message.h | 205 |
1 files changed, 57 insertions, 148 deletions
diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h index 41716057..eecd91a7 100644 --- a/src/google/protobuf/message.h +++ b/src/google/protobuf/message.h @@ -98,9 +98,9 @@ // const Reflection* reflection = foo->GetReflection(); // assert(reflection->GetString(foo, text_field) == "Hello World!"); // assert(reflection->FieldSize(foo, numbers_field) == 3); -// assert(reflection->GetInt32(foo, numbers_field, 0) == 1); -// assert(reflection->GetInt32(foo, numbers_field, 1) == 5); -// assert(reflection->GetInt32(foo, numbers_field, 2) == 42); +// assert(reflection->GetRepeatedInt32(foo, numbers_field, 0) == 1); +// assert(reflection->GetRepeatedInt32(foo, numbers_field, 1) == 5); +// assert(reflection->GetRepeatedInt32(foo, numbers_field, 2) == 42); // // delete foo; // } @@ -118,6 +118,10 @@ #include <iosfwd> #endif +#include <google/protobuf/message_lite.h> + +#include <google/protobuf/stubs/common.h> + #if defined(_WIN32) && defined(GetMessage) // windows.h defines GetMessage() as a macro. Let's re-define it as an inline // function. This is necessary because Reflection has a method called @@ -136,10 +140,8 @@ inline BOOL GetMessage( } #endif -#include <google/protobuf/stubs/common.h> namespace google { - namespace protobuf { // Defined in this file. @@ -149,6 +151,7 @@ class Reflection; // Defined in other files. class Descriptor; // descriptor.h class FieldDescriptor; // descriptor.h +class EnumDescriptor; // descriptor.h class EnumValueDescriptor; // descriptor.h namespace io { class ZeroCopyInputStream; // zero_copy_stream.h @@ -158,14 +161,28 @@ namespace io { } class UnknownFieldSet; // unknown_field_set.h +// A container to hold message metadata. +struct Metadata { + const Descriptor* descriptor; + const Reflection* reflection; +}; + +// Returns the EnumDescriptor for enum type E, which must be a +// proto-declared enum type. +template <typename E> +const EnumDescriptor* GetEnumDescriptor(); + // Abstract interface for protocol messages. // +// See also MessageLite, which contains most every-day operations. Message +// adds descriptors and reflection on top of that. +// // 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 { +class LIBPROTOBUF_EXPORT Message : public MessageLite { public: inline Message() {} virtual ~Message(); @@ -173,7 +190,8 @@ class LIBPROTOBUF_EXPORT Message { // Basic Operations ------------------------------------------------ // Construct a new instance of the same type. Ownership is passed to the - // caller. + // caller. (This is also defined in MessageLite, but is defined again here + // for return-type covariance.) virtual Message* New() const = 0; // Make this message into a copy of the given message. The given message @@ -187,16 +205,6 @@ class LIBPROTOBUF_EXPORT 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; @@ -238,41 +246,9 @@ class LIBPROTOBUF_EXPORT Message { // 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); - // Read a protocol buffer from the given zero-copy input stream, expecting - // the message to be exactly "size" bytes long. If successful, exactly - // this many bytes will have been consumed from the input. - bool ParseFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input, int size); - // Like ParseFromBoundedZeroCopyStream(), but accepts messages that are - // missing required fields. - bool ParsePartialFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input, - int size); - // 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); + // Heavy I/O ------------------------------------------------------- + // Additional parsing and serialization methods not implemented by + // MessageLite because they are not supported by the lite library. // Parse a protocol buffer from a file descriptor. If successful, the entire // input will be consumed. @@ -287,53 +263,6 @@ class LIBPROTOBUF_EXPORT Message { // 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; @@ -346,50 +275,18 @@ class LIBPROTOBUF_EXPORT Message { bool SerializePartialToOstream(ostream* output) const; - // Make a string encoding the message. Is equivalent to calling - // SerializeToString() on a string and using that. Returns the empty - // string if SerializeToString() would have returned an error. - // Note: If you intend to generate many such strings, you may - // reduce heap fragmentation by instead re-using the same string - // object with calls to SerializeToString(). - string SerializeAsString() const; - // Like SerializeAsString(), but allows missing required fields. - string SerializePartialAsString() 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; + // Reflection-based methods ---------------------------------------- + // These methods are pure-virtual in MessageLite, but Message provides + // reflection-based default implementations. - // 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 string GetTypeName() const; + virtual void Clear(); + virtual bool IsInitialized() const; + virtual void CheckTypeAndMergeFrom(const MessageLite& other); + virtual bool MergePartialFromCodedStream(io::CodedInputStream* input); + virtual int ByteSize() const; virtual void SerializeWithCachedSizes(io::CodedOutputStream* output) const; - // Like SerializeWithCachedSizes, but writes directly to *target, returning - // a pointer to the byte immediately after the last byte written. "target" - // must point at a byte array of at least ByteSize() bytes. - virtual uint8* SerializeWithCachedSizesToArray(uint8* target) 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 @@ -409,13 +306,24 @@ class LIBPROTOBUF_EXPORT Message { // 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; + const Descriptor* GetDescriptor() const { return GetMetadata().descriptor; } // 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; + // + // This method remains virtual in case a subclass does not implement + // reflection and wants to override the default behavior. + virtual const Reflection* GetReflection() const { + return GetMetadata().reflection; + } + + protected: + // Get a struct containing the metadata for the Message. Most subclasses only + // need to implement this method, rather than the GetDescriptor() and + // GetReflection() wrappers. + virtual Metadata GetMetadata() const = 0; private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Message); @@ -758,12 +666,13 @@ class LIBPROTOBUF_EXPORT MessageFactory { // For internal use only: Registers a .proto file at static initialization // time, to be placed in generated_factory. The first time GetPrototype() // is called with a descriptor from this file, |register_messages| will be - // called. It must call InternalRegisterGeneratedMessage() (below) to - // register each message type in the file. This strange mechanism is - // necessary because descriptors are built lazily, so we can't register - // types by their descriptor until we know that the descriptor exists. - static void InternalRegisterGeneratedFile(const char* filename, - void (*register_messages)()); + // called, with the file name as the parameter. It must call + // InternalRegisterGeneratedMessage() (below) to register each message type + // in the file. This strange mechanism is necessary because descriptors are + // built lazily, so we can't register types by their descriptor until we + // know that the descriptor exists. |filename| must be a permanent string. + static void InternalRegisterGeneratedFile( + const char* filename, void (*register_messages)(const string&)); // For internal use only: Registers a message type. Called only by the // functions which are registered with InternalRegisterGeneratedFile(), |