aboutsummaryrefslogtreecommitdiff
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.h244
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__