Index: third_party/protobuf/src/google/protobuf/message.h |
=================================================================== |
--- third_party/protobuf/src/google/protobuf/message.h (revision 216642) |
+++ third_party/protobuf/src/google/protobuf/message.h (working copy) |
@@ -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); |
@@ -122,6 +123,7 @@ |
#include <google/protobuf/message_lite.h> |
#include <google/protobuf/stubs/common.h> |
+#include <google/protobuf/descriptor.h> |
namespace google { |
@@ -133,30 +135,27 @@ |
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 { |
const Descriptor* descriptor; |
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 |
@@ -360,7 +359,6 @@ |
// write fields from a Reflection without paying attention to the type. |
class LIBPROTOBUF_EXPORT Reflection { |
public: |
- // TODO(kenton): Remove parameter. |
inline Reflection() {} |
virtual ~Reflection(); |
@@ -390,7 +388,7 @@ |
virtual void ClearField(Message* message, |
const FieldDescriptor* field) const = 0; |
- // Remove the last element of a repeated field. |
+ // 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 |
@@ -399,6 +397,10 @@ |
// 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; |
@@ -500,6 +502,16 @@ |
virtual Message* MutableMessage(Message* message, |
const FieldDescriptor* field, |
MessageFactory* factory = NULL) 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 ------------------------------------------ |
@@ -607,8 +619,40 @@ |
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. |
virtual const FieldDescriptor* FindKnownExtensionByName( |
@@ -619,7 +663,26 @@ |
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); |
}; |
@@ -682,10 +745,71 @@ |
static void InternalRegisterGeneratedMessage(const Descriptor* descriptor, |
const Message* prototype); |
+ |
private: |
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFactory); |
}; |
+// ============================================================================= |
+// 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 |