1 | // Copyright (C) 2021 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 QJSONRPCPROTOCOL_P_H |
5 | #define QJSONRPCPROTOCOL_P_H |
6 | |
7 | // |
8 | // W A R N I N G |
9 | // ------------- |
10 | // |
11 | // This file is not part of the Qt API. It exists purely as an |
12 | // implementation detail. This header file may change from version to |
13 | // version without notice, or even be removed. |
14 | // |
15 | // We mean it. |
16 | // |
17 | |
18 | #include <QtJsonRpc/qtjsonrpcglobal.h> |
19 | #include <QtCore/qjsonvalue.h> |
20 | #include <QtCore/qjsondocument.h> |
21 | |
22 | #include <memory> |
23 | |
24 | QT_BEGIN_NAMESPACE |
25 | |
26 | class QLaguageServer; |
27 | class QJsonRpcTransport; |
28 | class QJsonRpcProtocolPrivate; |
29 | class Q_JSONRPC_EXPORT QJsonRpcProtocol |
30 | { |
31 | Q_DISABLE_COPY(QJsonRpcProtocol) |
32 | public: |
33 | QJsonRpcProtocol(); |
34 | QJsonRpcProtocol(QJsonRpcProtocol &&) noexcept; |
35 | QJsonRpcProtocol &operator=(QJsonRpcProtocol &&) noexcept; |
36 | |
37 | ~QJsonRpcProtocol(); |
38 | |
39 | enum class ErrorCode { |
40 | ParseError = -32700, |
41 | InvalidRequest = -32600, |
42 | MethodNotFound = -32601, |
43 | InvalidParams = -32602, |
44 | InternalError = -32603, |
45 | }; |
46 | |
47 | struct Request |
48 | { |
49 | QJsonValue id = QJsonValue::Undefined; |
50 | QString method; |
51 | QJsonValue params = QJsonValue::Undefined; |
52 | }; |
53 | |
54 | struct Response |
55 | { |
56 | // ID is disregarded on responses generated from MessageHandlers. |
57 | // You cannot reply to a request you didn't handle. The original request ID is used instead. |
58 | QJsonValue id = QJsonValue::Undefined; |
59 | |
60 | // In case of !errorCode.isDouble(), data is the "data" member of the error object. |
61 | // Otherwise it's the "result" member of the base response. |
62 | QJsonValue data = QJsonValue::Undefined; |
63 | |
64 | // Error codes from and including -32768 to -32000 are reserved for pre-defined errors. |
65 | // Don't use them for your own protocol. We cannot enforce this here. |
66 | QJsonValue errorCode = QJsonValue::Undefined; |
67 | |
68 | QString errorMessage = QString(); |
69 | }; |
70 | |
71 | template<typename T> |
72 | using Handler = std::function<void(const T &)>; |
73 | |
74 | struct Notification |
75 | { |
76 | QString method; |
77 | QJsonValue params = QJsonValue::Undefined; |
78 | }; |
79 | |
80 | class Q_JSONRPC_EXPORT MessageHandler |
81 | { |
82 | Q_DISABLE_COPY_MOVE(MessageHandler) |
83 | public: |
84 | using ResponseHandler = std::function<void(const Response &)>; |
85 | |
86 | MessageHandler(); |
87 | virtual ~MessageHandler(); |
88 | virtual void handleRequest(const Request &request, const ResponseHandler &handler); |
89 | virtual void handleNotification(const Notification ¬ification); |
90 | |
91 | static Response error(ErrorCode code); |
92 | static Response error(int code, const QString &message, |
93 | const QJsonValue &data = QJsonValue::Undefined); |
94 | |
95 | protected: |
96 | static Response result(const QJsonValue &result); |
97 | }; |
98 | |
99 | class BatchPrivate; |
100 | class Q_JSONRPC_EXPORT Batch |
101 | { |
102 | Q_DISABLE_COPY(Batch) |
103 | public: |
104 | Batch(); |
105 | ~Batch(); |
106 | |
107 | Batch(Batch &&) noexcept; |
108 | Batch &operator=(Batch &&) noexcept; |
109 | |
110 | void addNotification(const Notification ¬ification); |
111 | void addRequest(const Request &request); |
112 | |
113 | private: |
114 | friend class QJsonRpcProtocol; |
115 | std::unique_ptr<BatchPrivate> d; |
116 | }; |
117 | |
118 | void setMessageHandler(const QString &method, MessageHandler *handler); |
119 | void setDefaultMessageHandler(MessageHandler *handler); |
120 | MessageHandler *messageHandler(const QString &method) const; |
121 | MessageHandler *defaultMessageHandler() const; |
122 | |
123 | void sendRequest(const Request &request, const QJsonRpcProtocol::Handler<Response> &handler); |
124 | void sendNotification(const Notification ¬ification); |
125 | void sendBatch(Batch &&batch, const QJsonRpcProtocol::Handler<Response> &handler); |
126 | |
127 | void setTransport(QJsonRpcTransport *transport); |
128 | |
129 | // For id:null responses |
130 | using ResponseHandler = std::function<void(const Response &)>; |
131 | void setProtocolErrorHandler(const ResponseHandler &handler); |
132 | ResponseHandler protocolErrorHandler() const; |
133 | |
134 | // For responses with unknown IDs |
135 | void setInvalidResponseHandler(const ResponseHandler &handler); |
136 | ResponseHandler invalidResponseHandler() const; |
137 | |
138 | enum class Processing { Continue, Stop }; |
139 | using MessagePreprocessor = |
140 | std::function<Processing(const QJsonDocument &, const QJsonParseError &, |
141 | const QJsonRpcProtocol::Handler<Response> &handler)>; |
142 | MessagePreprocessor messagePreprocessor() const; |
143 | void installMessagePreprocessor(const MessagePreprocessor &preHandler); |
144 | |
145 | private: |
146 | std::unique_ptr<QJsonRpcProtocolPrivate> d; |
147 | }; |
148 | |
149 | QT_END_NAMESPACE |
150 | |
151 | #endif // QJSONRPCPROTOCOL_P_H |
152 | |