This is an automated email from the ASF dual-hosted git repository.

guangmingchen pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brpc.git


The following commit(s) were added to refs/heads/master by this push:
     new 282776ac Add NonreflectableMessage and support Protobuf v5 (#2782)
282776ac is described below

commit 282776acaf2c894791d2b5d4c294a28cfa2d4138
Author: Xiaofeng Wang <wasp...@gmail.com>
AuthorDate: Wed Oct 30 19:49:19 2024 +0800

    Add NonreflectableMessage and support Protobuf v5 (#2782)
    
    * Add NonreflectableMessage and support Protobuf v5
    
    See https://github.com/apache/brpc/pull/2722#issuecomment-2272559689
    inspired by unreflectable_message of @oathdruid.
    
    * Remove unnecessary MessageHelper
---
 src/brpc/esp_head.h                |   2 +
 src/brpc/esp_message.cpp           |  90 ++--------------
 src/brpc/esp_message.h             |  48 ++-------
 src/brpc/memcache.cpp              | 122 ++++-----------------
 src/brpc/memcache.h                |  63 ++++-------
 src/brpc/nonreflectable_message.h  | 216 +++++++++++++++++++++++++++++++++++++
 src/brpc/nshead_message.cpp        |  71 ++----------
 src/brpc/nshead_message.h          |  47 +++-----
 src/brpc/pb_compat.h               |  24 +++--
 src/brpc/redis.cpp                 | 140 ++++--------------------
 src/brpc/redis.h                   |  95 ++++++----------
 src/brpc/serialized_request.cpp    |  79 ++------------
 src/brpc/serialized_request.h      |  50 +++------
 src/brpc/serialized_response.cpp   |  79 ++------------
 src/brpc/serialized_response.h     |  50 +++------
 src/brpc/thrift_message.cpp        |  74 +------------
 src/brpc/thrift_message.h          |  51 +++------
 tools/rpc_press/rpc_press_impl.cpp |   7 ++
 18 files changed, 439 insertions(+), 869 deletions(-)

diff --git a/src/brpc/esp_head.h b/src/brpc/esp_head.h
index b882ff90..c5d9cc1f 100644
--- a/src/brpc/esp_head.h
+++ b/src/brpc/esp_head.h
@@ -18,6 +18,8 @@
 #ifndef BRPC_ESP_HEAD_H
 #define BRPC_ESP_HEAD_H
 
+#include <cstdint>
+
 namespace brpc {
 
 #pragma pack(push, r1, 1)
diff --git a/src/brpc/esp_message.cpp b/src/brpc/esp_message.cpp
index 0c17c181..affebd26 100644
--- a/src/brpc/esp_message.cpp
+++ b/src/brpc/esp_message.cpp
@@ -17,22 +17,14 @@
 
 #include "esp_message.h"
 
-#include <google/protobuf/reflection_ops.h>     // ReflectionOps::Merge
-#include <google/protobuf/wire_format.h>        // 
WireFormatLite::GetTagWireType
-
+#include "brpc/proto_base.pb.h"
 #include "butil/logging.h"
 
 namespace brpc {
 
 EspMessage::EspMessage()
-    : ::google::protobuf::Message() {
-    SharedCtor();
-}
-
-EspMessage::EspMessage(const EspMessage& from)
-    : ::google::protobuf::Message() {
+    : NonreflectableMessage<EspMessage>() {
     SharedCtor();
-    MergeFrom(from);
 }
 
 void EspMessage::SharedCtor() {
@@ -46,91 +38,21 @@ EspMessage::~EspMessage() {
 void EspMessage::SharedDtor() {
 }
 
-const ::google::protobuf::Descriptor* EspMessage::descriptor() {
-    return EspMessageBase::descriptor();
-}
-
-EspMessage* EspMessage::New() const {
-    return new EspMessage;
-}
-
-#if GOOGLE_PROTOBUF_VERSION >= 3006000
-EspMessage* EspMessage::New(::google::protobuf::Arena* arena) const {
-    return CreateMaybeMessage<EspMessage>(arena);
-}
-#endif
-
 void EspMessage::Clear() {
     head.body_len = 0;
     body.clear();
 }
 
-bool EspMessage::MergePartialFromCodedStream(
-        ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
-    ::google::protobuf::uint32 tag;
-
-    while ((tag = input->ReadTag()) != 0) {
-        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) 
==
-                
::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
-            return true;
-        }
-    }
-    return true;
-#undef DO_
-}
-
-void EspMessage::SerializeWithCachedSizes(
-        ::google::protobuf::io::CodedOutputStream*) const {
-}
-
-::google::protobuf::uint8* EspMessage::SerializeWithCachedSizesToArray(
-        ::google::protobuf::uint8* target) const {
-    return target;
-}
-
-int EspMessage::ByteSize() const {
+size_t EspMessage::ByteSizeLong() const {
     return sizeof(head) + body.size();
 }
 
-void EspMessage::MergeFrom(const ::google::protobuf::Message& from) {
-    CHECK_NE(&from, this);
-    const EspMessage* source = dynamic_cast<const EspMessage*>(&from);
-    if (source == NULL) {
-        ::google::protobuf::internal::ReflectionOps::Merge(from, this);
-    } else {
-        MergeFrom(*source);
-    }
-}
-
 void EspMessage::MergeFrom(const EspMessage& from) {
     CHECK_NE(&from, this);
     head = from.head;
     body = from.body;
 }
 
-void EspMessage::CopyFrom(const ::google::protobuf::Message& from) {
-    if (&from == this) {
-        return;
-    }
-
-    Clear();
-    MergeFrom(from);
-}
-
-void EspMessage::CopyFrom(const EspMessage& from) {
-    if (&from == this) {
-        return;
-    }
-
-    Clear();
-    MergeFrom(from);
-}
-
-bool EspMessage::IsInitialized() const {
-    return true;
-}
-
 void EspMessage::Swap(EspMessage* other) {
     if (other != this) {
         const EspHead tmp = other->head;
@@ -141,9 +63,9 @@ void EspMessage::Swap(EspMessage* other) {
 }
 
 ::google::protobuf::Metadata EspMessage::GetMetadata() const {
-    ::google::protobuf::Metadata metadata;
-    metadata.descriptor = EspMessage::descriptor();
-    metadata.reflection = NULL;
+    ::google::protobuf::Metadata metadata{};
+    metadata.descriptor = EspMessageBase::descriptor();
+    metadata.reflection = nullptr;
     return metadata;
 }
 
diff --git a/src/brpc/esp_message.h b/src/brpc/esp_message.h
index aecc837c..4178b824 100644
--- a/src/brpc/esp_message.h
+++ b/src/brpc/esp_message.h
@@ -18,64 +18,32 @@
 #ifndef BRPC_ESP_MESSAGE_H
 #define BRPC_ESP_MESSAGE_H
 
-#include <string>
-
-#include <google/protobuf/message.h>
-#include <google/protobuf/generated_message_reflection.h>   // 
dynamic_cast_if_available
-#include <google/protobuf/reflection_ops.h>     // ReflectionOps::Merge
-
 #include "brpc/esp_head.h"
-#include "butil/iobuf.h"       
-#include "brpc/proto_base.pb.h"
-#include "brpc/pb_compat.h"
+#include "brpc/nonreflectable_message.h"
+#include "butil/iobuf.h"
 
 namespace brpc {
 
-class EspMessage : public ::google::protobuf::Message {
+class EspMessage : public NonreflectableMessage<EspMessage> {
 public:
     EspHead head;
     butil::IOBuf body;
 
 public:
     EspMessage();
-    virtual ~EspMessage();
-
-    EspMessage(const EspMessage& from);
-
-    inline EspMessage& operator=(const EspMessage& from) {
-        CopyFrom(from);
-        return *this;
-    }
-
-    static const ::google::protobuf::Descriptor* descriptor();
-    static const EspMessage& default_instance();
+    ~EspMessage() override;
 
     void Swap(EspMessage* other);
 
     // implements Message ----------------------------------------------
 
-    EspMessage* New() const PB_319_OVERRIDE;
-#if GOOGLE_PROTOBUF_VERSION >= 3006000
-    EspMessage* New(::google::protobuf::Arena* arena) const override;
-#endif
-    void CopyFrom(const ::google::protobuf::Message& from) PB_321_OVERRIDE;
-    void MergeFrom(const ::google::protobuf::Message& from) override;
-    void CopyFrom(const EspMessage& from);
-    void MergeFrom(const EspMessage& from);
+    void MergeFrom(const EspMessage& from) override;
     void Clear() override;
-    bool IsInitialized() const override;
 
-    int ByteSize() const;
-    bool MergePartialFromCodedStream(
-            ::google::protobuf::io::CodedInputStream* input) PB_310_OVERRIDE;
-    void SerializeWithCachedSizes(
-            ::google::protobuf::io::CodedOutputStream* output) const 
PB_310_OVERRIDE;
-    ::google::protobuf::uint8* SerializeWithCachedSizesToArray(
-            ::google::protobuf::uint8* output) const PB_310_OVERRIDE;
-    int GetCachedSize() const PB_422_OVERRIDE { return ByteSize(); }
+    size_t ByteSizeLong() const override;
+    int GetCachedSize() const PB_425_OVERRIDE { return ByteSize(); }
 
-protected:
-    ::google::protobuf::Metadata GetMetadata() const override;
+    ::google::protobuf::Metadata GetMetadata() const PB_527_OVERRIDE;
 
 private:
     void SharedCtor();
diff --git a/src/brpc/memcache.cpp b/src/brpc/memcache.cpp
index 43e8078a..c198d168 100644
--- a/src/brpc/memcache.cpp
+++ b/src/brpc/memcache.cpp
@@ -15,26 +15,24 @@
 // specific language governing permissions and limitations
 // under the License.
 
+#include "brpc/memcache.h"
 
-#include <algorithm>
-#include <google/protobuf/reflection_ops.h>
-#include <google/protobuf/wire_format.h>
-#include "butil/string_printf.h"
+#include "brpc/policy/memcache_binary_header.h"
+#include "brpc/proto_base.pb.h"
+#include "butil/logging.h"
 #include "butil/macros.h"
+#include "butil/string_printf.h"
 #include "butil/sys_byteorder.h"
-#include "butil/logging.h"
-#include "brpc/memcache.h"
-#include "brpc/policy/memcache_binary_header.h"
 
 namespace brpc {
 
 MemcacheRequest::MemcacheRequest()
-    : ::google::protobuf::Message() {
+    : NonreflectableMessage<MemcacheRequest>() {
     SharedCtor();
 }
 
 MemcacheRequest::MemcacheRequest(const MemcacheRequest& from)
-    : ::google::protobuf::Message() {
+    : NonreflectableMessage<MemcacheRequest>() {
     SharedCtor();
     MergeFrom(from);
 }
@@ -55,20 +53,6 @@ void MemcacheRequest::SetCachedSize(int size) const {
     _cached_size_ = size;
 }
 
-const ::google::protobuf::Descriptor* MemcacheRequest::descriptor() {
-    return MemcacheRequestBase::descriptor();
-}
-
-MemcacheRequest* MemcacheRequest::New() const {
-    return new MemcacheRequest;
-}
-
-#if GOOGLE_PROTOBUF_VERSION >= 3006000
-MemcacheRequest* MemcacheRequest::New(::google::protobuf::Arena* arena) const {
-    return CreateMaybeMessage<MemcacheRequest>(arena);
-}
-#endif
-
 void MemcacheRequest::Clear() {
     _buf.clear();
     _pipelined_count = 0;
@@ -122,45 +106,18 @@ void MemcacheRequest::SerializeWithCachedSizes(
     }
 }
 
-::google::protobuf::uint8* MemcacheRequest::SerializeWithCachedSizesToArray(
-    ::google::protobuf::uint8* target) const {
-    return target;
-}
-
-int MemcacheRequest::ByteSize() const {
-    int total_size =  _buf.size();
+size_t MemcacheRequest::ByteSizeLong() const {
+    int total_size =  static_cast<int>(_buf.size());
     _cached_size_ = total_size;
     return total_size;
 }
 
-void MemcacheRequest::MergeFrom(const ::google::protobuf::Message& from) {
-    CHECK_NE(&from, this);
-    const MemcacheRequest* source = dynamic_cast<const 
MemcacheRequest*>(&from);
-    if (source == NULL) {
-        ::google::protobuf::internal::ReflectionOps::Merge(from, this);
-    } else {
-        MergeFrom(*source);
-    }
-}
-
 void MemcacheRequest::MergeFrom(const MemcacheRequest& from) {
     CHECK_NE(&from, this);
     _buf.append(from._buf);
     _pipelined_count += from._pipelined_count;
 }
 
-void MemcacheRequest::CopyFrom(const ::google::protobuf::Message& from) {
-    if (&from == this) return;
-    Clear();
-    MergeFrom(from);
-}
-
-void MemcacheRequest::CopyFrom(const MemcacheRequest& from) {
-    if (&from == this) return;
-    Clear();
-    MergeFrom(from);
-}
-
 bool MemcacheRequest::IsInitialized() const {
     return _pipelined_count != 0;
 }
@@ -174,19 +131,19 @@ void MemcacheRequest::Swap(MemcacheRequest* other) {
 }
 
 ::google::protobuf::Metadata MemcacheRequest::GetMetadata() const {
-    ::google::protobuf::Metadata metadata;
-    metadata.descriptor = MemcacheRequest::descriptor();
-    metadata.reflection = NULL;
+    ::google::protobuf::Metadata metadata{};
+    metadata.descriptor = MemcacheRequestBase::descriptor();
+    metadata.reflection = nullptr;
     return metadata;
 }
 
 MemcacheResponse::MemcacheResponse()
-    : ::google::protobuf::Message() {
+    : NonreflectableMessage<MemcacheResponse>() {
     SharedCtor();
 }
 
 MemcacheResponse::MemcacheResponse(const MemcacheResponse& from)
-    : ::google::protobuf::Message() {
+    : NonreflectableMessage<MemcacheResponse>() {
     SharedCtor();
     MergeFrom(from);
 }
@@ -205,20 +162,6 @@ void MemcacheResponse::SharedDtor() {
 void MemcacheResponse::SetCachedSize(int size) const {
     _cached_size_ = size;
 }
-const ::google::protobuf::Descriptor* MemcacheResponse::descriptor() {
-    return MemcacheResponseBase::descriptor();
-}
-
-MemcacheResponse* MemcacheResponse::New() const {
-    return new MemcacheResponse;
-}
-
-#if GOOGLE_PROTOBUF_VERSION >= 3006000
-MemcacheResponse*
-MemcacheResponse::New(::google::protobuf::Arena* arena) const {
-    return CreateMaybeMessage<MemcacheResponse>(arena);
-}
-#endif
 
 void MemcacheResponse::Clear() {
 }
@@ -250,27 +193,12 @@ void MemcacheResponse::SerializeWithCachedSizes(
     }
 }
 
-::google::protobuf::uint8* MemcacheResponse::SerializeWithCachedSizesToArray(
-    ::google::protobuf::uint8* target) const {
-    return target;
-}
-
-int MemcacheResponse::ByteSize() const {
-    int total_size = _buf.size();
+size_t MemcacheResponse::ByteSizeLong() const {
+    int total_size = static_cast<int>(_buf.size());
     _cached_size_ = total_size;
     return total_size;
 }
 
-void MemcacheResponse::MergeFrom(const ::google::protobuf::Message& from) {
-    CHECK_NE(&from, this);
-    const MemcacheResponse* source = dynamic_cast<const 
MemcacheResponse*>(&from);
-    if (source == NULL) {
-        ::google::protobuf::internal::ReflectionOps::Merge(from, this);
-    } else {
-        MergeFrom(*source);
-    }
-}
-
 void MemcacheResponse::MergeFrom(const MemcacheResponse& from) {
     CHECK_NE(&from, this);
     _err = from._err;
@@ -279,18 +207,6 @@ void MemcacheResponse::MergeFrom(const MemcacheResponse& 
from) {
     _buf.append(from._buf);
 }
 
-void MemcacheResponse::CopyFrom(const ::google::protobuf::Message& from) {
-    if (&from == this) return;
-    Clear();
-    MergeFrom(from);
-}
-
-void MemcacheResponse::CopyFrom(const MemcacheResponse& from) {
-    if (&from == this) return;
-    Clear();
-    MergeFrom(from);
-}
-
 bool MemcacheResponse::IsInitialized() const {
     return !_buf.empty();
 }
@@ -303,9 +219,9 @@ void MemcacheResponse::Swap(MemcacheResponse* other) {
 }
 
 ::google::protobuf::Metadata MemcacheResponse::GetMetadata() const {
-    ::google::protobuf::Metadata metadata;
-    metadata.descriptor = MemcacheResponse::descriptor();
-    metadata.reflection = NULL;
+    ::google::protobuf::Metadata metadata{};
+    metadata.descriptor = MemcacheResponseBase::descriptor();
+    metadata.reflection = nullptr;
     return metadata;
 }
 
diff --git a/src/brpc/memcache.h b/src/brpc/memcache.h
index 014f075b..535516ed 100644
--- a/src/brpc/memcache.h
+++ b/src/brpc/memcache.h
@@ -20,11 +20,10 @@
 #define BRPC_MEMCACHE_H
 
 #include <string>
-#include <google/protobuf/message.h>
 
 #include "butil/iobuf.h"
 #include "butil/strings/string_piece.h"
-#include "brpc/proto_base.pb.h"
+#include "brpc/nonreflectable_message.h"
 #include "brpc/pb_compat.h"
 
 namespace brpc {
@@ -41,10 +40,10 @@ namespace brpc {
 //   MemcacheResponse response;
 //   // 2 GET and 1 SET are sent to the server together.
 //   channel.CallMethod(&controller, &request, &response, NULL/*done*/);
-class MemcacheRequest : public ::google::protobuf::Message {
+class MemcacheRequest : public NonreflectableMessage<MemcacheRequest> {
 public:
     MemcacheRequest();
-    virtual ~MemcacheRequest();
+    ~MemcacheRequest() override;
     MemcacheRequest(const MemcacheRequest& from);
     inline MemcacheRequest& operator=(const MemcacheRequest& from) {
         CopyFrom(from);
@@ -89,30 +88,20 @@ public:
     butil::IOBuf& raw_buffer() { return _buf; }
     const butil::IOBuf& raw_buffer() const { return _buf; }
 
+public:
     // Protobuf methods.
-    MemcacheRequest* New() const PB_319_OVERRIDE;
-#if GOOGLE_PROTOBUF_VERSION >= 3006000
-    MemcacheRequest* New(::google::protobuf::Arena* arena) const override;
-#endif
-    void CopyFrom(const ::google::protobuf::Message& from) PB_321_OVERRIDE;
-    void MergeFrom(const ::google::protobuf::Message& from) override;
-    void CopyFrom(const MemcacheRequest& from);
-    void MergeFrom(const MemcacheRequest& from);
+    void MergeFrom(const MemcacheRequest& from) override;
     void Clear() override;
-    bool IsInitialized() const override;
+    bool IsInitialized() const PB_527_OVERRIDE;
   
-    int ByteSize() const;
+    size_t ByteSizeLong() const override;
     bool MergePartialFromCodedStream(
         ::google::protobuf::io::CodedInputStream* input) PB_310_OVERRIDE;
     void SerializeWithCachedSizes(
         ::google::protobuf::io::CodedOutputStream* output) const 
PB_310_OVERRIDE;
-    ::google::protobuf::uint8* 
SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const 
PB_310_OVERRIDE;
-    int GetCachedSize() const PB_422_OVERRIDE { return _cached_size_; }
-    
-    static const ::google::protobuf::Descriptor* descriptor();
+    int GetCachedSize() const PB_425_OVERRIDE { return _cached_size_; }
 
-protected:
-    ::google::protobuf::Metadata GetMetadata() const override;
+    ::google::protobuf::Metadata GetMetadata() const PB_527_OVERRIDE;
     
 private:
     bool GetOrDelete(uint8_t command, const butil::StringPiece& key);
@@ -125,7 +114,7 @@ private:
 
     void SharedCtor();
     void SharedDtor();
-    void SetCachedSize(int size) const PB_422_OVERRIDE;
+    void SetCachedSize(int size) const PB_425_OVERRIDE;
 
     int _pipelined_count;
     butil::IOBuf _buf;
@@ -155,7 +144,7 @@ private:
 //   } else {
 //       // the SET was successful.
 //   }
-class MemcacheResponse : public ::google::protobuf::Message {
+class MemcacheResponse : public NonreflectableMessage<MemcacheResponse> {
 public:
     // Definition of the valid response status numbers.
     // See section 3.2 Response Status
@@ -174,7 +163,7 @@ public:
     };
 
     MemcacheResponse();
-    virtual ~MemcacheResponse();
+    ~MemcacheResponse() override;
     MemcacheResponse(const MemcacheResponse& from);
     inline MemcacheResponse& operator=(const MemcacheResponse& from) {
         CopyFrom(from);
@@ -200,32 +189,21 @@ public:
     butil::IOBuf& raw_buffer() { return _buf; }
     const butil::IOBuf& raw_buffer() const { return _buf; }
     static const char* status_str(Status);
-      
+
+public:
     // implements Message ----------------------------------------------
-  
-    MemcacheResponse* New() const PB_319_OVERRIDE;
-#if GOOGLE_PROTOBUF_VERSION >= 3006000
-    MemcacheResponse* New(::google::protobuf::Arena* arena) const override;
-#endif
-    void CopyFrom(const ::google::protobuf::Message& from) PB_321_OVERRIDE;
-    void MergeFrom(const ::google::protobuf::Message& from) override;
-    void CopyFrom(const MemcacheResponse& from);
-    void MergeFrom(const MemcacheResponse& from);
+    void MergeFrom(const MemcacheResponse& from) override;
     void Clear() override;
-    bool IsInitialized() const override;
+    bool IsInitialized() const PB_527_OVERRIDE;
   
-    int ByteSize() const;
+    size_t ByteSizeLong() const;
     bool MergePartialFromCodedStream(
         ::google::protobuf::io::CodedInputStream* input) PB_310_OVERRIDE;
     void SerializeWithCachedSizes(
         ::google::protobuf::io::CodedOutputStream* output) const 
PB_310_OVERRIDE;
-    ::google::protobuf::uint8* 
SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const 
PB_310_OVERRIDE;
-    int GetCachedSize() const PB_422_OVERRIDE { return _cached_size_; }
-
-    static const ::google::protobuf::Descriptor* descriptor();
+    int GetCachedSize() const PB_425_OVERRIDE { return _cached_size_; }
 
-protected:
-    ::google::protobuf::Metadata GetMetadata() const override;
+    ::google::protobuf::Metadata GetMetadata() const PB_527_OVERRIDE;
 
 private:
     bool PopCounter(uint8_t command, uint64_t* new_value, uint64_t* cas_value);
@@ -233,7 +211,7 @@ private:
 
     void SharedCtor();
     void SharedDtor();
-    void SetCachedSize(int size) const PB_422_OVERRIDE;
+    void SetCachedSize(int size) const PB_425_OVERRIDE;
 
     std::string _err;
     butil::IOBuf _buf;
@@ -242,5 +220,4 @@ private:
 
 } // namespace brpc
 
-
 #endif  // BRPC_MEMCACHE_H
diff --git a/src/brpc/nonreflectable_message.h 
b/src/brpc/nonreflectable_message.h
new file mode 100644
index 00000000..91de918b
--- /dev/null
+++ b/src/brpc/nonreflectable_message.h
@@ -0,0 +1,216 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#ifndef BRPC_NONREFLECTABLE_MESSAGE_H
+#define BRPC_NONREFLECTABLE_MESSAGE_H
+
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/message.h>
+
+#include "pb_compat.h"
+
+namespace brpc {
+
+//
+// In bRPC, some non-Protobuf based protocol messages are also designed to 
implement
+// Protobuf Message interfaces, to provide a unified protocol message.
+// The API of Protobuf Message changes frequently, and these non-Protobuf 
based protocol
+// messages do not rely on the reflection functionality of Protobuf.
+//
+// NonreflectableMessage is designed to isolate upstream API changes and
+// provides basic implementations to simplify the adaptation process.
+//
+// Function implementations are kept order with the upstream,
+// and use only #if version_check #endif, to make maintenance easier.
+//
+template <typename T>
+class NonreflectableMessage : public ::google::protobuf::Message {
+public:
+    inline NonreflectableMessage() = default;
+    inline NonreflectableMessage(const NonreflectableMessage&) : 
NonreflectableMessage() {}
+    inline NonreflectableMessage& operator=(const NonreflectableMessage& 
other) {
+        CopyFrom(other);
+        return *this;
+    }
+    inline NonreflectableMessage& operator=(const T& other) {
+        CopyFrom(other);
+        return *this;
+    }
+
+#if GOOGLE_PROTOBUF_VERSION >= 5026000
+    const ClassData* GetClassData() const override {
+        return nullptr;
+    }
+#endif
+
+#if GOOGLE_PROTOBUF_VERSION < 3019000
+    Message* New() const override {
+        return new T();
+    }
+#endif
+
+#if GOOGLE_PROTOBUF_VERSION >= 3000000
+    Message* New(::google::protobuf::Arena* arena) const override {
+        return ::google::protobuf::Arena::Create<T>(arena);
+    }
+#endif
+
+    void CopyFrom(const ::google::protobuf::Message& other) PB_321_OVERRIDE {
+        if (&other == this) {
+            return;
+        }
+        Clear();
+        MergeFrom(other);
+    }
+
+    inline void CopyFrom(const NonreflectableMessage& other) {
+        if (&other == this) {
+            return;
+        }
+        Clear();
+        MergeFrom(other);
+    }
+
+    void MergeFrom(const ::google::protobuf::Message& other) PB_526_OVERRIDE {
+        if (&other == this) {
+            return;
+        }
+
+        // Cross-type merging is meaningless, call implementation of subclass
+#if GOOGLE_PROTOBUF_VERSION >= 3007000
+        const T* same_type_other = 
::google::protobuf::DynamicCastToGenerated<T>(&other);
+#elif GOOGLE_PROTOBUF_VERSION >= 3000000
+        const T* same_type_other = 
::google::protobuf::internal::DynamicCastToGenerated<const T>(&other);
+#endif // GOOGLE_PROTOBUF_VERSION
+        if (same_type_other != nullptr) {
+            MergeFrom(*same_type_other);
+        } else {
+            Message::MergeFrom(other);
+        }
+    }
+
+    virtual void MergeFrom(const T&) = 0;
+
+#if GOOGLE_PROTOBUF_VERSION > 3019000 && GOOGLE_PROTOBUF_VERSION < 5026000
+    // Unsupported by default.
+    std::string InitializationErrorString() const override {
+        return "unknown error";
+    }
+#endif
+
+#if GOOGLE_PROTOBUF_VERSION < 3019000
+    // Unsupported by default.
+    void DiscardUnknownFields() override {}
+#endif
+
+#if GOOGLE_PROTOBUF_VERSION < 5026000
+    // Unsupported by default.
+    size_t SpaceUsedLong() const override {
+        return 0;
+    }
+#endif
+
+    // Unsupported by default.
+    ::std::string GetTypeName() const PB_526_OVERRIDE {
+        return {};
+    }
+
+    void Clear() override {}
+
+#if GOOGLE_PROTOBUF_VERSION < 3010000
+    bool 
MergePartialFromCodedStream(::google::protobuf::io::CodedInputStream*) override 
{
+        return true;
+    }
+#endif
+
+    // Quickly check if all required fields have values set.
+    // Unsupported by default.
+    bool IsInitialized() const PB_527_OVERRIDE {
+        return true;
+    }
+
+#if GOOGLE_PROTOBUF_VERSION >= 3010000 && GOOGLE_PROTOBUF_VERSION <= 5026000
+    const char* _InternalParse(
+            const char* ptr, ::google::protobuf::internal::ParseContext*) 
override {
+        return ptr;
+    }
+#endif
+
+    // Size of bytes after serialization.
+    size_t ByteSizeLong() const override {
+        return 0;
+    }
+
+#if GOOGLE_PROTOBUF_VERSION >= 3007000 && GOOGLE_PROTOBUF_VERSION < 3010000
+    void SerializeWithCachedSizes(::google::protobuf::io::CodedOutputStream*) 
const override {}
+#endif
+
+#if GOOGLE_PROTOBUF_VERSION >= 3010000 && GOOGLE_PROTOBUF_VERSION < 3011000
+    uint8_t* InternalSerializeWithCachedSizesToArray(
+            uint8_t* ptr, ::google::protobuf::io::EpsCopyOutputStream*) const 
override {
+        return ptr;
+    }
+#endif
+
+#if GOOGLE_PROTOBUF_VERSION >= 3011000
+    uint8_t* _InternalSerialize(
+            uint8_t* ptr, ::google::protobuf::io::EpsCopyOutputStream*) const 
override {
+        return ptr;
+    }
+#endif
+
+#if GOOGLE_PROTOBUF_VERSION < 4025000
+    // Unnecessary for Nonreflectable message.
+    int GetCachedSize() const override {
+        return 0;
+    }
+#endif
+
+#if GOOGLE_PROTOBUF_VERSION < 4025000
+    // Unnecessary for Nonreflectable message.
+    void SetCachedSize(int) const override {}
+#endif
+
+public:
+    // Only can be used to determine whether the Types are the same.
+    ::google::protobuf::Metadata GetMetadata() const PB_527_OVERRIDE {
+        ::google::protobuf::Metadata metadata{};
+        // can only be used to
+        metadata.descriptor = reinterpret_cast<const 
::google::protobuf::Descriptor*>(&_instance);
+        metadata.reflection = reinterpret_cast<const 
::google::protobuf::Reflection*>(&_instance);
+        return metadata;
+    }
+
+    // Only can be used to determine whether the Types are the same.
+    inline static const ::google::protobuf::Descriptor* descriptor() noexcept {
+        return default_instance().GetMetadata().descriptor;
+    }
+
+    inline static const T& default_instance() noexcept {
+        return _instance;
+    }
+
+private:
+    static T _instance;
+};
+
+template <typename T>
+T NonreflectableMessage<T>::_instance;
+
+} // namespace brpc
+
+#endif // BRPC_NONREFLECTABLE_MESSAGE_H
diff --git a/src/brpc/nshead_message.cpp b/src/brpc/nshead_message.cpp
index f991604a..fe9e4c96 100644
--- a/src/brpc/nshead_message.cpp
+++ b/src/brpc/nshead_message.cpp
@@ -15,22 +15,20 @@
 // specific language governing permissions and limitations
 // under the License.
 
-
-#include <algorithm>
-#include <google/protobuf/reflection_ops.h>                 // 
ReflectionOps::Merge
-#include <google/protobuf/wire_format.h>
 #include "brpc/nshead_message.h"
+
+#include "brpc/proto_base.pb.h"
 #include "butil/logging.h"
 
 namespace brpc {
 
 NsheadMessage::NsheadMessage()
-    : ::google::protobuf::Message() {
+    : NonreflectableMessage<NsheadMessage>() {
     SharedCtor();
 }
 
 NsheadMessage::NsheadMessage(const NsheadMessage& from)
-    : ::google::protobuf::Message() {
+    : NonreflectableMessage<NsheadMessage>() {
     SharedCtor();
     MergeFrom(from);
 }
@@ -46,49 +44,12 @@ NsheadMessage::~NsheadMessage() {
 void NsheadMessage::SharedDtor() {
 }
 
-const ::google::protobuf::Descriptor* NsheadMessage::descriptor() {
-    return NsheadMessageBase::descriptor();
-}
-
-NsheadMessage* NsheadMessage::New() const {
-    return new NsheadMessage;
-}
-
-#if GOOGLE_PROTOBUF_VERSION >= 3006000
-NsheadMessage* NsheadMessage::New(::google::protobuf::Arena* arena) const {
-    return CreateMaybeMessage<NsheadMessage>(arena);
-}
-#endif
-
 void NsheadMessage::Clear() {
     memset(&head, 0, sizeof(head));
     body.clear();
 }
 
-bool NsheadMessage::MergePartialFromCodedStream(
-    ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
-    ::google::protobuf::uint32 tag;
-    while ((tag = input->ReadTag()) != 0) {
-        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) 
==
-            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
-            return true;
-        }
-    }
-    return true;
-#undef DO_
-}
-
-void NsheadMessage::SerializeWithCachedSizes(
-    ::google::protobuf::io::CodedOutputStream*) const {
-}
-
-::google::protobuf::uint8* NsheadMessage::SerializeWithCachedSizesToArray(
-    ::google::protobuf::uint8* target) const {
-    return target;
-}
-
-int NsheadMessage::ByteSize() const {
+size_t NsheadMessage::ByteSizeLong() const {
     return sizeof(nshead_t) + body.size();
 }
 
@@ -110,22 +71,6 @@ void NsheadMessage::MergeFrom(const NsheadMessage& from) {
     body = from.body;
 }
 
-void NsheadMessage::CopyFrom(const ::google::protobuf::Message& from) {
-    if (&from == this) return;
-    Clear();
-    MergeFrom(from);
-}
-
-void NsheadMessage::CopyFrom(const NsheadMessage& from) {
-    if (&from == this) return;
-    Clear();
-    MergeFrom(from);
-}
-
-bool NsheadMessage::IsInitialized() const {
-    return true;
-}
-
 void NsheadMessage::Swap(NsheadMessage* other) {
     if (other != this) {
         const nshead_t tmp = other->head;
@@ -136,9 +81,9 @@ void NsheadMessage::Swap(NsheadMessage* other) {
 }
 
 ::google::protobuf::Metadata NsheadMessage::GetMetadata() const {
-    ::google::protobuf::Metadata metadata;
-    metadata.descriptor = NsheadMessage::descriptor();
-    metadata.reflection = NULL;
+    ::google::protobuf::Metadata metadata{};
+    metadata.descriptor = NsheadMessageBase::descriptor();
+    metadata.reflection = nullptr;
     return metadata;
 }
 
diff --git a/src/brpc/nshead_message.h b/src/brpc/nshead_message.h
index 6cd06caf..6b48c7aa 100644
--- a/src/brpc/nshead_message.h
+++ b/src/brpc/nshead_message.h
@@ -19,58 +19,41 @@
 #ifndef BRPC_NSHEAD_MESSAGE_H
 #define BRPC_NSHEAD_MESSAGE_H
 
-#include <google/protobuf/message.h>
-#include "brpc/nshead.h"                     // nshead_t
-#include "butil/iobuf.h"                     // IOBuf
-#include "brpc/proto_base.pb.h"
+#include "brpc/nonreflectable_message.h"
+#include "brpc/nshead.h" // nshead_t
 #include "brpc/pb_compat.h"
+#include "butil/iobuf.h" // IOBuf
 
 namespace brpc {
 
 // Representing a nshead request or response.
-class NsheadMessage : public ::google::protobuf::Message {
+class NsheadMessage : public NonreflectableMessage<NsheadMessage> {
 public:
     nshead_t head;
     butil::IOBuf body;
     
 public:
     NsheadMessage();
-    virtual ~NsheadMessage();
-  
+    ~NsheadMessage() override;
+
     NsheadMessage(const NsheadMessage& from);
-  
+
     inline NsheadMessage& operator=(const NsheadMessage& from) {
         CopyFrom(from);
         return *this;
     }
-  
-    static const ::google::protobuf::Descriptor* descriptor();
-  
+
     void Swap(NsheadMessage* other);
-  
+
     // implements Message ----------------------------------------------
-  
-    NsheadMessage* New() const PB_319_OVERRIDE;
-#if GOOGLE_PROTOBUF_VERSION >= 3006000
-    NsheadMessage* New(::google::protobuf::Arena* arena) const override;
-#endif
-    void CopyFrom(const ::google::protobuf::Message& from) PB_321_OVERRIDE;
-    void MergeFrom(const ::google::protobuf::Message& from) override;
-    void CopyFrom(const NsheadMessage& from);
-    void MergeFrom(const NsheadMessage& from);
+    void MergeFrom(const ::google::protobuf::Message& from) PB_526_OVERRIDE;
+    void MergeFrom(const NsheadMessage& from) override;
     void Clear() override;
-    bool IsInitialized() const override;
-  
-    int ByteSize() const;
-    bool MergePartialFromCodedStream(
-        ::google::protobuf::io::CodedInputStream* input) PB_310_OVERRIDE;
-    void SerializeWithCachedSizes(
-        ::google::protobuf::io::CodedOutputStream* output) const 
PB_310_OVERRIDE;
-    ::google::protobuf::uint8* 
SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const 
PB_310_OVERRIDE;
-    int GetCachedSize() const PB_422_OVERRIDE { return ByteSize(); }
 
-protected:
-    ::google::protobuf::Metadata GetMetadata() const override;
+    size_t ByteSizeLong() const override;
+    int GetCachedSize() const PB_425_OVERRIDE { return ByteSize(); }
+
+    ::google::protobuf::Metadata GetMetadata() const PB_527_OVERRIDE;
 
 private:
     void SharedCtor();
diff --git a/src/brpc/pb_compat.h b/src/brpc/pb_compat.h
index d089530f..68874c1b 100644
--- a/src/brpc/pb_compat.h
+++ b/src/brpc/pb_compat.h
@@ -19,22 +19,28 @@
 #ifndef BRPC_PB_COMPAT_H
 #define BRPC_PB_COMPAT_H
 
-#if GOOGLE_PROTOBUF_VERSION < 4022000
-# define PB_422_OVERRIDE override
+#if GOOGLE_PROTOBUF_VERSION < 5027000
+# define PB_527_OVERRIDE override
 #else
-# define PB_422_OVERRIDE
+# define PB_527_OVERRIDE
 #endif
 
-#if GOOGLE_PROTOBUF_VERSION < 3021000
-# define PB_321_OVERRIDE override
+#if GOOGLE_PROTOBUF_VERSION < 5026000
+# define PB_526_OVERRIDE override
 #else
-# define PB_321_OVERRIDE
+# define PB_526_OVERRIDE
 #endif
 
-#if GOOGLE_PROTOBUF_VERSION < 3019000
-# define PB_319_OVERRIDE override
+#if GOOGLE_PROTOBUF_VERSION < 4025000
+# define PB_425_OVERRIDE override
 #else
-# define PB_319_OVERRIDE
+# define PB_425_OVERRIDE
+#endif
+
+#if GOOGLE_PROTOBUF_VERSION < 3021000
+# define PB_321_OVERRIDE override
+#else
+# define PB_321_OVERRIDE
 #endif
 
 #if GOOGLE_PROTOBUF_VERSION < 3010000
diff --git a/src/brpc/redis.cpp b/src/brpc/redis.cpp
index 07313610..777e1999 100644
--- a/src/brpc/redis.cpp
+++ b/src/brpc/redis.cpp
@@ -15,25 +15,27 @@
 // specific language governing permissions and limitations
 // under the License.
 
+#include "brpc/redis.h"
 
-#include <google/protobuf/reflection_ops.h>     // ReflectionOps::Merge
 #include <gflags/gflags.h>
-#include "butil/status.h"
-#include "butil/strings/string_util.h"          // StringToLowerASCII
-#include "brpc/redis.h"
+#include <google/protobuf/reflection_ops.h> // ReflectionOps::Merge
+
 #include "brpc/redis_command.h"
+#include "brpc/proto_base.pb.h"
+#include "butil/status.h"
+#include "butil/strings/string_util.h" // StringToLowerASCII
 
 namespace brpc {
 
 DEFINE_bool(redis_verbose_crlf2space, false, "[DEBUG] Show \\r\\n as a space");
 
 RedisRequest::RedisRequest()
-    : ::google::protobuf::Message() {
+    : NonreflectableMessage<RedisRequest>() {
     SharedCtor();
 }
 
 RedisRequest::RedisRequest(const RedisRequest& from)
-    : ::google::protobuf::Message() {
+    : NonreflectableMessage<RedisRequest>() {
     SharedCtor();
     MergeFrom(from);
 }
@@ -55,54 +57,18 @@ void RedisRequest::SetCachedSize(int size) const {
     _cached_size_ = size;
 }
 
-RedisRequest* RedisRequest::New() const {
-    return new RedisRequest;
-}
-
-#if GOOGLE_PROTOBUF_VERSION >= 3006000
-RedisRequest* RedisRequest::New(::google::protobuf::Arena* arena) const {
-    return CreateMaybeMessage<RedisRequest>(arena);
-}
-#endif
-
 void RedisRequest::Clear() {
     _ncommand = 0;
     _has_error = false;
     _buf.clear();
 }
 
-bool RedisRequest::MergePartialFromCodedStream(
-    ::google::protobuf::io::CodedInputStream*) {
-    LOG(WARNING) << "You're not supposed to parse a RedisRequest";
-    return true;
-}
-
-void RedisRequest::SerializeWithCachedSizes(
-    ::google::protobuf::io::CodedOutputStream*) const {
-    LOG(WARNING) << "You're not supposed to serialize a RedisRequest";
-}
-
-::google::protobuf::uint8* RedisRequest::SerializeWithCachedSizesToArray(
-    ::google::protobuf::uint8* target) const {
-    return target;
-}
-
-int RedisRequest::ByteSize() const {
-    int total_size =  _buf.size();
+size_t RedisRequest::ByteSizeLong() const {
+    int total_size =  static_cast<int>(_buf.size());
     _cached_size_ = total_size;
     return total_size;
 }
 
-void RedisRequest::MergeFrom(const ::google::protobuf::Message& from) {
-    CHECK_NE(&from, this);
-    const RedisRequest* source = dynamic_cast<const RedisRequest*>(&from);
-    if (source == NULL) {
-        ::google::protobuf::internal::ReflectionOps::Merge(from, this);
-    } else {
-        MergeFrom(*source);
-    }
-}
-
 void RedisRequest::MergeFrom(const RedisRequest& from) {
     CHECK_NE(&from, this);
     _has_error = _has_error || from._has_error;
@@ -110,18 +76,6 @@ void RedisRequest::MergeFrom(const RedisRequest& from) {
     _ncommand += from._ncommand;
 }
 
-void RedisRequest::CopyFrom(const ::google::protobuf::Message& from) {
-    if (&from == this) return;
-    Clear();
-    MergeFrom(from);
-}
-
-void RedisRequest::CopyFrom(const RedisRequest& from) {
-    if (&from == this) return;
-    Clear();
-    MergeFrom(from);
-}
-
 bool RedisRequest::IsInitialized() const {
     return _ncommand != 0;
 }
@@ -208,14 +162,10 @@ bool RedisRequest::SerializeTo(butil::IOBuf* buf) const {
     return true;
 }
 
-const ::google::protobuf::Descriptor* RedisRequest::descriptor() {
-    return RedisRequestBase::descriptor();
-}
-
 ::google::protobuf::Metadata RedisRequest::GetMetadata() const {
-    ::google::protobuf::Metadata metadata;
-    metadata.descriptor = RedisRequest::descriptor();
-    metadata.reflection = NULL;
+    ::google::protobuf::Metadata metadata{};
+    metadata.descriptor = RedisRequestBase::descriptor();
+    metadata.reflection = nullptr;
     return metadata;
 }
 
@@ -245,12 +195,12 @@ std::ostream& operator<<(std::ostream& os, const 
RedisRequest& r) {
 }
 
 RedisResponse::RedisResponse()
-    : ::google::protobuf::Message()
+    : NonreflectableMessage<RedisResponse>()
     , _first_reply(&_arena) {
     SharedCtor();
 }
 RedisResponse::RedisResponse(const RedisResponse& from)
-    : ::google::protobuf::Message()
+    : NonreflectableMessage<RedisResponse>()
     , _first_reply(&_arena) {
     SharedCtor();
     MergeFrom(from);
@@ -273,16 +223,6 @@ void RedisResponse::SetCachedSize(int size) const {
     _cached_size_ = size;
 }
 
-RedisResponse* RedisResponse::New() const {
-    return new RedisResponse;
-}
-
-#if GOOGLE_PROTOBUF_VERSION >= 3006000
-RedisResponse* RedisResponse::New(::google::protobuf::Arena* arena) const {
-    return CreateMaybeMessage<RedisResponse>(arena);
-}
-#endif
-
 void RedisResponse::Clear() {
     _first_reply.Reset();
     _other_replies = NULL;
@@ -291,36 +231,10 @@ void RedisResponse::Clear() {
     _cached_size_ = 0;
 }
 
-bool RedisResponse::MergePartialFromCodedStream(
-    ::google::protobuf::io::CodedInputStream*) {
-    LOG(WARNING) << "You're not supposed to parse a RedisResponse";
-    return true;
-}
-
-void RedisResponse::SerializeWithCachedSizes(
-    ::google::protobuf::io::CodedOutputStream*) const {
-    LOG(WARNING) << "You're not supposed to serialize a RedisResponse";
-}
-
-::google::protobuf::uint8* RedisResponse::SerializeWithCachedSizesToArray(
-    ::google::protobuf::uint8* target) const {
-    return target;
-}
-
-int RedisResponse::ByteSize() const {
+size_t RedisResponse::ByteSizeLong() const {
     return _cached_size_;
 }
 
-void RedisResponse::MergeFrom(const ::google::protobuf::Message& from) {
-    CHECK_NE(&from, this);
-    const RedisResponse* source = dynamic_cast<const RedisResponse*>(&from);
-    if (source == NULL) {
-        ::google::protobuf::internal::ReflectionOps::Merge(from, this);
-    } else {
-        MergeFrom(*source);
-    }
-}
-
 void RedisResponse::MergeFrom(const RedisResponse& from) {
     CHECK_NE(&from, this);
     if (from._nreply == 0) {
@@ -353,18 +267,6 @@ void RedisResponse::MergeFrom(const RedisResponse& from) {
     _nreply = new_nreply;
 }
 
-void RedisResponse::CopyFrom(const ::google::protobuf::Message& from) {
-    if (&from == this) return;
-    Clear();
-    MergeFrom(from);
-}
-
-void RedisResponse::CopyFrom(const RedisResponse& from) {
-    if (&from == this) return;
-    Clear();
-    MergeFrom(from);
-}
-
 bool RedisResponse::IsInitialized() const {
     return reply_size() > 0;
 }
@@ -379,14 +281,10 @@ void RedisResponse::Swap(RedisResponse* other) {
     }
 }
 
-const ::google::protobuf::Descriptor* RedisResponse::descriptor() {
-    return RedisResponseBase::descriptor();
-}
-
 ::google::protobuf::Metadata RedisResponse::GetMetadata() const {
-    ::google::protobuf::Metadata metadata;
-    metadata.descriptor = RedisResponse::descriptor();
-    metadata.reflection = NULL;
+    ::google::protobuf::Metadata metadata{};
+    metadata.descriptor = RedisResponseBase::descriptor();
+    metadata.reflection = nullptr;
     return metadata;
 }
 
diff --git a/src/brpc/redis.h b/src/brpc/redis.h
index 6b949ea4..c6b0ea21 100644
--- a/src/brpc/redis.h
+++ b/src/brpc/redis.h
@@ -19,19 +19,15 @@
 #ifndef BRPC_REDIS_H
 #define BRPC_REDIS_H
 
-#include <google/protobuf/message.h>
 #include <unordered_map>
-#include <memory>
-#include <list>
-#include "butil/iobuf.h"
-#include "butil/strings/string_piece.h"
-#include "butil/arena.h"
-#include "brpc/proto_base.pb.h"
-#include "brpc/redis_reply.h"
+
+#include "brpc/nonreflectable_message.h"
 #include "brpc/parse_result.h"
-#include "brpc/callback.h"
-#include "brpc/socket.h"
 #include "brpc/pb_compat.h"
+#include "brpc/redis_reply.h"
+#include "butil/arena.h"
+#include "butil/iobuf.h"
+#include "butil/strings/string_piece.h"
 
 namespace brpc {
 
@@ -46,10 +42,10 @@ namespace brpc {
 //   if (!cntl.Failed()) {
 //       LOG(INFO) << response.reply(0);
 //   }
-class RedisRequest : public ::google::protobuf::Message {
+class RedisRequest : public NonreflectableMessage<RedisRequest> {
 public:
     RedisRequest();
-    virtual ~RedisRequest();
+    ~RedisRequest() override;
     RedisRequest(const RedisRequest& from);
     inline RedisRequest& operator=(const RedisRequest& from) {
         CopyFrom(from);
@@ -68,28 +64,28 @@ public:
     //   butil::StringPiece components[] = { "set", "key", "value" };
     //   request.AddCommandByComponents(components, arraysize(components));
     bool AddCommandByComponents(const butil::StringPiece* components, size_t 
n);
-    
+
     // Add a command with variadic args to this request.
     // The reason that adding so many overloads rather than using ... is that
     // it's the only way to dispatch the AddCommand w/o args differently.
     bool AddCommand(const butil::StringPiece& command);
-    
+
     template <typename A1>
     bool AddCommand(const char* format, A1 a1)
     { return AddCommandWithArgs(format, a1); }
-    
+
     template <typename A1, typename A2>
     bool AddCommand(const char* format, A1 a1, A2 a2)
     { return AddCommandWithArgs(format, a1, a2); }
-    
+
     template <typename A1, typename A2, typename A3>
     bool AddCommand(const char* format, A1 a1, A2 a2, A3 a3)
     { return AddCommandWithArgs(format, a1, a2, a3); }
-    
+
     template <typename A1, typename A2, typename A3, typename A4>
     bool AddCommand(const char* format, A1 a1, A2 a2, A3 a3, A4 a4)
     { return AddCommandWithArgs(format, a1, a2, a3, a4); }
-    
+
     template <typename A1, typename A2, typename A3, typename A4, typename A5>
     bool AddCommand(const char* format, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
     { return AddCommandWithArgs(format, a1, a2, a3, a4, a5); }
@@ -108,36 +104,21 @@ public:
     bool SerializeTo(butil::IOBuf* buf) const;
 
     // Protobuf methods.
-    RedisRequest* New() const PB_319_OVERRIDE;
-#if GOOGLE_PROTOBUF_VERSION >= 3006000
-    RedisRequest* New(::google::protobuf::Arena* arena) const override;
-#endif
-    void CopyFrom(const ::google::protobuf::Message& from) PB_321_OVERRIDE;
-    void MergeFrom(const ::google::protobuf::Message& from) override;
-    void CopyFrom(const RedisRequest& from);
-    void MergeFrom(const RedisRequest& from);
+    void MergeFrom(const RedisRequest& from) override;
     void Clear() override;
-    bool IsInitialized() const override;
-  
-    int ByteSize() const;
-    bool MergePartialFromCodedStream(
-        ::google::protobuf::io::CodedInputStream* input) PB_310_OVERRIDE;
-    void SerializeWithCachedSizes(
-        ::google::protobuf::io::CodedOutputStream* output) const 
PB_310_OVERRIDE;
-    ::google::protobuf::uint8* 
SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const 
PB_310_OVERRIDE;
-    int GetCachedSize() const PB_422_OVERRIDE { return _cached_size_; }
-
-    static const ::google::protobuf::Descriptor* descriptor();
-    
+    bool IsInitialized() const PB_527_OVERRIDE;
+
+    size_t ByteSizeLong() const override;
+    int GetCachedSize() const PB_425_OVERRIDE { return _cached_size_; }
+
     void Print(std::ostream&) const;
 
-protected:
-    ::google::protobuf::Metadata GetMetadata() const override;
+    ::google::protobuf::Metadata GetMetadata() const PB_527_OVERRIDE;
 
 private:
     void SharedCtor();
     void SharedDtor();
-    void SetCachedSize(int size) const PB_422_OVERRIDE;
+    void SetCachedSize(int size) const PB_425_OVERRIDE;
     bool AddCommandWithArgs(const char* fmt, ...);
 
     int _ncommand;    // # of valid commands
@@ -149,10 +130,10 @@ private:
 // Response from Redis.
 // Notice that a RedisResponse instance may contain multiple replies
 // due to pipelining.
-class RedisResponse : public ::google::protobuf::Message {
+class RedisResponse : public NonreflectableMessage<RedisResponse> {
 public:
     RedisResponse();
-    virtual ~RedisResponse();
+    ~RedisResponse() override;
     RedisResponse(const RedisResponse& from);
     inline RedisResponse& operator=(const RedisResponse& from) {
         CopyFrom(from);
@@ -180,35 +161,19 @@ public:
     ParseError ConsumePartialIOBuf(butil::IOBuf& buf, int reply_count);
     
     // implements Message ----------------------------------------------
-  
-    RedisResponse* New() const PB_319_OVERRIDE;
-#if GOOGLE_PROTOBUF_VERSION >= 3006000
-    RedisResponse* New(::google::protobuf::Arena* arena) const override;
-#endif
-    void CopyFrom(const ::google::protobuf::Message& from) PB_321_OVERRIDE;
-    void MergeFrom(const ::google::protobuf::Message& from) override;
-    void CopyFrom(const RedisResponse& from);
-    void MergeFrom(const RedisResponse& from);
+    void MergeFrom(const RedisResponse& from) override;
     void Clear() override;
-    bool IsInitialized() const override;
+    bool IsInitialized() const PB_527_OVERRIDE;
   
-    int ByteSize() const;
-    bool MergePartialFromCodedStream(
-        ::google::protobuf::io::CodedInputStream* input) PB_310_OVERRIDE;
-    void SerializeWithCachedSizes(
-        ::google::protobuf::io::CodedOutputStream* output) const 
PB_310_OVERRIDE;
-    ::google::protobuf::uint8* 
SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const 
PB_310_OVERRIDE;
-    int GetCachedSize() const PB_422_OVERRIDE { return _cached_size_; }
-
-    static const ::google::protobuf::Descriptor* descriptor();
+    size_t ByteSizeLong() const override;
+    int GetCachedSize() const PB_425_OVERRIDE { return _cached_size_; }
 
-protected:
-    ::google::protobuf::Metadata GetMetadata() const override;
+    ::google::protobuf::Metadata GetMetadata() const PB_527_OVERRIDE;
 
 private:
     void SharedCtor();
     void SharedDtor();
-    void SetCachedSize(int size) const PB_422_OVERRIDE;
+    void SetCachedSize(int size) const PB_425_OVERRIDE;
 
     RedisReply _first_reply;
     RedisReply* _other_replies;
diff --git a/src/brpc/serialized_request.cpp b/src/brpc/serialized_request.cpp
index 33082883..f4cabad2 100644
--- a/src/brpc/serialized_request.cpp
+++ b/src/brpc/serialized_request.cpp
@@ -15,19 +15,20 @@
 // specific language governing permissions and limitations
 // under the License.
 
-
 #include "brpc/serialized_request.h"
+
+#include "brpc/proto_base.pb.h"
 #include "butil/logging.h"
 
 namespace brpc {
 
 SerializedRequest::SerializedRequest()
-    : ::google::protobuf::Message() {
+    : NonreflectableMessage<SerializedRequest>() {
     SharedCtor();
 }
 
 SerializedRequest::SerializedRequest(const SerializedRequest& from)
-    : ::google::protobuf::Message() {
+    : NonreflectableMessage<SerializedRequest>() {
     SharedCtor();
     MergeFrom(from);
 }
@@ -42,77 +43,19 @@ SerializedRequest::~SerializedRequest() {
 void SerializedRequest::SharedDtor() {
 }
 
-void SerializedRequest::SetCachedSize(int /*size*/) const {
-    CHECK(false) << "You're not supposed to call " << __func__;
-}
-const ::google::protobuf::Descriptor* SerializedRequest::descriptor() {
-    return SerializedRequestBase::descriptor();
-}
-
-SerializedRequest* SerializedRequest::New() const {
-    return new SerializedRequest;
-}
-
-#if GOOGLE_PROTOBUF_VERSION >= 3006000
-SerializedRequest*
-SerializedRequest::New(::google::protobuf::Arena* arena) const {
-    return CreateMaybeMessage<SerializedRequest>(arena);
-}
-#endif
-
 void SerializedRequest::Clear() {
     _serialized.clear();
 }
 
-bool SerializedRequest::MergePartialFromCodedStream(
-    ::google::protobuf::io::CodedInputStream*) {
-    CHECK(false) << "You're not supposed to call " << __FUNCTION__;
-    return false;
-}
-
-void SerializedRequest::SerializeWithCachedSizes(
-    ::google::protobuf::io::CodedOutputStream*) const {
-    CHECK(false) << "You're not supposed to call " << __FUNCTION__;
-}
-
-::google::protobuf::uint8* SerializedRequest::SerializeWithCachedSizesToArray(
-    ::google::protobuf::uint8* target) const {
-    CHECK(false) << "You're not supposed to call " << __FUNCTION__;
-    return target;
-}
-
-int SerializedRequest::ByteSize() const {
-    return (int)_serialized.size();
-}
-
-void SerializedRequest::MergeFrom(const ::google::protobuf::Message&) {
-    CHECK(false) << "You're not supposed to call " << __FUNCTION__;
-}
-
-void SerializedRequest::MergeFrom(const SerializedRequest&) {
-    CHECK(false) << "You're not supposed to call " << __FUNCTION__;
-}
-
-void SerializedRequest::CopyFrom(const ::google::protobuf::Message& from) {
-    if (&from == this) return;
-    const SerializedRequest* source = dynamic_cast<const 
SerializedRequest*>(&from);
-    if (source == NULL) {
-        CHECK(false) << "SerializedRequest can only CopyFrom 
SerializedRequest";
-    } else {
-        _serialized = source->_serialized;
-    }
+size_t SerializedRequest::ByteSizeLong() const {
+    return _serialized.size();
 }
 
-void SerializedRequest::CopyFrom(const SerializedRequest& from) {
-    if (&from == this) return;
+void SerializedRequest::MergeFrom(const SerializedRequest& from) {
+    CHECK_NE(&from, this);
     _serialized = from._serialized;
 }
 
-bool SerializedRequest::IsInitialized() const {
-    // Always true because it's already serialized.
-    return true;
-}
-
 void SerializedRequest::Swap(SerializedRequest* other) {
     if (other != this) {
         _serialized.swap(other->_serialized);
@@ -120,9 +63,9 @@ void SerializedRequest::Swap(SerializedRequest* other) {
 }
 
 ::google::protobuf::Metadata SerializedRequest::GetMetadata() const {
-    ::google::protobuf::Metadata metadata;
-    metadata.descriptor = SerializedRequest::descriptor();
-    metadata.reflection = NULL;
+    ::google::protobuf::Metadata metadata{};
+    metadata.descriptor = SerializedRequestBase::descriptor();
+    metadata.reflection = nullptr;
     return metadata;
 }
 
diff --git a/src/brpc/serialized_request.h b/src/brpc/serialized_request.h
index 5b68262e..00d959f3 100644
--- a/src/brpc/serialized_request.h
+++ b/src/brpc/serialized_request.h
@@ -19,65 +19,45 @@
 #ifndef BRPC_SERIALIZED_REQUEST_H
 #define BRPC_SERIALIZED_REQUEST_H
 
-#include <google/protobuf/message.h>
-#include "butil/iobuf.h"
-#include "brpc/proto_base.pb.h"
+#include "brpc/nonreflectable_message.h"
 #include "brpc/pb_compat.h"
+#include "butil/iobuf.h"
 
 namespace brpc {
 
-class SerializedRequest : public ::google::protobuf::Message {
+class SerializedRequest : public NonreflectableMessage<SerializedRequest> {
 public:
     SerializedRequest();
-    virtual ~SerializedRequest();
-  
+    ~SerializedRequest() override;
+
     SerializedRequest(const SerializedRequest& from);
-  
+
     inline SerializedRequest& operator=(const SerializedRequest& from) {
         CopyFrom(from);
         return *this;
     }
-  
-    static const ::google::protobuf::Descriptor* descriptor();
-  
+
     void Swap(SerializedRequest* other);
-  
+
+    void MergeFrom(const SerializedRequest& from) override;
+
     // implements Message ----------------------------------------------
-  
-    SerializedRequest* New() const PB_319_OVERRIDE;
-#if GOOGLE_PROTOBUF_VERSION >= 3006000
-    SerializedRequest* New(::google::protobuf::Arena* arena) const override;
-#endif
-    void CopyFrom(const ::google::protobuf::Message& from) PB_321_OVERRIDE;
-    void CopyFrom(const SerializedRequest& from);
     void Clear() override;
-    bool IsInitialized() const override;
-    int ByteSize() const;
-    int GetCachedSize() const PB_422_OVERRIDE { return 
(int)_serialized.size(); }
+    size_t ByteSizeLong() const override;
+    int GetCachedSize() const PB_425_OVERRIDE { return ByteSize(); }
     butil::IOBuf& serialized_data() { return _serialized; }
     const butil::IOBuf& serialized_data() const { return _serialized; }
 
-protected:
-    ::google::protobuf::Metadata GetMetadata() const override;
-    
+    ::google::protobuf::Metadata GetMetadata() const PB_527_OVERRIDE;
+
 private:
-    bool MergePartialFromCodedStream(
-        ::google::protobuf::io::CodedInputStream* input) PB_310_OVERRIDE;
-    void SerializeWithCachedSizes(
-        ::google::protobuf::io::CodedOutputStream* output) const 
PB_310_OVERRIDE;
-    ::google::protobuf::uint8* SerializeWithCachedSizesToArray(
-        ::google::protobuf::uint8* output) const PB_310_OVERRIDE;
-    void MergeFrom(const ::google::protobuf::Message& from) override;
-    void MergeFrom(const SerializedRequest& from);
     void SharedCtor();
     void SharedDtor();
-    void SetCachedSize(int size) const PB_422_OVERRIDE;
-  
+
 private:
     butil::IOBuf _serialized;
 };
 
 } // namespace brpc
 
-
 #endif  // BRPC_SERIALIZED_REQUEST_H
diff --git a/src/brpc/serialized_response.cpp b/src/brpc/serialized_response.cpp
index 817ccb4c..6d5d8fef 100644
--- a/src/brpc/serialized_response.cpp
+++ b/src/brpc/serialized_response.cpp
@@ -15,19 +15,20 @@
 // specific language governing permissions and limitations
 // under the License.
 
-
 #include "brpc/serialized_response.h"
+
+#include "brpc/proto_base.pb.h"
 #include "butil/logging.h"
 
 namespace brpc {
 
 SerializedResponse::SerializedResponse()
-    : ::google::protobuf::Message() {
+    : NonreflectableMessage<SerializedResponse>() {
     SharedCtor();
 }
 
 SerializedResponse::SerializedResponse(const SerializedResponse& from)
-    : ::google::protobuf::Message() {
+    : NonreflectableMessage<SerializedResponse>() {
     SharedCtor();
     MergeFrom(from);
 }
@@ -42,77 +43,19 @@ SerializedResponse::~SerializedResponse() {
 void SerializedResponse::SharedDtor() {
 }
 
-void SerializedResponse::SetCachedSize(int /*size*/) const {
-    CHECK(false) << "You're not supposed to call " << __func__;
-}
-const ::google::protobuf::Descriptor* SerializedResponse::descriptor() {
-    return SerializedResponseBase::descriptor();
-}
-
-SerializedResponse* SerializedResponse::New() const {
-    return new SerializedResponse;
-}
-
-#if GOOGLE_PROTOBUF_VERSION >= 3006000
-SerializedResponse*
-SerializedResponse::New(::google::protobuf::Arena* arena) const {
-    return CreateMaybeMessage<SerializedResponse>(arena);
-}
-#endif
-
 void SerializedResponse::Clear() {
     _serialized.clear();
 }
 
-bool SerializedResponse::MergePartialFromCodedStream(
-    ::google::protobuf::io::CodedInputStream*) {
-    CHECK(false) << "You're not supposed to call " << __FUNCTION__;
-    return false;
-}
-
-void SerializedResponse::SerializeWithCachedSizes(
-    ::google::protobuf::io::CodedOutputStream*) const {
-    CHECK(false) << "You're not supposed to call " << __FUNCTION__;
-}
-
-::google::protobuf::uint8* SerializedResponse::SerializeWithCachedSizesToArray(
-    ::google::protobuf::uint8* target) const {
-    CHECK(false) << "You're not supposed to call " << __FUNCTION__;
-    return target;
-}
-
-int SerializedResponse::ByteSize() const {
-    return (int)_serialized.size();
-}
-
-void SerializedResponse::MergeFrom(const ::google::protobuf::Message&) {
-    CHECK(false) << "You're not supposed to call " << __FUNCTION__;
-}
-
-void SerializedResponse::MergeFrom(const SerializedResponse&) {
-    CHECK(false) << "You're not supposed to call " << __FUNCTION__;
-}
-
-void SerializedResponse::CopyFrom(const ::google::protobuf::Message& from) {
-    if (&from == this) return;
-    const SerializedResponse* source = dynamic_cast<const 
SerializedResponse*>(&from);
-    if (source == NULL) {
-        CHECK(false) << "SerializedResponse can only CopyFrom 
SerializedResponse";
-    } else {
-        _serialized = source->_serialized;
-    }
+size_t SerializedResponse::ByteSizeLong() const {
+    return _serialized.size();
 }
 
-void SerializedResponse::CopyFrom(const SerializedResponse& from) {
-    if (&from == this) return;
+void SerializedResponse::MergeFrom(const SerializedResponse& from) {
+    CHECK_NE(&from, this);
     _serialized = from._serialized;
 }
 
-bool SerializedResponse::IsInitialized() const {
-    // Always true because it's already serialized.
-    return true;
-}
-
 void SerializedResponse::Swap(SerializedResponse* other) {
     if (other != this) {
         _serialized.swap(other->_serialized);
@@ -120,9 +63,9 @@ void SerializedResponse::Swap(SerializedResponse* other) {
 }
 
 ::google::protobuf::Metadata SerializedResponse::GetMetadata() const {
-    ::google::protobuf::Metadata metadata;
-    metadata.descriptor = SerializedResponse::descriptor();
-    metadata.reflection = NULL;
+    ::google::protobuf::Metadata metadata{};
+    metadata.descriptor = SerializedResponseBase::descriptor();
+    metadata.reflection = nullptr;
     return metadata;
 }
 
diff --git a/src/brpc/serialized_response.h b/src/brpc/serialized_response.h
index 3b33cb24..a724be4d 100644
--- a/src/brpc/serialized_response.h
+++ b/src/brpc/serialized_response.h
@@ -19,65 +19,45 @@
 #ifndef BRPC_SERIALIZED_RESPONSE_H
 #define BRPC_SERIALIZED_RESPONSE_H
 
-#include <google/protobuf/message.h>
-#include "butil/iobuf.h"
-#include "brpc/proto_base.pb.h"
+#include "brpc/nonreflectable_message.h"
 #include "brpc/pb_compat.h"
+#include "butil/iobuf.h"
 
 namespace brpc {
 
-class SerializedResponse : public ::google::protobuf::Message {
+class SerializedResponse : public NonreflectableMessage<SerializedResponse> {
 public:
     SerializedResponse();
-    virtual ~SerializedResponse();
-  
+    ~SerializedResponse() override;
+
     SerializedResponse(const SerializedResponse& from);
-  
+
     inline SerializedResponse& operator=(const SerializedResponse& from) {
         CopyFrom(from);
         return *this;
     }
-  
-    static const ::google::protobuf::Descriptor* descriptor();
-  
+
     void Swap(SerializedResponse* other);
-  
+
+    void MergeFrom(const SerializedResponse& from) override;
+
     // implements Message ----------------------------------------------
-  
-    SerializedResponse* New() const PB_319_OVERRIDE;
-#if GOOGLE_PROTOBUF_VERSION >= 3006000
-    SerializedResponse* New(::google::protobuf::Arena* arena) const override;
-#endif
-    void CopyFrom(const ::google::protobuf::Message& from) PB_321_OVERRIDE;
-    void CopyFrom(const SerializedResponse& from);
     void Clear() override;
-    bool IsInitialized() const override;
-    int ByteSize() const;
-    int GetCachedSize() const PB_422_OVERRIDE { return 
(int)_serialized.size(); }
+    size_t ByteSizeLong() const override;
+    int GetCachedSize() const PB_425_OVERRIDE { return ByteSize(); }
     butil::IOBuf& serialized_data() { return _serialized; }
     const butil::IOBuf& serialized_data() const { return _serialized; }
 
-protected:
-    ::google::protobuf::Metadata GetMetadata() const override;
-    
+    ::google::protobuf::Metadata GetMetadata() const PB_527_OVERRIDE;
+
 private:
-    bool MergePartialFromCodedStream(
-        ::google::protobuf::io::CodedInputStream* input) PB_310_OVERRIDE;
-    void SerializeWithCachedSizes(
-        ::google::protobuf::io::CodedOutputStream* output) const 
PB_310_OVERRIDE;
-    ::google::protobuf::uint8* SerializeWithCachedSizesToArray(
-        ::google::protobuf::uint8* output) const PB_310_OVERRIDE;
-    void MergeFrom(const ::google::protobuf::Message& from) override;
-    void MergeFrom(const SerializedResponse& from);
     void SharedCtor();
     void SharedDtor();
-    void SetCachedSize(int size) const PB_422_OVERRIDE;
-  
+
 private:
     butil::IOBuf _serialized;
 };
 
 } // namespace brpc
 
-
 #endif  // BRPC_SERIALIZED_RESPONSE_H
diff --git a/src/brpc/thrift_message.cpp b/src/brpc/thrift_message.cpp
index ed3d7557..9265ed96 100644
--- a/src/brpc/thrift_message.cpp
+++ b/src/brpc/thrift_message.cpp
@@ -19,19 +19,12 @@
 #define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
 #include "brpc/thrift_message.h"
 
-#include <algorithm>
 #include "butil/logging.h"
 
-#include <google/protobuf/stubs/once.h>
-#include <google/protobuf/io/coded_stream.h>
-#include <google/protobuf/descriptor.h>
-#include <google/protobuf/reflection_ops.h>
-#include <google/protobuf/wire_format.h>
-
 namespace brpc {
 
 ThriftFramedMessage::ThriftFramedMessage()
-    : ::google::protobuf::Message() {
+    : NonreflectableMessage<ThriftFramedMessage>() {
     SharedCtor();
 }
 
@@ -51,21 +44,6 @@ ThriftFramedMessage::~ThriftFramedMessage() {
 void ThriftFramedMessage::SharedDtor() {
 }
 
-const ::google::protobuf::Descriptor* ThriftFramedMessage::descriptor() {
-    return ThriftFramedMessageBase::descriptor();
-}
-
-ThriftFramedMessage* ThriftFramedMessage::New() const {
-    return new ThriftFramedMessage;
-}
-
-#if GOOGLE_PROTOBUF_VERSION >= 3006000
-ThriftFramedMessage*
-ThriftFramedMessage::New(::google::protobuf::Arena* arena) const {
-    return CreateMaybeMessage<ThriftFramedMessage>(arena);
-}
-#endif
-
 void ThriftFramedMessage::Clear() {
     body.clear();
     if (_own_raw_instance) {
@@ -75,30 +53,7 @@ void ThriftFramedMessage::Clear() {
     }
 }
 
-bool ThriftFramedMessage::MergePartialFromCodedStream(
-    ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
-    ::google::protobuf::uint32 tag;
-    while ((tag = input->ReadTag()) != 0) {
-        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) 
==
-            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
-            return true;
-        }
-    }
-    return true;
-#undef DO_
-}
-
-void ThriftFramedMessage::SerializeWithCachedSizes(
-    ::google::protobuf::io::CodedOutputStream*) const {
-}
-
-::google::protobuf::uint8* 
ThriftFramedMessage::SerializeWithCachedSizesToArray(
-    ::google::protobuf::uint8* target) const {
-    return target;
-}
-
-int ThriftFramedMessage::ByteSize() const {
+size_t ThriftFramedMessage::ByteSizeLong() const {
     if (_raw_instance) {
         LOG(ERROR) << "ByteSize() is always 0 when _raw_instance is set";
         return 0;
@@ -106,30 +61,11 @@ int ThriftFramedMessage::ByteSize() const {
     return body.size();
 }
 
-void ThriftFramedMessage::MergeFrom(const ::google::protobuf::Message& from) {
-    CHECK_NE(&from, this);
-    LOG(ERROR) << "ThriftFramedMessage does not support MergeFrom";
-}
-
 void ThriftFramedMessage::MergeFrom(const ThriftFramedMessage& from) {
     CHECK_NE(&from, this);
     LOG(ERROR) << "ThriftFramedMessage does not support MergeFrom";
 }
 
-void ThriftFramedMessage::CopyFrom(const ::google::protobuf::Message& from) {
-    if (&from == this) return;
-    LOG(ERROR) << "ThriftFramedMessage does not support CopyFrom";
-}
-
-void ThriftFramedMessage::CopyFrom(const ThriftFramedMessage& from) {
-    if (&from == this) return;
-    LOG(ERROR) << "ThriftFramedMessage does not support CopyFrom";
-}
-
-bool ThriftFramedMessage::IsInitialized() const {
-    return true;
-}
-
 void ThriftFramedMessage::Swap(ThriftFramedMessage* other) {
     if (other != this) {
         body.swap(other->body);
@@ -140,9 +76,9 @@ void ThriftFramedMessage::Swap(ThriftFramedMessage* other) {
 }
 
 ::google::protobuf::Metadata ThriftFramedMessage::GetMetadata() const {
-    ::google::protobuf::Metadata metadata;
-    metadata.descriptor = ThriftFramedMessage::descriptor();
-    metadata.reflection = NULL;
+    ::google::protobuf::Metadata metadata{};
+    metadata.descriptor = ThriftFramedMessageBase::descriptor();
+    metadata.reflection = nullptr;
     return metadata;
 }
 
diff --git a/src/brpc/thrift_message.h b/src/brpc/thrift_message.h
index 53041c85..881b5cf7 100644
--- a/src/brpc/thrift_message.h
+++ b/src/brpc/thrift_message.h
@@ -19,13 +19,13 @@
 #ifndef BRPC_THRIFT_MESSAGE_H
 #define BRPC_THRIFT_MESSAGE_H
 
-#include <google/protobuf/message.h>
-#include "butil/iobuf.h"
-#include "butil/class_name.h"
 #include "brpc/channel_base.h"
 #include "brpc/controller.h"
-#include "brpc/proto_base.pb.h"
+#include "brpc/nonreflectable_message.h"
 #include "brpc/pb_compat.h"
+#include "brpc/proto_base.pb.h"
+#include "butil/class_name.h"
+#include "butil/iobuf.h"
 
 namespace apache {
 namespace thrift {
@@ -55,12 +55,12 @@ public:
 };
 
 // Representing a thrift framed request or response.
-class ThriftFramedMessage : public ::google::protobuf::Message {
+class ThriftFramedMessage : public NonreflectableMessage<ThriftFramedMessage> {
 friend class ThriftStub;
 public:
     butil::IOBuf body; // ~= "{ raw_instance }"
     int16_t field_id;  // must be set when body is set.
-    
+
 private:
     bool _own_raw_instance;
     ThriftMessageBase* _raw_instance;
@@ -69,42 +69,25 @@ public:
     ThriftMessageBase* raw_instance() const { return _raw_instance; }
 
     template <typename T> T* Cast();
-    
+
     ThriftFramedMessage();
 
-    virtual ~ThriftFramedMessage();
-  
+    ~ThriftFramedMessage() override;
+
     ThriftFramedMessage(const ThriftFramedMessage& from) = delete;
-  
+
     ThriftFramedMessage& operator=(const ThriftFramedMessage& from) = delete;
-  
-    static const ::google::protobuf::Descriptor* descriptor();
-  
+
     void Swap(ThriftFramedMessage* other);
-  
+
     // implements Message ----------------------------------------------
-  
-    ThriftFramedMessage* New() const PB_319_OVERRIDE;
-#if GOOGLE_PROTOBUF_VERSION >= 3006000
-    ThriftFramedMessage* New(::google::protobuf::Arena* arena) const override;
-#endif
-    void CopyFrom(const ::google::protobuf::Message& from) PB_321_OVERRIDE;
-    void MergeFrom(const ::google::protobuf::Message& from) override;
-    void CopyFrom(const ThriftFramedMessage& from);
     void MergeFrom(const ThriftFramedMessage& from);
     void Clear() override;
-    bool IsInitialized() const override;
-  
-    int ByteSize() const;
-    bool MergePartialFromCodedStream(
-        ::google::protobuf::io::CodedInputStream* input) PB_310_OVERRIDE;
-    void SerializeWithCachedSizes(
-        ::google::protobuf::io::CodedOutputStream* output) const 
PB_310_OVERRIDE;
-    ::google::protobuf::uint8* 
SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const 
PB_310_OVERRIDE;
-    int GetCachedSize() const override { return ByteSize(); }
-
-protected:
-    ::google::protobuf::Metadata GetMetadata() const override;
+
+    size_t ByteSizeLong() const override;
+    int GetCachedSize() const PB_425_OVERRIDE { return ByteSize(); }
+
+    ::google::protobuf::Metadata GetMetadata() const PB_527_OVERRIDE;
 
 private:
     void SharedCtor();
diff --git a/tools/rpc_press/rpc_press_impl.cpp 
b/tools/rpc_press/rpc_press_impl.cpp
index 3ae85fe4..07c8dbcf 100644
--- a/tools/rpc_press/rpc_press_impl.cpp
+++ b/tools/rpc_press/rpc_press_impl.cpp
@@ -46,6 +46,13 @@ public:
                           int /*column*/, const std::string& message) {
         LOG_AT(ERROR, filename.c_str(), line) << message;
     }
+
+#if GOOGLE_PROTOBUF_VERSION >= 5026000
+    void RecordError(absl::string_view filename, int line, int column,
+                     absl::string_view message) override {
+        LOG_AT(ERROR, filename.data(), line) << message;
+    }
+#endif
 };
 
 int PressClient::init() {


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@brpc.apache.org
For additional commands, e-mail: dev-h...@brpc.apache.org

Reply via email to