1cc290419Sopenharmony_ci/*
2cc290419Sopenharmony_ci * Copyright (C) 2021 Huawei Device Co., Ltd.
3cc290419Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4cc290419Sopenharmony_ci * you may not use this file except in compliance with the License.
5cc290419Sopenharmony_ci * You may obtain a copy of the License at
6cc290419Sopenharmony_ci *
7cc290419Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8cc290419Sopenharmony_ci *
9cc290419Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10cc290419Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11cc290419Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12cc290419Sopenharmony_ci * See the License for the specific language governing permissions and
13cc290419Sopenharmony_ci * limitations under the License.
14cc290419Sopenharmony_ci */
15cc290419Sopenharmony_ci#ifndef HDC_SERIAL_STRUCT_DEFINE_H
16cc290419Sopenharmony_ci#define HDC_SERIAL_STRUCT_DEFINE_H
17cc290419Sopenharmony_ci#include <cmath>
18cc290419Sopenharmony_ci#include <cstdint>
19cc290419Sopenharmony_ci#include <cstring>
20cc290419Sopenharmony_ci#include <map>
21cc290419Sopenharmony_ci#include <optional>
22cc290419Sopenharmony_ci#include <string>
23cc290419Sopenharmony_ci#include <tuple>
24cc290419Sopenharmony_ci#include <variant>
25cc290419Sopenharmony_ci#include <vector>
26cc290419Sopenharmony_ci
27cc290419Sopenharmony_ci// static file define. No need not modify. by zako
28cc290419Sopenharmony_cinamespace Hdc {
29cc290419Sopenharmony_ci// clang-format off
30cc290419Sopenharmony_cinamespace SerialStruct {
31cc290419Sopenharmony_ci    namespace SerialDetail {
32cc290419Sopenharmony_ci        template<class MemPtrT> struct MemPtr {
33cc290419Sopenharmony_ci        };
34cc290419Sopenharmony_ci        template<class T, class U> struct MemPtr<U T::*> {
35cc290419Sopenharmony_ci            using type = T;
36cc290419Sopenharmony_ci            using MemberType = U;
37cc290419Sopenharmony_ci        };
38cc290419Sopenharmony_ci        template<class... Fields> struct MessageImpl {
39cc290419Sopenharmony_ci        public:
40cc290419Sopenharmony_ci            MessageImpl(Fields &&... fields)
41cc290419Sopenharmony_ci                : _fields(std::move(fields)...)
42cc290419Sopenharmony_ci            {
43cc290419Sopenharmony_ci            }
44cc290419Sopenharmony_ci
45cc290419Sopenharmony_ci            template<class Handler> void Visit(Handler &&handler) const
46cc290419Sopenharmony_ci            {
47cc290419Sopenharmony_ci                VisitImpl(std::forward<Handler>(handler), std::make_index_sequence<sizeof...(Fields)>());
48cc290419Sopenharmony_ci            }
49cc290419Sopenharmony_ci
50cc290419Sopenharmony_ci        private:
51cc290419Sopenharmony_ci            std::tuple<Fields...> _fields;
52cc290419Sopenharmony_ci
53cc290419Sopenharmony_ci            template<class Handler, size_t... I> void VisitImpl(Handler &&handler, std::index_sequence<I...>) const
54cc290419Sopenharmony_ci            {
55cc290419Sopenharmony_ci                (handler(std::get<I>(_fields)), ...);
56cc290419Sopenharmony_ci            }
57cc290419Sopenharmony_ci        };
58cc290419Sopenharmony_ci
59cc290419Sopenharmony_ci        template<uint32_t Tag, class MemPtrT, MemPtrT MemPtr, uint32_t Flags> struct FieldImpl {
60cc290419Sopenharmony_ci            using type = typename SerialDetail::MemPtr<MemPtrT>::type;
61cc290419Sopenharmony_ci            using MemberType = typename SerialDetail::MemPtr<MemPtrT>::MemberType;
62cc290419Sopenharmony_ci            constexpr static const uint32_t TAG = Tag;
63cc290419Sopenharmony_ci            constexpr static const uint32_t FLAGS = Flags;
64cc290419Sopenharmony_ci            const std::string field_name;
65cc290419Sopenharmony_ci
66cc290419Sopenharmony_ci            static decltype(auto) get(const type &value)
67cc290419Sopenharmony_ci            {
68cc290419Sopenharmony_ci                return value.*MemPtr;
69cc290419Sopenharmony_ci            }
70cc290419Sopenharmony_ci
71cc290419Sopenharmony_ci            static decltype(auto) get(type &value)
72cc290419Sopenharmony_ci            {
73cc290419Sopenharmony_ci                return value.*MemPtr;
74cc290419Sopenharmony_ci            }
75cc290419Sopenharmony_ci        };
76cc290419Sopenharmony_ci
77cc290419Sopenharmony_ci        template<uint32_t Tag, size_t Index, class MemPtrT, MemPtrT MemPtr, uint32_t Flags> struct OneofFieldImpl {
78cc290419Sopenharmony_ci            using type = typename SerialDetail::MemPtr<MemPtrT>::type;
79cc290419Sopenharmony_ci            using MemberType = typename SerialDetail::MemPtr<MemPtrT>::MemberType;
80cc290419Sopenharmony_ci            constexpr static const uint32_t TAG = Tag;
81cc290419Sopenharmony_ci            constexpr static const size_t index = Index;
82cc290419Sopenharmony_ci            constexpr static const uint32_t FLAGS = Flags;
83cc290419Sopenharmony_ci            const std::string field_name;
84cc290419Sopenharmony_ci
85cc290419Sopenharmony_ci            static decltype(auto) get(const type &value)
86cc290419Sopenharmony_ci            {
87cc290419Sopenharmony_ci                return value.*MemPtr;
88cc290419Sopenharmony_ci            }
89cc290419Sopenharmony_ci
90cc290419Sopenharmony_ci            static decltype(auto) get(type &value)
91cc290419Sopenharmony_ci            {
92cc290419Sopenharmony_ci                return value.*MemPtr;
93cc290419Sopenharmony_ci            }
94cc290419Sopenharmony_ci        };
95cc290419Sopenharmony_ci
96cc290419Sopenharmony_ci        template<uint32_t Tag, class MemPtrT, MemPtrT MemPtr, uint32_t KeyFlags, uint32_t ValueFlags>
97cc290419Sopenharmony_ci        struct MapFieldImpl {
98cc290419Sopenharmony_ci            using type = typename SerialDetail::MemPtr<MemPtrT>::type;
99cc290419Sopenharmony_ci            using MemberType = typename SerialDetail::MemPtr<MemPtrT>::MemberType;
100cc290419Sopenharmony_ci            constexpr static const uint32_t TAG = Tag;
101cc290419Sopenharmony_ci            constexpr static const uint32_t KEY_FLAGS = KeyFlags;
102cc290419Sopenharmony_ci            constexpr static const uint32_t VALUE_FLAGS = ValueFlags;
103cc290419Sopenharmony_ci
104cc290419Sopenharmony_ci            const std::string field_name;
105cc290419Sopenharmony_ci
106cc290419Sopenharmony_ci            static decltype(auto) get(const type &value)
107cc290419Sopenharmony_ci            {
108cc290419Sopenharmony_ci                return value.*MemPtr;
109cc290419Sopenharmony_ci            }
110cc290419Sopenharmony_ci
111cc290419Sopenharmony_ci            static decltype(auto) get(type &value)
112cc290419Sopenharmony_ci            {
113cc290419Sopenharmony_ci                return value.*MemPtr;
114cc290419Sopenharmony_ci            }
115cc290419Sopenharmony_ci        };
116cc290419Sopenharmony_ci    }
117cc290419Sopenharmony_ci
118cc290419Sopenharmony_ci    enum class WireType : uint32_t {
119cc290419Sopenharmony_ci        VARINT = 0,
120cc290419Sopenharmony_ci        FIXED64 = 1,
121cc290419Sopenharmony_ci        LENGTH_DELIMETED = 2,
122cc290419Sopenharmony_ci        START_GROUP = 3,
123cc290419Sopenharmony_ci        END_GROUP = 4,
124cc290419Sopenharmony_ci        FIXED32 = 5,
125cc290419Sopenharmony_ci    };
126cc290419Sopenharmony_ci    enum flags { no = 0, s = 1, f = 2 };
127cc290419Sopenharmony_ci    template<uint32_t flags = flags::no> struct FlagsType {
128cc290419Sopenharmony_ci    };
129cc290419Sopenharmony_ci
130cc290419Sopenharmony_ci    template<class T> struct Descriptor {
131cc290419Sopenharmony_ci        static_assert(sizeof(T) == 0, "You need to implement descriptor for your own types");
132cc290419Sopenharmony_ci        static void type()
133cc290419Sopenharmony_ci        {
134cc290419Sopenharmony_ci        }
135cc290419Sopenharmony_ci    };
136cc290419Sopenharmony_ci
137cc290419Sopenharmony_ci    template<class... Fields> constexpr auto Message(Fields &&... fields)
138cc290419Sopenharmony_ci    {
139cc290419Sopenharmony_ci        return SerialDetail::MessageImpl<Fields...>(std::forward<Fields>(fields)...);
140cc290419Sopenharmony_ci    }
141cc290419Sopenharmony_ci
142cc290419Sopenharmony_ci    template<uint32_t Tag, auto MemPtr, uint32_t Flags = flags::no> constexpr auto Field(const std::string &fieldName)
143cc290419Sopenharmony_ci    {
144cc290419Sopenharmony_ci        return SerialDetail::FieldImpl<Tag, decltype(MemPtr), MemPtr, Flags> { fieldName };
145cc290419Sopenharmony_ci    }
146cc290419Sopenharmony_ci
147cc290419Sopenharmony_ci    template<uint32_t Tag, size_t Index, auto MemPtr, uint32_t Flags = flags::no>
148cc290419Sopenharmony_ci    constexpr auto OneofField(const std::string &fieldName)
149cc290419Sopenharmony_ci    {
150cc290419Sopenharmony_ci        return SerialDetail::OneofFieldImpl<Tag, Index, decltype(MemPtr), MemPtr, Flags> { fieldName };
151cc290419Sopenharmony_ci    }
152cc290419Sopenharmony_ci
153cc290419Sopenharmony_ci    template<uint32_t Tag, auto MemPtr, uint32_t KeyFlags = flags::no, uint32_t ValueFlags = flags::no>
154cc290419Sopenharmony_ci    constexpr auto MapField(const std::string &fieldName)
155cc290419Sopenharmony_ci    {
156cc290419Sopenharmony_ci        return SerialDetail::MapFieldImpl<Tag, decltype(MemPtr), MemPtr, KeyFlags, ValueFlags> { fieldName };
157cc290419Sopenharmony_ci    }
158cc290419Sopenharmony_ci
159cc290419Sopenharmony_ci    template<class T> const auto &MessageType()
160cc290419Sopenharmony_ci    {
161cc290419Sopenharmony_ci        static const auto message = Descriptor<T>::type();
162cc290419Sopenharmony_ci        return message;
163cc290419Sopenharmony_ci    }
164cc290419Sopenharmony_ci
165cc290419Sopenharmony_ci    template<class T, class Enable = void> struct Serializer;
166cc290419Sopenharmony_ci
167cc290419Sopenharmony_ci    struct Writer {
168cc290419Sopenharmony_ci        virtual void Write(const void *bytes, size_t size) = 0;
169cc290419Sopenharmony_ci    };
170cc290419Sopenharmony_ci
171cc290419Sopenharmony_ci    struct reader {
172cc290419Sopenharmony_ci        virtual size_t Read(void *bytes, size_t size) = 0;
173cc290419Sopenharmony_ci    };
174cc290419Sopenharmony_ci
175cc290419Sopenharmony_ci    namespace SerialDetail {
176cc290419Sopenharmony_ci        template<class T, class V, class F, class W, class Enable = void>
177cc290419Sopenharmony_ci        struct HasSerializePacked : public std::false_type {
178cc290419Sopenharmony_ci        };
179cc290419Sopenharmony_ci
180cc290419Sopenharmony_ci        template<class T, class V, class F, class W>
181cc290419Sopenharmony_ci        struct HasSerializePacked<T, V, F, W,
182cc290419Sopenharmony_ci            std::void_t<decltype(std::declval<T>().SerializePacked(
183cc290419Sopenharmony_ci                std::declval<V>(), std::declval<F>(), std::declval<W &>()))>> : public std::true_type {
184cc290419Sopenharmony_ci        };
185cc290419Sopenharmony_ci
186cc290419Sopenharmony_ci        template<class T, class V, class F, class W>
187cc290419Sopenharmony_ci        constexpr bool HAS_SERIALIZE_PACKED_V = HasSerializePacked<T, V, F, W>::value;
188cc290419Sopenharmony_ci
189cc290419Sopenharmony_ci        template<class T, class V, class F, class R, class Enable = void>
190cc290419Sopenharmony_ci        struct HasParsePacked : public std::false_type {
191cc290419Sopenharmony_ci        };
192cc290419Sopenharmony_ci
193cc290419Sopenharmony_ci        template<class T, class V, class F, class R>
194cc290419Sopenharmony_ci        struct HasParsePacked<T, V, F, R,
195cc290419Sopenharmony_ci            std::void_t<decltype(std::declval<T>().ParsePacked(
196cc290419Sopenharmony_ci                std::declval<V &>(), std::declval<F>(), std::declval<R &>()))>> : public std::true_type {
197cc290419Sopenharmony_ci        };
198cc290419Sopenharmony_ci
199cc290419Sopenharmony_ci        template<class T, class V, class F, class R>
200cc290419Sopenharmony_ci        constexpr bool HAS_PARSE_PACKED_V = HasParsePacked<T, V, F, R>::value;
201cc290419Sopenharmony_ci
202cc290419Sopenharmony_ci        static uint32_t MakeTagWireType(uint32_t tag, WireType wireType)
203cc290419Sopenharmony_ci        {
204cc290419Sopenharmony_ci            return (tag << 3) | static_cast<uint32_t>(wireType);  // 3:tag type offset
205cc290419Sopenharmony_ci        }
206cc290419Sopenharmony_ci
207cc290419Sopenharmony_ci        static inline void ReadTagWireType(uint32_t tagKey, uint32_t &tag, WireType &wireType)
208cc290419Sopenharmony_ci        {
209cc290419Sopenharmony_ci            wireType = static_cast<WireType>(tagKey & 0b0111);
210cc290419Sopenharmony_ci            tag = tagKey >> 3;  // 3:tag type offset
211cc290419Sopenharmony_ci        }
212cc290419Sopenharmony_ci
213cc290419Sopenharmony_ci        static uint32_t MakeZigzagValue(int32_t value)
214cc290419Sopenharmony_ci        {
215cc290419Sopenharmony_ci            return (static_cast<uint32_t>(value) << 1) ^ static_cast<uint32_t>(value >> 31);  //31:uint32_t val offset
216cc290419Sopenharmony_ci        }
217cc290419Sopenharmony_ci
218cc290419Sopenharmony_ci        static uint64_t MakeZigzagValue(int64_t value)
219cc290419Sopenharmony_ci        {
220cc290419Sopenharmony_ci            return (static_cast<uint64_t>(value) << 1) ^ static_cast<uint64_t>(value >> 63);  //63:uint64_t val offset
221cc290419Sopenharmony_ci        }
222cc290419Sopenharmony_ci
223cc290419Sopenharmony_ci        static int32_t ReadZigzagValue(uint32_t value)
224cc290419Sopenharmony_ci        {
225cc290419Sopenharmony_ci            return static_cast<int32_t>((value >> 1) ^ (~(value & 1) + 1));
226cc290419Sopenharmony_ci        }
227cc290419Sopenharmony_ci
228cc290419Sopenharmony_ci        static int64_t ReadZigzagValue(uint64_t value)
229cc290419Sopenharmony_ci        {
230cc290419Sopenharmony_ci            return static_cast<int64_t>((value >> 1) ^ (~(value & 1) + 1));
231cc290419Sopenharmony_ci        }
232cc290419Sopenharmony_ci
233cc290419Sopenharmony_ci        template<class To, class From> To BitCast(From from)
234cc290419Sopenharmony_ci        {
235cc290419Sopenharmony_ci            static_assert(sizeof(To) == sizeof(From), "");
236cc290419Sopenharmony_ci            static_assert(std::is_trivially_copyable_v<To>, "");
237cc290419Sopenharmony_ci            static_assert(std::is_trivially_copyable_v<From>, "");
238cc290419Sopenharmony_ci            To to;
239cc290419Sopenharmony_ci            memcpy_s(&to, sizeof(To), &from, sizeof(from));
240cc290419Sopenharmony_ci            return to;
241cc290419Sopenharmony_ci        }
242cc290419Sopenharmony_ci
243cc290419Sopenharmony_ci        struct WriterSizeCollector : public Writer {
244cc290419Sopenharmony_ci            void Write(const void *, size_t size) override
245cc290419Sopenharmony_ci            {
246cc290419Sopenharmony_ci                byte_size += size;
247cc290419Sopenharmony_ci            }
248cc290419Sopenharmony_ci            size_t byte_size = 0;
249cc290419Sopenharmony_ci        };
250cc290419Sopenharmony_ci
251cc290419Sopenharmony_ci        struct LimitedReader : public reader {
252cc290419Sopenharmony_ci            LimitedReader(reader &parent, size_t sizeLimit)
253cc290419Sopenharmony_ci                : _parent(parent), _size_limit(sizeLimit)
254cc290419Sopenharmony_ci            {
255cc290419Sopenharmony_ci            }
256cc290419Sopenharmony_ci
257cc290419Sopenharmony_ci            size_t Read(void *bytes, size_t size)
258cc290419Sopenharmony_ci            {
259cc290419Sopenharmony_ci                auto sizeToRead = std::min(size, _size_limit);
260cc290419Sopenharmony_ci                auto readSize = _parent.Read(bytes, sizeToRead);
261cc290419Sopenharmony_ci                _size_limit -= readSize;
262cc290419Sopenharmony_ci                return readSize;
263cc290419Sopenharmony_ci            }
264cc290419Sopenharmony_ci
265cc290419Sopenharmony_ci            size_t AvailableBytes() const
266cc290419Sopenharmony_ci            {
267cc290419Sopenharmony_ci                return _size_limit;
268cc290419Sopenharmony_ci            }
269cc290419Sopenharmony_ci
270cc290419Sopenharmony_ci        private:
271cc290419Sopenharmony_ci            reader &_parent;
272cc290419Sopenharmony_ci            size_t _size_limit;
273cc290419Sopenharmony_ci        };
274cc290419Sopenharmony_ci
275cc290419Sopenharmony_ci        static bool ReadByte(uint8_t &value, reader &in)
276cc290419Sopenharmony_ci        {
277cc290419Sopenharmony_ci            return in.Read(&value, 1) == 1;
278cc290419Sopenharmony_ci        }
279cc290419Sopenharmony_ci
280cc290419Sopenharmony_ci        static void WriteVarint(uint32_t value, Writer &out)
281cc290419Sopenharmony_ci        {
282cc290419Sopenharmony_ci            constexpr uint8_t bytesSize = 5;
283cc290419Sopenharmony_ci            constexpr uint8_t bytesOffset = 7;
284cc290419Sopenharmony_ci            uint8_t b[bytesSize] {};
285cc290419Sopenharmony_ci            for (size_t i = 0; i < bytesSize; ++i) {
286cc290419Sopenharmony_ci                b[i] = value & 0b0111'1111;
287cc290419Sopenharmony_ci                value >>= bytesOffset;
288cc290419Sopenharmony_ci                if (value) {
289cc290419Sopenharmony_ci                    b[i] |= 0b1000'0000;
290cc290419Sopenharmony_ci                } else {
291cc290419Sopenharmony_ci                    out.Write(b, i + 1);
292cc290419Sopenharmony_ci                    break;
293cc290419Sopenharmony_ci                }
294cc290419Sopenharmony_ci            }
295cc290419Sopenharmony_ci        }
296cc290419Sopenharmony_ci
297cc290419Sopenharmony_ci        static void WriteVarint(uint64_t value, Writer &out)
298cc290419Sopenharmony_ci        {
299cc290419Sopenharmony_ci            constexpr uint8_t bytesSize = 10;
300cc290419Sopenharmony_ci            constexpr uint8_t bytesOffset = 7;
301cc290419Sopenharmony_ci            uint8_t b[bytesSize] {};
302cc290419Sopenharmony_ci            for (size_t i = 0; i < bytesSize; ++i) {
303cc290419Sopenharmony_ci                b[i] = value & 0b0111'1111;
304cc290419Sopenharmony_ci                value >>= bytesOffset;
305cc290419Sopenharmony_ci                if (value) {
306cc290419Sopenharmony_ci                    b[i] |= 0b1000'0000;
307cc290419Sopenharmony_ci                } else {
308cc290419Sopenharmony_ci                    out.Write(b, i + 1);
309cc290419Sopenharmony_ci                    break;
310cc290419Sopenharmony_ci                }
311cc290419Sopenharmony_ci            }
312cc290419Sopenharmony_ci        }
313cc290419Sopenharmony_ci
314cc290419Sopenharmony_ci#if defined(HOST_MAC)
315cc290419Sopenharmony_ci        static void WriteVarint(unsigned long value, Writer &out)
316cc290419Sopenharmony_ci        {
317cc290419Sopenharmony_ci            WriteVarint(static_cast<uint64_t>(value), out);
318cc290419Sopenharmony_ci        }
319cc290419Sopenharmony_ci#endif
320cc290419Sopenharmony_ci
321cc290419Sopenharmony_ci        static bool ReadVarint(uint32_t &value, reader &in)
322cc290419Sopenharmony_ci        {
323cc290419Sopenharmony_ci            constexpr uint8_t bytesSize = 5;
324cc290419Sopenharmony_ci            constexpr uint8_t bytesOffset = 7;
325cc290419Sopenharmony_ci            value = 0;
326cc290419Sopenharmony_ci            for (size_t c = 0; c < bytesSize; ++c) {
327cc290419Sopenharmony_ci                uint8_t x;
328cc290419Sopenharmony_ci                if (!ReadByte(x, in)) {
329cc290419Sopenharmony_ci                    return false;
330cc290419Sopenharmony_ci                }
331cc290419Sopenharmony_ci                value |= static_cast<uint32_t>(x & 0b0111'1111) << bytesOffset * c;
332cc290419Sopenharmony_ci                if (!(x & 0b1000'0000)) {
333cc290419Sopenharmony_ci                    return true;
334cc290419Sopenharmony_ci                }
335cc290419Sopenharmony_ci            }
336cc290419Sopenharmony_ci
337cc290419Sopenharmony_ci            return false;
338cc290419Sopenharmony_ci        }
339cc290419Sopenharmony_ci
340cc290419Sopenharmony_ci        static bool ReadVarint(uint64_t &value, reader &in)
341cc290419Sopenharmony_ci        {
342cc290419Sopenharmony_ci            constexpr uint8_t bytesSize = 10;
343cc290419Sopenharmony_ci            constexpr uint8_t bytesOffset = 7;
344cc290419Sopenharmony_ci            value = 0;
345cc290419Sopenharmony_ci            for (size_t c = 0; c < bytesSize; ++c) {
346cc290419Sopenharmony_ci                uint8_t x;
347cc290419Sopenharmony_ci                if (!ReadByte(x, in)) {
348cc290419Sopenharmony_ci                    return false;
349cc290419Sopenharmony_ci                }
350cc290419Sopenharmony_ci                value |= static_cast<uint64_t>(x & 0b0111'1111) << bytesOffset * c;
351cc290419Sopenharmony_ci                if (!(x & 0b1000'0000)) {
352cc290419Sopenharmony_ci                    return true;
353cc290419Sopenharmony_ci                }
354cc290419Sopenharmony_ci            }
355cc290419Sopenharmony_ci            return false;
356cc290419Sopenharmony_ci        }
357cc290419Sopenharmony_ci
358cc290419Sopenharmony_ci#if defined(HOST_MAC)
359cc290419Sopenharmony_ci        static bool ReadVarint(unsigned long &value, reader &in)
360cc290419Sopenharmony_ci        {
361cc290419Sopenharmony_ci            uint64_t intermediateValue;
362cc290419Sopenharmony_ci            if (ReadVarint(intermediateValue, in)) {
363cc290419Sopenharmony_ci                value = static_cast<unsigned long>(intermediateValue);
364cc290419Sopenharmony_ci                return true;
365cc290419Sopenharmony_ci            }
366cc290419Sopenharmony_ci            return false;
367cc290419Sopenharmony_ci        }
368cc290419Sopenharmony_ci#endif
369cc290419Sopenharmony_ci
370cc290419Sopenharmony_ci        static void WriteFixed(uint32_t value, Writer &out)
371cc290419Sopenharmony_ci        {
372cc290419Sopenharmony_ci#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
373cc290419Sopenharmony_ci            out.Write(&value, sizeof(value));
374cc290419Sopenharmony_ci#else
375cc290419Sopenharmony_ci            static_assert(false, "Not a little-endian");
376cc290419Sopenharmony_ci#endif
377cc290419Sopenharmony_ci        }
378cc290419Sopenharmony_ci
379cc290419Sopenharmony_ci        static void WriteFixed(uint64_t value, Writer &out)
380cc290419Sopenharmony_ci        {
381cc290419Sopenharmony_ci#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
382cc290419Sopenharmony_ci            out.Write(&value, sizeof(value));
383cc290419Sopenharmony_ci#else
384cc290419Sopenharmony_ci            static_assert(false, "Not a little-endian");
385cc290419Sopenharmony_ci#endif
386cc290419Sopenharmony_ci        }
387cc290419Sopenharmony_ci
388cc290419Sopenharmony_ci        static void WriteFixed(double value, Writer &out)
389cc290419Sopenharmony_ci        {
390cc290419Sopenharmony_ci            WriteFixed(BitCast<uint64_t>(value), out);
391cc290419Sopenharmony_ci        }
392cc290419Sopenharmony_ci
393cc290419Sopenharmony_ci        static void WriteFixed(float value, Writer &out)
394cc290419Sopenharmony_ci        {
395cc290419Sopenharmony_ci            WriteFixed(BitCast<uint32_t>(value), out);
396cc290419Sopenharmony_ci        }
397cc290419Sopenharmony_ci
398cc290419Sopenharmony_ci        static void WriteVarint(int32_t value, Writer &out)
399cc290419Sopenharmony_ci        {
400cc290419Sopenharmony_ci            WriteVarint(BitCast<uint32_t>(value), out);
401cc290419Sopenharmony_ci        }
402cc290419Sopenharmony_ci
403cc290419Sopenharmony_ci        static void WriteVarint(int64_t value, Writer &out)
404cc290419Sopenharmony_ci        {
405cc290419Sopenharmony_ci            WriteVarint(BitCast<uint64_t>(value), out);
406cc290419Sopenharmony_ci        }
407cc290419Sopenharmony_ci
408cc290419Sopenharmony_ci        static void WriteSignedVarint(int32_t value, Writer &out)
409cc290419Sopenharmony_ci        {
410cc290419Sopenharmony_ci            WriteVarint(MakeZigzagValue(value), out);
411cc290419Sopenharmony_ci        }
412cc290419Sopenharmony_ci
413cc290419Sopenharmony_ci        static void WriteSignedVarint(int64_t value, Writer &out)
414cc290419Sopenharmony_ci        {
415cc290419Sopenharmony_ci            WriteVarint(MakeZigzagValue(value), out);
416cc290419Sopenharmony_ci        }
417cc290419Sopenharmony_ci
418cc290419Sopenharmony_ci        static void WriteSignedFixed(int32_t value, Writer &out)
419cc290419Sopenharmony_ci        {
420cc290419Sopenharmony_ci            WriteFixed(static_cast<uint32_t>(value), out);
421cc290419Sopenharmony_ci        }
422cc290419Sopenharmony_ci
423cc290419Sopenharmony_ci        static void WriteSignedFixed(int64_t value, Writer &out)
424cc290419Sopenharmony_ci        {
425cc290419Sopenharmony_ci            WriteFixed(static_cast<uint64_t>(value), out);
426cc290419Sopenharmony_ci        }
427cc290419Sopenharmony_ci
428cc290419Sopenharmony_ci        static void WriteTagWriteType(uint32_t tag, WireType wireType, Writer &out)
429cc290419Sopenharmony_ci        {
430cc290419Sopenharmony_ci            WriteVarint(MakeTagWireType(tag, wireType), out);
431cc290419Sopenharmony_ci        }
432cc290419Sopenharmony_ci
433cc290419Sopenharmony_ci        static bool ReadFixed(uint32_t &value, reader &in)
434cc290419Sopenharmony_ci        {
435cc290419Sopenharmony_ci#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
436cc290419Sopenharmony_ci            return in.Read(&value, sizeof(value)) == sizeof(value);
437cc290419Sopenharmony_ci#else
438cc290419Sopenharmony_ci            static_assert(false, "Not a little-endian");
439cc290419Sopenharmony_ci#endif
440cc290419Sopenharmony_ci        }
441cc290419Sopenharmony_ci
442cc290419Sopenharmony_ci        static bool ReadFixed(uint64_t &value, reader &in)
443cc290419Sopenharmony_ci        {
444cc290419Sopenharmony_ci#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
445cc290419Sopenharmony_ci            return in.Read(&value, sizeof(value)) == sizeof(value);
446cc290419Sopenharmony_ci#else
447cc290419Sopenharmony_ci            static_assert(false, "Not a little-endian");
448cc290419Sopenharmony_ci#endif
449cc290419Sopenharmony_ci        }
450cc290419Sopenharmony_ci
451cc290419Sopenharmony_ci        static bool ReadFixed(double &value, reader &in)
452cc290419Sopenharmony_ci        {
453cc290419Sopenharmony_ci            uint64_t intermediateValue;
454cc290419Sopenharmony_ci            if (ReadFixed(intermediateValue, in)) {
455cc290419Sopenharmony_ci                value = BitCast<double>(intermediateValue);
456cc290419Sopenharmony_ci                return true;
457cc290419Sopenharmony_ci            }
458cc290419Sopenharmony_ci            return false;
459cc290419Sopenharmony_ci        }
460cc290419Sopenharmony_ci
461cc290419Sopenharmony_ci        static bool ReadFixed(float &value, reader &in)
462cc290419Sopenharmony_ci        {
463cc290419Sopenharmony_ci            uint32_t intermediateValue;
464cc290419Sopenharmony_ci            if (ReadFixed(intermediateValue, in)) {
465cc290419Sopenharmony_ci                value = BitCast<float>(intermediateValue);
466cc290419Sopenharmony_ci                return true;
467cc290419Sopenharmony_ci            }
468cc290419Sopenharmony_ci            return false;
469cc290419Sopenharmony_ci        }
470cc290419Sopenharmony_ci
471cc290419Sopenharmony_ci        static bool ReadVarint(int32_t &value, reader &in)
472cc290419Sopenharmony_ci        {
473cc290419Sopenharmony_ci            uint32_t intermediateValue;
474cc290419Sopenharmony_ci            if (ReadVarint(intermediateValue, in)) {
475cc290419Sopenharmony_ci                value = BitCast<int32_t>(intermediateValue);
476cc290419Sopenharmony_ci                return true;
477cc290419Sopenharmony_ci            }
478cc290419Sopenharmony_ci            return false;
479cc290419Sopenharmony_ci        }
480cc290419Sopenharmony_ci
481cc290419Sopenharmony_ci        static bool ReadVarint(int64_t &value, reader &in)
482cc290419Sopenharmony_ci        {
483cc290419Sopenharmony_ci            uint64_t intermediateValue;
484cc290419Sopenharmony_ci            if (ReadVarint(intermediateValue, in)) {
485cc290419Sopenharmony_ci                value = BitCast<int64_t>(intermediateValue);
486cc290419Sopenharmony_ci                return true;
487cc290419Sopenharmony_ci            }
488cc290419Sopenharmony_ci            return false;
489cc290419Sopenharmony_ci        }
490cc290419Sopenharmony_ci
491cc290419Sopenharmony_ci        static bool ReadSignedVarint(int32_t &value, reader &in)
492cc290419Sopenharmony_ci        {
493cc290419Sopenharmony_ci            uint32_t intermediateValue;
494cc290419Sopenharmony_ci            if (ReadVarint(intermediateValue, in)) {
495cc290419Sopenharmony_ci                value = ReadZigzagValue(intermediateValue);
496cc290419Sopenharmony_ci                return true;
497cc290419Sopenharmony_ci            }
498cc290419Sopenharmony_ci            return false;
499cc290419Sopenharmony_ci        }
500cc290419Sopenharmony_ci
501cc290419Sopenharmony_ci        static bool ReadSignedVarint(int64_t &value, reader &in)
502cc290419Sopenharmony_ci        {
503cc290419Sopenharmony_ci            uint64_t intermediateValue;
504cc290419Sopenharmony_ci            if (ReadVarint(intermediateValue, in)) {
505cc290419Sopenharmony_ci                value = ReadZigzagValue(intermediateValue);
506cc290419Sopenharmony_ci                return true;
507cc290419Sopenharmony_ci            }
508cc290419Sopenharmony_ci            return false;
509cc290419Sopenharmony_ci        }
510cc290419Sopenharmony_ci
511cc290419Sopenharmony_ci        static bool ReadSignedFixed(int32_t &value, reader &in)
512cc290419Sopenharmony_ci        {
513cc290419Sopenharmony_ci            uint32_t intermediateValue;
514cc290419Sopenharmony_ci            if (ReadFixed(intermediateValue, in)) {
515cc290419Sopenharmony_ci                value = static_cast<int64_t>(intermediateValue);
516cc290419Sopenharmony_ci                return true;
517cc290419Sopenharmony_ci            }
518cc290419Sopenharmony_ci            return false;
519cc290419Sopenharmony_ci        }
520cc290419Sopenharmony_ci
521cc290419Sopenharmony_ci        static bool ReadSignedFixed(int64_t &value, reader &in)
522cc290419Sopenharmony_ci        {
523cc290419Sopenharmony_ci            uint64_t intermediateValue;
524cc290419Sopenharmony_ci            if (ReadFixed(intermediateValue, in)) {
525cc290419Sopenharmony_ci                value = static_cast<int64_t>(intermediateValue);
526cc290419Sopenharmony_ci                return true;
527cc290419Sopenharmony_ci            }
528cc290419Sopenharmony_ci            return false;
529cc290419Sopenharmony_ci        }
530cc290419Sopenharmony_ci
531cc290419Sopenharmony_ci        template<class T, uint32_t Tag, size_t Index, class MemPtrT, MemPtrT MemPtr, uint32_t Flags>
532cc290419Sopenharmony_ci        void WriteField(const T &value,
533cc290419Sopenharmony_ci            const SerialDetail::OneofFieldImpl<Tag, Index, MemPtrT, MemPtr, Flags> &, Writer &out)
534cc290419Sopenharmony_ci        {
535cc290419Sopenharmony_ci            using OneOf = SerialDetail::OneofFieldImpl<Tag, Index, MemPtrT, MemPtr, Flags>;
536cc290419Sopenharmony_ci            Serializer<typename OneOf::MemberType>::template SerializeOneof<OneOf::index>(
537cc290419Sopenharmony_ci                OneOf::TAG, OneOf::get(value), FlagsType<OneOf::FLAGS>(), out);
538cc290419Sopenharmony_ci        }
539cc290419Sopenharmony_ci
540cc290419Sopenharmony_ci        template<class T, uint32_t Tag, class MemPtrT, MemPtrT MemPtr, uint32_t KeyFlags, uint32_t ValueFlags>
541cc290419Sopenharmony_ci        void WriteField(const T &value,
542cc290419Sopenharmony_ci            const SerialDetail::MapFieldImpl<Tag, MemPtrT, MemPtr, KeyFlags, ValueFlags> &, Writer &out)
543cc290419Sopenharmony_ci        {
544cc290419Sopenharmony_ci            using Map = SerialDetail::MapFieldImpl<Tag, MemPtrT, MemPtr, KeyFlags, ValueFlags>;
545cc290419Sopenharmony_ci            Serializer<typename Map::MemberType>::SerializeMap(
546cc290419Sopenharmony_ci                Map::TAG, Map::get(value), FlagsType<Map::KEY_FLAGS>(), FlagsType<Map::VALUE_FLAGS>(), out);
547cc290419Sopenharmony_ci        }
548cc290419Sopenharmony_ci
549cc290419Sopenharmony_ci        template<class T, uint32_t Tag, class MemPtrT, MemPtrT MemPtr, uint32_t Flags>
550cc290419Sopenharmony_ci        void WriteField(const T &value, const SerialDetail::FieldImpl<Tag, MemPtrT, MemPtr, Flags> &, Writer &out)
551cc290419Sopenharmony_ci        {
552cc290419Sopenharmony_ci            using Field = SerialDetail::FieldImpl<Tag, MemPtrT, MemPtr, Flags>;
553cc290419Sopenharmony_ci            Serializer<typename Field::MemberType>::Serialize(
554cc290419Sopenharmony_ci                Field::TAG, Field::get(value), FlagsType<Field::FLAGS>(), out);
555cc290419Sopenharmony_ci        }
556cc290419Sopenharmony_ci
557cc290419Sopenharmony_ci        template<class T, class... Field>
558cc290419Sopenharmony_ci        void WriteMessage(const T &value, const SerialDetail::MessageImpl<Field...> &message, Writer &out)
559cc290419Sopenharmony_ci        {
560cc290419Sopenharmony_ci            message.Visit([&](const auto &field) { WriteField(value, field, out); });
561cc290419Sopenharmony_ci        }
562cc290419Sopenharmony_ci
563cc290419Sopenharmony_ci        template<uint32_t Flags, class ValueType, class It>
564cc290419Sopenharmony_ci        void WriteRepeated(uint32_t tag, It begin, It end, Writer &out)
565cc290419Sopenharmony_ci        {
566cc290419Sopenharmony_ci            if (begin == end) {
567cc290419Sopenharmony_ci                return;
568cc290419Sopenharmony_ci            }
569cc290419Sopenharmony_ci            if constexpr (SerialDetail::HAS_SERIALIZE_PACKED_V<Serializer<ValueType>, ValueType, FlagsType<Flags>,
570cc290419Sopenharmony_ci                Writer>) {
571cc290419Sopenharmony_ci                WriteVarint(MakeTagWireType(tag, WireType::LENGTH_DELIMETED), out);
572cc290419Sopenharmony_ci                WriterSizeCollector sizeCollector;
573cc290419Sopenharmony_ci                for (auto it = begin; it != end; ++it) {
574cc290419Sopenharmony_ci                    Serializer<ValueType>::SerializePacked(*it, FlagsType<Flags> {}, sizeCollector);
575cc290419Sopenharmony_ci                }
576cc290419Sopenharmony_ci                WriteVarint(sizeCollector.byte_size, out);
577cc290419Sopenharmony_ci                for (auto it = begin; it != end; ++it) {
578cc290419Sopenharmony_ci                    Serializer<ValueType>::SerializePacked(*it, FlagsType<Flags> {}, out);
579cc290419Sopenharmony_ci                }
580cc290419Sopenharmony_ci            } else {
581cc290419Sopenharmony_ci                for (auto it = begin; it != end; ++it) {
582cc290419Sopenharmony_ci                    Serializer<ValueType>::Serialize(tag, *it, FlagsType<Flags>(), out);
583cc290419Sopenharmony_ci                }
584cc290419Sopenharmony_ci            }
585cc290419Sopenharmony_ci        }
586cc290419Sopenharmony_ci
587cc290419Sopenharmony_ci        template<uint32_t KeyFlags, uint32_t ValueFlags, class Key, class Value>
588cc290419Sopenharmony_ci        void WriteMapKeyValue(const std::pair<const Key, Value> &value, Writer &out)
589cc290419Sopenharmony_ci        {
590cc290419Sopenharmony_ci            Serializer<Key>::Serialize(1, value.first, FlagsType<KeyFlags> {}, out, true);
591cc290419Sopenharmony_ci            Serializer<Value>::Serialize(2, value.second, FlagsType<ValueFlags> {}, out, true);  // 2:tag value
592cc290419Sopenharmony_ci        }
593cc290419Sopenharmony_ci
594cc290419Sopenharmony_ci        template<uint32_t KeyFlags, uint32_t ValueFlags, class T>
595cc290419Sopenharmony_ci        void WriteMap(uint32_t tag, const T &value, Writer &out)
596cc290419Sopenharmony_ci        {
597cc290419Sopenharmony_ci            auto begin = std::begin(value);
598cc290419Sopenharmony_ci            auto end = std::end(value);
599cc290419Sopenharmony_ci
600cc290419Sopenharmony_ci            for (auto it = begin; it != end; ++it) {
601cc290419Sopenharmony_ci                WriteTagWriteType(tag, WireType::LENGTH_DELIMETED, out);
602cc290419Sopenharmony_ci                WriterSizeCollector sizeCollector;
603cc290419Sopenharmony_ci                WriteMapKeyValue<KeyFlags, ValueFlags>(*it, sizeCollector);
604cc290419Sopenharmony_ci                WriteVarint(sizeCollector.byte_size, out);
605cc290419Sopenharmony_ci                WriteMapKeyValue<KeyFlags, ValueFlags>(*it, out);
606cc290419Sopenharmony_ci            }
607cc290419Sopenharmony_ci        }
608cc290419Sopenharmony_ci
609cc290419Sopenharmony_ci        template<uint32_t KeyFlags, uint32_t ValueFlags, class Key, class Value>
610cc290419Sopenharmony_ci        bool ReadMapKeyValue(std::pair<Key, Value> &value, reader &in)
611cc290419Sopenharmony_ci        {
612cc290419Sopenharmony_ci            static const auto pairAsMessage = Message(Field<1, &std::pair<Key, Value>::first, KeyFlags>("key"),
613cc290419Sopenharmony_ci                Field<2, &std::pair<Key, Value>::second, ValueFlags>("value"));
614cc290419Sopenharmony_ci            return ReadMessage(value, pairAsMessage, in);
615cc290419Sopenharmony_ci        }
616cc290419Sopenharmony_ci
617cc290419Sopenharmony_ci        template<uint32_t KeyFlags, uint32_t ValueFlags, class T>
618cc290419Sopenharmony_ci        bool ReadMap(WireType wireType, T &value, reader &in)
619cc290419Sopenharmony_ci        {
620cc290419Sopenharmony_ci            if (wireType != WireType::LENGTH_DELIMETED) {
621cc290419Sopenharmony_ci                return false;
622cc290419Sopenharmony_ci            }
623cc290419Sopenharmony_ci            size_t size;
624cc290419Sopenharmony_ci            if (ReadVarint(size, in)) {
625cc290419Sopenharmony_ci                LimitedReader limitedIn(in, size);
626cc290419Sopenharmony_ci                while (limitedIn.AvailableBytes() > 0) {
627cc290419Sopenharmony_ci                    std::pair<typename T::key_type, typename T::mapped_type> item;
628cc290419Sopenharmony_ci                    if (!ReadMapKeyValue<KeyFlags, ValueFlags>(item, limitedIn)) {
629cc290419Sopenharmony_ci                        return false;
630cc290419Sopenharmony_ci                    }
631cc290419Sopenharmony_ci                    value.insert(std::move(item));
632cc290419Sopenharmony_ci                }
633cc290419Sopenharmony_ci                return true;
634cc290419Sopenharmony_ci            }
635cc290419Sopenharmony_ci            return false;
636cc290419Sopenharmony_ci        }
637cc290419Sopenharmony_ci
638cc290419Sopenharmony_ci        template<uint32_t Flags, class ValueType, class OutputIt>
639cc290419Sopenharmony_ci        bool ReadRepeated(WireType wireType, OutputIt output_it, reader &in)
640cc290419Sopenharmony_ci        {
641cc290419Sopenharmony_ci            if constexpr (SerialDetail::HAS_PARSE_PACKED_V<Serializer<ValueType>, ValueType, FlagsType<Flags>,
642cc290419Sopenharmony_ci                reader>) {
643cc290419Sopenharmony_ci                if (wireType != WireType::LENGTH_DELIMETED) {
644cc290419Sopenharmony_ci                    return false;
645cc290419Sopenharmony_ci                }
646cc290419Sopenharmony_ci
647cc290419Sopenharmony_ci                size_t size;
648cc290419Sopenharmony_ci                if (ReadVarint(size, in)) {
649cc290419Sopenharmony_ci                    LimitedReader limitedIn(in, size);
650cc290419Sopenharmony_ci
651cc290419Sopenharmony_ci                    while (limitedIn.AvailableBytes() > 0) {
652cc290419Sopenharmony_ci                        ValueType value;
653cc290419Sopenharmony_ci                        if (!Serializer<ValueType>::ParsePacked(value, FlagsType<Flags>(), limitedIn)) {
654cc290419Sopenharmony_ci                            return false;
655cc290419Sopenharmony_ci                        }
656cc290419Sopenharmony_ci                        output_it = value;
657cc290419Sopenharmony_ci                        ++output_it;
658cc290419Sopenharmony_ci                    }
659cc290419Sopenharmony_ci                    return true;
660cc290419Sopenharmony_ci                }
661cc290419Sopenharmony_ci                return false;
662cc290419Sopenharmony_ci            } else {
663cc290419Sopenharmony_ci                ValueType value;
664cc290419Sopenharmony_ci                if (Serializer<ValueType>::Parse(wireType, value, FlagsType<Flags>(), in)) {
665cc290419Sopenharmony_ci                    output_it = value;
666cc290419Sopenharmony_ci                    ++output_it;
667cc290419Sopenharmony_ci                    return true;
668cc290419Sopenharmony_ci                }
669cc290419Sopenharmony_ci                return false;
670cc290419Sopenharmony_ci            }
671cc290419Sopenharmony_ci        }
672cc290419Sopenharmony_ci
673cc290419Sopenharmony_ci        template<class T, uint32_t Tag, size_t Index, class MemPtrT, MemPtrT MemPtr, uint32_t Flags>
674cc290419Sopenharmony_ci        void ReadField(T &value, uint32_t tag, WireType wireType,
675cc290419Sopenharmony_ci            const SerialDetail::OneofFieldImpl<Tag, Index, MemPtrT, MemPtr, Flags> &, reader &in)
676cc290419Sopenharmony_ci        {
677cc290419Sopenharmony_ci            if (Tag != tag) {
678cc290419Sopenharmony_ci                return;
679cc290419Sopenharmony_ci            }
680cc290419Sopenharmony_ci            using OneOf = SerialDetail::OneofFieldImpl<Tag, Index, MemPtrT, MemPtr, Flags>;
681cc290419Sopenharmony_ci            Serializer<typename OneOf::MemberType>::template ParseOneof<OneOf::index>(
682cc290419Sopenharmony_ci                wireType, OneOf::get(value), FlagsType<OneOf::FLAGS>(), in);
683cc290419Sopenharmony_ci        }
684cc290419Sopenharmony_ci
685cc290419Sopenharmony_ci        template<class T, uint32_t Tag, class MemPtrT, MemPtrT MemPtr, uint32_t KeyFlags, uint32_t ValueFlags>
686cc290419Sopenharmony_ci        void ReadField(T &value, uint32_t tag, WireType wireType,
687cc290419Sopenharmony_ci            const SerialDetail::MapFieldImpl<Tag, MemPtrT, MemPtr, KeyFlags, ValueFlags> &, reader &in)
688cc290419Sopenharmony_ci        {
689cc290419Sopenharmony_ci            if (Tag != tag) {
690cc290419Sopenharmony_ci                return;
691cc290419Sopenharmony_ci            }
692cc290419Sopenharmony_ci            using Map = SerialDetail::MapFieldImpl<Tag, MemPtrT, MemPtr, KeyFlags, ValueFlags>;
693cc290419Sopenharmony_ci            Serializer<typename Map::MemberType>::ParseMap(
694cc290419Sopenharmony_ci                wireType, Map::get(value), FlagsType<Map::KEY_FLAGS>(), FlagsType<Map::VALUE_FLAGS>(), in);
695cc290419Sopenharmony_ci        }
696cc290419Sopenharmony_ci
697cc290419Sopenharmony_ci        template<class T, uint32_t Tag, class MemPtrT, MemPtrT MemPtr, uint32_t Flags>
698cc290419Sopenharmony_ci        void ReadField(T &value, uint32_t tag, WireType wireType,
699cc290419Sopenharmony_ci            const SerialDetail::FieldImpl<Tag, MemPtrT, MemPtr, Flags> &, reader &in)
700cc290419Sopenharmony_ci        {
701cc290419Sopenharmony_ci            if (Tag != tag) {
702cc290419Sopenharmony_ci                return;
703cc290419Sopenharmony_ci            }
704cc290419Sopenharmony_ci            using Field = SerialDetail::FieldImpl<Tag, MemPtrT, MemPtr, Flags>;
705cc290419Sopenharmony_ci            Serializer<typename Field::MemberType>::Parse(wireType, Field::get(value), FlagsType<Field::FLAGS>(), in);
706cc290419Sopenharmony_ci        }
707cc290419Sopenharmony_ci
708cc290419Sopenharmony_ci        template<class T, class... Field> bool ReadMessage(T &value, const MessageImpl<Field...> &message, reader &in)
709cc290419Sopenharmony_ci        {
710cc290419Sopenharmony_ci            uint32_t tagKey;
711cc290419Sopenharmony_ci            while (ReadVarint(tagKey, in)) {
712cc290419Sopenharmony_ci                uint32_t tag;
713cc290419Sopenharmony_ci                WireType wireType;
714cc290419Sopenharmony_ci                ReadTagWireType(tagKey, tag, wireType);
715cc290419Sopenharmony_ci                message.Visit([&](const auto &field) { ReadField(value, tag, wireType, field, in); });
716cc290419Sopenharmony_ci            }
717cc290419Sopenharmony_ci            return true;
718cc290419Sopenharmony_ci        }
719cc290419Sopenharmony_ci    }
720cc290419Sopenharmony_ci
721cc290419Sopenharmony_ci    template<class T, class Enable> struct Serializer {
722cc290419Sopenharmony_ci        // Commion Serializer threat type as Message
723cc290419Sopenharmony_ci        static void Serialize(uint32_t tag, const T &value, FlagsType<>, Writer &out, bool force = false)
724cc290419Sopenharmony_ci        {
725cc290419Sopenharmony_ci            SerialDetail::WriterSizeCollector sizeCollector;
726cc290419Sopenharmony_ci            SerialDetail::WriteMessage(value, MessageType<T>(), sizeCollector);
727cc290419Sopenharmony_ci            if (!force && sizeCollector.byte_size == 0) {
728cc290419Sopenharmony_ci                return;
729cc290419Sopenharmony_ci            }
730cc290419Sopenharmony_ci            SerialDetail::WriteTagWriteType(tag, WireType::LENGTH_DELIMETED, out);
731cc290419Sopenharmony_ci            SerialDetail::WriteVarint(sizeCollector.byte_size, out);
732cc290419Sopenharmony_ci            SerialDetail::WriteMessage(value, MessageType<T>(), out);
733cc290419Sopenharmony_ci        }
734cc290419Sopenharmony_ci
735cc290419Sopenharmony_ci        static bool Parse(WireType wireType, T &value, FlagsType<>, reader &in)
736cc290419Sopenharmony_ci        {
737cc290419Sopenharmony_ci            if (wireType != WireType::LENGTH_DELIMETED) {
738cc290419Sopenharmony_ci                return false;
739cc290419Sopenharmony_ci            }
740cc290419Sopenharmony_ci            size_t size;
741cc290419Sopenharmony_ci            if (SerialDetail::ReadVarint(size, in)) {
742cc290419Sopenharmony_ci                SerialDetail::LimitedReader limitedIn(in, size);
743cc290419Sopenharmony_ci                return SerialDetail::ReadMessage(value, MessageType<T>(), limitedIn);
744cc290419Sopenharmony_ci            }
745cc290419Sopenharmony_ci            return false;
746cc290419Sopenharmony_ci        }
747cc290419Sopenharmony_ci    };
748cc290419Sopenharmony_ci
749cc290419Sopenharmony_ci    template<> struct Serializer<int32_t> {
750cc290419Sopenharmony_ci        static void Serialize(uint32_t tag, int32_t value, FlagsType<>, Writer &out, bool force = false)
751cc290419Sopenharmony_ci        {
752cc290419Sopenharmony_ci            SerialDetail::WriteTagWriteType(tag, WireType::VARINT, out);
753cc290419Sopenharmony_ci            SerialDetail::WriteVarint(value, out);
754cc290419Sopenharmony_ci        }
755cc290419Sopenharmony_ci
756cc290419Sopenharmony_ci        static void Serialize(uint32_t tag, int32_t value, FlagsType<flags::s>, Writer &out, bool force = false)
757cc290419Sopenharmony_ci        {
758cc290419Sopenharmony_ci            SerialDetail::WriteTagWriteType(tag, WireType::VARINT, out);
759cc290419Sopenharmony_ci            SerialDetail::WriteSignedVarint(value, out);
760cc290419Sopenharmony_ci        }
761cc290419Sopenharmony_ci
762cc290419Sopenharmony_ci        static void Serialize(
763cc290419Sopenharmony_ci            uint32_t tag, int32_t value, FlagsType<flags::s | flags::f>, Writer &out, bool force = false)
764cc290419Sopenharmony_ci        {
765cc290419Sopenharmony_ci            SerialDetail::WriteTagWriteType(tag, WireType::FIXED32, out);
766cc290419Sopenharmony_ci            SerialDetail::WriteSignedFixed(value, out);
767cc290419Sopenharmony_ci        }
768cc290419Sopenharmony_ci
769cc290419Sopenharmony_ci        static void SerializePacked(int32_t value, FlagsType<>, Writer &out)
770cc290419Sopenharmony_ci        {
771cc290419Sopenharmony_ci            SerialDetail::WriteVarint(value, out);
772cc290419Sopenharmony_ci        }
773cc290419Sopenharmony_ci
774cc290419Sopenharmony_ci        static void SerializePacked(int32_t value, FlagsType<flags::s>, Writer &out)
775cc290419Sopenharmony_ci        {
776cc290419Sopenharmony_ci            SerialDetail::WriteSignedVarint(value, out);
777cc290419Sopenharmony_ci        }
778cc290419Sopenharmony_ci
779cc290419Sopenharmony_ci        static void SerializePacked(int32_t value, FlagsType<flags::s | flags::f>, Writer &out)
780cc290419Sopenharmony_ci        {
781cc290419Sopenharmony_ci            SerialDetail::WriteSignedFixed(value, out);
782cc290419Sopenharmony_ci        }
783cc290419Sopenharmony_ci
784cc290419Sopenharmony_ci        static bool Parse(WireType wire_type, int32_t &value, FlagsType<>, reader &in)
785cc290419Sopenharmony_ci        {
786cc290419Sopenharmony_ci            if (wire_type != WireType::VARINT)
787cc290419Sopenharmony_ci                return false;
788cc290419Sopenharmony_ci            return SerialDetail::ReadVarint(value, in);
789cc290419Sopenharmony_ci        }
790cc290419Sopenharmony_ci
791cc290419Sopenharmony_ci        static bool Parse(WireType wire_type, int32_t &value, FlagsType<flags::s>, reader &in)
792cc290419Sopenharmony_ci        {
793cc290419Sopenharmony_ci            if (wire_type != WireType::VARINT)
794cc290419Sopenharmony_ci                return false;
795cc290419Sopenharmony_ci            return SerialDetail::ReadSignedVarint(value, in);
796cc290419Sopenharmony_ci        }
797cc290419Sopenharmony_ci
798cc290419Sopenharmony_ci        static bool Parse(WireType wire_type, int32_t &value, FlagsType<flags::s | flags::f>, reader &in)
799cc290419Sopenharmony_ci        {
800cc290419Sopenharmony_ci            if (wire_type != WireType::FIXED32)
801cc290419Sopenharmony_ci                return false;
802cc290419Sopenharmony_ci            return SerialDetail::ReadSignedFixed(value, in);
803cc290419Sopenharmony_ci        }
804cc290419Sopenharmony_ci
805cc290419Sopenharmony_ci        static bool ParsePacked(int32_t &value, FlagsType<>, reader &in)
806cc290419Sopenharmony_ci        {
807cc290419Sopenharmony_ci            return SerialDetail::ReadVarint(value, in);
808cc290419Sopenharmony_ci        }
809cc290419Sopenharmony_ci
810cc290419Sopenharmony_ci        static bool ParsePacked(int32_t &value, FlagsType<flags::s>, reader &in)
811cc290419Sopenharmony_ci        {
812cc290419Sopenharmony_ci            return SerialDetail::ReadSignedVarint(value, in);
813cc290419Sopenharmony_ci        }
814cc290419Sopenharmony_ci
815cc290419Sopenharmony_ci        static bool ParsePacked(int32_t &value, FlagsType<flags::s | flags::f>, reader &in)
816cc290419Sopenharmony_ci        {
817cc290419Sopenharmony_ci            return SerialDetail::ReadSignedFixed(value, in);
818cc290419Sopenharmony_ci        }
819cc290419Sopenharmony_ci    };
820cc290419Sopenharmony_ci
821cc290419Sopenharmony_ci    template<> struct Serializer<uint32_t> {
822cc290419Sopenharmony_ci        static void Serialize(uint32_t tag, uint32_t value, FlagsType<>, Writer &out, bool force = false)
823cc290419Sopenharmony_ci        {
824cc290419Sopenharmony_ci            SerialDetail::WriteTagWriteType(tag, WireType::VARINT, out);
825cc290419Sopenharmony_ci            SerialDetail::WriteVarint(value, out);
826cc290419Sopenharmony_ci        }
827cc290419Sopenharmony_ci
828cc290419Sopenharmony_ci        static void Serialize(uint32_t tag, uint32_t value, FlagsType<flags::f>, Writer &out, bool force = false)
829cc290419Sopenharmony_ci        {
830cc290419Sopenharmony_ci            SerialDetail::WriteTagWriteType(tag, WireType::FIXED32, out);
831cc290419Sopenharmony_ci            SerialDetail::WriteFixed(value, out);
832cc290419Sopenharmony_ci        }
833cc290419Sopenharmony_ci
834cc290419Sopenharmony_ci        static void SerializePacked(uint32_t value, FlagsType<>, Writer &out)
835cc290419Sopenharmony_ci        {
836cc290419Sopenharmony_ci            SerialDetail::WriteVarint(value, out);
837cc290419Sopenharmony_ci        }
838cc290419Sopenharmony_ci
839cc290419Sopenharmony_ci        static void SerializePacked(uint32_t value, FlagsType<flags::f>, Writer &out)
840cc290419Sopenharmony_ci        {
841cc290419Sopenharmony_ci            SerialDetail::WriteFixed(value, out);
842cc290419Sopenharmony_ci        }
843cc290419Sopenharmony_ci
844cc290419Sopenharmony_ci        static bool Parse(WireType wire_type, uint32_t &value, FlagsType<>, reader &in)
845cc290419Sopenharmony_ci        {
846cc290419Sopenharmony_ci            if (wire_type != WireType::VARINT)
847cc290419Sopenharmony_ci                return false;
848cc290419Sopenharmony_ci            return SerialDetail::ReadVarint(value, in);
849cc290419Sopenharmony_ci        }
850cc290419Sopenharmony_ci
851cc290419Sopenharmony_ci        static bool Parse(WireType wire_type, uint32_t &value, FlagsType<flags::f>, reader &in)
852cc290419Sopenharmony_ci        {
853cc290419Sopenharmony_ci            if (wire_type != WireType::FIXED32)
854cc290419Sopenharmony_ci                return false;
855cc290419Sopenharmony_ci            return SerialDetail::ReadFixed(value, in);
856cc290419Sopenharmony_ci        }
857cc290419Sopenharmony_ci
858cc290419Sopenharmony_ci        static bool ParsePacked(uint32_t &value, FlagsType<>, reader &in)
859cc290419Sopenharmony_ci        {
860cc290419Sopenharmony_ci            return SerialDetail::ReadVarint(value, in);
861cc290419Sopenharmony_ci        }
862cc290419Sopenharmony_ci
863cc290419Sopenharmony_ci        static bool ParsePacked(uint32_t &value, FlagsType<flags::f>, reader &in)
864cc290419Sopenharmony_ci        {
865cc290419Sopenharmony_ci            return SerialDetail::ReadFixed(value, in);
866cc290419Sopenharmony_ci        }
867cc290419Sopenharmony_ci    };
868cc290419Sopenharmony_ci
869cc290419Sopenharmony_ci    template<> struct Serializer<int64_t> {
870cc290419Sopenharmony_ci        static void Serialize(uint32_t tag, int64_t value, FlagsType<>, Writer &out, bool force = false)
871cc290419Sopenharmony_ci        {
872cc290419Sopenharmony_ci            SerialDetail::WriteTagWriteType(tag, WireType::VARINT, out);
873cc290419Sopenharmony_ci            SerialDetail::WriteVarint(value, out);
874cc290419Sopenharmony_ci        }
875cc290419Sopenharmony_ci
876cc290419Sopenharmony_ci        static void Serialize(uint32_t tag, int64_t value, FlagsType<flags::s>, Writer &out, bool force = false)
877cc290419Sopenharmony_ci        {
878cc290419Sopenharmony_ci            SerialDetail::WriteTagWriteType(tag, WireType::VARINT, out);
879cc290419Sopenharmony_ci            SerialDetail::WriteSignedVarint(value, out);
880cc290419Sopenharmony_ci        }
881cc290419Sopenharmony_ci
882cc290419Sopenharmony_ci        static void Serialize(
883cc290419Sopenharmony_ci            uint32_t tag, int64_t value, FlagsType<flags::s | flags::f>, Writer &out, bool force = false)
884cc290419Sopenharmony_ci        {
885cc290419Sopenharmony_ci            SerialDetail::WriteTagWriteType(tag, WireType::FIXED64, out);
886cc290419Sopenharmony_ci            SerialDetail::WriteSignedFixed(value, out);
887cc290419Sopenharmony_ci        }
888cc290419Sopenharmony_ci
889cc290419Sopenharmony_ci        static void SerializePacked(int64_t value, FlagsType<>, Writer &out)
890cc290419Sopenharmony_ci        {
891cc290419Sopenharmony_ci            SerialDetail::WriteVarint(value, out);
892cc290419Sopenharmony_ci        }
893cc290419Sopenharmony_ci
894cc290419Sopenharmony_ci        static void SerializePacked(int64_t value, FlagsType<flags::s>, Writer &out)
895cc290419Sopenharmony_ci        {
896cc290419Sopenharmony_ci            SerialDetail::WriteSignedVarint(value, out);
897cc290419Sopenharmony_ci        }
898cc290419Sopenharmony_ci
899cc290419Sopenharmony_ci        static void SerializePacked(int64_t value, FlagsType<flags::s | flags::f>, Writer &out)
900cc290419Sopenharmony_ci        {
901cc290419Sopenharmony_ci            SerialDetail::WriteSignedFixed(value, out);
902cc290419Sopenharmony_ci        }
903cc290419Sopenharmony_ci
904cc290419Sopenharmony_ci        static bool Parse(WireType wire_type, int64_t &value, FlagsType<>, reader &in)
905cc290419Sopenharmony_ci        {
906cc290419Sopenharmony_ci            if (wire_type != WireType::VARINT)
907cc290419Sopenharmony_ci                return false;
908cc290419Sopenharmony_ci            return SerialDetail::ReadVarint(value, in);
909cc290419Sopenharmony_ci        }
910cc290419Sopenharmony_ci
911cc290419Sopenharmony_ci        static bool Parse(WireType wire_type, int64_t &value, FlagsType<flags::s>, reader &in)
912cc290419Sopenharmony_ci        {
913cc290419Sopenharmony_ci            if (wire_type != WireType::VARINT)
914cc290419Sopenharmony_ci                return false;
915cc290419Sopenharmony_ci            return SerialDetail::ReadSignedVarint(value, in);
916cc290419Sopenharmony_ci        }
917cc290419Sopenharmony_ci
918cc290419Sopenharmony_ci        static bool Parse(WireType wire_type, int64_t &value, FlagsType<flags::s | flags::f>, reader &in)
919cc290419Sopenharmony_ci        {
920cc290419Sopenharmony_ci            if (wire_type != WireType::FIXED64)
921cc290419Sopenharmony_ci                return false;
922cc290419Sopenharmony_ci            return SerialDetail::ReadSignedFixed(value, in);
923cc290419Sopenharmony_ci        }
924cc290419Sopenharmony_ci
925cc290419Sopenharmony_ci        static bool ParsePacked(int64_t &value, FlagsType<>, reader &in)
926cc290419Sopenharmony_ci        {
927cc290419Sopenharmony_ci            return SerialDetail::ReadVarint(value, in);
928cc290419Sopenharmony_ci        }
929cc290419Sopenharmony_ci
930cc290419Sopenharmony_ci        static bool ParsePacked(int64_t &value, FlagsType<flags::s>, reader &in)
931cc290419Sopenharmony_ci        {
932cc290419Sopenharmony_ci            return SerialDetail::ReadSignedVarint(value, in);
933cc290419Sopenharmony_ci        }
934cc290419Sopenharmony_ci
935cc290419Sopenharmony_ci        static bool ParsePacked(int64_t &value, FlagsType<flags::s | flags::f>, reader &in)
936cc290419Sopenharmony_ci        {
937cc290419Sopenharmony_ci            return SerialDetail::ReadSignedFixed(value, in);
938cc290419Sopenharmony_ci        }
939cc290419Sopenharmony_ci    };
940cc290419Sopenharmony_ci
941cc290419Sopenharmony_ci    template<> struct Serializer<uint64_t> {
942cc290419Sopenharmony_ci        static void Serialize(uint32_t tag, uint64_t value, FlagsType<>, Writer &out, bool force = false)
943cc290419Sopenharmony_ci        {
944cc290419Sopenharmony_ci            SerialDetail::WriteTagWriteType(tag, WireType::VARINT, out);
945cc290419Sopenharmony_ci            SerialDetail::WriteVarint(value, out);
946cc290419Sopenharmony_ci        }
947cc290419Sopenharmony_ci
948cc290419Sopenharmony_ci        static void Serialize(uint32_t tag, uint64_t value, FlagsType<flags::f>, Writer &out, bool force = false)
949cc290419Sopenharmony_ci        {
950cc290419Sopenharmony_ci            if (!force && value == UINT64_C(0))
951cc290419Sopenharmony_ci                return;
952cc290419Sopenharmony_ci
953cc290419Sopenharmony_ci            SerialDetail::WriteTagWriteType(tag, WireType::FIXED64, out);
954cc290419Sopenharmony_ci            SerialDetail::WriteFixed(value, out);
955cc290419Sopenharmony_ci        }
956cc290419Sopenharmony_ci
957cc290419Sopenharmony_ci        static void SerializePacked(uint64_t value, FlagsType<>, Writer &out)
958cc290419Sopenharmony_ci        {
959cc290419Sopenharmony_ci            SerialDetail::WriteVarint(value, out);
960cc290419Sopenharmony_ci        }
961cc290419Sopenharmony_ci
962cc290419Sopenharmony_ci        static void SerializePacked(uint64_t value, FlagsType<flags::f>, Writer &out)
963cc290419Sopenharmony_ci        {
964cc290419Sopenharmony_ci            SerialDetail::WriteFixed(value, out);
965cc290419Sopenharmony_ci        }
966cc290419Sopenharmony_ci
967cc290419Sopenharmony_ci        static bool Parse(WireType wire_type, uint64_t &value, FlagsType<>, reader &in)
968cc290419Sopenharmony_ci        {
969cc290419Sopenharmony_ci            if (wire_type != WireType::VARINT)
970cc290419Sopenharmony_ci                return false;
971cc290419Sopenharmony_ci            return SerialDetail::ReadVarint(value, in);
972cc290419Sopenharmony_ci        }
973cc290419Sopenharmony_ci
974cc290419Sopenharmony_ci        static bool Parse(WireType wire_type, uint64_t &value, FlagsType<flags::f>, reader &in)
975cc290419Sopenharmony_ci        {
976cc290419Sopenharmony_ci            if (wire_type != WireType::FIXED64)
977cc290419Sopenharmony_ci                return false;
978cc290419Sopenharmony_ci            return SerialDetail::ReadFixed(value, in);
979cc290419Sopenharmony_ci        }
980cc290419Sopenharmony_ci
981cc290419Sopenharmony_ci        static bool ParsePacked(uint64_t &value, FlagsType<>, reader &in)
982cc290419Sopenharmony_ci        {
983cc290419Sopenharmony_ci            return SerialDetail::ReadVarint(value, in);
984cc290419Sopenharmony_ci        }
985cc290419Sopenharmony_ci
986cc290419Sopenharmony_ci        static bool ParsePacked(uint64_t &value, FlagsType<flags::f>, reader &in)
987cc290419Sopenharmony_ci        {
988cc290419Sopenharmony_ci            return SerialDetail::ReadFixed(value, in);
989cc290419Sopenharmony_ci        }
990cc290419Sopenharmony_ci    };
991cc290419Sopenharmony_ci
992cc290419Sopenharmony_ci    template<> struct Serializer<double> {
993cc290419Sopenharmony_ci        static void Serialize(uint32_t tag, double value, FlagsType<>, Writer &out, bool force = false)
994cc290419Sopenharmony_ci        {
995cc290419Sopenharmony_ci            if (!force && std::fpclassify(value) == FP_ZERO) {
996cc290419Sopenharmony_ci                return;
997cc290419Sopenharmony_ci            }
998cc290419Sopenharmony_ci            SerialDetail::WriteTagWriteType(tag, WireType::FIXED64, out);
999cc290419Sopenharmony_ci            SerialDetail::WriteFixed(value, out);
1000cc290419Sopenharmony_ci        }
1001cc290419Sopenharmony_ci
1002cc290419Sopenharmony_ci        static void SerializePacked(double value, FlagsType<>, Writer &out)
1003cc290419Sopenharmony_ci        {
1004cc290419Sopenharmony_ci            SerialDetail::WriteFixed(value, out);
1005cc290419Sopenharmony_ci        }
1006cc290419Sopenharmony_ci
1007cc290419Sopenharmony_ci        static bool Parse(WireType wire_type, double &value, FlagsType<>, reader &in)
1008cc290419Sopenharmony_ci        {
1009cc290419Sopenharmony_ci            if (wire_type != WireType::FIXED64) {
1010cc290419Sopenharmony_ci                return false;
1011cc290419Sopenharmony_ci            }
1012cc290419Sopenharmony_ci            return SerialDetail::ReadFixed(value, in);
1013cc290419Sopenharmony_ci        }
1014cc290419Sopenharmony_ci
1015cc290419Sopenharmony_ci        static bool ParsePacked(double &value, FlagsType<>, reader &in)
1016cc290419Sopenharmony_ci        {
1017cc290419Sopenharmony_ci            return SerialDetail::ReadFixed(value, in);
1018cc290419Sopenharmony_ci        }
1019cc290419Sopenharmony_ci    };
1020cc290419Sopenharmony_ci
1021cc290419Sopenharmony_ci    template<> struct Serializer<float> {
1022cc290419Sopenharmony_ci        static void Serialize(uint32_t tag, float value, FlagsType<>, Writer &out, bool force = false)
1023cc290419Sopenharmony_ci        {
1024cc290419Sopenharmony_ci            if (!force && std::fpclassify(value) == FP_ZERO) {
1025cc290419Sopenharmony_ci                return;
1026cc290419Sopenharmony_ci            }
1027cc290419Sopenharmony_ci            SerialDetail::WriteTagWriteType(tag, WireType::FIXED32, out);
1028cc290419Sopenharmony_ci            SerialDetail::WriteFixed(value, out);
1029cc290419Sopenharmony_ci        }
1030cc290419Sopenharmony_ci
1031cc290419Sopenharmony_ci        static void SerializePacked(float value, FlagsType<>, Writer &out)
1032cc290419Sopenharmony_ci        {
1033cc290419Sopenharmony_ci            SerialDetail::WriteFixed(value, out);
1034cc290419Sopenharmony_ci        }
1035cc290419Sopenharmony_ci
1036cc290419Sopenharmony_ci        static bool Parse(WireType wire_type, float &value, FlagsType<>, reader &in)
1037cc290419Sopenharmony_ci        {
1038cc290419Sopenharmony_ci            if (wire_type != WireType::FIXED32) {
1039cc290419Sopenharmony_ci                return false;
1040cc290419Sopenharmony_ci            }
1041cc290419Sopenharmony_ci            return SerialDetail::ReadFixed(value, in);
1042cc290419Sopenharmony_ci        }
1043cc290419Sopenharmony_ci
1044cc290419Sopenharmony_ci        static bool ParsePacked(float &value, FlagsType<>, reader &in)
1045cc290419Sopenharmony_ci        {
1046cc290419Sopenharmony_ci            return SerialDetail::ReadFixed(value, in);
1047cc290419Sopenharmony_ci        }
1048cc290419Sopenharmony_ci    };
1049cc290419Sopenharmony_ci
1050cc290419Sopenharmony_ci    template<> struct Serializer<bool> {
1051cc290419Sopenharmony_ci        static void Serialize(uint32_t tag, bool value, FlagsType<>, Writer &out, bool force = false)
1052cc290419Sopenharmony_ci        {
1053cc290419Sopenharmony_ci            Serializer<uint32_t>::Serialize(tag, value ? 1 : 0, FlagsType(), out, force);
1054cc290419Sopenharmony_ci        }
1055cc290419Sopenharmony_ci
1056cc290419Sopenharmony_ci        static void SerializePacked(bool value, FlagsType<>, Writer &out)
1057cc290419Sopenharmony_ci        {
1058cc290419Sopenharmony_ci            Serializer<uint32_t>::SerializePacked(value ? 1 : 0, FlagsType(), out);
1059cc290419Sopenharmony_ci        }
1060cc290419Sopenharmony_ci
1061cc290419Sopenharmony_ci        static bool Parse(WireType wire_type, bool &value, FlagsType<>, reader &in)
1062cc290419Sopenharmony_ci        {
1063cc290419Sopenharmony_ci            uint32_t intermedaite_value;
1064cc290419Sopenharmony_ci            if (Serializer<uint32_t>::Parse(wire_type, intermedaite_value, FlagsType<>(), in)) {
1065cc290419Sopenharmony_ci                value = static_cast<bool>(intermedaite_value);
1066cc290419Sopenharmony_ci                return true;
1067cc290419Sopenharmony_ci            }
1068cc290419Sopenharmony_ci            return false;
1069cc290419Sopenharmony_ci        }
1070cc290419Sopenharmony_ci
1071cc290419Sopenharmony_ci        static bool ParsePacked(bool &value, FlagsType<>, reader &in)
1072cc290419Sopenharmony_ci        {
1073cc290419Sopenharmony_ci            uint32_t intermedaite_value;
1074cc290419Sopenharmony_ci            if (Serializer<uint32_t>::ParsePacked(intermedaite_value, FlagsType<>(), in)) {
1075cc290419Sopenharmony_ci                value = static_cast<bool>(intermedaite_value);
1076cc290419Sopenharmony_ci                return true;
1077cc290419Sopenharmony_ci            }
1078cc290419Sopenharmony_ci            return false;
1079cc290419Sopenharmony_ci        }
1080cc290419Sopenharmony_ci    };
1081cc290419Sopenharmony_ci
1082cc290419Sopenharmony_ci    template<class T> struct Serializer<T, std::enable_if_t<std::is_enum_v<T>>> {
1083cc290419Sopenharmony_ci        using U = std::underlying_type_t<T>;
1084cc290419Sopenharmony_ci
1085cc290419Sopenharmony_ci        static void Serialize(uint32_t tag, T value, FlagsType<>, Writer &out, bool force = false)
1086cc290419Sopenharmony_ci        {
1087cc290419Sopenharmony_ci            Serializer<U>::Serialize(tag, static_cast<U>(value), FlagsType<>(), out, force);
1088cc290419Sopenharmony_ci        }
1089cc290419Sopenharmony_ci
1090cc290419Sopenharmony_ci        static void SerializePacked(T value, FlagsType<>, Writer &out)
1091cc290419Sopenharmony_ci        {
1092cc290419Sopenharmony_ci            Serializer<U>::SerializePacked(static_cast<U>(value), FlagsType<>(), out);
1093cc290419Sopenharmony_ci        }
1094cc290419Sopenharmony_ci
1095cc290419Sopenharmony_ci        static bool Parse(WireType wire_type, T &value, FlagsType<>, reader &in)
1096cc290419Sopenharmony_ci        {
1097cc290419Sopenharmony_ci            U intermedaite_value;
1098cc290419Sopenharmony_ci            if (Serializer<U>::Parse(wire_type, intermedaite_value, FlagsType<>(), in)) {
1099cc290419Sopenharmony_ci                value = static_cast<T>(intermedaite_value);
1100cc290419Sopenharmony_ci                return true;
1101cc290419Sopenharmony_ci            }
1102cc290419Sopenharmony_ci            return false;
1103cc290419Sopenharmony_ci        }
1104cc290419Sopenharmony_ci
1105cc290419Sopenharmony_ci        static bool ParsePacked(T &value, FlagsType<>, reader &in)
1106cc290419Sopenharmony_ci        {
1107cc290419Sopenharmony_ci            U intermedaite_value;
1108cc290419Sopenharmony_ci            if (Serializer<U>::ParsePacked(intermedaite_value, FlagsType<>(), in)) {
1109cc290419Sopenharmony_ci                value = static_cast<T>(intermedaite_value);
1110cc290419Sopenharmony_ci                return true;
1111cc290419Sopenharmony_ci            }
1112cc290419Sopenharmony_ci            return false;
1113cc290419Sopenharmony_ci        }
1114cc290419Sopenharmony_ci    };
1115cc290419Sopenharmony_ci
1116cc290419Sopenharmony_ci    template<> struct Serializer<std::string> {
1117cc290419Sopenharmony_ci        static void Serialize(uint32_t tag, const std::string &value, FlagsType<>, Writer &out, bool force = false)
1118cc290419Sopenharmony_ci        {
1119cc290419Sopenharmony_ci            SerialDetail::WriteTagWriteType(tag, WireType::LENGTH_DELIMETED, out);
1120cc290419Sopenharmony_ci            SerialDetail::WriteVarint(value.size(), out);
1121cc290419Sopenharmony_ci            out.Write(value.data(), value.size());
1122cc290419Sopenharmony_ci        }
1123cc290419Sopenharmony_ci
1124cc290419Sopenharmony_ci        static bool Parse(WireType wire_type, std::string &value, FlagsType<>, reader &in)
1125cc290419Sopenharmony_ci        {
1126cc290419Sopenharmony_ci            if (wire_type != WireType::LENGTH_DELIMETED) {
1127cc290419Sopenharmony_ci                return false;
1128cc290419Sopenharmony_ci            }
1129cc290419Sopenharmony_ci            size_t size;
1130cc290419Sopenharmony_ci            if (SerialDetail::ReadVarint(size, in)) {
1131cc290419Sopenharmony_ci                value.resize(size);
1132cc290419Sopenharmony_ci                if (in.Read(value.data(), size) == size) {
1133cc290419Sopenharmony_ci                    return true;
1134cc290419Sopenharmony_ci                }
1135cc290419Sopenharmony_ci            }
1136cc290419Sopenharmony_ci            return false;
1137cc290419Sopenharmony_ci        }
1138cc290419Sopenharmony_ci    };
1139cc290419Sopenharmony_ci
1140cc290419Sopenharmony_ci    template<class T> struct Serializer<std::vector<T>> {
1141cc290419Sopenharmony_ci        template<uint32_t Flags>
1142cc290419Sopenharmony_ci        static void Serialize(uint32_t tag, const std::vector<T> &value, FlagsType<Flags>, Writer &out)
1143cc290419Sopenharmony_ci        {
1144cc290419Sopenharmony_ci            SerialDetail::WriteRepeated<Flags, T>(tag, value.begin(), value.end(), out);
1145cc290419Sopenharmony_ci        }
1146cc290419Sopenharmony_ci
1147cc290419Sopenharmony_ci        template<uint32_t Flags>
1148cc290419Sopenharmony_ci        static bool Parse(WireType wire_type, std::vector<T> &value, FlagsType<Flags>, reader &in)
1149cc290419Sopenharmony_ci        {
1150cc290419Sopenharmony_ci            return SerialDetail::ReadRepeated<Flags, T>(wire_type, std::back_inserter(value), in);
1151cc290419Sopenharmony_ci        }
1152cc290419Sopenharmony_ci    };
1153cc290419Sopenharmony_ci
1154cc290419Sopenharmony_ci    template<class T> struct Serializer<std::optional<T>> {
1155cc290419Sopenharmony_ci        template<uint32_t Flags>
1156cc290419Sopenharmony_ci        static void Serialize(uint32_t tag, const std::optional<T> &value, FlagsType<Flags>, Writer &out)
1157cc290419Sopenharmony_ci        {
1158cc290419Sopenharmony_ci            if (!value.has_value()) {
1159cc290419Sopenharmony_ci                return;
1160cc290419Sopenharmony_ci            }
1161cc290419Sopenharmony_ci            Serializer<T>::Serialize(tag, *value, FlagsType<Flags>(), out);
1162cc290419Sopenharmony_ci        }
1163cc290419Sopenharmony_ci
1164cc290419Sopenharmony_ci        template<uint32_t Flags>
1165cc290419Sopenharmony_ci        static bool Parse(WireType wire_type, std::optional<T> &value, FlagsType<Flags>, reader &in)
1166cc290419Sopenharmony_ci        {
1167cc290419Sopenharmony_ci            return Serializer<T>::Parse(wire_type, value.emplace(), FlagsType<Flags>(), in);
1168cc290419Sopenharmony_ci        }
1169cc290419Sopenharmony_ci    };
1170cc290419Sopenharmony_ci
1171cc290419Sopenharmony_ci    template<class... T> struct Serializer<std::variant<T...>> {
1172cc290419Sopenharmony_ci        template<size_t Index, uint32_t Flags>
1173cc290419Sopenharmony_ci        static void SerializeOneof(uint32_t tag, const std::variant<T...> &value, FlagsType<Flags>, Writer &out)
1174cc290419Sopenharmony_ci        {
1175cc290419Sopenharmony_ci            if (value.index() != Index)
1176cc290419Sopenharmony_ci                return;
1177cc290419Sopenharmony_ci
1178cc290419Sopenharmony_ci            Serializer<std::variant_alternative_t<Index, std::variant<T...>>>::Serialize(
1179cc290419Sopenharmony_ci                tag, std::get<Index>(value), FlagsType<Flags>(), out);
1180cc290419Sopenharmony_ci        }
1181cc290419Sopenharmony_ci
1182cc290419Sopenharmony_ci        template<size_t Index, uint32_t Flags>
1183cc290419Sopenharmony_ci        static bool ParseOneof(WireType wire_type, std::variant<T...> &value, FlagsType<Flags>, reader &in)
1184cc290419Sopenharmony_ci        {
1185cc290419Sopenharmony_ci            return Serializer<std::variant_alternative_t<Index, std::variant<T...>>>::Parse(
1186cc290419Sopenharmony_ci                wire_type, value.template emplace<Index>(), FlagsType<Flags>(), in);
1187cc290419Sopenharmony_ci        }
1188cc290419Sopenharmony_ci    };
1189cc290419Sopenharmony_ci
1190cc290419Sopenharmony_ci    template<class Key, class Value> struct Serializer<std::map<Key, Value>> {
1191cc290419Sopenharmony_ci        template<uint32_t KeyFlags, uint32_t ValueFlags>
1192cc290419Sopenharmony_ci        static void SerializeMap(
1193cc290419Sopenharmony_ci            uint32_t tag, const std::map<Key, Value> &value, FlagsType<KeyFlags>, FlagsType<ValueFlags>, Writer &out)
1194cc290419Sopenharmony_ci        {
1195cc290419Sopenharmony_ci            SerialDetail::WriteMap<KeyFlags, ValueFlags>(tag, value, out);
1196cc290419Sopenharmony_ci        }
1197cc290419Sopenharmony_ci
1198cc290419Sopenharmony_ci        template<uint32_t KeyFlags, uint32_t ValueFlags>
1199cc290419Sopenharmony_ci        static bool ParseMap(
1200cc290419Sopenharmony_ci            WireType wire_type, std::map<Key, Value> &value, FlagsType<KeyFlags>, FlagsType<ValueFlags>, reader &in)
1201cc290419Sopenharmony_ci        {
1202cc290419Sopenharmony_ci            return SerialDetail::ReadMap<KeyFlags, ValueFlags>(wire_type, value, in);
1203cc290419Sopenharmony_ci        }
1204cc290419Sopenharmony_ci    };
1205cc290419Sopenharmony_ci
1206cc290419Sopenharmony_ci    struct StringWriter : public Writer {
1207cc290419Sopenharmony_ci        StringWriter(std::string &out)
1208cc290419Sopenharmony_ci            : _out(out)
1209cc290419Sopenharmony_ci        {
1210cc290419Sopenharmony_ci        }
1211cc290419Sopenharmony_ci
1212cc290419Sopenharmony_ci        void Write(const void *bytes, size_t size) override
1213cc290419Sopenharmony_ci        {
1214cc290419Sopenharmony_ci            _out.append(reinterpret_cast<const char *>(bytes), size);
1215cc290419Sopenharmony_ci        }
1216cc290419Sopenharmony_ci
1217cc290419Sopenharmony_ci    private:
1218cc290419Sopenharmony_ci        std::string &_out;
1219cc290419Sopenharmony_ci    };
1220cc290419Sopenharmony_ci
1221cc290419Sopenharmony_ci    struct StringReader : public reader {
1222cc290419Sopenharmony_ci        StringReader(const std::string &in)
1223cc290419Sopenharmony_ci            : _in(in), _pos(0)
1224cc290419Sopenharmony_ci        {
1225cc290419Sopenharmony_ci        }
1226cc290419Sopenharmony_ci
1227cc290419Sopenharmony_ci        size_t Read(void *bytes, size_t size) override
1228cc290419Sopenharmony_ci        {
1229cc290419Sopenharmony_ci            if (_in.size() < _pos) {
1230cc290419Sopenharmony_ci                return 0;
1231cc290419Sopenharmony_ci            }
1232cc290419Sopenharmony_ci            size_t readSize = std::min(size, _in.size() - _pos);
1233cc290419Sopenharmony_ci            if (memcpy_s(bytes, size, _in.data() + _pos, readSize) != EOK) {
1234cc290419Sopenharmony_ci                return readSize;
1235cc290419Sopenharmony_ci            }
1236cc290419Sopenharmony_ci            _pos += readSize;
1237cc290419Sopenharmony_ci            return readSize;
1238cc290419Sopenharmony_ci        }
1239cc290419Sopenharmony_ci
1240cc290419Sopenharmony_ci    private:
1241cc290419Sopenharmony_ci        const std::string &_in;
1242cc290419Sopenharmony_ci        size_t _pos;
1243cc290419Sopenharmony_ci    };
1244cc290419Sopenharmony_ci    // mytype begin, just support base type, but really use protobuf raw type(uint32)
1245cc290419Sopenharmony_ci    template<> struct Serializer<uint8_t> {
1246cc290419Sopenharmony_ci        static void Serialize(uint32_t tag, uint8_t value, FlagsType<>, Writer &out, bool force = false)
1247cc290419Sopenharmony_ci        {
1248cc290419Sopenharmony_ci            Serializer<uint32_t>::Serialize(tag, value, FlagsType(), out, force);
1249cc290419Sopenharmony_ci        }
1250cc290419Sopenharmony_ci
1251cc290419Sopenharmony_ci        static void SerializePacked(uint8_t value, FlagsType<>, Writer &out)
1252cc290419Sopenharmony_ci        {
1253cc290419Sopenharmony_ci            Serializer<uint32_t>::SerializePacked(value, FlagsType(), out);
1254cc290419Sopenharmony_ci        }
1255cc290419Sopenharmony_ci
1256cc290419Sopenharmony_ci        static bool Parse(WireType wire_type, uint8_t &value, FlagsType<>, reader &in)
1257cc290419Sopenharmony_ci        {
1258cc290419Sopenharmony_ci            uint32_t intermedaite_value;
1259cc290419Sopenharmony_ci            if (Serializer<uint32_t>::Parse(wire_type, intermedaite_value, FlagsType<>(), in)) {
1260cc290419Sopenharmony_ci                value = static_cast<uint8_t>(intermedaite_value);
1261cc290419Sopenharmony_ci                return true;
1262cc290419Sopenharmony_ci            }
1263cc290419Sopenharmony_ci            return false;
1264cc290419Sopenharmony_ci        }
1265cc290419Sopenharmony_ci
1266cc290419Sopenharmony_ci        static bool ParsePacked(uint8_t &value, FlagsType<>, reader &in)
1267cc290419Sopenharmony_ci        {
1268cc290419Sopenharmony_ci            uint32_t intermedaite_value;
1269cc290419Sopenharmony_ci            if (Serializer<uint32_t>::ParsePacked(intermedaite_value, FlagsType<>(), in)) {
1270cc290419Sopenharmony_ci                value = static_cast<uint8_t>(intermedaite_value);
1271cc290419Sopenharmony_ci                return true;
1272cc290419Sopenharmony_ci            }
1273cc290419Sopenharmony_ci            return false;
1274cc290419Sopenharmony_ci        }
1275cc290419Sopenharmony_ci    };
1276cc290419Sopenharmony_ci    template<> struct Serializer<uint16_t> {
1277cc290419Sopenharmony_ci        static void Serialize(uint32_t tag, uint16_t value, FlagsType<>, Writer &out, bool force = false)
1278cc290419Sopenharmony_ci        {
1279cc290419Sopenharmony_ci            Serializer<uint32_t>::Serialize(tag, value, FlagsType(), out, force);
1280cc290419Sopenharmony_ci        }
1281cc290419Sopenharmony_ci
1282cc290419Sopenharmony_ci        static void SerializePacked(uint16_t value, FlagsType<>, Writer &out)
1283cc290419Sopenharmony_ci        {
1284cc290419Sopenharmony_ci            Serializer<uint32_t>::SerializePacked(value, FlagsType(), out);
1285cc290419Sopenharmony_ci        }
1286cc290419Sopenharmony_ci
1287cc290419Sopenharmony_ci        static bool Parse(WireType wire_type, uint16_t &value, FlagsType<>, reader &in)
1288cc290419Sopenharmony_ci        {
1289cc290419Sopenharmony_ci            uint32_t intermedaite_value;
1290cc290419Sopenharmony_ci            if (Serializer<uint32_t>::Parse(wire_type, intermedaite_value, FlagsType<>(), in)) {
1291cc290419Sopenharmony_ci                value = static_cast<uint16_t>(intermedaite_value);
1292cc290419Sopenharmony_ci                return true;
1293cc290419Sopenharmony_ci            }
1294cc290419Sopenharmony_ci            return false;
1295cc290419Sopenharmony_ci        }
1296cc290419Sopenharmony_ci
1297cc290419Sopenharmony_ci        static bool ParsePacked(uint16_t &value, FlagsType<>, reader &in)
1298cc290419Sopenharmony_ci        {
1299cc290419Sopenharmony_ci            uint32_t intermedaite_value;
1300cc290419Sopenharmony_ci            if (Serializer<uint32_t>::ParsePacked(intermedaite_value, FlagsType<>(), in)) {
1301cc290419Sopenharmony_ci                value = static_cast<uint16_t>(intermedaite_value);
1302cc290419Sopenharmony_ci                return true;
1303cc290419Sopenharmony_ci            }
1304cc290419Sopenharmony_ci            return false;
1305cc290419Sopenharmony_ci        }
1306cc290419Sopenharmony_ci    };
1307cc290419Sopenharmony_ci    // mytype finish
1308cc290419Sopenharmony_ci
1309cc290419Sopenharmony_ci    template<class T> std::string SerializeToString(const T &value)
1310cc290419Sopenharmony_ci    {
1311cc290419Sopenharmony_ci        std::string out;
1312cc290419Sopenharmony_ci        StringWriter stringOut(out);
1313cc290419Sopenharmony_ci        SerialDetail::WriteMessage(value, MessageType<T>(), stringOut);
1314cc290419Sopenharmony_ci        return out;
1315cc290419Sopenharmony_ci    }
1316cc290419Sopenharmony_ci
1317cc290419Sopenharmony_ci    template<class T> bool ParseFromString(T &value, const std::string &in)
1318cc290419Sopenharmony_ci    {
1319cc290419Sopenharmony_ci        StringReader stringIn(in);
1320cc290419Sopenharmony_ci        return SerialDetail::ReadMessage(value, MessageType<T>(), stringIn);
1321cc290419Sopenharmony_ci    }
1322cc290419Sopenharmony_ci}
1323cc290419Sopenharmony_ci// clang-format on
1324cc290419Sopenharmony_ci}  // Hdc
1325cc290419Sopenharmony_ci#endif  // HDC_SERIAL_STRUCT_DEFINE_H
1326