serializer: make visitor/vis value/v consistent

This commit is contained in:
Fangrui Song 2018-11-23 11:53:21 -08:00
parent 741d8f2130
commit 98be09cc2e
3 changed files with 221 additions and 225 deletions

View File

@ -15,16 +15,16 @@ struct Hover {
std::optional<lsRange> range; std::optional<lsRange> range;
}; };
void Reflect(Writer &visitor, MarkedString &value) { void Reflect(Writer &vis, MarkedString &v) {
// If there is a language, emit a `{language:string, value:string}` object. If // If there is a language, emit a `{language:string, value:string}` object. If
// not, emit a string. // not, emit a string.
if (value.language) { if (v.language) {
REFLECT_MEMBER_START(); REFLECT_MEMBER_START();
REFLECT_MEMBER(language); REFLECT_MEMBER(language);
REFLECT_MEMBER(value); REFLECT_MEMBER(value);
REFLECT_MEMBER_END(); REFLECT_MEMBER_END();
} else { } else {
Reflect(visitor, value.value); Reflect(vis, v.value);
} }
} }
MAKE_REFLECT_STRUCT(Hover, contents, range); MAKE_REFLECT_STRUCT(Hover, contents, range);

View File

@ -29,96 +29,94 @@ Writer::~Writer() {}
BinaryWriter::~BinaryWriter() {} BinaryWriter::~BinaryWriter() {}
JsonWriter::~JsonWriter() {} JsonWriter::~JsonWriter() {}
void Reflect(Reader &visitor, uint8_t &value) { value = visitor.GetUInt8(); } void Reflect(Reader &vis, uint8_t &v) { v = vis.GetUInt8(); }
void Reflect(Writer &visitor, uint8_t &value) { visitor.UInt8(value); } void Reflect(Writer &vis, uint8_t &v) { vis.UInt8(v); }
void Reflect(Reader &visitor, short &value) { void Reflect(Reader &vis, short &v) {
if (!visitor.IsInt()) if (!vis.IsInt())
throw std::invalid_argument("short"); throw std::invalid_argument("short");
value = (short)visitor.GetInt(); v = (short)vis.GetInt();
} }
void Reflect(Writer &visitor, short &value) { visitor.Int(value); } void Reflect(Writer &vis, short &v) { vis.Int(v); }
void Reflect(Reader &visitor, unsigned short &value) { void Reflect(Reader &vis, unsigned short &v) {
if (!visitor.IsInt()) if (!vis.IsInt())
throw std::invalid_argument("unsigned short"); throw std::invalid_argument("unsigned short");
value = (unsigned short)visitor.GetInt(); v = (unsigned short)vis.GetInt();
} }
void Reflect(Writer &visitor, unsigned short &value) { visitor.Int(value); } void Reflect(Writer &vis, unsigned short &v) { vis.Int(v); }
void Reflect(Reader &visitor, int &value) { void Reflect(Reader &vis, int &v) {
if (!visitor.IsInt()) if (!vis.IsInt())
throw std::invalid_argument("int"); throw std::invalid_argument("int");
value = visitor.GetInt(); v = vis.GetInt();
} }
void Reflect(Writer &visitor, int &value) { visitor.Int(value); } void Reflect(Writer &vis, int &v) { vis.Int(v); }
void Reflect(Reader &visitor, unsigned &value) { void Reflect(Reader &vis, unsigned &v) {
if (!visitor.IsUInt64()) if (!vis.IsUInt64())
throw std::invalid_argument("unsigned"); throw std::invalid_argument("unsigned");
value = visitor.GetUInt32(); v = vis.GetUInt32();
} }
void Reflect(Writer &visitor, unsigned &value) { visitor.UInt32(value); } void Reflect(Writer &vis, unsigned &v) { vis.UInt32(v); }
void Reflect(Reader &visitor, long &value) { void Reflect(Reader &vis, long &v) {
if (!visitor.IsInt64()) if (!vis.IsInt64())
throw std::invalid_argument("long"); throw std::invalid_argument("long");
value = long(visitor.GetInt64()); v = long(vis.GetInt64());
} }
void Reflect(Writer &visitor, long &value) { visitor.Int64(value); } void Reflect(Writer &vis, long &v) { vis.Int64(v); }
void Reflect(Reader &visitor, unsigned long &value) { void Reflect(Reader &vis, unsigned long &v) {
if (!visitor.IsUInt64()) if (!vis.IsUInt64())
throw std::invalid_argument("unsigned long"); throw std::invalid_argument("unsigned long");
value = (unsigned long)visitor.GetUInt64(); v = (unsigned long)vis.GetUInt64();
} }
void Reflect(Writer &visitor, unsigned long &value) { visitor.UInt64(value); } void Reflect(Writer &vis, unsigned long &v) { vis.UInt64(v); }
void Reflect(Reader &visitor, long long &value) { void Reflect(Reader &vis, long long &v) {
if (!visitor.IsInt64()) if (!vis.IsInt64())
throw std::invalid_argument("long long"); throw std::invalid_argument("long long");
value = visitor.GetInt64(); v = vis.GetInt64();
} }
void Reflect(Writer &visitor, long long &value) { visitor.Int64(value); } void Reflect(Writer &vis, long long &v) { vis.Int64(v); }
void Reflect(Reader &visitor, unsigned long long &value) { void Reflect(Reader &vis, unsigned long long &v) {
if (!visitor.IsUInt64()) if (!vis.IsUInt64())
throw std::invalid_argument("unsigned long long"); throw std::invalid_argument("unsigned long long");
value = visitor.GetUInt64(); v = vis.GetUInt64();
}
void Reflect(Writer &visitor, unsigned long long &value) {
visitor.UInt64(value);
} }
void Reflect(Writer &vis, unsigned long long &v) { vis.UInt64(v); }
void Reflect(Reader &visitor, double &value) { void Reflect(Reader &vis, double &v) {
if (!visitor.IsDouble()) if (!vis.IsDouble())
throw std::invalid_argument("double"); throw std::invalid_argument("double");
value = visitor.GetDouble(); v = vis.GetDouble();
} }
void Reflect(Writer &visitor, double &value) { visitor.Double(value); } void Reflect(Writer &vis, double &v) { vis.Double(v); }
void Reflect(Reader &visitor, bool &value) { void Reflect(Reader &vis, bool &v) {
if (!visitor.IsBool()) if (!vis.IsBool())
throw std::invalid_argument("bool"); throw std::invalid_argument("bool");
value = visitor.GetBool(); v = vis.GetBool();
} }
void Reflect(Writer &visitor, bool &value) { visitor.Bool(value); } void Reflect(Writer &vis, bool &v) { vis.Bool(v); }
void Reflect(Reader &visitor, std::string &value) { void Reflect(Reader &vis, std::string &v) {
if (!visitor.IsString()) if (!vis.IsString())
throw std::invalid_argument("std::string"); throw std::invalid_argument("std::string");
value = visitor.GetString(); v = vis.GetString();
} }
void Reflect(Writer &visitor, std::string &value) { void Reflect(Writer &vis, std::string &v) {
visitor.String(value.c_str(), (rapidjson::SizeType)value.size()); vis.String(v.c_str(), (rapidjson::SizeType)v.size());
} }
void Reflect(Reader &, std::string_view &) { assert(0); } void Reflect(Reader &, std::string_view &) { assert(0); }
void Reflect(Writer &visitor, std::string_view &data) { void Reflect(Writer &vis, std::string_view &data) {
if (data.empty()) if (data.empty())
visitor.String(""); vis.String("");
else else
visitor.String(&data[0], (rapidjson::SizeType)data.size()); vis.String(&data[0], (rapidjson::SizeType)data.size());
} }
void Reflect(Reader &vis, const char *&v) { void Reflect(Reader &vis, const char *&v) {
@ -127,17 +125,17 @@ void Reflect(Reader &vis, const char *&v) {
} }
void Reflect(Writer &vis, const char *&v) { vis.String(v); } void Reflect(Writer &vis, const char *&v) { vis.String(v); }
void Reflect(Reader &visitor, JsonNull &value) { void Reflect(Reader &vis, JsonNull &v) {
assert(visitor.Format() == SerializeFormat::Json); assert(vis.Format() == SerializeFormat::Json);
visitor.GetNull(); vis.GetNull();
} }
void Reflect(Writer &visitor, JsonNull &value) { visitor.Null(); } void Reflect(Writer &vis, JsonNull &v) { vis.Null(); }
// std::unordered_map // std::unordered_map
template <typename V> template <typename V>
void Reflect(Reader &visitor, std::unordered_map<Usr, V> &map) { void Reflect(Reader &vis, std::unordered_map<Usr, V> &map) {
visitor.IterArray([&](Reader &entry) { vis.IterArray([&](Reader &entry) {
V val; V val;
Reflect(entry, val); Reflect(entry, val);
auto usr = val.usr; auto usr = val.usr;
@ -145,14 +143,14 @@ void Reflect(Reader &visitor, std::unordered_map<Usr, V> &map) {
}); });
} }
template <typename V> template <typename V>
void Reflect(Writer &visitor, std::unordered_map<Usr, V> &map) { void Reflect(Writer &vis, std::unordered_map<Usr, V> &map) {
std::vector<std::pair<uint64_t, V>> xs(map.begin(), map.end()); std::vector<std::pair<uint64_t, V>> xs(map.begin(), map.end());
std::sort(xs.begin(), xs.end(), std::sort(xs.begin(), xs.end(),
[](const auto &a, const auto &b) { return a.first < b.first; }); [](const auto &a, const auto &b) { return a.first < b.first; });
visitor.StartArray(xs.size()); vis.StartArray(xs.size());
for (auto &it : xs) for (auto &it : xs)
Reflect(visitor, it.second); Reflect(vis, it.second);
visitor.EndArray(); vis.EndArray();
} }
// Used by IndexFile::dependencies. // Used by IndexFile::dependencies.
@ -190,18 +188,18 @@ void Reflect(Writer &vis, DenseMap<CachedHashStringRef, int64_t> &v) {
} }
// TODO: Move this to indexer.cc // TODO: Move this to indexer.cc
void Reflect(Reader &visitor, IndexInclude &value) { void Reflect(Reader &vis, IndexInclude &v) {
REFLECT_MEMBER_START(); REFLECT_MEMBER_START();
REFLECT_MEMBER(line); REFLECT_MEMBER(line);
REFLECT_MEMBER(resolved_path); REFLECT_MEMBER(resolved_path);
REFLECT_MEMBER_END(); REFLECT_MEMBER_END();
} }
void Reflect(Writer &visitor, IndexInclude &value) { void Reflect(Writer &vis, IndexInclude &v) {
REFLECT_MEMBER_START(); REFLECT_MEMBER_START();
REFLECT_MEMBER(line); REFLECT_MEMBER(line);
if (gTestOutputMode) { if (gTestOutputMode) {
std::string basename = llvm::sys::path::filename(value.resolved_path); std::string basename = llvm::sys::path::filename(v.resolved_path);
if (value.resolved_path[0] != '&') if (v.resolved_path[0] != '&')
basename = "&" + basename; basename = "&" + basename;
REFLECT_MEMBER2("resolved_path", basename); REFLECT_MEMBER2("resolved_path", basename);
} else { } else {
@ -210,114 +208,112 @@ void Reflect(Writer &visitor, IndexInclude &value) {
REFLECT_MEMBER_END(); REFLECT_MEMBER_END();
} }
template <typename Def> template <typename Def> void ReflectHoverAndComments(Reader &vis, Def &def) {
void ReflectHoverAndComments(Reader &visitor, Def &def) { ReflectMember(vis, "hover", def.hover);
ReflectMember(visitor, "hover", def.hover); ReflectMember(vis, "comments", def.comments);
ReflectMember(visitor, "comments", def.comments);
} }
template <typename Def> template <typename Def> void ReflectHoverAndComments(Writer &vis, Def &def) {
void ReflectHoverAndComments(Writer &visitor, Def &def) {
// Don't emit empty hover and comments in JSON test mode. // Don't emit empty hover and comments in JSON test mode.
if (!gTestOutputMode || def.hover[0]) if (!gTestOutputMode || def.hover[0])
ReflectMember(visitor, "hover", def.hover); ReflectMember(vis, "hover", def.hover);
if (!gTestOutputMode || def.comments[0]) if (!gTestOutputMode || def.comments[0])
ReflectMember(visitor, "comments", def.comments); ReflectMember(vis, "comments", def.comments);
} }
template <typename Def> void ReflectShortName(Reader &visitor, Def &def) { template <typename Def> void ReflectShortName(Reader &vis, Def &def) {
if (gTestOutputMode) { if (gTestOutputMode) {
std::string short_name; std::string short_name;
ReflectMember(visitor, "short_name", short_name); ReflectMember(vis, "short_name", short_name);
def.short_name_offset = def.short_name_offset =
std::string_view(def.detailed_name).find(short_name); std::string_view(def.detailed_name).find(short_name);
assert(def.short_name_offset != std::string::npos); assert(def.short_name_offset != std::string::npos);
def.short_name_size = short_name.size(); def.short_name_size = short_name.size();
} else { } else {
ReflectMember(visitor, "short_name_offset", def.short_name_offset); ReflectMember(vis, "short_name_offset", def.short_name_offset);
ReflectMember(visitor, "short_name_size", def.short_name_size); ReflectMember(vis, "short_name_size", def.short_name_size);
} }
} }
template <typename Def> void ReflectShortName(Writer &visitor, Def &def) { template <typename Def> void ReflectShortName(Writer &vis, Def &def) {
if (gTestOutputMode) { if (gTestOutputMode) {
std::string_view short_name(def.detailed_name + def.short_name_offset, std::string_view short_name(def.detailed_name + def.short_name_offset,
def.short_name_size); def.short_name_size);
ReflectMember(visitor, "short_name", short_name); ReflectMember(vis, "short_name", short_name);
} else { } else {
ReflectMember(visitor, "short_name_offset", def.short_name_offset); ReflectMember(vis, "short_name_offset", def.short_name_offset);
ReflectMember(visitor, "short_name_size", def.short_name_size); ReflectMember(vis, "short_name_size", def.short_name_size);
} }
} }
template <typename TVisitor> void Reflect(TVisitor &visitor, IndexFunc &value) { template <typename TVisitor> void Reflect(TVisitor &vis, IndexFunc &v) {
REFLECT_MEMBER_START(); REFLECT_MEMBER_START();
REFLECT_MEMBER2("usr", value.usr); REFLECT_MEMBER2("usr", v.usr);
REFLECT_MEMBER2("detailed_name", value.def.detailed_name); REFLECT_MEMBER2("detailed_name", v.def.detailed_name);
REFLECT_MEMBER2("qual_name_offset", value.def.qual_name_offset); REFLECT_MEMBER2("qual_name_offset", v.def.qual_name_offset);
ReflectShortName(visitor, value.def); ReflectShortName(vis, v.def);
REFLECT_MEMBER2("spell", value.def.spell); REFLECT_MEMBER2("spell", v.def.spell);
ReflectHoverAndComments(visitor, value.def); ReflectHoverAndComments(vis, v.def);
REFLECT_MEMBER2("bases", value.def.bases); REFLECT_MEMBER2("bases", v.def.bases);
REFLECT_MEMBER2("vars", value.def.vars); REFLECT_MEMBER2("vars", v.def.vars);
REFLECT_MEMBER2("callees", value.def.callees); REFLECT_MEMBER2("callees", v.def.callees);
REFLECT_MEMBER2("kind", value.def.kind); REFLECT_MEMBER2("kind", v.def.kind);
REFLECT_MEMBER2("parent_kind", value.def.parent_kind); REFLECT_MEMBER2("parent_kind", v.def.parent_kind);
REFLECT_MEMBER2("storage", value.def.storage); REFLECT_MEMBER2("storage", v.def.storage);
REFLECT_MEMBER2("declarations", value.declarations); REFLECT_MEMBER2("declarations", v.declarations);
REFLECT_MEMBER2("derived", value.derived); REFLECT_MEMBER2("derived", v.derived);
REFLECT_MEMBER2("uses", value.uses); REFLECT_MEMBER2("uses", v.uses);
REFLECT_MEMBER_END(); REFLECT_MEMBER_END();
} }
template <typename TVisitor> void Reflect(TVisitor &visitor, IndexType &value) { template <typename TVisitor> void Reflect(TVisitor &vis, IndexType &v) {
REFLECT_MEMBER_START(); REFLECT_MEMBER_START();
REFLECT_MEMBER2("usr", value.usr); REFLECT_MEMBER2("usr", v.usr);
REFLECT_MEMBER2("detailed_name", value.def.detailed_name); REFLECT_MEMBER2("detailed_name", v.def.detailed_name);
REFLECT_MEMBER2("qual_name_offset", value.def.qual_name_offset); REFLECT_MEMBER2("qual_name_offset", v.def.qual_name_offset);
ReflectShortName(visitor, value.def); ReflectShortName(vis, v.def);
ReflectHoverAndComments(visitor, value.def); ReflectHoverAndComments(vis, v.def);
REFLECT_MEMBER2("spell", value.def.spell); REFLECT_MEMBER2("spell", v.def.spell);
REFLECT_MEMBER2("bases", value.def.bases); REFLECT_MEMBER2("bases", v.def.bases);
REFLECT_MEMBER2("funcs", value.def.funcs); REFLECT_MEMBER2("funcs", v.def.funcs);
REFLECT_MEMBER2("types", value.def.types); REFLECT_MEMBER2("types", v.def.types);
REFLECT_MEMBER2("vars", value.def.vars); REFLECT_MEMBER2("vars", v.def.vars);
REFLECT_MEMBER2("alias_of", value.def.alias_of); REFLECT_MEMBER2("alias_of", v.def.alias_of);
REFLECT_MEMBER2("kind", value.def.kind); REFLECT_MEMBER2("kind", v.def.kind);
REFLECT_MEMBER2("parent_kind", value.def.parent_kind); REFLECT_MEMBER2("parent_kind", v.def.parent_kind);
REFLECT_MEMBER2("declarations", value.declarations); REFLECT_MEMBER2("declarations", v.declarations);
REFLECT_MEMBER2("derived", value.derived); REFLECT_MEMBER2("derived", v.derived);
REFLECT_MEMBER2("instances", value.instances); REFLECT_MEMBER2("instances", v.instances);
REFLECT_MEMBER2("uses", value.uses); REFLECT_MEMBER2("uses", v.uses);
REFLECT_MEMBER_END(); REFLECT_MEMBER_END();
} }
template <typename TVisitor> void Reflect(TVisitor &visitor, IndexVar &value) { template <typename TVisitor> void Reflect(TVisitor &vis, IndexVar &v) {
REFLECT_MEMBER_START(); REFLECT_MEMBER_START();
REFLECT_MEMBER2("usr", value.usr); REFLECT_MEMBER2("usr", v.usr);
REFLECT_MEMBER2("detailed_name", value.def.detailed_name); REFLECT_MEMBER2("detailed_name", v.def.detailed_name);
REFLECT_MEMBER2("qual_name_offset", value.def.qual_name_offset); REFLECT_MEMBER2("qual_name_offset", v.def.qual_name_offset);
ReflectShortName(visitor, value.def); ReflectShortName(vis, v.def);
ReflectHoverAndComments(visitor, value.def); ReflectHoverAndComments(vis, v.def);
REFLECT_MEMBER2("spell", value.def.spell); REFLECT_MEMBER2("spell", v.def.spell);
REFLECT_MEMBER2("type", value.def.type); REFLECT_MEMBER2("type", v.def.type);
REFLECT_MEMBER2("kind", value.def.kind); REFLECT_MEMBER2("kind", v.def.kind);
REFLECT_MEMBER2("parent_kind", value.def.parent_kind); REFLECT_MEMBER2("parent_kind", v.def.parent_kind);
REFLECT_MEMBER2("storage", value.def.storage); REFLECT_MEMBER2("storage", v.def.storage);
REFLECT_MEMBER2("declarations", value.declarations); REFLECT_MEMBER2("declarations", v.declarations);
REFLECT_MEMBER2("uses", value.uses); REFLECT_MEMBER2("uses", v.uses);
REFLECT_MEMBER_END(); REFLECT_MEMBER_END();
} }
// IndexFile // IndexFile
bool ReflectMemberStart(Writer &visitor, IndexFile &value) { bool ReflectMemberStart(Writer &vis, IndexFile &v) {
visitor.StartObject(); vis.StartObject();
return true; return true;
} }
template <typename TVisitor> void Reflect(TVisitor &visitor, IndexFile &value) { template <typename TVisitor> void Reflect(TVisitor &vis, IndexFile &v) {
REFLECT_MEMBER_START(); REFLECT_MEMBER_START();
if (!gTestOutputMode) { if (!gTestOutputMode) {
REFLECT_MEMBER(mtime); REFLECT_MEMBER(mtime);
@ -340,13 +336,13 @@ void Reflect(Reader &vis, SerializeFormat &v) {
: SerializeFormat::Binary; : SerializeFormat::Binary;
} }
void Reflect(Writer &visitor, SerializeFormat &value) { void Reflect(Writer &vis, SerializeFormat &v) {
switch (value) { switch (v) {
case SerializeFormat::Binary: case SerializeFormat::Binary:
visitor.String("binary"); vis.String("binary");
break; break;
case SerializeFormat::Json: case SerializeFormat::Json:
visitor.String("json"); vis.String("json");
break; break;
} }
} }

View File

@ -82,34 +82,34 @@ public:
struct IndexFile; struct IndexFile;
#define REFLECT_MEMBER_START() ReflectMemberStart(visitor) #define REFLECT_MEMBER_START() ReflectMemberStart(vis)
#define REFLECT_MEMBER_END() ReflectMemberEnd(visitor); #define REFLECT_MEMBER_END() ReflectMemberEnd(vis);
#define REFLECT_MEMBER(name) ReflectMember(visitor, #name, value.name) #define REFLECT_MEMBER(name) ReflectMember(vis, #name, v.name)
#define REFLECT_MEMBER2(name, value) ReflectMember(visitor, name, value) #define REFLECT_MEMBER2(name, v) ReflectMember(vis, name, v)
#define MAKE_REFLECT_TYPE_PROXY(type_name) \ #define MAKE_REFLECT_TYPE_PROXY(type_name) \
MAKE_REFLECT_TYPE_PROXY2(type_name, std::underlying_type_t<type_name>) MAKE_REFLECT_TYPE_PROXY2(type_name, std::underlying_type_t<type_name>)
#define MAKE_REFLECT_TYPE_PROXY2(type, as_type) \ #define MAKE_REFLECT_TYPE_PROXY2(type, as_type) \
LLVM_ATTRIBUTE_UNUSED inline void Reflect(Reader &visitor, type &value) { \ LLVM_ATTRIBUTE_UNUSED inline void Reflect(Reader &vis, type &v) { \
as_type value0; \ as_type value0; \
::ccls::Reflect(visitor, value0); \ ::ccls::Reflect(vis, value0); \
value = static_cast<type>(value0); \ v = static_cast<type>(value0); \
} \ } \
LLVM_ATTRIBUTE_UNUSED inline void Reflect(Writer &visitor, type &value) { \ LLVM_ATTRIBUTE_UNUSED inline void Reflect(Writer &vis, type &v) { \
auto value0 = static_cast<as_type>(value); \ auto value0 = static_cast<as_type>(v); \
::ccls::Reflect(visitor, value0); \ ::ccls::Reflect(vis, value0); \
} }
#define _MAPPABLE_REFLECT_MEMBER(name) REFLECT_MEMBER(name); #define _MAPPABLE_REFLECT_MEMBER(name) REFLECT_MEMBER(name);
#define MAKE_REFLECT_EMPTY_STRUCT(type, ...) \ #define MAKE_REFLECT_EMPTY_STRUCT(type, ...) \
template <typename TVisitor> void Reflect(TVisitor &visitor, type &value) { \ template <typename TVisitor> void Reflect(TVisitor &vis, type &v) { \
REFLECT_MEMBER_START(); \ REFLECT_MEMBER_START(); \
REFLECT_MEMBER_END(); \ REFLECT_MEMBER_END(); \
} }
#define MAKE_REFLECT_STRUCT(type, ...) \ #define MAKE_REFLECT_STRUCT(type, ...) \
template <typename TVisitor> void Reflect(TVisitor &visitor, type &value) { \ template <typename TVisitor> void Reflect(TVisitor &vis, type &v) { \
REFLECT_MEMBER_START(); \ REFLECT_MEMBER_START(); \
MACRO_MAP(_MAPPABLE_REFLECT_MEMBER, __VA_ARGS__) \ MACRO_MAP(_MAPPABLE_REFLECT_MEMBER, __VA_ARGS__) \
REFLECT_MEMBER_END(); \ REFLECT_MEMBER_END(); \
@ -121,66 +121,66 @@ struct IndexFile;
#define NUM_VA_ARGS(...) NUM_VA_ARGS_IMPL(__VA_ARGS__,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1) #define NUM_VA_ARGS(...) NUM_VA_ARGS_IMPL(__VA_ARGS__,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1)
// clang-format on // clang-format on
#define _MAPPABLE_REFLECT_ARRAY(name) Reflect(visitor, value.name); #define _MAPPABLE_REFLECT_ARRAY(name) Reflect(vis, v.name);
// Reflects the struct so it is serialized as an array instead of an object. // Reflects the struct so it is serialized as an array instead of an object.
// This currently only supports writers. // This currently only supports writers.
#define MAKE_REFLECT_STRUCT_WRITER_AS_ARRAY(type, ...) \ #define MAKE_REFLECT_STRUCT_WRITER_AS_ARRAY(type, ...) \
inline void Reflect(Writer &visitor, type &value) { \ inline void Reflect(Writer &vis, type &v) { \
visitor.StartArray(NUM_VA_ARGS(__VA_ARGS__)); \ vis.StartArray(NUM_VA_ARGS(__VA_ARGS__)); \
MACRO_MAP(_MAPPABLE_REFLECT_ARRAY, __VA_ARGS__) \ MACRO_MAP(_MAPPABLE_REFLECT_ARRAY, __VA_ARGS__) \
visitor.EndArray(); \ vis.EndArray(); \
} }
//// Elementary types //// Elementary types
void Reflect(Reader &visitor, uint8_t &value); void Reflect(Reader &vis, uint8_t &v);
void Reflect(Writer &visitor, uint8_t &value); void Reflect(Writer &vis, uint8_t &v);
void Reflect(Reader &visitor, short &value); void Reflect(Reader &vis, short &v);
void Reflect(Writer &visitor, short &value); void Reflect(Writer &vis, short &v);
void Reflect(Reader &visitor, unsigned short &value); void Reflect(Reader &vis, unsigned short &v);
void Reflect(Writer &visitor, unsigned short &value); void Reflect(Writer &vis, unsigned short &v);
void Reflect(Reader &visitor, int &value); void Reflect(Reader &vis, int &v);
void Reflect(Writer &visitor, int &value); void Reflect(Writer &vis, int &v);
void Reflect(Reader &visitor, unsigned &value); void Reflect(Reader &vis, unsigned &v);
void Reflect(Writer &visitor, unsigned &value); void Reflect(Writer &vis, unsigned &v);
void Reflect(Reader &visitor, long &value); void Reflect(Reader &vis, long &v);
void Reflect(Writer &visitor, long &value); void Reflect(Writer &vis, long &v);
void Reflect(Reader &visitor, unsigned long &value); void Reflect(Reader &vis, unsigned long &v);
void Reflect(Writer &visitor, unsigned long &value); void Reflect(Writer &vis, unsigned long &v);
void Reflect(Reader &visitor, long long &value); void Reflect(Reader &vis, long long &v);
void Reflect(Writer &visitor, long long &value); void Reflect(Writer &vis, long long &v);
void Reflect(Reader &visitor, unsigned long long &value); void Reflect(Reader &vis, unsigned long long &v);
void Reflect(Writer &visitor, unsigned long long &value); void Reflect(Writer &vis, unsigned long long &v);
void Reflect(Reader &visitor, double &value); void Reflect(Reader &vis, double &v);
void Reflect(Writer &visitor, double &value); void Reflect(Writer &vis, double &v);
void Reflect(Reader &visitor, bool &value); void Reflect(Reader &vis, bool &v);
void Reflect(Writer &visitor, bool &value); void Reflect(Writer &vis, bool &v);
void Reflect(Reader &visitor, std::string &value); void Reflect(Reader &vis, std::string &v);
void Reflect(Writer &visitor, std::string &value); void Reflect(Writer &vis, std::string &v);
void Reflect(Reader &visitor, std::string_view &view); void Reflect(Reader &vis, std::string_view &v);
void Reflect(Writer &visitor, std::string_view &view); void Reflect(Writer &vis, std::string_view &v);
void Reflect(Reader &vis, const char *&v); void Reflect(Reader &vis, const char *&v);
void Reflect(Writer &vis, const char *&v); void Reflect(Writer &vis, const char *&v);
void Reflect(Reader &visitor, JsonNull &value); void Reflect(Reader &vis, JsonNull &v);
void Reflect(Writer &visitor, JsonNull &value); void Reflect(Writer &vis, JsonNull &v);
void Reflect(Reader &visitor, SerializeFormat &value); void Reflect(Reader &vis, SerializeFormat &v);
void Reflect(Writer &visitor, SerializeFormat &value); void Reflect(Writer &vis, SerializeFormat &v);
//// Type constructors //// Type constructors
@ -188,60 +188,60 @@ void Reflect(Writer &visitor, SerializeFormat &value);
// properties (in `key: value` context). Reflect std::optional<T> is used for a // properties (in `key: value` context). Reflect std::optional<T> is used for a
// different purpose, whether an object is nullable (possibly in `value` // different purpose, whether an object is nullable (possibly in `value`
// context). // context).
template <typename T> void Reflect(Reader &visitor, std::optional<T> &value) { template <typename T> void Reflect(Reader &vis, std::optional<T> &v) {
if (visitor.IsNull()) { if (vis.IsNull()) {
visitor.GetNull(); vis.GetNull();
return; return;
} }
T real_value; T val;
Reflect(visitor, real_value); Reflect(vis, val);
value = std::move(real_value); v = std::move(val);
} }
template <typename T> void Reflect(Writer &visitor, std::optional<T> &value) { template <typename T> void Reflect(Writer &vis, std::optional<T> &v) {
if (value) { if (v) {
if (visitor.Format() != SerializeFormat::Json) if (vis.Format() != SerializeFormat::Json)
visitor.UInt8(1); vis.UInt8(1);
Reflect(visitor, *value); Reflect(vis, *v);
} else } else
visitor.Null(); vis.Null();
} }
// The same as std::optional // The same as std::optional
template <typename T> void Reflect(Reader &visitor, Maybe<T> &value) { template <typename T> void Reflect(Reader &vis, Maybe<T> &v) {
if (visitor.IsNull()) { if (vis.IsNull()) {
visitor.GetNull(); vis.GetNull();
return; return;
} }
T real_value; T val;
Reflect(visitor, real_value); Reflect(vis, val);
value = std::move(real_value); v = std::move(val);
} }
template <typename T> void Reflect(Writer &visitor, Maybe<T> &value) { template <typename T> void Reflect(Writer &vis, Maybe<T> &v) {
if (value) { if (v) {
if (visitor.Format() != SerializeFormat::Json) if (vis.Format() != SerializeFormat::Json)
visitor.UInt8(1); vis.UInt8(1);
Reflect(visitor, *value); Reflect(vis, *v);
} else } else
visitor.Null(); vis.Null();
} }
template <typename T> template <typename T>
void ReflectMember(Writer &visitor, const char *name, std::optional<T> &value) { void ReflectMember(Writer &vis, const char *name, std::optional<T> &v) {
// For TypeScript std::optional property key?: value in the spec, // For TypeScript std::optional property key?: value in the spec,
// We omit both key and value if value is std::nullopt (null) for JsonWriter // We omit both key and value if value is std::nullopt (null) for JsonWriter
// to reduce output. But keep it for other serialization formats. // to reduce output. But keep it for other serialization formats.
if (value || visitor.Format() != SerializeFormat::Json) { if (v || vis.Format() != SerializeFormat::Json) {
visitor.Key(name); vis.Key(name);
Reflect(visitor, value); Reflect(vis, v);
} }
} }
// The same as std::optional // The same as std::optional
template <typename T> template <typename T>
void ReflectMember(Writer &visitor, const char *name, Maybe<T> &value) { void ReflectMember(Writer &vis, const char *name, Maybe<T> &v) {
if (value.Valid() || visitor.Format() != SerializeFormat::Json) { if (v.Valid() || vis.Format() != SerializeFormat::Json) {
visitor.Key(name); vis.Key(name);
Reflect(visitor, value); Reflect(vis, v);
} }
} }
@ -259,18 +259,18 @@ void Reflect(Writer &vis, std::pair<L, R> &v) {
} }
// std::vector // std::vector
template <typename T> void Reflect(Reader &visitor, std::vector<T> &values) { template <typename T> void Reflect(Reader &vis, std::vector<T> &vs) {
visitor.IterArray([&](Reader &entry) { vis.IterArray([&](Reader &entry) {
T entry_value; T entry_value;
Reflect(entry, entry_value); Reflect(entry, entry_value);
values.push_back(std::move(entry_value)); vs.push_back(std::move(entry_value));
}); });
} }
template <typename T> void Reflect(Writer &visitor, std::vector<T> &values) { template <typename T> void Reflect(Writer &vis, std::vector<T> &vs) {
visitor.StartArray(values.size()); vis.StartArray(vs.size());
for (auto &value : values) for (auto &v : vs)
Reflect(visitor, value); Reflect(vis, v);
visitor.EndArray(); vis.EndArray();
} }
// ReflectMember // ReflectMember