diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc index eb81694daf..2cf07dbdf4 100644 --- a/src/google/protobuf/message.cc +++ b/src/google/protobuf/message.cc @@ -188,7 +188,13 @@ size_t Message::MaybeComputeUnknownFieldsSize( } size_t Message::SpaceUsedLong() const { - return GetReflection()->SpaceUsedLong(*this); + auto* reflection = GetReflection(); + if (PROTOBUF_PREDICT_TRUE(reflection != nullptr)) { + return reflection->SpaceUsedLong(*this); + } + // The only case that does not have reflection is RawMessage. + return internal::DownCast(*this) + .SpaceUsedLong(); } static std::string GetTypeNameImpl(const MessageLite& msg) { diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h index 83ba793e93..47f41b89ec 100644 --- a/src/google/protobuf/message.h +++ b/src/google/protobuf/message.h @@ -286,8 +286,7 @@ class PROTOBUF_EXPORT Message : public MessageLite { void DiscardUnknownFields(); // Computes (an estimate of) the total number of bytes currently used for - // storing the message in memory. The default implementation calls the - // Reflection object's SpaceUsed() method. + // storing the message in memory. // // SpaceUsed() is noticeably slower than ByteSize(), as it is implemented // using reflection (rather than the generated code implementation for @@ -297,7 +296,7 @@ class PROTOBUF_EXPORT Message : public MessageLite { // Note: The precise value of this method should never be depended on, and can // change substantially due to internal details. In debug builds, this will // include a random fuzz factor to prevent these dependencies. - virtual size_t SpaceUsedLong() const; + size_t SpaceUsedLong() const; [[deprecated("Please use SpaceUsedLong() instead")]] int SpaceUsed() const { return internal::ToIntSize(SpaceUsedLong()); @@ -1573,6 +1572,12 @@ bool SplitFieldHasExtraIndirectionStatic(const FieldDescriptor* field) { return ret; } +class RawMessageBase : public Message { + public: + using Message::Message; + virtual size_t SpaceUsedLong() const = 0; +}; + } // namespace internal template