1// Copyright (C) 2022 The Qt Company Ltd.
2// Copyright (C) 2019 Alexey Edelev <semlanik@gmail.com>
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#ifndef QTPROTOBUFTYPES_H
6#define QTPROTOBUFTYPES_H
7
8#include <QtProtobuf/qtprotobufglobal.h>
9
10#include <QtCore/QList>
11#include <QtCore/QHash>
12#include <QtCore/QMetaType>
13#include <QtCore/QtEndian>
14#include <QtProtobuf/QProtobufMessage>
15
16#include <memory>
17#include <functional>
18#include <list>
19#include <type_traits>
20#include <utility>
21
22QT_BEGIN_NAMESPACE
23
24namespace QtProtobufPrivate {
25
26enum FieldFlag : uint { NoFlags = 0x0, NonPacked = 0x1, Oneof = 0x02 };
27
28struct QProtobufPropertyOrdering
29{
30 const struct Data
31 {
32 uint version;
33 uint numFields;
34 uint fieldNumberOffset;
35 uint propertyIndexOffset;
36 uint flagsOffset;
37 uint fullPackageNameSize;
38 } *data;
39
40 Q_PROTOBUF_EXPORT QUtf8StringView getMessageFullName() const;
41 Q_PROTOBUF_EXPORT QUtf8StringView getJsonName(int index) const;
42 Q_PROTOBUF_EXPORT int getFieldNumber(int index) const;
43 Q_PROTOBUF_EXPORT int getPropertyIndex(int index) const;
44 Q_PROTOBUF_EXPORT uint getFieldFlags(int index) const;
45 Q_PROTOBUF_EXPORT int indexOfFieldNumber(int fieldNumber) const;
46 int fieldCount() const { return int(data->numFields); }
47
48private:
49 const uint *uint_data() const;
50 const char *char_data() const;
51 const uint &uint_dataForIndex(int index, uint offset) const;
52};
53static_assert(std::is_trivially_destructible_v<QProtobufPropertyOrdering>);
54
55extern Q_PROTOBUF_EXPORT void registerOrdering(QMetaType type, QProtobufPropertyOrdering ordering);
56
57// Convenience structure to hold a reference to a single entry
58struct QProtobufPropertyOrderingInfo
59{
60 QProtobufPropertyOrderingInfo(QProtobufPropertyOrdering ord, int ind)
61 : ordering(ord), index(ind)
62 {
63 Q_ASSERT(index >= 0);
64 }
65
66 QUtf8StringView getJsonName() const { return ordering.getJsonName(index); }
67 int getFieldNumber() const
68 {
69 return (overrideFieldNumber >= 0) ? overrideFieldNumber : ordering.getFieldNumber(index);
70 }
71 int getPropertyIndex() const { return ordering.getPropertyIndex(index); }
72 uint getFieldFlags() const { return ordering.getFieldFlags(index); }
73
74 // Needed for maps, which uses field number 1 and 2 for key and value respectively
75 QProtobufPropertyOrderingInfo infoForMapKey() const { return { ordering, index, 1 }; }
76 QProtobufPropertyOrderingInfo infoForMapValue() const { return { ordering, index, 2 }; }
77
78private:
79 QProtobufPropertyOrderingInfo(QProtobufPropertyOrdering ord, int ind, int fieldNumber)
80 : ordering(ord), index(ind), overrideFieldNumber(fieldNumber)
81 {
82 }
83 const QProtobufPropertyOrdering ordering;
84 const int index;
85 const int overrideFieldNumber = -1; // special case for maps
86};
87
88template<typename>
89using sfinae = void;
90template<typename T, typename = void>
91[[maybe_unused]] static constexpr bool HasProtobufPropertyOrdering = false;
92template<typename T>
93[[maybe_unused]] static constexpr bool
94 HasProtobufPropertyOrdering<T, sfinae<decltype(T::propertyOrdering)>> = true;
95} // namespace QtProtobufPrivate
96
97namespace QtProtobuf {
98Q_NAMESPACE_EXPORT(Q_PROTOBUF_EXPORT)
99
100[[maybe_unused]] constexpr int InvalidFieldNumber = 0;
101
102enum class WireTypes
103{
104 Unknown = -1,
105 Varint = 0,
106 Fixed64 = 1,
107 LengthDelimited = 2,
108 StartGroup = 3,
109 EndGroup = 4,
110 Fixed32 = 5
111};
112Q_ENUM_NS(WireTypes)
113
114// The 'tag' template param exists only create a unique type
115template<typename T, typename tag>
116struct TransparentWrapper
117{
118 TransparentWrapper(T t = T()) : _t(t) { }
119 T _t;
120 operator T &() { return _t; }
121 operator T() const { return _t; }
122 TransparentWrapper &operator=(const T &t)
123 {
124 _t = t;
125 return *this;
126 }
127
128 static T toType(TransparentWrapper t) { return t._t; }
129 static TransparentWrapper fromType(T _t) { return TransparentWrapper(_t); }
130
131 static QString toString(TransparentWrapper t) { return QString::number(t._t); }
132};
133
134template<typename T, typename tag>
135constexpr TransparentWrapper<T, tag> qbswap(TransparentWrapper<T, tag> source)
136{
137 return { QT_PREPEND_NAMESPACE(qbswap)(source._t) };
138}
139
140using int32 = TransparentWrapper<int32_t, struct int_tag>;
141using int64 = TransparentWrapper<int64_t, struct int_tag>;
142using uint32 = uint32_t;
143using uint64 = uint64_t;
144using sint32 = int32_t;
145using sint64 = int64_t;
146using fixed32 = TransparentWrapper<uint32_t, struct fixed_tag>;
147using fixed64 = TransparentWrapper<uint64_t, struct fixed_tag>;
148using sfixed32 = TransparentWrapper<int32_t, struct fixed_tag>;
149using sfixed64 = TransparentWrapper<int64_t, struct fixed_tag>;
150using boolean = bool;
151using int32List = QList<int32>;
152using int64List = QList<int64>;
153using uint32List = QList<uint32>;
154using uint64List = QList<uint64>;
155using sint32List = QList<sint32>;
156using sint64List = QList<sint64>;
157using fixed32List = QList<fixed32>;
158using fixed64List = QList<fixed64>;
159using sfixed32List = QList<sfixed32>;
160using sfixed64List = QList<sfixed64>;
161using floatList = QList<float>;
162using doubleList = QList<double>;
163using boolList = QList<bool>;
164
165using RegisterFunction = void (*)();
166// This struct is used for type registrations in generated code
167struct ProtoTypeRegistrar
168{
169 Q_PROTOBUF_EXPORT explicit ProtoTypeRegistrar(QtProtobuf::RegisterFunction initializer);
170};
171
172template<typename T>
173bool repeatedValueCompare(const QList<T> &a, const QList<T> &b)
174{
175 return std::equal(a.begin(), a.end(), b.begin(), b.end());
176}
177
178template<typename K, typename V>
179bool repeatedValueCompare(const QHash<K, V> &a, const QHash<K, V> &b)
180{
181 return a == b;
182}
183
184template<typename T>
185struct qMakeUnsignedImpl
186{
187 using type = std::make_unsigned_t<T>;
188};
189template<typename T>
190struct qMakeUnsignedImpl<TransparentWrapper<T, struct fixed_tag>>
191{
192 using type = TransparentWrapper<std::make_unsigned_t<T>, fixed_tag>;
193};
194template<>
195struct qMakeUnsignedImpl<int32>
196{
197 using type = uint32_t;
198};
199template<>
200struct qMakeUnsignedImpl<int64>
201{
202 using type = uint64_t;
203};
204template<typename T>
205using qMakeUnsigned = typename qMakeUnsignedImpl<T>::type;
206
207} // namespace QtProtobuf
208
209Q_PROTOBUF_EXPORT void qRegisterProtobufTypes();
210
211QT_END_NAMESPACE
212
213QT_DECL_METATYPE_EXTERN_TAGGED(QtProtobuf::int32, QtProtobuf_int32, Q_PROTOBUF_EXPORT)
214QT_DECL_METATYPE_EXTERN_TAGGED(QtProtobuf::int64, QtProtobuf_int64, Q_PROTOBUF_EXPORT)
215QT_DECL_METATYPE_EXTERN_TAGGED(QtProtobuf::fixed32, QtProtobuf_fixed32, Q_PROTOBUF_EXPORT)
216QT_DECL_METATYPE_EXTERN_TAGGED(QtProtobuf::fixed64, QtProtobuf_fixed64, Q_PROTOBUF_EXPORT)
217QT_DECL_METATYPE_EXTERN_TAGGED(QtProtobuf::sfixed32, QtProtobuf_sfixed32, Q_PROTOBUF_EXPORT)
218QT_DECL_METATYPE_EXTERN_TAGGED(QtProtobuf::sfixed64, QtProtobuf_sfixed64, Q_PROTOBUF_EXPORT)
219
220#endif // QTPROTOBUFTYPES_H
221

source code of qtgrpc/src/protobuf/qtprotobuftypes.h