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