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
23QT_BEGIN_NAMESPACE
24
25class QProtobufMessage;
26
27namespace QtProtobuf {
28using RegisterFunction = void (*)();
29// This struct is used for type registrations in generated code
30struct ProtoTypeRegistrar
31{
32 Q_PROTOBUF_EXPORT explicit ProtoTypeRegistrar(QtProtobuf::RegisterFunction initializer);
33};
34}
35
36namespace QtProtobufPrivate {
37extern Q_PROTOBUF_EXPORT void registerOrdering(QMetaType type, QProtobufPropertyOrdering ordering);
38
39template <typename T, typename std::enable_if_t<std::is_enum<T>::value, bool> = true>
40static 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
49template <typename T, typename std::enable_if_t<std::is_enum<T>::value, bool> = true>
50static 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
59template <typename T, typename std::enable_if_t<std::is_enum<T>::value, bool> = true>
60static 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
76template <typename T, typename std::enable_if_t<std::is_enum<T>::value, bool> = true>
77static 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
89Q_PROTOBUF_EXPORT void qRegisterProtobufTypes();
90
91template<typename T, QtProtobuf::if_protobuf_message<T> = true>
92inline 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
100template <typename K, typename V, QtProtobuf::if_protobuf_map<K, V> = true>
101inline void qRegisterProtobufMapType()
102{
103 QMetaType::registerMutableView<
104 QHash<K, V>, QProtobufRepeatedIterator>(&QProtobufRepeatedIterator::fromHash<K, V>);
105}
106
107template <typename T, typename std::enable_if_t<std::is_enum<T>::value, bool> = true>
108inline 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
118QT_END_NAMESPACE
119
120#endif // QPROTOBUFREGISTRATION_H
121

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