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

xiaofeng pushed a commit to branch feature/nonreflectable-message
in repository https://gitbox.apache.org/repos/asf/brpc.git

commit 2f1fbfe70e82409a36631721d72bd741b4ff10b9
Author: Xiaofeng Wang <wasp...@gmail.com>
AuthorDate: Mon Oct 14 00:36:34 2024 +0800

    Add NonreflectableMessage
    
    See https://github.com/apache/brpc/pull/2722#issuecomment-2272559689
    inspired by unreflectable_message of oathdruid.
---
 src/brpc/message_helper.h         |  32 ++++++
 src/brpc/nonreflectable_message.h | 201 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 233 insertions(+)

diff --git a/src/brpc/message_helper.h b/src/brpc/message_helper.h
new file mode 100644
index 00000000..a9108900
--- /dev/null
+++ b/src/brpc/message_helper.h
@@ -0,0 +1,32 @@
+// 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_MESSAGE_HELPER_H
+#define BRPC_MESSAGE_HELPER_H
+
+#include "brpc/nonreflectable_message.h"
+
+namespace brpc {
+
+template <typename T>
+struct MessageHelper {
+    using BaseType = NonreflectableMessage<T>;
+};
+
+} // namespace brpc
+
+#endif // BRPC_MESSAGE_HELPER_H
diff --git a/src/brpc/nonreflectable_message.h 
b/src/brpc/nonreflectable_message.h
new file mode 100644
index 00000000..8bdaedea
--- /dev/null
+++ b/src/brpc/nonreflectable_message.h
@@ -0,0 +1,201 @@
+// 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/message.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:
+#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
+
+#if GOOGLE_PROTOBUF_VERSION < 3021000
+    void CopyFrom(const ::google::protobuf::Message& other) override {
+        if (&other == this) {
+            return;
+        }
+        Clear();
+        MergeFrom(other);
+    }
+#endif
+
+    inline void CopyFrom(const NonreflectableMessage& other) {
+        if (&other == this) {
+            return;
+        }
+        Clear();
+        MergeFrom(other);
+    }
+
+#if GOOGLE_PROTOBUF_VERSION < 5026000
+    void MergeFrom(const ::google::protobuf::Message& other) 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);
+        }
+    }
+#endif // member function closure
+
+    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 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 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
+
+private:
+#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 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


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

Reply via email to