1 #pragma once
2
3 #include "maybe.h"
4
5 #include <macro_map.h>
6 #include <optional.h>
7 #include <string_view.h>
8
9 #include <cassert>
10 #include <memory>
11 #include <string>
12 #include <type_traits>
13 #include <vector>
14
15 struct AbsolutePath;
16
17 enum class SerializeFormat { Json, MessagePack };
18
19 // A tag type that can be used to write `null` to json.
20 struct JsonNull {};
21
22 class Reader {
23 public:
~Reader()24 virtual ~Reader() {}
25 virtual SerializeFormat Format() const = 0;
26
27 virtual bool IsBool() = 0;
28 virtual bool IsNull() = 0;
29 virtual bool IsArray() = 0;
30 virtual bool IsInt() = 0;
31 virtual bool IsInt64() = 0;
32 virtual bool IsUint64() = 0;
33 virtual bool IsDouble() = 0;
34 virtual bool IsString() = 0;
35
36 virtual void GetNull() = 0;
37 virtual bool GetBool() = 0;
38 virtual int GetInt() = 0;
39 virtual uint32_t GetUint32() = 0;
40 virtual int64_t GetInt64() = 0;
41 virtual uint64_t GetUint64() = 0;
42 virtual double GetDouble() = 0;
43 virtual std::string GetString() = 0;
44
45 virtual bool HasMember(const char* x) = 0;
46 virtual std::unique_ptr<Reader> operator[](const char* x) = 0;
47
48 virtual void IterArray(std::function<void(Reader&)> fn) = 0;
49 virtual void DoMember(const char* name, std::function<void(Reader&)> fn) = 0;
50 };
51
52 class Writer {
53 public:
~Writer()54 virtual ~Writer() {}
55 virtual SerializeFormat Format() const = 0;
56
57 virtual void Null() = 0;
58 virtual void Bool(bool x) = 0;
59 virtual void Int(int x) = 0;
60 virtual void Uint32(uint32_t x) = 0;
61 virtual void Int64(int64_t x) = 0;
62 virtual void Uint64(uint64_t x) = 0;
63 virtual void Double(double x) = 0;
64 virtual void String(const char* x) = 0;
65 virtual void String(const char* x, size_t len) = 0;
66 virtual void StartArray(size_t) = 0;
67 virtual void EndArray() = 0;
68 virtual void StartObject() = 0;
69 virtual void EndObject() = 0;
70 virtual void Key(const char* name) = 0;
71 };
72
73 struct IndexFile;
74
75 struct optionals_mandatory_tag {};
76
77 #define REFLECT_MEMBER_START() ReflectMemberStart(visitor, value)
78 #define REFLECT_MEMBER_END() ReflectMemberEnd(visitor, value);
79 #define REFLECT_MEMBER_END1(value) ReflectMemberEnd(visitor, value);
80 #define REFLECT_MEMBER(name) ReflectMember(visitor, #name, value.name)
81 #define REFLECT_MEMBER_OPTIONALS(name) \
82 ReflectMember(visitor, #name, value.name, optionals_mandatory_tag{})
83 #define REFLECT_MEMBER2(name, value) ReflectMember(visitor, name, value)
84
85 #define MAKE_REFLECT_TYPE_PROXY(type_name) \
86 MAKE_REFLECT_TYPE_PROXY2(type_name, std::underlying_type<type_name>::type)
87 #define MAKE_REFLECT_TYPE_PROXY2(type, as_type) \
88 inline void Reflect(Reader& visitor, type& value) { \
89 as_type value0; \
90 ::Reflect(visitor, value0); \
91 value = static_cast<type>(value0); \
92 } \
93 inline void Reflect(Writer& visitor, type& value) { \
94 auto value0 = static_cast<as_type>(value); \
95 ::Reflect(visitor, value0); \
96 }
97
98 #define _MAPPABLE_REFLECT_MEMBER(name) REFLECT_MEMBER(name);
99 #define _MAPPABLE_REFLECT_MEMBER_OPTIONALS(name) REFLECT_MEMBER_OPTIONALS(name);
100
101 #define MAKE_REFLECT_EMPTY_STRUCT(type, ...) \
102 template <typename TVisitor> \
103 void Reflect(TVisitor& visitor, type& value) { \
104 REFLECT_MEMBER_START(); \
105 REFLECT_MEMBER_END(); \
106 }
107
108 #define MAKE_REFLECT_STRUCT(type, ...) \
109 template <typename TVisitor> \
110 void Reflect(TVisitor& visitor, type& value) { \
111 REFLECT_MEMBER_START(); \
112 MACRO_MAP(_MAPPABLE_REFLECT_MEMBER, __VA_ARGS__) \
113 REFLECT_MEMBER_END(); \
114 }
115
116 #define MAKE_REFLECT_STRUCT_OPTIONALS_MANDATORY(type, ...) \
117 template <typename TVisitor> \
118 void Reflect(TVisitor& visitor, type& value) { \
119 REFLECT_MEMBER_START(); \
120 MACRO_MAP(_MAPPABLE_REFLECT_MEMBER_OPTIONALS, __VA_ARGS__) \
121 REFLECT_MEMBER_END(); \
122 }
123
124 // clang-format off
125 // Config has many fields, we need to support at least its number of fields.
126 #define NUM_VA_ARGS_IMPL(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,N,...) N
127 #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)
128 // clang-format on
129
130 #define _MAPPABLE_REFLECT_ARRAY(name) Reflect(visitor, value.name);
131
132 // Reflects the struct so it is serialized as an array instead of an object.
133 // This currently only supports writers.
134 #define MAKE_REFLECT_STRUCT_WRITER_AS_ARRAY(type, ...) \
135 inline void Reflect(Writer& visitor, type& value) { \
136 visitor.StartArray(NUM_VA_ARGS(__VA_ARGS__)); \
137 MACRO_MAP(_MAPPABLE_REFLECT_ARRAY, __VA_ARGS__) \
138 visitor.EndArray(); \
139 }
140
141 //// Elementary types
142
143 void Reflect(Reader& visitor, uint8_t& value);
144 void Reflect(Writer& visitor, uint8_t& value);
145
146 void Reflect(Reader& visitor, short& value);
147 void Reflect(Writer& visitor, short& value);
148
149 void Reflect(Reader& visitor, unsigned short& value);
150 void Reflect(Writer& visitor, unsigned short& value);
151
152 void Reflect(Reader& visitor, int& value);
153 void Reflect(Writer& visitor, int& value);
154
155 void Reflect(Reader& visitor, unsigned& value);
156 void Reflect(Writer& visitor, unsigned& value);
157
158 void Reflect(Reader& visitor, long& value);
159 void Reflect(Writer& visitor, long& value);
160
161 void Reflect(Reader& visitor, unsigned long& value);
162 void Reflect(Writer& visitor, unsigned long& value);
163
164 void Reflect(Reader& visitor, long long& value);
165 void Reflect(Writer& visitor, long long& value);
166
167 void Reflect(Reader& visitor, unsigned long long& value);
168 void Reflect(Writer& visitor, unsigned long long& value);
169
170 void Reflect(Reader& visitor, double& value);
171 void Reflect(Writer& visitor, double& value);
172
173 void Reflect(Reader& visitor, bool& value);
174 void Reflect(Writer& visitor, bool& value);
175
176 void Reflect(Reader& visitor, std::string& value);
177 void Reflect(Writer& visitor, std::string& value);
178
179 void Reflect(Reader& visitor, std::string_view& view);
180 void Reflect(Writer& visitor, std::string_view& view);
181
182 void Reflect(Reader& visitor, JsonNull& value);
183 void Reflect(Writer& visitor, JsonNull& value);
184
185 void Reflect(Reader& visitor, SerializeFormat& value);
186 void Reflect(Writer& visitor, SerializeFormat& value);
187
188 //// Type constructors
189
190 template <typename T>
Reflect(Reader & visitor,optional<T> & value)191 void Reflect(Reader& visitor, optional<T>& value) {
192 if (visitor.IsNull()) {
193 visitor.GetNull();
194 return;
195 }
196 T real_value;
197 Reflect(visitor, real_value);
198 value = std::move(real_value);
199 }
200 template <typename T>
Reflect(Writer & visitor,optional<T> & value)201 void Reflect(Writer& visitor, optional<T>& value) {
202 if (value)
203 Reflect(visitor, *value);
204 else
205 visitor.Null();
206 }
207
208 // The same as std::optional
209 template <typename T>
Reflect(Reader & visitor,Maybe<T> & value)210 void Reflect(Reader& visitor, Maybe<T>& value) {
211 if (visitor.IsNull()) {
212 visitor.GetNull();
213 return;
214 }
215 T real_value;
216 Reflect(visitor, real_value);
217 value = std::move(real_value);
218 }
219 template <typename T>
Reflect(Writer & visitor,Maybe<T> & value)220 void Reflect(Writer& visitor, Maybe<T>& value) {
221 if (value)
222 Reflect(visitor, *value);
223 else
224 visitor.Null();
225 }
226
227 template <typename T>
ReflectMember(Writer & visitor,const char * name,optional<T> & value)228 void ReflectMember(Writer& visitor, const char* name, optional<T>& value) {
229 // For TypeScript optional property key?: value in the spec,
230 // We omit both key and value if value is std::nullopt (null) for JsonWriter
231 // to reduce output. But keep it for other serialization formats.
232 if (value || visitor.Format() != SerializeFormat::Json) {
233 visitor.Key(name);
234 Reflect(visitor, value);
235 }
236 }
237
238 // The same as std::optional
239 template <typename T>
ReflectMember(Writer & visitor,const char * name,Maybe<T> & value)240 void ReflectMember(Writer& visitor, const char* name, Maybe<T>& value) {
241 if (value.HasValue() || visitor.Format() != SerializeFormat::Json) {
242 visitor.Key(name);
243 Reflect(visitor, value);
244 }
245 }
246
247 template <typename T>
ReflectMember(Writer & visitor,const char * name,T & value,optionals_mandatory_tag)248 void ReflectMember(Writer& visitor,
249 const char* name,
250 T& value,
251 optionals_mandatory_tag) {
252 visitor.Key(name);
253 Reflect(visitor, value);
254 }
255
256 // std::vector
257 template <typename T>
Reflect(Reader & visitor,std::vector<T> & values)258 void Reflect(Reader& visitor, std::vector<T>& values) {
259 visitor.IterArray([&](Reader& entry) {
260 T entry_value;
261 Reflect(entry, entry_value);
262 values.push_back(std::move(entry_value));
263 });
264 }
265 template <typename T>
Reflect(Writer & visitor,std::vector<T> & values)266 void Reflect(Writer& visitor, std::vector<T>& values) {
267 visitor.StartArray(values.size());
268 for (auto& value : values)
269 Reflect(visitor, value);
270 visitor.EndArray();
271 }
272
273 // ReflectMember
274
DefaultReflectMemberStart(Writer & visitor)275 inline void DefaultReflectMemberStart(Writer& visitor) {
276 visitor.StartObject();
277 }
DefaultReflectMemberStart(Reader & visitor)278 inline void DefaultReflectMemberStart(Reader& visitor) {}
279
280 template <typename T>
ReflectMemberStart(Reader & visitor,T & value)281 bool ReflectMemberStart(Reader& visitor, T& value) {
282 return false;
283 }
284 template <typename T>
ReflectMemberStart(Writer & visitor,T & value)285 bool ReflectMemberStart(Writer& visitor, T& value) {
286 visitor.StartObject();
287 return true;
288 }
289
290 template <typename T>
ReflectMemberEnd(Reader & visitor,T & value)291 void ReflectMemberEnd(Reader& visitor, T& value) {}
292 template <typename T>
ReflectMemberEnd(Writer & visitor,T & value)293 void ReflectMemberEnd(Writer& visitor, T& value) {
294 visitor.EndObject();
295 }
296
297 template <typename T>
ReflectMember(Reader & visitor,const char * name,T & value)298 void ReflectMember(Reader& visitor, const char* name, T& value) {
299 visitor.DoMember(name, [&](Reader& child) { Reflect(child, value); });
300 }
301 template <typename T>
ReflectMember(Writer & visitor,const char * name,T & value)302 void ReflectMember(Writer& visitor, const char* name, T& value) {
303 visitor.Key(name);
304 Reflect(visitor, value);
305 }
306
307 // API
308
309 std::string Serialize(SerializeFormat format, IndexFile& file);
310 std::unique_ptr<IndexFile> Deserialize(
311 SerializeFormat format,
312 const AbsolutePath& path,
313 const std::string& serialized_index_content,
314 const std::string& file_content,
315 optional<int> expected_version);
316
317 void SetTestOutputMode();
318