diff options
Diffstat (limited to 'src/google/protobuf/message.h')
-rw-r--r-- | src/google/protobuf/message.h | 244 |
1 files changed, 162 insertions, 82 deletions
diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h index f3d1a58a..9f44132b 100644 --- a/src/google/protobuf/message.h +++ b/src/google/protobuf/message.h @@ -115,16 +115,23 @@ #include <type_traits> #include <vector> -#include <google/protobuf/arena.h> -#include <google/protobuf/message_lite.h> - +#include <google/protobuf/stubs/casts.h> #include <google/protobuf/stubs/common.h> +#include <google/protobuf/arena.h> #include <google/protobuf/descriptor.h> +#include <google/protobuf/message_lite.h> +#include <google/protobuf/port.h> #define GOOGLE_PROTOBUF_HAS_ONEOF #define GOOGLE_PROTOBUF_HAS_ARENAS +#include <google/protobuf/port_def.inc> + +#ifdef SWIG +#error "You cannot SWIG proto headers" +#endif + namespace google { namespace protobuf { @@ -156,8 +163,13 @@ namespace expr { class CelMapReflectionFriend; // field_backed_map_impl.cc } +namespace internal { +class MapFieldPrinterHelper; // text_format.cc +} + namespace internal { +class ReflectionAccessor; // message.cc class ReflectionOps; // reflection_ops.h class MapKeySorter; // wire_format.cc class WireFormat; // wire_format.h @@ -186,7 +198,7 @@ struct Metadata { // 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 MessageLite { +class PROTOBUF_EXPORT Message : public MessageLite { public: inline Message() {} virtual ~Message() {} @@ -196,12 +208,12 @@ class LIBPROTOBUF_EXPORT Message : public MessageLite { // Construct a new instance of the same type. Ownership is passed to the // caller. (This is also defined in MessageLite, but is defined again here // for return-type covariance.) - virtual Message* New() const = 0; + Message* New() const override = 0; // Construct a new instance on the arena. Ownership is passed to the caller // if arena is a NULL. Default implementation allows for API compatibility // during the Arena transition. - virtual Message* New(::google::protobuf::Arena* arena) const { + Message* New(Arena* arena) const override { Message* message = New(); if (arena != NULL) { arena->Own(message); @@ -229,11 +241,11 @@ 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(std::vector<string>* errors) const; + void FindInitializationErrors(std::vector<std::string>* errors) const; // Like FindInitializationErrors, but joins all the strings, delimited by // commas, and returns them. - string InitializationErrorString() const; + std::string InitializationErrorString() const override; // Clears all unknown fields from this message and all embedded messages. // Normally, if unknown tag numbers are encountered when parsing a message, @@ -257,18 +269,18 @@ class LIBPROTOBUF_EXPORT Message : public MessageLite { // fields defined for the proto. virtual size_t SpaceUsedLong() const; - PROTOBUF_RUNTIME_DEPRECATED("Please use SpaceUsedLong() instead") + PROTOBUF_DEPRECATED_MSG("Please use SpaceUsedLong() instead") int SpaceUsed() const { return internal::ToIntSize(SpaceUsedLong()); } // Debugging & Testing---------------------------------------------- // Generates a human readable form of this message, useful for debugging // and other purposes. - string DebugString() const; + std::string DebugString() const; // Like DebugString(), but with less whitespace. - string ShortDebugString() const; + std::string ShortDebugString() const; // Like DebugString(), but do not escape UTF-8 byte sequences. - string Utf8DebugString() const; + std::string Utf8DebugString() const; // Convenience function useful in GDB. Prints DebugString() to stdout. void PrintDebugString() const; @@ -305,13 +317,23 @@ class LIBPROTOBUF_EXPORT Message : public MessageLite { // These methods are pure-virtual in MessageLite, but Message provides // reflection-based default implementations. - virtual string GetTypeName() const; - virtual void Clear(); - virtual bool IsInitialized() const; - virtual void CheckTypeAndMergeFrom(const MessageLite& other); - virtual bool MergePartialFromCodedStream(io::CodedInputStream* input); - virtual size_t ByteSizeLong() const; - virtual void SerializeWithCachedSizes(io::CodedOutputStream* output) const; + std::string GetTypeName() const override; + void Clear() override; + bool IsInitialized() const override; + void CheckTypeAndMergeFrom(const MessageLite& other) override; +#if !GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER + bool MergePartialFromCodedStream(io::CodedInputStream* input) override; +#endif + size_t ByteSizeLong() const override; + void SerializeWithCachedSizes(io::CodedOutputStream* output) const override; + +#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER + internal::ParseFunc _ParseFunc() const override { return _InternalParse; } + + // Reflective parser + static const char* _InternalParse(const char* begin, const char* end, + void* object, internal::ParseContext* ctx); +#endif private: // This is called only by the default implementation of ByteSize(), to @@ -327,8 +349,6 @@ class LIBPROTOBUF_EXPORT Message : public MessageLite { // Introspection --------------------------------------------------- - // Typedef for backwards-compatibility. - typedef google::protobuf::Reflection Reflection; // Get a non-owning pointer to a Descriptor for this message's type. This // describes what fields the message contains, the types of those fields, etc. @@ -409,7 +429,7 @@ class MutableRepeatedFieldRef; // 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. -class LIBPROTOBUF_EXPORT Reflection { +class PROTOBUF_EXPORT Reflection { public: inline Reflection() {} virtual ~Reflection(); @@ -430,7 +450,7 @@ class LIBPROTOBUF_EXPORT Reflection { // Estimate the amount of memory used by the message object. virtual size_t SpaceUsedLong(const Message& message) const = 0; - PROTOBUF_RUNTIME_DEPRECATED("Please use SpaceUsedLong() instead") + PROTOBUF_DEPRECATED_MSG("Please use SpaceUsedLong() instead") int SpaceUsed(const Message& message) const { return internal::ToIntSize(SpaceUsedLong(message)); } @@ -527,7 +547,7 @@ class LIBPROTOBUF_EXPORT Reflection { const FieldDescriptor* field) const = 0; virtual bool GetBool (const Message& message, const FieldDescriptor* field) const = 0; - virtual string GetString(const Message& message, + virtual std::string GetString(const Message& message, const FieldDescriptor* field) const = 0; virtual const EnumValueDescriptor* GetEnum( const Message& message, const FieldDescriptor* field) const = 0; @@ -554,15 +574,15 @@ class LIBPROTOBUF_EXPORT Reflection { // *scratch and return that. // // Note: It is perfectly reasonable and useful to write code like: - // str = reflection->GetStringReference(field, &str); + // str = reflection->GetStringReference(message, 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(message, field); - virtual const string& GetStringReference(const Message& message, + virtual const std::string& GetStringReference(const Message& message, const FieldDescriptor* field, - string* scratch) const = 0; + std::string* scratch) const = 0; // Singular field mutators ----------------------------------------- @@ -584,14 +604,17 @@ class LIBPROTOBUF_EXPORT Reflection { const FieldDescriptor* field, bool value) const = 0; virtual void SetString(Message* message, const FieldDescriptor* field, - const string& value) const = 0; + const std::string& value) const = 0; virtual void SetEnum (Message* message, const FieldDescriptor* field, const EnumValueDescriptor* value) const = 0; // Set an enum field's value with an integer rather than EnumValueDescriptor. - // If the value does not correspond to a known enum value, either behavior is - // undefined (for proto2 messages), or the value is accepted silently for - // messages with new unknown-enum-value semantics. + // For proto3 this is just setting the enum field to the value specified, for + // proto2 it's more complicated. If value is a known enum value the field is + // set as usual. If the value is unknown then it is added to the unknown field + // set. Note this matches the behavior of parsing unknown enum values. + // If multiple calls with unknown values happen than they are all added to the + // unknown field set in order of the calls. virtual void SetEnumValue(Message* message, const FieldDescriptor* field, int value) const = 0; @@ -652,7 +675,7 @@ class LIBPROTOBUF_EXPORT Reflection { virtual bool GetRepeatedBool (const Message& message, const FieldDescriptor* field, int index) const = 0; - virtual string GetRepeatedString(const Message& message, + virtual std::string GetRepeatedString(const Message& message, const FieldDescriptor* field, int index) const = 0; virtual const EnumValueDescriptor* GetRepeatedEnum( @@ -671,9 +694,9 @@ class LIBPROTOBUF_EXPORT Reflection { const FieldDescriptor* field, int index) const = 0; // See GetStringReference(), above. - virtual const string& GetRepeatedStringReference( + virtual const std::string& GetRepeatedStringReference( const Message& message, const FieldDescriptor* field, - int index, string* scratch) const = 0; + int index, std::string* scratch) const = 0; // Repeated field mutators ----------------------------------------- @@ -702,14 +725,17 @@ class LIBPROTOBUF_EXPORT Reflection { int index, bool value) const = 0; virtual void SetRepeatedString(Message* message, const FieldDescriptor* field, - int index, const string& value) const = 0; + int index, const std::string& value) const = 0; virtual void SetRepeatedEnum(Message* message, const FieldDescriptor* field, int index, const EnumValueDescriptor* value) const = 0; // Set an enum field's value with an integer rather than EnumValueDescriptor. - // If the value does not correspond to a known enum value, either behavior is - // undefined (for proto2 messages), or the value is accepted silently for - // messages with new unknown-enum-value semantics. + // For proto3 this is just setting the enum field to the value specified, for + // proto2 it's more complicated. If value is a known enum value the field is + // set as usual. If the value is unknown then it is added to the unknown field + // set. Note this matches the behavior of parsing unknown enum values. + // If multiple calls with unknown values happen than they are all added to the + // unknown field set in order of the calls. virtual void SetRepeatedEnumValue(Message* message, const FieldDescriptor* field, int index, int value) const = 0; @@ -738,14 +764,17 @@ class LIBPROTOBUF_EXPORT Reflection { const FieldDescriptor* field, bool value) const = 0; virtual void AddString(Message* message, const FieldDescriptor* field, - const string& value) const = 0; + const std::string& value) const = 0; virtual void AddEnum (Message* message, const FieldDescriptor* field, const EnumValueDescriptor* value) const = 0; - // Set an enum field's value with an integer rather than EnumValueDescriptor. - // If the value does not correspond to a known enum value, either behavior is - // undefined (for proto2 messages), or the value is accepted silently for - // messages with new unknown-enum-value semantics. + // Add an integer value to a repeated enum field rather than + // EnumValueDescriptor. For proto3 this is just setting the enum field to the + // value specified, for proto2 it's more complicated. If value is a known enum + // value the field is set as usual. If the value is unknown then it is added + // to the unknown field set. Note this matches the behavior of parsing unknown + // enum values. If multiple calls with unknown values happen than they are all + // added to the unknown field set in order of the calls. virtual void AddEnumValue(Message* message, const FieldDescriptor* field, int value) const = 0; @@ -755,7 +784,7 @@ class LIBPROTOBUF_EXPORT Reflection { MessageFactory* factory = NULL) const = 0; // Appends an already-allocated object 'new_entry' to the repeated field - // specifyed by 'field' passing ownership to the message. + // specified by 'field' passing ownership to the message. // TODO(tmarek): Make virtual after all subclasses have been // updated. virtual void AddAllocatedMessage(Message* message, @@ -785,7 +814,7 @@ class LIBPROTOBUF_EXPORT Reflection { // long as the message is not destroyed. // // Note that to use this method users need to include the header file - // "google/protobuf/reflection.h" (which defines the RepeatedFieldRef + // "net/proto2/public/reflection.h" (which defines the RepeatedFieldRef // class templates). template<typename T> RepeatedFieldRef<T> GetRepeatedFieldRef( @@ -814,43 +843,43 @@ class LIBPROTOBUF_EXPORT Reflection { // DEPRECATED. Please use GetRepeatedFieldRef(). // // for T = Cord and all protobuf scalar types except enums. - template<typename T> - PROTOBUF_RUNTIME_DEPRECATED("Please use GetRepeatedFieldRef() instead") - const RepeatedField<T>& GetRepeatedField( - const Message&, const FieldDescriptor*) const; + template <typename T> + PROTOBUF_DEPRECATED_MSG("Please use GetRepeatedFieldRef() instead") + const RepeatedField<T>& GetRepeatedField(const Message&, + const FieldDescriptor*) const; // DEPRECATED. Please use GetMutableRepeatedFieldRef(). // // for T = Cord and all protobuf scalar types except enums. - template<typename T> - PROTOBUF_RUNTIME_DEPRECATED("Please use GetMutableRepeatedFieldRef() instead") - RepeatedField<T>* MutableRepeatedField( - Message*, const FieldDescriptor*) const; + template <typename T> + PROTOBUF_DEPRECATED_MSG("Please use GetMutableRepeatedFieldRef() instead") + RepeatedField<T>* MutableRepeatedField(Message*, + const FieldDescriptor*) const; // DEPRECATED. Please use GetRepeatedFieldRef(). // // for T = string, google::protobuf::internal::StringPieceField // google::protobuf::Message & descendants. - template<typename T> - PROTOBUF_RUNTIME_DEPRECATED("Please use GetRepeatedFieldRef() instead") - const RepeatedPtrField<T>& GetRepeatedPtrField( - const Message&, const FieldDescriptor*) const; + template <typename T> + PROTOBUF_DEPRECATED_MSG("Please use GetRepeatedFieldRef() instead") + const RepeatedPtrField<T>& GetRepeatedPtrField(const Message&, + const FieldDescriptor*) const; // DEPRECATED. Please use GetMutableRepeatedFieldRef(). // // for T = string, google::protobuf::internal::StringPieceField // google::protobuf::Message & descendants. - template<typename T> - PROTOBUF_RUNTIME_DEPRECATED("Please use GetMutableRepeatedFieldRef() instead") - RepeatedPtrField<T>* MutableRepeatedPtrField( - Message*, const FieldDescriptor*) const; + template <typename T> + PROTOBUF_DEPRECATED_MSG("Please use GetMutableRepeatedFieldRef() instead") + 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( - const string& name) const = 0; + const std::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. @@ -952,13 +981,16 @@ class LIBPROTOBUF_EXPORT Reflection { friend class RepeatedFieldRef; template<typename T, typename Enable> friend class MutableRepeatedFieldRef; - friend class ::google::protobuf::python::MapReflectionFriend; + friend class python::MapReflectionFriend; #define GOOGLE_PROTOBUF_HAS_CEL_MAP_REFLECTION_FRIEND - friend class ::google::protobuf::expr::CelMapReflectionFriend; + friend class expr::CelMapReflectionFriend; friend class internal::MapFieldReflectionTest; friend class internal::MapKeySorter; friend class internal::WireFormat; friend class internal::ReflectionOps; + // Needed for implementing text format for map. + friend class internal::MapFieldPrinterHelper; + friend class internal::ReflectionAccessor; // Special version for specialized implementations of string. We can't call // MutableRawRepeatedField directly here because we don't have access to @@ -1029,7 +1061,7 @@ class LIBPROTOBUF_EXPORT Reflection { }; // Abstract interface for a factory for message objects. -class LIBPROTOBUF_EXPORT MessageFactory { +class PROTOBUF_EXPORT MessageFactory { public: inline MessageFactory() {} virtual ~MessageFactory(); @@ -1078,8 +1110,8 @@ class LIBPROTOBUF_EXPORT MessageFactory { // 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&)); + static void InternalRegisterGeneratedFile(const char* filename, + void* assign_descriptors_table); // For internal use only: Registers a message type. Called only by the // functions which are registered with InternalRegisterGeneratedFile(), @@ -1092,16 +1124,15 @@ class LIBPROTOBUF_EXPORT MessageFactory { 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<> \ -LIBPROTOBUF_EXPORT \ -RepeatedField<TYPE>* Reflection::MutableRepeatedField<TYPE>( \ - Message* message, const FieldDescriptor* field) const; +#define DECLARE_GET_REPEATED_FIELD(TYPE) \ + template <> \ + PROTOBUF_EXPORT const RepeatedField<TYPE>& \ + Reflection::GetRepeatedField<TYPE>(const Message& message, \ + const FieldDescriptor* field) const; \ + \ + template <> \ + PROTOBUF_EXPORT RepeatedField<TYPE>* Reflection::MutableRepeatedField<TYPE>( \ + Message * message, const FieldDescriptor* field) const; DECLARE_GET_REPEATED_FIELD(int32) DECLARE_GET_REPEATED_FIELD(int64) @@ -1113,6 +1144,53 @@ DECLARE_GET_REPEATED_FIELD(bool) #undef DECLARE_GET_REPEATED_FIELD +// Tries to downcast this message to a generated message type. Returns NULL if +// this class is not an instance of T. This works even if RTTI is disabled. +// +// This also has the effect of creating a strong reference to T that will +// prevent the linker from stripping it out at link time. This can be important +// if you are using a DynamicMessageFactory that delegates to the generated +// factory. +template <typename T> +const T* DynamicCastToGenerated(const Message* from) { + // Compile-time assert that T is a generated type that has a + // default_instance() accessor, but avoid actually calling it. + const T&(*get_default_instance)() = &T::default_instance; + (void)get_default_instance; + + // Compile-time assert that T is a subclass of google::protobuf::Message. + const Message* unused = static_cast<T*>(nullptr); + (void)unused; + +#ifdef GOOGLE_PROTOBUF_NO_RTTI + bool ok = T::default_instance().GetReflection() == from->GetReflection(); + return ok ? down_cast<const T*>(from) : nullptr; +#else + return dynamic_cast<const T*>(from); +#endif +} + +template <typename T> +T* DynamicCastToGenerated(Message* from) { + const Message* message_const = from; + return const_cast<T*>(DynamicCastToGenerated<T>(message_const)); +} + +namespace internal { + +// Legacy functions, to preserve compatibility with existing callers. +// These had a slightly different signature, so we have to adjust "T". +template <typename T> +T dynamic_cast_if_available(const Message* from) { + return DynamicCastToGenerated<typename std::remove_pointer<T>::type>(from); +} +template <typename T> +T dynamic_cast_if_available(Message* from) { + return DynamicCastToGenerated<typename std::remove_pointer<T>::type>(from); +} + +} // namespace internal + // ============================================================================= // Implementation details for {Get,Mutable}RawRepeatedPtrField. We provide // specializations for <string>, <StringPieceField> and <Message> and handle @@ -1121,16 +1199,16 @@ DECLARE_GET_REPEATED_FIELD(bool) // Such a type presumably is a descendant of google::protobuf::Message. template<> -inline const RepeatedPtrField<string>& Reflection::GetRepeatedPtrField<string>( +inline const RepeatedPtrField<std::string>& Reflection::GetRepeatedPtrField<std::string>( const Message& message, const FieldDescriptor* field) const { - return *static_cast<RepeatedPtrField<string>* >( + return *static_cast<RepeatedPtrField<std::string>* >( MutableRawRepeatedString(const_cast<Message*>(&message), field, true)); } template<> -inline RepeatedPtrField<string>* Reflection::MutableRepeatedPtrField<string>( +inline RepeatedPtrField<std::string>* Reflection::MutableRepeatedPtrField<std::string>( Message* message, const FieldDescriptor* field) const { - return static_cast<RepeatedPtrField<string>* >( + return static_cast<RepeatedPtrField<std::string>* >( MutableRawRepeatedString(message, field, true)); } @@ -1171,6 +1249,8 @@ inline RepeatedPtrField<PB>* Reflection::MutableRepeatedPtrField( PB::default_instance().GetDescriptor())); } } // namespace protobuf - } // namespace google + +#include <google/protobuf/port_undef.inc> + #endif // GOOGLE_PROTOBUF_MESSAGE_H__ |