/**************************************************************************** ** ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of Qt Creator. ** ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3 as published by the Free Software ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ****************************************************************************/ #pragma once #include "languageserverprotocol_global.h" #include "lsputils.h" #include #include #include namespace LanguageServerProtocol { class LANGUAGESERVERPROTOCOL_EXPORT JsonObject { Q_DECLARE_TR_FUNCTIONS(LanguageServerProtocol::JsonObject) public: using iterator = QJsonObject::iterator; using const_iterator = QJsonObject::const_iterator; JsonObject() = default; explicit JsonObject(const QJsonObject &object) : m_jsonObject(object) { } explicit JsonObject(QJsonObject &&object) : m_jsonObject(std::move(object)) { } JsonObject(const JsonObject &object) : m_jsonObject(object.m_jsonObject) { } JsonObject(JsonObject &&object) : m_jsonObject(std::move(object.m_jsonObject)) { } explicit JsonObject(const QJsonValue &value) : m_jsonObject(value.toObject()) { } virtual ~JsonObject() = default; JsonObject &operator=(const JsonObject &other); JsonObject &operator=(JsonObject &&other); bool operator==(const JsonObject &other) const { return m_jsonObject == other.m_jsonObject; } operator const QJsonObject&() const { return m_jsonObject; } virtual bool isValid() const { return true; } iterator end() { return m_jsonObject.end(); } const_iterator end() const { return m_jsonObject.end(); } protected: iterator insert(const QString &key, const JsonObject &value); iterator insert(const QString &key, const QJsonValue &value); template iterator insertVariant(const QString &key, const V &variant); template iterator insertVariant(const QString &key, const V &variant); // QJSonObject redirections QJsonValue value(const QString &key) const { return m_jsonObject.value(key); } bool contains(const QString &key) const { return m_jsonObject.contains(key); } iterator find(const QString &key) { return m_jsonObject.find(key); } const_iterator find(const QString &key) const { return m_jsonObject.find(key); } void remove(const QString &key) { m_jsonObject.remove(key); } QStringList keys() const { return m_jsonObject.keys(); } // convenience value access template T typedValue(const QString &key) const; template Utils::optional optionalValue(const QString &key) const; template LanguageClientValue clientValue(const QString &key) const; template Utils::optional> optionalClientValue(const QString &key) const; template QList array(const QString &key) const; template Utils::optional> optionalArray(const QString &key) const; template LanguageClientArray clientArray(const QString &key) const; template Utils::optional> optionalClientArray(const QString &key) const; template void insertArray(const QString &key, const QList &array); template void insertArray(const QString &key, const QList &array); private: QJsonObject m_jsonObject; }; template JsonObject::iterator JsonObject::insertVariant(const QString &key, const V &variant) { return Utils::holds_alternative(variant) ? insert(key, Utils::get(variant)) : end(); } template JsonObject::iterator JsonObject::insertVariant(const QString &key, const V &variant) { auto result = insertVariant(key, variant); return result != end() ? result : insertVariant(key, variant); } template T JsonObject::typedValue(const QString &key) const { return fromJsonValue(value(key)); } template Utils::optional JsonObject::optionalValue(const QString &key) const { const QJsonValue &val = value(key); return val.isUndefined() ? Utils::nullopt : Utils::make_optional(fromJsonValue(val)); } template LanguageClientValue JsonObject::clientValue(const QString &key) const { return LanguageClientValue(value(key)); } template Utils::optional> JsonObject::optionalClientValue(const QString &key) const { return contains(key) ? Utils::make_optional(clientValue(key)) : Utils::nullopt; } template QList JsonObject::array(const QString &key) const { const Utils::optional> &array = optionalArray(key); if (array.has_value()) return array.value(); qCDebug(conversionLog) << QString("Expected array under %1 in:").arg(key) << *this; return {}; } template Utils::optional> JsonObject::optionalArray(const QString &key) const { const QJsonValue &jsonValue = value(key); if (jsonValue.isUndefined()) return Utils::nullopt; return Utils::transform>(jsonValue.toArray(), &fromJsonValue); } template LanguageClientArray JsonObject::clientArray(const QString &key) const { return LanguageClientArray(value(key)); } template Utils::optional> JsonObject::optionalClientArray(const QString &key) const { const QJsonValue &val = value(key); return !val.isUndefined() ? Utils::make_optional(LanguageClientArray(value(key))) : Utils::nullopt; } template void JsonObject::insertArray(const QString &key, const QList &array) { QJsonArray jsonArray; for (const T &item : array) jsonArray.append(QJsonValue(item)); insert(key, jsonArray); } template void JsonObject::insertArray(const QString &key, const QList &array) { QJsonArray jsonArray; for (const JsonObject &item : array) jsonArray.append(item.m_jsonObject); insert(key, jsonArray); } } // namespace LanguageServerProtocol