xref: /aosp_15_r20/external/grpc-grpc/include/grpcpp/impl/proto_utils.h (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1*cc02d7e2SAndroid Build Coastguard Worker //
2*cc02d7e2SAndroid Build Coastguard Worker //
3*cc02d7e2SAndroid Build Coastguard Worker // Copyright 2015 gRPC authors.
4*cc02d7e2SAndroid Build Coastguard Worker //
5*cc02d7e2SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
6*cc02d7e2SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
7*cc02d7e2SAndroid Build Coastguard Worker // You may obtain a copy of the License at
8*cc02d7e2SAndroid Build Coastguard Worker //
9*cc02d7e2SAndroid Build Coastguard Worker //     http://www.apache.org/licenses/LICENSE-2.0
10*cc02d7e2SAndroid Build Coastguard Worker //
11*cc02d7e2SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
12*cc02d7e2SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
13*cc02d7e2SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*cc02d7e2SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
15*cc02d7e2SAndroid Build Coastguard Worker // limitations under the License.
16*cc02d7e2SAndroid Build Coastguard Worker //
17*cc02d7e2SAndroid Build Coastguard Worker //
18*cc02d7e2SAndroid Build Coastguard Worker 
19*cc02d7e2SAndroid Build Coastguard Worker #ifndef GRPCPP_IMPL_PROTO_UTILS_H
20*cc02d7e2SAndroid Build Coastguard Worker #define GRPCPP_IMPL_PROTO_UTILS_H
21*cc02d7e2SAndroid Build Coastguard Worker 
22*cc02d7e2SAndroid Build Coastguard Worker #include <type_traits>
23*cc02d7e2SAndroid Build Coastguard Worker 
24*cc02d7e2SAndroid Build Coastguard Worker #include <grpc/byte_buffer_reader.h>
25*cc02d7e2SAndroid Build Coastguard Worker #include <grpc/impl/grpc_types.h>
26*cc02d7e2SAndroid Build Coastguard Worker #include <grpc/slice.h>
27*cc02d7e2SAndroid Build Coastguard Worker #include <grpc/support/log.h>
28*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/impl/codegen/config_protobuf.h>
29*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/impl/serialization_traits.h>
30*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/support/byte_buffer.h>
31*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/support/proto_buffer_reader.h>
32*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/support/proto_buffer_writer.h>
33*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/support/slice.h>
34*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/support/status.h>
35*cc02d7e2SAndroid Build Coastguard Worker 
36*cc02d7e2SAndroid Build Coastguard Worker /// This header provides serialization and deserialization between gRPC
37*cc02d7e2SAndroid Build Coastguard Worker /// messages serialized using protobuf and the C++ objects they represent.
38*cc02d7e2SAndroid Build Coastguard Worker 
39*cc02d7e2SAndroid Build Coastguard Worker namespace grpc {
40*cc02d7e2SAndroid Build Coastguard Worker 
41*cc02d7e2SAndroid Build Coastguard Worker // ProtoBufferWriter must be a subclass of ::protobuf::io::ZeroCopyOutputStream.
42*cc02d7e2SAndroid Build Coastguard Worker template <class ProtoBufferWriter, class T>
GenericSerialize(const grpc::protobuf::MessageLite & msg,ByteBuffer * bb,bool * own_buffer)43*cc02d7e2SAndroid Build Coastguard Worker Status GenericSerialize(const grpc::protobuf::MessageLite& msg, ByteBuffer* bb,
44*cc02d7e2SAndroid Build Coastguard Worker                         bool* own_buffer) {
45*cc02d7e2SAndroid Build Coastguard Worker   static_assert(std::is_base_of<protobuf::io::ZeroCopyOutputStream,
46*cc02d7e2SAndroid Build Coastguard Worker                                 ProtoBufferWriter>::value,
47*cc02d7e2SAndroid Build Coastguard Worker                 "ProtoBufferWriter must be a subclass of "
48*cc02d7e2SAndroid Build Coastguard Worker                 "::protobuf::io::ZeroCopyOutputStream");
49*cc02d7e2SAndroid Build Coastguard Worker   *own_buffer = true;
50*cc02d7e2SAndroid Build Coastguard Worker   int byte_size = static_cast<int>(msg.ByteSizeLong());
51*cc02d7e2SAndroid Build Coastguard Worker   if (static_cast<size_t>(byte_size) <= GRPC_SLICE_INLINED_SIZE) {
52*cc02d7e2SAndroid Build Coastguard Worker     Slice slice(byte_size);
53*cc02d7e2SAndroid Build Coastguard Worker     // We serialize directly into the allocated slices memory
54*cc02d7e2SAndroid Build Coastguard Worker     GPR_ASSERT(slice.end() == msg.SerializeWithCachedSizesToArray(
55*cc02d7e2SAndroid Build Coastguard Worker                                   const_cast<uint8_t*>(slice.begin())));
56*cc02d7e2SAndroid Build Coastguard Worker     ByteBuffer tmp(&slice, 1);
57*cc02d7e2SAndroid Build Coastguard Worker     bb->Swap(&tmp);
58*cc02d7e2SAndroid Build Coastguard Worker 
59*cc02d7e2SAndroid Build Coastguard Worker     return grpc::Status::OK;
60*cc02d7e2SAndroid Build Coastguard Worker   }
61*cc02d7e2SAndroid Build Coastguard Worker   ProtoBufferWriter writer(bb, kProtoBufferWriterMaxBufferLength, byte_size);
62*cc02d7e2SAndroid Build Coastguard Worker   return msg.SerializeToZeroCopyStream(&writer)
63*cc02d7e2SAndroid Build Coastguard Worker              ? grpc::Status::OK
64*cc02d7e2SAndroid Build Coastguard Worker              : Status(StatusCode::INTERNAL, "Failed to serialize message");
65*cc02d7e2SAndroid Build Coastguard Worker }
66*cc02d7e2SAndroid Build Coastguard Worker 
67*cc02d7e2SAndroid Build Coastguard Worker // BufferReader must be a subclass of ::protobuf::io::ZeroCopyInputStream.
68*cc02d7e2SAndroid Build Coastguard Worker template <class ProtoBufferReader, class T>
GenericDeserialize(ByteBuffer * buffer,grpc::protobuf::MessageLite * msg)69*cc02d7e2SAndroid Build Coastguard Worker Status GenericDeserialize(ByteBuffer* buffer,
70*cc02d7e2SAndroid Build Coastguard Worker                           grpc::protobuf::MessageLite* msg) {
71*cc02d7e2SAndroid Build Coastguard Worker   static_assert(std::is_base_of<protobuf::io::ZeroCopyInputStream,
72*cc02d7e2SAndroid Build Coastguard Worker                                 ProtoBufferReader>::value,
73*cc02d7e2SAndroid Build Coastguard Worker                 "ProtoBufferReader must be a subclass of "
74*cc02d7e2SAndroid Build Coastguard Worker                 "::protobuf::io::ZeroCopyInputStream");
75*cc02d7e2SAndroid Build Coastguard Worker   if (buffer == nullptr) {
76*cc02d7e2SAndroid Build Coastguard Worker     return Status(StatusCode::INTERNAL, "No payload");
77*cc02d7e2SAndroid Build Coastguard Worker   }
78*cc02d7e2SAndroid Build Coastguard Worker   Status result = grpc::Status::OK;
79*cc02d7e2SAndroid Build Coastguard Worker   {
80*cc02d7e2SAndroid Build Coastguard Worker     ProtoBufferReader reader(buffer);
81*cc02d7e2SAndroid Build Coastguard Worker     if (!reader.status().ok()) {
82*cc02d7e2SAndroid Build Coastguard Worker       return reader.status();
83*cc02d7e2SAndroid Build Coastguard Worker     }
84*cc02d7e2SAndroid Build Coastguard Worker     if (!msg->ParseFromZeroCopyStream(&reader)) {
85*cc02d7e2SAndroid Build Coastguard Worker       result = Status(StatusCode::INTERNAL, msg->InitializationErrorString());
86*cc02d7e2SAndroid Build Coastguard Worker     }
87*cc02d7e2SAndroid Build Coastguard Worker   }
88*cc02d7e2SAndroid Build Coastguard Worker   buffer->Clear();
89*cc02d7e2SAndroid Build Coastguard Worker   return result;
90*cc02d7e2SAndroid Build Coastguard Worker }
91*cc02d7e2SAndroid Build Coastguard Worker 
92*cc02d7e2SAndroid Build Coastguard Worker // this is needed so the following class does not conflict with protobuf
93*cc02d7e2SAndroid Build Coastguard Worker // serializers that utilize internal-only tools.
94*cc02d7e2SAndroid Build Coastguard Worker #ifdef GRPC_OPEN_SOURCE_PROTO
95*cc02d7e2SAndroid Build Coastguard Worker // This class provides a protobuf serializer. It translates between protobuf
96*cc02d7e2SAndroid Build Coastguard Worker // objects and grpc_byte_buffers. More information about SerializationTraits can
97*cc02d7e2SAndroid Build Coastguard Worker // be found in include/grpcpp/impl/codegen/serialization_traits.h.
98*cc02d7e2SAndroid Build Coastguard Worker template <class T>
99*cc02d7e2SAndroid Build Coastguard Worker class SerializationTraits<
100*cc02d7e2SAndroid Build Coastguard Worker     T, typename std::enable_if<
101*cc02d7e2SAndroid Build Coastguard Worker            std::is_base_of<grpc::protobuf::MessageLite, T>::value>::type> {
102*cc02d7e2SAndroid Build Coastguard Worker  public:
Serialize(const grpc::protobuf::MessageLite & msg,ByteBuffer * bb,bool * own_buffer)103*cc02d7e2SAndroid Build Coastguard Worker   static Status Serialize(const grpc::protobuf::MessageLite& msg,
104*cc02d7e2SAndroid Build Coastguard Worker                           ByteBuffer* bb, bool* own_buffer) {
105*cc02d7e2SAndroid Build Coastguard Worker     return GenericSerialize<ProtoBufferWriter, T>(msg, bb, own_buffer);
106*cc02d7e2SAndroid Build Coastguard Worker   }
107*cc02d7e2SAndroid Build Coastguard Worker 
Deserialize(ByteBuffer * buffer,grpc::protobuf::MessageLite * msg)108*cc02d7e2SAndroid Build Coastguard Worker   static Status Deserialize(ByteBuffer* buffer,
109*cc02d7e2SAndroid Build Coastguard Worker                             grpc::protobuf::MessageLite* msg) {
110*cc02d7e2SAndroid Build Coastguard Worker     return GenericDeserialize<ProtoBufferReader, T>(buffer, msg);
111*cc02d7e2SAndroid Build Coastguard Worker   }
112*cc02d7e2SAndroid Build Coastguard Worker };
113*cc02d7e2SAndroid Build Coastguard Worker #endif
114*cc02d7e2SAndroid Build Coastguard Worker 
115*cc02d7e2SAndroid Build Coastguard Worker }  // namespace grpc
116*cc02d7e2SAndroid Build Coastguard Worker 
117*cc02d7e2SAndroid Build Coastguard Worker #endif  // GRPCPP_IMPL_PROTO_UTILS_H
118