1 | // Copyright (C) 2024 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #ifndef QPROTOBUFREGISTRATION_H |
5 | #define QPROTOBUFREGISTRATION_H |
6 | |
7 | #if 0 |
8 | # pragma qt_sync_skip_header_check |
9 | # pragma qt_sync_stop_processing |
10 | #endif |
11 | |
12 | #include <QtProtobuf/qtprotobufexports.h> |
13 | |
14 | #include <QtProtobuf/qprotobufpropertyordering.h> |
15 | #include <QtProtobuf/qprotobufrepeatediterator.h> |
16 | #include <QtProtobuf/qtprotobuftypes.h> |
17 | |
18 | #include <QtCore/qhash.h> |
19 | #include <QtCore/qlist.h> |
20 | #include <QtCore/qmetaobject.h> |
21 | #include <QtCore/qmetatype.h> |
22 | |
23 | QT_BEGIN_NAMESPACE |
24 | |
25 | class QProtobufMessage; |
26 | |
27 | namespace QtProtobuf { |
28 | using RegisterFunction = void (*)(); |
29 | // This struct is used for type registrations in generated code |
30 | struct ProtoTypeRegistrar |
31 | { |
32 | Q_PROTOBUF_EXPORT explicit ProtoTypeRegistrar(QtProtobuf::RegisterFunction initializer); |
33 | }; |
34 | } |
35 | |
36 | namespace QtProtobufPrivate { |
37 | extern Q_PROTOBUF_EXPORT void registerOrdering(QMetaType type, QProtobufPropertyOrdering ordering); |
38 | |
39 | template <typename T, typename std::enable_if_t<std::is_enum<T>::value, bool> = true> |
40 | static std::optional<QList<T>> intToEnumList(const QList<QtProtobuf::int64> &v) |
41 | { |
42 | QList<T> enumList; |
43 | for (const auto &intValue : v) |
44 | enumList.append(static_cast<T>(intValue.t)); |
45 | |
46 | return enumList; |
47 | } |
48 | |
49 | template <typename T, typename std::enable_if_t<std::is_enum<T>::value, bool> = true> |
50 | static QList<QtProtobuf::int64> enumToIntList(const QList<T> &v) |
51 | { |
52 | QList<QtProtobuf::int64> intList; |
53 | for (const auto enumValue : v) |
54 | intList.append(t: QtProtobuf::int64(qToUnderlying(enumValue))); |
55 | |
56 | return intList; |
57 | } |
58 | |
59 | template <typename T, typename std::enable_if_t<std::is_enum<T>::value, bool> = true> |
60 | static std::optional<QList<T>> stringToEnumList(const QStringList &v) |
61 | { |
62 | static const QMetaEnum metaEnum = QMetaEnum::fromType<T>(); |
63 | QList<T> enumList; |
64 | bool ok = false; |
65 | for (const auto &stringValue : v) { |
66 | T enumV = T(metaEnum.keyToValue(key: stringValue.toUtf8().data(), ok: &ok)); |
67 | if (!ok) |
68 | return std::nullopt; |
69 | |
70 | enumList.append(enumV); |
71 | } |
72 | |
73 | return enumList; |
74 | } |
75 | |
76 | template <typename T, typename std::enable_if_t<std::is_enum<T>::value, bool> = true> |
77 | static QStringList enumToStringList(const QList<T> &v) |
78 | { |
79 | static const QMetaEnum metaEnum = QMetaEnum::fromType<T>(); |
80 | QStringList stringList; |
81 | for (const auto enumValue : v) |
82 | stringList.append(QString::fromUtf8(metaEnum.valueToKey(value: qToUnderlying(enumValue)))); |
83 | |
84 | return stringList; |
85 | } |
86 | |
87 | } // namespace QtProtobufPrivate |
88 | |
89 | Q_PROTOBUF_EXPORT void qRegisterProtobufTypes(); |
90 | |
91 | template<typename T, QtProtobuf::if_protobuf_message<T> = true> |
92 | inline void qRegisterProtobufType() |
93 | { |
94 | T::registerTypes(); |
95 | QMetaType::registerMutableView< |
96 | QList<T>, QProtobufRepeatedIterator>(&QProtobufRepeatedIterator::fromList<T>); |
97 | QtProtobufPrivate::registerOrdering(type: QMetaType::fromType<T>(), ordering: T::staticPropertyOrdering); |
98 | } |
99 | |
100 | template <typename K, typename V, QtProtobuf::if_protobuf_map<K, V> = true> |
101 | inline void qRegisterProtobufMapType() |
102 | { |
103 | QMetaType::registerMutableView< |
104 | QHash<K, V>, QProtobufRepeatedIterator>(&QProtobufRepeatedIterator::fromHash<K, V>); |
105 | } |
106 | |
107 | template <typename T, typename std::enable_if_t<std::is_enum<T>::value, bool> = true> |
108 | inline void qRegisterProtobufEnumType() |
109 | { |
110 | QMetaType::registerConverter<QList<T>, |
111 | QList<QtProtobuf::int64>>(QtProtobufPrivate::enumToIntList<T>); |
112 | QMetaType::registerConverter<QList<QtProtobuf::int64>, |
113 | QList<T>>(QtProtobufPrivate::intToEnumList<T>); |
114 | QMetaType::registerConverter<QList<T>, QStringList>(QtProtobufPrivate::enumToStringList<T>); |
115 | QMetaType::registerConverter<QStringList, QList<T>>(QtProtobufPrivate::stringToEnumList<T>); |
116 | } |
117 | |
118 | QT_END_NAMESPACE |
119 | |
120 | #endif // QPROTOBUFREGISTRATION_H |
121 | |