11#include < sourcemeta/blaze/compiler.h>
22
3+ #include < cassert> // assert
34#include < variant> // std::visit
45
5- namespace sourcemeta ::blaze {
6+ namespace {
7+ auto value_from_json (const sourcemeta::core::JSON &wrapper)
8+ -> sourcemeta::blaze::Value {
9+ assert (wrapper.is_object ());
10+ assert (wrapper.defines (" t" ));
11+ assert (wrapper.defines (" v" ));
12+ const auto &type{wrapper.at (" t" )};
13+ const auto &value{wrapper.at (" v" )};
14+ assert (type.is_integer () && type.is_positive ());
15+ using namespace sourcemeta ::blaze;
16+ switch (type.to_integer ()) {
17+ // clang-format off
18+ case 0 : return sourcemeta::core::from_json<ValueNone>(value);
19+ case 1 : return sourcemeta::core::from_json<ValueJSON>(value);
20+ case 2 : return sourcemeta::core::from_json<ValueSet>(value);
21+ case 3 : return sourcemeta::core::from_json<ValueString>(value);
22+ case 4 : return sourcemeta::core::from_json<ValueProperty>(value);
23+ case 5 : return sourcemeta::core::from_json<ValueStrings>(value);
24+ case 6 : return sourcemeta::core::from_json<ValueStringSet>(value);
25+ case 7 : return sourcemeta::core::from_json<ValueTypes>(value);
26+ case 8 : return sourcemeta::core::from_json<ValueType>(value);
27+ case 9 : return sourcemeta::core::from_json<ValueRegex>(value);
28+ case 10 : return sourcemeta::core::from_json<ValueUnsignedInteger>(value);
29+ case 11 : return sourcemeta::core::from_json<ValueRange>(value);
30+ case 12 : return sourcemeta::core::from_json<ValueBoolean>(value);
31+ case 13 : return sourcemeta::core::from_json<ValueNamedIndexes>(value);
32+ case 14 : return sourcemeta::core::from_json<ValueStringType>(value);
33+ case 15 : return sourcemeta::core::from_json<ValueStringMap>(value);
34+ case 16 : return sourcemeta::core::from_json<ValuePropertyFilter>(value);
35+ case 17 : return sourcemeta::core::from_json<ValueIndexPair>(value);
36+ case 18 : return sourcemeta::core::from_json<ValuePointer>(value);
37+ case 19 : return sourcemeta::core::from_json<ValueTypedProperties>(value);
38+ case 20 : return sourcemeta::core::from_json<ValueStringHashes>(value);
39+ case 21 : return sourcemeta::core::from_json<ValueTypedHashes>(value);
40+ // clang-format on
41+ default :
42+ assert (false );
43+ return ValueNone{};
44+ }
45+ }
46+
47+ auto instructions_from_json (const sourcemeta::core::JSON &instructions)
48+ -> sourcemeta::blaze::Instructions {
49+ assert (instructions.is_array ());
50+ sourcemeta::blaze::Instructions result;
51+ result.reserve (instructions.size ());
52+ for (const auto &instruction : instructions.as_array ()) {
53+ assert (instruction.is_object ());
54+ assert (instruction.defines (" t" ));
55+ assert (instruction.defines (" s" ));
56+ assert (instruction.defines (" i" ));
57+ assert (instruction.defines (" k" ));
58+ assert (instruction.defines (" r" ));
59+ assert (instruction.defines (" v" ));
60+ assert (instruction.defines (" c" ));
61+ const auto &type{instruction.at (" t" )};
62+ const auto &relative_schema_location{instruction.at (" s" )};
63+ const auto &relative_instance_location{instruction.at (" i" )};
64+ const auto &keyword_location{instruction.at (" k" )};
65+ const auto &schema_resource{instruction.at (" r" )};
66+ const auto &value{instruction.at (" v" )};
67+ const auto &children{instruction.at (" c" )};
68+ assert (type.is_integer () && type.is_positive ());
69+ assert (relative_schema_location.is_string ());
70+ assert (relative_instance_location.is_string ());
71+ assert (keyword_location.is_string ());
72+ assert (schema_resource.is_integer () && schema_resource.is_positive ());
73+ assert (value.is_object ());
74+ assert (children.is_array ());
675
7- auto to_json (const Instruction &instruction) -> sourcemeta::core::JSON {
76+ // TODO: Maybe we should emplace here?
77+ result.push_back (
78+ {sourcemeta::core::from_json<sourcemeta::blaze::InstructionIndex>(type),
79+ sourcemeta::core::from_json<sourcemeta::core::Pointer>(
80+ relative_schema_location),
81+ sourcemeta::core::from_json<sourcemeta::core::Pointer>(
82+ relative_instance_location),
83+ sourcemeta::core::from_json<std::string>(keyword_location),
84+ sourcemeta::core::from_json<std::size_t >(schema_resource),
85+ value_from_json (value), instructions_from_json (children)});
86+ }
87+
88+ return result;
89+ }
90+
91+ auto to_json (const sourcemeta::blaze::Instruction &instruction)
92+ -> sourcemeta::core::JSON {
893 auto result{sourcemeta::core::JSON::make_object ()};
994 // We use single characters to save space, as this serialised format
1095 // is not meant to be human-readable anyway
@@ -38,6 +123,9 @@ auto to_json(const Instruction &instruction) -> sourcemeta::core::JSON {
38123 }));
39124 return result;
40125}
126+ } // namespace
127+
128+ namespace sourcemeta ::blaze {
41129
42130auto to_json (const Template &schema_template) -> sourcemeta::core::JSON {
43131 auto result{sourcemeta::core::JSON::make_object ()};
@@ -46,9 +134,24 @@ auto to_json(const Template &schema_template) -> sourcemeta::core::JSON {
46134 result.assign (" instructions" ,
47135 sourcemeta::core::to_json (schema_template.instructions ,
48136 [](const auto &instruction) {
49- return to_json (instruction);
137+ return :: to_json (instruction);
50138 }));
51139 return result;
52140}
53141
142+ auto from_json (const sourcemeta::core::JSON &json) -> Template {
143+ assert (json.is_object ());
144+ assert (json.defines (" instructions" ));
145+ assert (json.defines (" dynamic" ));
146+ assert (json.defines (" track" ));
147+ const auto &instructions{json.at (" instructions" )};
148+ const auto &dynamic{json.at (" dynamic" )};
149+ const auto &track{json.at (" track" )};
150+ assert (instructions.is_array ());
151+ assert (dynamic.is_boolean ());
152+ assert (track.is_boolean ());
153+ return {instructions_from_json (instructions), dynamic.to_boolean (),
154+ track.to_boolean ()};
155+ }
156+
54157} // namespace sourcemeta::blaze
0 commit comments