blob: 0d3159bd1a5e1e7c5e2344679d6317eac39dc29c [file] [log] [blame]
Václav Kubernát0a2a2e82018-05-11 13:59:12 +02001/*
2 * Copyright (C) 2018 CESNET, https://photonics.cesnet.cz/
3 * Copyright (C) 2018 FIT CVUT, https://fit.cvut.cz/
4 *
5 * Written by Václav Kubernát <kubervac@fit.cvut.cz>
6 *
7*/
8
9#pragma once
Václav Kubernát195eeea2018-05-18 13:52:36 +020010
Václav Kubernát195eeea2018-05-18 13:52:36 +020011#include "parser_context.hpp"
Václav Kubernát48fc3832018-05-28 14:21:22 +020012#include "schema.hpp"
Václav Kubernát0a2a2e82018-05-11 13:59:12 +020013
Václav Kubernát0a2a2e82018-05-11 13:59:12 +020014struct keyValue_class {
15 template <typename T, typename Iterator, typename Context>
16 void on_success(Iterator const&, Iterator const&, T& ast, Context const& context)
17 {
18 auto& parserContext = x3::get<parser_context_tag>(context);
Václav Kubernát48fc3832018-05-28 14:21:22 +020019 const Schema& schema = parserContext.m_schema;
Václav Kubernát0a2a2e82018-05-11 13:59:12 +020020
21 if (parserContext.m_tmpListKeys.find(ast.first) != parserContext.m_tmpListKeys.end()) {
22 _pass(context) = false;
23 parserContext.m_errorMsg = "Key \"" + ast.first + "\" was entered more than once.";
Václav Kubernát41378452018-06-06 16:29:40 +020024 } else if (!schema.listHasKey(parserContext.m_curPath, parserContext.m_tmpListName, ast.first)) {
Václav Kubernát0a2a2e82018-05-11 13:59:12 +020025 _pass(context) = false;
26 parserContext.m_errorMsg = parserContext.m_tmpListName + " is not indexed by \"" + ast.first + "\".";
Václav Kubernát41378452018-06-06 16:29:40 +020027 } else {
28 parserContext.m_tmpListKeys.insert(ast.first);
Václav Kubernát0a2a2e82018-05-11 13:59:12 +020029 }
30 }
Václav Kubernát41378452018-06-06 16:29:40 +020031
32 template <typename Iterator, typename Exception, typename Context>
33 x3::error_handler_result on_error(Iterator&, Iterator const&, Exception const&, Context const& context)
34 {
35 auto& parserContext = x3::get<parser_context_tag>(context);
36 parserContext.m_errorMsg = "Error parsing key values here:";
37 return x3::error_handler_result::rethrow;
38 }
Václav Kubernát0a2a2e82018-05-11 13:59:12 +020039};
Václav Kubernát41378452018-06-06 16:29:40 +020040
Václav Kubernát0a2a2e82018-05-11 13:59:12 +020041struct identifier_class;
42
43struct listPrefix_class {
44 template <typename T, typename Iterator, typename Context>
45 void on_success(Iterator const&, Iterator const&, T& ast, Context const& context)
46 {
47 auto& parserContext = x3::get<parser_context_tag>(context);
Václav Kubernát48fc3832018-05-28 14:21:22 +020048 const Schema& schema = parserContext.m_schema;
Václav Kubernát0a2a2e82018-05-11 13:59:12 +020049
Václav Kubernát48fc3832018-05-28 14:21:22 +020050 if (schema.isList(parserContext.m_curPath, ast)) {
Václav Kubernát0a2a2e82018-05-11 13:59:12 +020051 parserContext.m_tmpListName = ast;
52 } else {
53 _pass(context) = false;
54 }
55 }
56};
57
58struct listSuffix_class {
59 template <typename T, typename Iterator, typename Context>
60 void on_success(Iterator const&, Iterator const&, T& ast, Context const& context)
61 {
62 auto& parserContext = x3::get<parser_context_tag>(context);
Václav Kubernát48fc3832018-05-28 14:21:22 +020063 const Schema& schema = parserContext.m_schema;
Václav Kubernát0a2a2e82018-05-11 13:59:12 +020064
Václav Kubernát48fc3832018-05-28 14:21:22 +020065 const auto& keysNeeded = schema.listKeys(parserContext.m_curPath, parserContext.m_tmpListName);
Václav Kubernát0a2a2e82018-05-11 13:59:12 +020066 std::set<std::string> keysSupplied;
67 for (const auto& it : ast)
68 keysSupplied.insert(it.first);
69
70 if (keysNeeded != keysSupplied) {
71 parserContext.m_errorMsg = "Not enough keys for " + parserContext.m_tmpListName + ". " +
72 "These keys were not supplied:";
73 std::set<std::string> missingKeys;
74 std::set_difference(keysNeeded.begin(), keysNeeded.end(),
75 keysSupplied.begin(), keysSupplied.end(),
76 std::inserter(missingKeys, missingKeys.end()));
77
78 for (const auto& it : missingKeys)
79 parserContext.m_errorMsg += " " + it;
80 parserContext.m_errorMsg += ".";
81
82 _pass(context) = false;
83 }
84 }
Václav Kubernát41378452018-06-06 16:29:40 +020085
86 template <typename Iterator, typename Exception, typename Context>
87 x3::error_handler_result on_error(Iterator&, Iterator const&, Exception const&, Context const& context)
88 {
89 auto& parserContext = x3::get<parser_context_tag>(context);
90 if (parserContext.m_errorMsg.empty())
91 parserContext.m_errorMsg = "Expecting ']' here:";
92 return x3::error_handler_result::rethrow;
93
94 }
Václav Kubernát0a2a2e82018-05-11 13:59:12 +020095};
96struct listElement_class {
97 template <typename T, typename Iterator, typename Context>
98 void on_success(Iterator const&, Iterator const&, T& ast, Context const& context)
99 {
100 auto& parserContext = x3::get<parser_context_tag>(context);
Václav Kubernát814fa412018-05-25 19:47:18 +0200101 parserContext.m_curPath.m_nodes.push_back(ast);
Václav Kubernát0a2a2e82018-05-11 13:59:12 +0200102 }
103
104 template <typename Iterator, typename Exception, typename Context>
Václav Kubernát41378452018-06-06 16:29:40 +0200105 x3::error_handler_result on_error(Iterator&, Iterator const&, Exception const&, Context const& context)
Václav Kubernát0a2a2e82018-05-11 13:59:12 +0200106 {
107 auto& parserContext = x3::get<parser_context_tag>(context);
Václav Kubernát41378452018-06-06 16:29:40 +0200108 if (parserContext.m_errorMsg.empty()) {
Václav Kubernát0a2a2e82018-05-11 13:59:12 +0200109 return x3::error_handler_result::fail;
Václav Kubernát41378452018-06-06 16:29:40 +0200110 } else {
111 return x3::error_handler_result::rethrow;
112 }
Václav Kubernát0a2a2e82018-05-11 13:59:12 +0200113
Václav Kubernát0a2a2e82018-05-11 13:59:12 +0200114 }
115};
116
Václav Kubernát60d6f292018-05-25 09:45:32 +0200117struct nodeup_class {
118 template <typename T, typename Iterator, typename Context>
119 void on_success(Iterator const&, Iterator const&, T&, Context const& context)
120 {
121 auto& parserContext = x3::get<parser_context_tag>(context);
122
Václav Kubernát814fa412018-05-25 19:47:18 +0200123 if (!parserContext.m_curPath.m_nodes.empty()) {
124 parserContext.m_curPath.m_nodes.pop_back();
Václav Kubernát60d6f292018-05-25 09:45:32 +0200125 } else {
126 _pass(context) = false;
127 }
Václav Kubernát60d6f292018-05-25 09:45:32 +0200128 }
129};
130
Václav Kubernát0a2a2e82018-05-11 13:59:12 +0200131struct container_class {
132 template <typename T, typename Iterator, typename Context>
133 void on_success(Iterator const&, Iterator const&, T& ast, Context const& context)
134 {
135 auto& parserContext = x3::get<parser_context_tag>(context);
Václav Kubernát48fc3832018-05-28 14:21:22 +0200136 const auto& schema = parserContext.m_schema;
Václav Kubernát0a2a2e82018-05-11 13:59:12 +0200137
Václav Kubernát48fc3832018-05-28 14:21:22 +0200138 if (schema.isContainer(parserContext.m_curPath, ast.m_name)) {
Václav Kubernát814fa412018-05-25 19:47:18 +0200139 parserContext.m_curPath.m_nodes.push_back(ast);
Václav Kubernát0a2a2e82018-05-11 13:59:12 +0200140 } else {
141 _pass(context) = false;
142 }
143 }
144};
145
Václav Kubernát07204242018-06-04 18:12:09 +0200146struct leaf_class {
147 template <typename T, typename Iterator, typename Context>
148 void on_success(Iterator const&, Iterator const&, T& ast, Context const& context)
149 {
150 auto& parserContext = x3::get<parser_context_tag>(context);
151 const auto& schema = parserContext.m_schema;
152
153 if (schema.isLeaf(parserContext.m_curPath, ast.m_name)) {
154 parserContext.m_curPath.m_nodes.push_back(ast);
155 } else {
156 _pass(context) = false;
157 }
158 }
159};
160
Václav Kubernát0a2a2e82018-05-11 13:59:12 +0200161struct path_class {
162 template <typename T, typename Iterator, typename Context>
163 void on_success(Iterator const&, Iterator const&, T&, Context const&)
164 {
165 }
Václav Kubernát07204242018-06-04 18:12:09 +0200166
167 template <typename Iterator, typename Exception, typename Context>
Václav Kubernát41378452018-06-06 16:29:40 +0200168 x3::error_handler_result on_error(Iterator&, Iterator const&, Exception const&, Context const& context)
Václav Kubernát07204242018-06-04 18:12:09 +0200169 {
170 auto& parserContext = x3::get<parser_context_tag>(context);
Václav Kubernát41378452018-06-06 16:29:40 +0200171 if (parserContext.m_errorMsg.empty()) {
172 parserContext.m_errorMsg = "Expected path.";
Václav Kubernát07204242018-06-04 18:12:09 +0200173 return x3::error_handler_result::fail;
Václav Kubernát41378452018-06-06 16:29:40 +0200174 } else {
175 return x3::error_handler_result::rethrow;
176 }
Václav Kubernát07204242018-06-04 18:12:09 +0200177 }
178};
179
180struct data_string_class {
Václav Kubernát0a2a2e82018-05-11 13:59:12 +0200181};
182
183struct cd_class {
184 template <typename T, typename Iterator, typename Context>
185 void on_success(Iterator const&, Iterator const&, T&, Context const&)
186 {
187 }
188
189 template <typename Iterator, typename Exception, typename Context>
190 x3::error_handler_result on_error(Iterator&, Iterator const&, Exception const& x, Context const& context)
191 {
192 auto& parserContext = x3::get<parser_context_tag>(context);
Václav Kubernát41378452018-06-06 16:29:40 +0200193 if (parserContext.m_errorMsg.empty())
194 parserContext.m_errorMsg = "Expected " + x.which() + " here:";
195 return x3::error_handler_result::rethrow;
Václav Kubernát0a2a2e82018-05-11 13:59:12 +0200196 }
197};
Václav Kubernátb61336d2018-05-28 17:35:03 +0200198
199struct presenceContainerPathHandler {
200 template <typename T, typename Iterator, typename Context>
201 void on_success(Iterator const&, Iterator const&, T& ast, Context const& context)
202 {
203 auto& parserContext = x3::get<parser_context_tag>(context);
204 const auto& schema = parserContext.m_schema;
205 try {
206 container_ cont = boost::get<container_>(ast.m_path.m_nodes.back());
207 path_ location{decltype(path_::m_nodes)(parserContext.m_curPath.m_nodes.begin(),
208 parserContext.m_curPath.m_nodes.end() - 1)};
209
210 if (!schema.isPresenceContainer(location, cont.m_name)) {
Václav Kubernát41378452018-06-06 16:29:40 +0200211 parserContext.m_errorMsg = "This container is not a presence container.";
Václav Kubernátb61336d2018-05-28 17:35:03 +0200212 _pass(context) = false;
Václav Kubernátb61336d2018-05-28 17:35:03 +0200213 }
214 } catch (boost::bad_get&) {
Václav Kubernát41378452018-06-06 16:29:40 +0200215 parserContext.m_errorMsg = "This is not a container.";
Václav Kubernátb61336d2018-05-28 17:35:03 +0200216 _pass(context) = false;
Václav Kubernátb61336d2018-05-28 17:35:03 +0200217 }
218 }
219
220 template <typename Iterator, typename Exception, typename Context>
Václav Kubernát41378452018-06-06 16:29:40 +0200221 x3::error_handler_result on_error(Iterator&, Iterator const&, Exception const&, Context const& context)
Václav Kubernátb61336d2018-05-28 17:35:03 +0200222 {
223 auto& parserContext = x3::get<parser_context_tag>(context);
Václav Kubernát41378452018-06-06 16:29:40 +0200224 if (parserContext.m_errorMsg.empty())
225 parserContext.m_errorMsg = "Couldn't parse create/delete command.";
226 return x3::error_handler_result::rethrow;
Václav Kubernátb61336d2018-05-28 17:35:03 +0200227 }
228};
229
230struct create_class : public presenceContainerPathHandler {
231};
232
233struct delete_class : public presenceContainerPathHandler {
234};
235
Václav Kubernát07204242018-06-04 18:12:09 +0200236struct set_class {
237 template <typename T, typename Iterator, typename Context>
238 void on_success(Iterator const&, Iterator const&, T& ast, Context const& context)
239 {
Václav Kubernát41378452018-06-06 16:29:40 +0200240 auto& parserContext = x3::get<parser_context_tag>(context);
Václav Kubernát07204242018-06-04 18:12:09 +0200241 try {
242 auto leaf = boost::get<leaf_>(ast.m_path.m_nodes.back());
243 } catch (boost::bad_get&) {
Václav Kubernát41378452018-06-06 16:29:40 +0200244 parserContext.m_errorMsg = "This is not a leaf.";
Václav Kubernát07204242018-06-04 18:12:09 +0200245 _pass(context) = false;
Václav Kubernát07204242018-06-04 18:12:09 +0200246 }
247 }
248
249 template <typename Iterator, typename Exception, typename Context>
250 x3::error_handler_result on_error(Iterator&, Iterator const&, Exception const& x, Context const& context)
251 {
252 auto& parserContext = x3::get<parser_context_tag>(context);
Václav Kubernát41378452018-06-06 16:29:40 +0200253 if (parserContext.m_errorMsg.empty())
254 parserContext.m_errorMsg = "Expected " + x.which() + " here:";
255 return x3::error_handler_result::rethrow;
Václav Kubernát07204242018-06-04 18:12:09 +0200256 }
257};
258
Václav Kubernátb61336d2018-05-28 17:35:03 +0200259struct command_class {
260 template <typename Iterator, typename Exception, typename Context>
261 x3::error_handler_result on_error(Iterator&, Iterator const&, Exception const& x, Context const& context)
262 {
263 auto& parserContext = x3::get<parser_context_tag>(context);
264 auto& error_handler = x3::get<x3::error_handler_tag>(context).get();
Václav Kubernát41378452018-06-06 16:29:40 +0200265 if (parserContext.m_errorMsg.empty()) {
266 parserContext.m_errorMsg = "Unknown command.";
267 }
268 error_handler(x.where(), parserContext.m_errorMsg);
Václav Kubernátb61336d2018-05-28 17:35:03 +0200269 return x3::error_handler_result::fail;
270 }
271};