Make Reader/Writer abstract classes instead of type aliases of rapidjson classes

Added src/serializers/json.h (which includes rapidjson)
This commit is contained in:
Fangrui Song 2018-01-06 13:46:41 -08:00
parent 007bc5362c
commit 02a457f65d
7 changed files with 73 additions and 25 deletions

View File

@ -1,5 +1,7 @@
#include "language_server_api.h"
#include "serializers/json.h"
#include <doctest/doctest.h>
#include <loguru.hpp>
@ -155,12 +157,13 @@ std::unique_ptr<BaseIpcMessage> MessageRegistry::ReadMessageFromStdin(
document.Parse(content->c_str(), content->length());
assert(!document.HasParseError());
return Parse(document);
JsonReader json_reader{&document};
return Parse(json_reader);
}
std::unique_ptr<BaseIpcMessage> MessageRegistry::Parse(Reader& visitor) {
if (!visitor.HasMember("jsonrpc") ||
std::string(visitor["jsonrpc"].GetString()) != "2.0") {
std::string(visitor["jsonrpc"]->GetString()) != "2.0") {
LOG_S(FATAL) << "Bad or missing jsonrpc version";
exit(1);
}

View File

@ -3,6 +3,7 @@
#include "config.h"
#include "ipc.h"
#include "serializer.h"
#include "serializers/json.h"
#include "utils.h"
#include <optional.h>
@ -79,9 +80,10 @@ struct lsOutMessage : lsBaseOutMessage {
// Send the message to the language client by writing it to stdout.
void Write(std::ostream& out) override {
rapidjson::StringBuffer output;
Writer writer(output);
rapidjson::Writer<rapidjson::StringBuffer> writer(output);
JsonWriter json_writer(&writer);
auto that = static_cast<TDerived*>(this);
Reflect(writer, *that);
Reflect(json_writer, *that);
out << "Content-Length: " << output.GetSize();
out << (char)13 << char(10) << char(13) << char(10); // CRLFCRLF

View File

@ -4,6 +4,7 @@
#include "platform.h"
#include "project.h"
#include "queue_manager.h"
#include "serializers/json.h"
#include "timer.h"
#include "working_files.h"
@ -42,8 +43,9 @@ struct InitializeHandler : BaseMessageHandler<Ipc_InitializeRequest> {
void Run(Ipc_InitializeRequest* request) override {
// Log initialization parameters.
rapidjson::StringBuffer output;
Writer writer(output);
Reflect(writer, request->params.initializationOptions);
rapidjson::Writer<rapidjson::StringBuffer> writer(output);
JsonWriter json_writer(&writer);
Reflect(json_writer, request->params.initializationOptions);
LOG_S(INFO) << "Init parameters: " << output.GetString();
if (request->params.rootUri) {

View File

@ -153,7 +153,7 @@ void Reflect(Reader& visitor, Position& value) {
}
void Reflect(Writer& visitor, Position& value) {
std::string output = value.ToString();
visitor.String(output.c_str(), (rapidjson::SizeType)output.size());
visitor.String(output.c_str(), output.size());
}
// Range
@ -165,5 +165,5 @@ void Reflect(Reader& visitor, Range& value) {
}
void Reflect(Writer& visitor, Range& value) {
std::string output = value.ToString();
visitor.String(output.c_str(), (rapidjson::SizeType)output.size());
}
visitor.String(output.c_str(), output.size());
}

View File

@ -1,6 +1,7 @@
#include "query.h"
#include "indexer.h"
#include "serializers/json.h"
#include <doctest/doctest.h>
#include <optional.h>
@ -674,9 +675,10 @@ void IndexUpdate::Merge(const IndexUpdate& update) {
std::string IndexUpdate::ToString() {
rapidjson::StringBuffer output;
Writer writer(output);
rapidjson::Writer<rapidjson::StringBuffer> writer;
JsonWriter json_writer(&writer);
IndexUpdate& update = *this;
Reflect(writer, update);
Reflect(json_writer, update);
return output.GetString();
}

View File

@ -1,5 +1,8 @@
#include "serializer.h"
// TODO Move Json* to serializers/json.cc
#include "serializers/json.h"
#include "indexer.h"
#include <doctest/doctest.h>
@ -195,12 +198,12 @@ void Reflect(TVisitor& visitor, IndexFile& value) {
std::string Serialize(IndexFile& file) {
rapidjson::StringBuffer output;
rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(output);
// Writer writer(output);
writer.SetFormatOptions(
rapidjson::PrettyFormatOptions::kFormatSingleLineArray);
writer.SetIndent(' ', 2);
Reflect(writer, file);
JsonWriter json_writer(&writer);
Reflect(json_writer, file);
return output.GetString();
}
@ -224,7 +227,8 @@ std::unique_ptr<IndexFile> Deserialize(std::string path,
}
auto file = MakeUnique<IndexFile>(path);
Reflect(reader, *file);
JsonReader json_reader{&reader};
Reflect(json_reader, *file);
// Restore non-serialized state.
file->path = path;

View File

@ -3,15 +3,54 @@
#include <macro_map.h>
#include <optional.h>
#include <variant.h>
#include <rapidjson/document.h>
#include <rapidjson/prettywriter.h>
#include <memory>
#include <string>
#include <vector>
using Reader = rapidjson::GenericValue<rapidjson::UTF8<>>;
using Writer = rapidjson::Writer<rapidjson::StringBuffer>;
class Reader {
public:
virtual ~Reader() {}
virtual bool IsBool() = 0;
virtual bool IsNull() = 0;
virtual bool IsArray() = 0;
virtual bool IsInt() = 0;
virtual bool IsInt64() = 0;
virtual bool IsUint64() = 0;
virtual bool IsString() = 0;
virtual bool GetBool() = 0;
virtual int GetInt() = 0;
virtual int64_t GetInt64() = 0;
virtual uint64_t GetUint64() = 0;
virtual const char* GetString() = 0;
virtual bool HasMember(const char* x) = 0;
virtual std::unique_ptr<Reader> operator[](const char* x) = 0;
virtual void IterArray(std::function<void(Reader&)> fn) = 0;
virtual void DoMember(const char* name, std::function<void(Reader&)> fn) = 0;
};
class Writer {
public:
virtual ~Writer() {}
virtual void Null() = 0;
virtual void Bool(bool x) = 0;
virtual void Int(uint64_t x) = 0;
virtual void Int64(uint64_t x) = 0;
virtual void Uint64(uint64_t x) = 0;
virtual void String(const char* x) = 0;
virtual void String(const char* x, size_t len) = 0;
virtual void StartArray() = 0;
virtual void EndArray() = 0;
virtual void StartObject() = 0;
virtual void EndObject() = 0;
virtual void Key(const char* name) = 0;
};
struct IndexFile;
#define REFLECT_MEMBER_START() \
@ -131,11 +170,11 @@ template <typename T>
void Reflect(Reader& visitor, std::vector<T>& values) {
if (!visitor.IsArray())
return;
for (auto& entry : visitor.GetArray()) {
visitor.IterArray([&](Reader& entry) {
T entry_value;
Reflect(entry, entry_value);
values.push_back(entry_value);
}
});
}
template <typename T>
void Reflect(Writer& visitor, std::vector<T>& values) {
@ -193,11 +232,7 @@ template <typename T>
void ReflectMemberEnd(Reader& visitor, T& value) {}
template <typename T>
void ReflectMember(Reader& visitor, const char* name, T& value) {
auto it = visitor.FindMember(name);
if (it != visitor.MemberEnd()) {
Reader& child_visitor = it->value;
Reflect(child_visitor, value);
}
visitor.DoMember(name, [&](Reader& child) { Reflect(child, value); });
}
std::string Serialize(IndexFile& file);