| 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 | #include <QtJsonRpc/private/qjsonrpcprotocol_p.h> |
| 5 | #include <QtLanguageServer/private/qlanguageserverprotocol_p.h> |
| 6 | #include <QtLanguageServer/private/qlanguageservergen_p_p.h> |
| 7 | |
| 8 | #include <QtCore/qjsonobject.h> |
| 9 | |
| 10 | #include <memory> |
| 11 | |
| 12 | QT_BEGIN_NAMESPACE |
| 13 | |
| 14 | using namespace QLspSpecification; |
| 15 | using namespace Qt::StringLiterals; |
| 16 | |
| 17 | /*! |
| 18 | \internal |
| 19 | \class QLanguageServerProtocol |
| 20 | \brief Implements the language server protocol |
| 21 | |
| 22 | QLanguageServerProtocol objects handles the language server |
| 23 | protocol both to send and receive (ask the client and reply to the |
| 24 | client). |
| 25 | |
| 26 | To ask the client you use the requestXX or notifyXX methods. |
| 27 | To reply to client request you have to register your handlers via |
| 28 | registerXXRequestHandler, notifications can be handled connecting the |
| 29 | receivedXXNotification signals. |
| 30 | |
| 31 | The method themselves are implemented in qlanguageservergen* |
| 32 | files which are generated form the specification. |
| 33 | |
| 34 | You have to provide a function to send the data that the protocol |
| 35 | generates to the constructor, and you have to feed the data you |
| 36 | receive to it via the receivedData method. |
| 37 | |
| 38 | Limitations: for the client use case (Creator),the handling of partial |
| 39 | results could be improved. A clean solution should handle the progress |
| 40 | notification, do some extra tracking and give the partial results back |
| 41 | to the call that did the request. |
| 42 | */ |
| 43 | |
| 44 | QLanguageServerProtocol::QLanguageServerProtocol(const QJsonRpcTransport::DataHandler &sender) |
| 45 | : ProtocolGen(std::make_unique<ProtocolGenPrivate>()) |
| 46 | { |
| 47 | transport()->setDataHandler(sender); |
| 48 | transport()->setDiagnosticHandler([this](QJsonRpcTransport::DiagnosticLevel l, |
| 49 | const QString &msg) { |
| 50 | handleResponseError( |
| 51 | err: ResponseError { .code: int(ErrorCodes::InternalError), .message: msg.toUtf8(), |
| 52 | .data: QJsonObject({ { u"errorLevel"_s , |
| 53 | ((l == QJsonRpcTransport::DiagnosticLevel::Error) |
| 54 | ? u"error"_s |
| 55 | : u"warning"_s ) } }) }); |
| 56 | }); |
| 57 | } |
| 58 | |
| 59 | void QLanguageServerProtocol::receiveData(const QByteArray &data) |
| 60 | { |
| 61 | transport()->receiveData(data); |
| 62 | } |
| 63 | |
| 64 | QT_END_NAMESPACE |
| 65 | |