aboutsummaryrefslogtreecommitdiffstats
path: root/src/google/protobuf/message.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/google/protobuf/message.h')
-rw-r--r--src/google/protobuf/message.h262
1 files changed, 209 insertions, 53 deletions
diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h
index c0062f9..8bbf405 100644
--- a/src/google/protobuf/message.h
+++ b/src/google/protobuf/message.h
@@ -79,18 +79,19 @@
// // Same as the last block, but do it dynamically via the Message
// // reflection interface.
// Message* foo = new Foo;
-// Descriptor* descriptor = foo->GetDescriptor();
+// const Descriptor* descriptor = foo->GetDescriptor();
//
// // Get the descriptors for the fields we're interested in and verify
// // their types.
-// FieldDescriptor* text_field = descriptor->FindFieldByName("text");
+// const 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(text_field->label() == FieldDescriptor::LABEL_OPTIONAL);
+// const FieldDescriptor* numbers_field = descriptor->
+// FindFieldByName("numbers");
// assert(numbers_field != NULL);
// assert(numbers_field->type() == FieldDescriptor::TYPE_INT32);
-// assert(numbers_field->label() == FieldDescriptor::TYPE_REPEATED);
+// assert(numbers_field->label() == FieldDescriptor::LABEL_REPEATED);
//
// // Parse the message.
// foo->ParseFromString(data);
@@ -109,38 +110,17 @@
#ifndef GOOGLE_PROTOBUF_MESSAGE_H__
#define GOOGLE_PROTOBUF_MESSAGE_H__
-#include <vector>
-#include <string>
-
-#ifdef __DECCXX
-// HP C++'s iosfwd doesn't work.
-#include <iostream>
-#else
#include <iosfwd>
-#endif
+#include <string>
+#include <vector>
#include <google/protobuf/message_lite.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/descriptor.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
-// GetMessage() which we don't want overridden. The inline function should be
-// equivalent for C++ users.
-inline BOOL GetMessage_Win32(
- LPMSG lpMsg, HWND hWnd,
- UINT wMsgFilterMin, UINT wMsgFilterMax) {
- return GetMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax);
-}
-#undef GetMessage
-inline BOOL GetMessage(
- LPMSG lpMsg, HWND hWnd,
- UINT wMsgFilterMin, UINT wMsgFilterMax) {
- return GetMessage_Win32(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax);
-}
-#endif
+#define GOOGLE_PROTOBUF_HAS_ONEOF
namespace google {
namespace protobuf {
@@ -151,17 +131,20 @@ class Reflection;
class MessageFactory;
// Defined in other files.
-class Descriptor; // descriptor.h
-class FieldDescriptor; // descriptor.h
-class EnumDescriptor; // descriptor.h
-class EnumValueDescriptor; // descriptor.h
+class UnknownFieldSet; // unknown_field_set.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
+
+
+template<typename T>
+class RepeatedField; // repeated_field.h
+
+template<typename T>
+class RepeatedPtrField; // repeated_field.h
// A container to hold message metadata.
struct Metadata {
@@ -169,12 +152,6 @@ struct Metadata {
const Reflection* reflection;
};
-// Returns the EnumDescriptor for enum type E, which must be a
-// proto-declared enum type. Code generated by the protocol compiler
-// will include specializations of this template for each enum type declared.
-template <typename E>
-const EnumDescriptor* GetEnumDescriptor();
-
// Abstract interface for protocol messages.
//
// See also MessageLite, which contains most every-day operations. Message
@@ -203,9 +180,10 @@ class LIBPROTOBUF_EXPORT Message : public MessageLite {
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).
+ // fields will be overwritten, if specified in from, 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);
// Verifies that IsInitialized() returns true. GOOGLE_CHECK-fails otherwise, with
@@ -216,7 +194,7 @@ class LIBPROTOBUF_EXPORT Message : public MessageLite {
// 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;
+ void FindInitializationErrors(std::vector<string>* errors) const;
// Like FindInitializationErrors, but joins all the strings, delimited by
// commas, and returns them.
@@ -378,7 +356,6 @@ class LIBPROTOBUF_EXPORT Message : public MessageLite {
// write fields from a Reflection without paying attention to the type.
class LIBPROTOBUF_EXPORT Reflection {
public:
- // TODO(kenton): Remove parameter.
inline Reflection() {}
virtual ~Reflection();
@@ -408,7 +385,27 @@ class LIBPROTOBUF_EXPORT Reflection {
virtual void ClearField(Message* message,
const FieldDescriptor* field) const = 0;
- // Remove the last element of a repeated field.
+ // Check if the oneof is set. Returns ture if any field in oneof
+ // is set, false otherwise.
+ // TODO(jieluo) - make it pure virtual after updating all
+ // the subclasses.
+ virtual bool HasOneof(const Message& message,
+ const OneofDescriptor* oneof_descriptor) const {
+ return false;
+ }
+
+ virtual void ClearOneof(Message* message,
+ const OneofDescriptor* oneof_descriptor) const {}
+
+ // Returns the field descriptor if the oneof is set. NULL otherwise.
+ // TODO(jieluo) - make it pure virtual.
+ virtual const FieldDescriptor* GetOneofFieldDescriptor(
+ const Message& message,
+ const OneofDescriptor* oneof_descriptor) const {
+ return NULL;
+ }
+
+ // Removes the last element of a repeated field.
// We don't provide a way to remove any element other than the last
// because it invites inefficient use, such as O(n^2) filtering loops
// that should have been O(n). If you want to remove an element other
@@ -417,15 +414,25 @@ class LIBPROTOBUF_EXPORT Reflection {
// call RemoveLast().
virtual void RemoveLast(Message* message,
const FieldDescriptor* field) const = 0;
+ // Removes the last element of a repeated message field, and returns the
+ // pointer to the caller. Caller takes ownership of the returned pointer.
+ virtual Message* ReleaseLast(Message* message,
+ const FieldDescriptor* field) const = 0;
// Swap the complete contents of two messages.
virtual void Swap(Message* message1, Message* message2) const = 0;
+ // Swap fields listed in fields vector of two messages.
+ virtual void SwapFields(Message* message1,
+ Message* message2,
+ const std::vector<const FieldDescriptor*>& fields)
+ const = 0;
+
// Swap two elements of a repeated field.
virtual void SwapElements(Message* message,
- const FieldDescriptor* field,
- int index1,
- int index2) const = 0;
+ const FieldDescriptor* field,
+ int index1,
+ int index2) const = 0;
// List all fields of the message which are currently set. This includes
// extensions. Singular fields will only be listed if HasField(field) would
@@ -433,7 +440,7 @@ class LIBPROTOBUF_EXPORT Reflection {
// would return non-zero. Fields (both normal fields and extension fields)
// will be listed ordered by field number.
virtual void ListFields(const Message& message,
- vector<const FieldDescriptor*>* output) const = 0;
+ std::vector<const FieldDescriptor*>* output) const = 0;
// Singular field getters ------------------------------------------
// These get the value of a non-repeated field. They return the default
@@ -518,6 +525,23 @@ class LIBPROTOBUF_EXPORT Reflection {
virtual Message* MutableMessage(Message* message,
const FieldDescriptor* field,
MessageFactory* factory = NULL) const = 0;
+ // Replaces the message specified by 'field' with the already-allocated object
+ // sub_message, passing ownership to the message. If the field contained a
+ // message, that message is deleted. If sub_message is NULL, the field is
+ // cleared.
+ virtual void SetAllocatedMessage(Message* message,
+ Message* sub_message,
+ const FieldDescriptor* field) const = 0;
+ // Releases the message specified by 'field' and returns the pointer,
+ // ReleaseMessage() will return the message the message object if it exists.
+ // Otherwise, it may or may not return NULL. In any case, if the return value
+ // is non-NULL, the caller takes ownership of the pointer.
+ // If the field existed (HasField() is true), then the returned pointer will
+ // be the same as the pointer returned by MutableMessage().
+ // This function has the same effect as ClearField().
+ virtual Message* ReleaseMessage(Message* message,
+ const FieldDescriptor* field,
+ MessageFactory* factory = NULL) const = 0;
// Repeated field getters ------------------------------------------
@@ -625,7 +649,39 @@ class LIBPROTOBUF_EXPORT Reflection {
MessageFactory* factory = NULL) const = 0;
- // Extensions ------------------------------------------------------
+ // Repeated field accessors -------------------------------------------------
+ // The methods above, e.g. GetRepeatedInt32(msg, fd, index), provide singular
+ // access to the data in a RepeatedField. The methods below provide aggregate
+ // access by exposing the RepeatedField object itself with the Message.
+ // Applying these templates to inappropriate types will lead to an undefined
+ // reference at link time (e.g. GetRepeatedField<***double>), or possibly a
+ // template matching error at compile time (e.g. GetRepeatedPtrField<File>).
+ //
+ // Usage example: my_doubs = refl->GetRepeatedField<double>(msg, fd);
+
+ // for T = Cord and all protobuf scalar types except enums.
+ template<typename T>
+ const RepeatedField<T>& GetRepeatedField(
+ const Message&, const FieldDescriptor*) const;
+
+ // for T = Cord and all protobuf scalar types except enums.
+ template<typename T>
+ RepeatedField<T>* MutableRepeatedField(
+ Message*, const FieldDescriptor*) const;
+
+ // for T = string, google::protobuf::internal::StringPieceField
+ // google::protobuf::Message & descendants.
+ template<typename T>
+ const RepeatedPtrField<T>& GetRepeatedPtrField(
+ const Message&, const FieldDescriptor*) const;
+
+ // for T = string, google::protobuf::internal::StringPieceField
+ // google::protobuf::Message & descendants.
+ template<typename T>
+ RepeatedPtrField<T>* MutableRepeatedPtrField(
+ Message*, const FieldDescriptor*) const;
+
+ // 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.
@@ -637,7 +693,26 @@ class LIBPROTOBUF_EXPORT Reflection {
virtual const FieldDescriptor* FindKnownExtensionByNumber(
int number) const = 0;
+ // ---------------------------------------------------------------------------
+
+ protected:
+ // Obtain a pointer to a Repeated Field Structure and do some type checking:
+ // on field->cpp_type(),
+ // on field->field_option().ctype() (if ctype >= 0)
+ // of field->message_type() (if message_type != NULL).
+ // We use 1 routine rather than 4 (const vs mutable) x (scalar vs pointer).
+ virtual void* MutableRawRepeatedField(
+ Message* message, const FieldDescriptor* field, FieldDescriptor::CppType,
+ int ctype, const Descriptor* message_type) const = 0;
+
private:
+ // Special version for specialized implementations of string. We can't call
+ // MutableRawRepeatedField directly here because we don't have access to
+ // FieldOptions::* which are defined in descriptor.pb.h. Including that
+ // file here is not possible because it would cause a circular include cycle.
+ void* MutableRawRepeatedString(
+ Message* message, const FieldDescriptor* field, bool is_string) const;
+
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Reflection);
};
@@ -654,7 +729,7 @@ class LIBPROTOBUF_EXPORT MessageFactory {
// 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
+ // with the prototype, so these must be destroyed before the MessageFactory
// is destroyed.
//
// The given descriptor must outlive the returned message, and hence must
@@ -700,10 +775,91 @@ class LIBPROTOBUF_EXPORT MessageFactory {
static void InternalRegisterGeneratedMessage(const Descriptor* descriptor,
const Message* prototype);
+
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFactory);
};
+#define DECLARE_GET_REPEATED_FIELD(TYPE) \
+template<> \
+LIBPROTOBUF_EXPORT \
+const RepeatedField<TYPE>& Reflection::GetRepeatedField<TYPE>( \
+ const Message& message, const FieldDescriptor* field) const; \
+ \
+template<> \
+RepeatedField<TYPE>* Reflection::MutableRepeatedField<TYPE>( \
+ Message* message, const FieldDescriptor* field) const;
+
+DECLARE_GET_REPEATED_FIELD(int32)
+DECLARE_GET_REPEATED_FIELD(int64)
+DECLARE_GET_REPEATED_FIELD(uint32)
+DECLARE_GET_REPEATED_FIELD(uint64)
+DECLARE_GET_REPEATED_FIELD(float)
+DECLARE_GET_REPEATED_FIELD(double)
+DECLARE_GET_REPEATED_FIELD(bool)
+
+#undef DECLARE_GET_REPEATED_FIELD
+
+// =============================================================================
+// Implementation details for {Get,Mutable}RawRepeatedPtrField. We provide
+// specializations for <string>, <StringPieceField> and <Message> and handle
+// everything else with the default template which will match any type having
+// a method with signature "static const google::protobuf::Descriptor* descriptor()".
+// Such a type presumably is a descendant of google::protobuf::Message.
+
+template<>
+inline const RepeatedPtrField<string>& Reflection::GetRepeatedPtrField<string>(
+ const Message& message, const FieldDescriptor* field) const {
+ return *static_cast<RepeatedPtrField<string>* >(
+ MutableRawRepeatedString(const_cast<Message*>(&message), field, true));
+}
+
+template<>
+inline RepeatedPtrField<string>* Reflection::MutableRepeatedPtrField<string>(
+ Message* message, const FieldDescriptor* field) const {
+ return static_cast<RepeatedPtrField<string>* >(
+ MutableRawRepeatedString(message, field, true));
+}
+
+
+// -----
+
+template<>
+inline const RepeatedPtrField<Message>& Reflection::GetRepeatedPtrField(
+ const Message& message, const FieldDescriptor* field) const {
+ return *static_cast<RepeatedPtrField<Message>* >(
+ MutableRawRepeatedField(const_cast<Message*>(&message), field,
+ FieldDescriptor::CPPTYPE_MESSAGE, -1,
+ NULL));
+}
+
+template<>
+inline RepeatedPtrField<Message>* Reflection::MutableRepeatedPtrField(
+ Message* message, const FieldDescriptor* field) const {
+ return static_cast<RepeatedPtrField<Message>* >(
+ MutableRawRepeatedField(message, field,
+ FieldDescriptor::CPPTYPE_MESSAGE, -1,
+ NULL));
+}
+
+template<typename PB>
+inline const RepeatedPtrField<PB>& Reflection::GetRepeatedPtrField(
+ const Message& message, const FieldDescriptor* field) const {
+ return *static_cast<RepeatedPtrField<PB>* >(
+ MutableRawRepeatedField(const_cast<Message*>(&message), field,
+ FieldDescriptor::CPPTYPE_MESSAGE, -1,
+ PB::default_instance().GetDescriptor()));
+}
+
+template<typename PB>
+inline RepeatedPtrField<PB>* Reflection::MutableRepeatedPtrField(
+ Message* message, const FieldDescriptor* field) const {
+ return static_cast<RepeatedPtrField<PB>* >(
+ MutableRawRepeatedField(message, field,
+ FieldDescriptor::CPPTYPE_MESSAGE, -1,
+ PB::default_instance().GetDescriptor()));
+}
+
} // namespace protobuf
} // namespace google