blob: b9b91017645d241f7080cf92b3b443d1cf419253 [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átebca2552018-06-08 19:06:02 +020013#include "utils.hpp"
Václav Kubernát0a2a2e82018-05-11 13:59:12 +020014
Václav Kubernát0a2a2e82018-05-11 13:59:12 +020015struct keyValue_class {
16 template <typename T, typename Iterator, typename Context>
17 void on_success(Iterator const&, Iterator const&, T& ast, Context const& context)
18 {
19 auto& parserContext = x3::get<parser_context_tag>(context);
Václav Kubernát48fc3832018-05-28 14:21:22 +020020 const Schema& schema = parserContext.m_schema;
Václav Kubernát0a2a2e82018-05-11 13:59:12 +020021
22 if (parserContext.m_tmpListKeys.find(ast.first) != parserContext.m_tmpListKeys.end()) {
23 _pass(context) = false;
24 parserContext.m_errorMsg = "Key \"" + ast.first + "\" was entered more than once.";
Václav Kubernát744f57f2018-06-29 22:46:26 +020025 } else if (!schema.listHasKey(parserContext.m_curPath, {parserContext.m_curModule, parserContext.m_tmpListName}, ast.first)) {
Václav Kubernát0a2a2e82018-05-11 13:59:12 +020026 _pass(context) = false;
27 parserContext.m_errorMsg = parserContext.m_tmpListName + " is not indexed by \"" + ast.first + "\".";
Václav Kubernát41378452018-06-06 16:29:40 +020028 } else {
29 parserContext.m_tmpListKeys.insert(ast.first);
Václav Kubernát0a2a2e82018-05-11 13:59:12 +020030 }
31 }
Václav Kubernát41378452018-06-06 16:29:40 +020032
33 template <typename Iterator, typename Exception, typename Context>
34 x3::error_handler_result on_error(Iterator&, Iterator const&, Exception const&, Context const& context)
35 {
36 auto& parserContext = x3::get<parser_context_tag>(context);
37 parserContext.m_errorMsg = "Error parsing key values here:";
38 return x3::error_handler_result::rethrow;
39 }
Václav Kubernát0a2a2e82018-05-11 13:59:12 +020040};
Václav Kubernát41378452018-06-06 16:29:40 +020041
Václav Kubernát744f57f2018-06-29 22:46:26 +020042struct node_identifier_class {
43 template <typename T, typename Iterator, typename Context>
44 void on_success(Iterator const&, Iterator const&, T&, Context const& context)
45 {
46 auto& parserContext = x3::get<parser_context_tag>(context);
47
48 if (!parserContext.m_topLevelModulePresent) {
49 if (parserContext.m_errorMsg.empty())
50 parserContext.m_errorMsg = "You have to specify a top level module.";
51 _pass(context) = false;
52 }
53 }
54};
55
Václav Kubernát89728d82018-09-13 16:28:28 +020056struct key_identifier_class;
57
Václav Kubernát744f57f2018-06-29 22:46:26 +020058struct module_identifier_class;
Václav Kubernát0a2a2e82018-05-11 13:59:12 +020059
60struct listPrefix_class {
61 template <typename T, typename Iterator, typename Context>
62 void on_success(Iterator const&, Iterator const&, T& ast, Context const& context)
63 {
64 auto& parserContext = x3::get<parser_context_tag>(context);
Václav Kubernát48fc3832018-05-28 14:21:22 +020065 const Schema& schema = parserContext.m_schema;
Václav Kubernát0a2a2e82018-05-11 13:59:12 +020066
Václav Kubernát744f57f2018-06-29 22:46:26 +020067 if (schema.isList(parserContext.m_curPath, {parserContext.m_curModule, ast})) {
Václav Kubernát0a2a2e82018-05-11 13:59:12 +020068 parserContext.m_tmpListName = ast;
69 } else {
70 _pass(context) = false;
71 }
72 }
73};
74
75struct listSuffix_class {
76 template <typename T, typename Iterator, typename Context>
77 void on_success(Iterator const&, Iterator const&, T& ast, Context const& context)
78 {
79 auto& parserContext = x3::get<parser_context_tag>(context);
Václav Kubernát48fc3832018-05-28 14:21:22 +020080 const Schema& schema = parserContext.m_schema;
Václav Kubernát0a2a2e82018-05-11 13:59:12 +020081
Václav Kubernát744f57f2018-06-29 22:46:26 +020082 const auto& keysNeeded = schema.listKeys(parserContext.m_curPath, {parserContext.m_curModule, parserContext.m_tmpListName});
Václav Kubernát0a2a2e82018-05-11 13:59:12 +020083 std::set<std::string> keysSupplied;
84 for (const auto& it : ast)
85 keysSupplied.insert(it.first);
86
87 if (keysNeeded != keysSupplied) {
88 parserContext.m_errorMsg = "Not enough keys for " + parserContext.m_tmpListName + ". " +
89 "These keys were not supplied:";
90 std::set<std::string> missingKeys;
91 std::set_difference(keysNeeded.begin(), keysNeeded.end(),
92 keysSupplied.begin(), keysSupplied.end(),
93 std::inserter(missingKeys, missingKeys.end()));
94
95 for (const auto& it : missingKeys)
96 parserContext.m_errorMsg += " " + it;
97 parserContext.m_errorMsg += ".";
98
99 _pass(context) = false;
100 }
101 }
Václav Kubernát41378452018-06-06 16:29:40 +0200102
103 template <typename Iterator, typename Exception, typename Context>
104 x3::error_handler_result on_error(Iterator&, Iterator const&, Exception const&, Context const& context)
105 {
106 auto& parserContext = x3::get<parser_context_tag>(context);
107 if (parserContext.m_errorMsg.empty())
108 parserContext.m_errorMsg = "Expecting ']' here:";
109 return x3::error_handler_result::rethrow;
Václav Kubernát41378452018-06-06 16:29:40 +0200110 }
Václav Kubernát0a2a2e82018-05-11 13:59:12 +0200111};
112struct listElement_class {
Václav Kubernát0a2a2e82018-05-11 13:59:12 +0200113 template <typename Iterator, typename Exception, typename Context>
Václav Kubernát41378452018-06-06 16:29:40 +0200114 x3::error_handler_result on_error(Iterator&, Iterator const&, Exception const&, Context const& context)
Václav Kubernát0a2a2e82018-05-11 13:59:12 +0200115 {
116 auto& parserContext = x3::get<parser_context_tag>(context);
Václav Kubernát41378452018-06-06 16:29:40 +0200117 if (parserContext.m_errorMsg.empty()) {
Václav Kubernát0a2a2e82018-05-11 13:59:12 +0200118 return x3::error_handler_result::fail;
Václav Kubernát41378452018-06-06 16:29:40 +0200119 } else {
120 return x3::error_handler_result::rethrow;
121 }
Václav Kubernát0a2a2e82018-05-11 13:59:12 +0200122 }
123};
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200124struct list_class {
125 template <typename T, typename Iterator, typename Context>
126 void on_success(Iterator const&, Iterator const&, T& ast, Context const& context)
127 {
128 auto& parserContext = x3::get<parser_context_tag>(context);
129 const Schema& schema = parserContext.m_schema;
Václav Kubernát0a2a2e82018-05-11 13:59:12 +0200130
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200131 if (!schema.isList(parserContext.m_curPath, {parserContext.m_curModule, ast.m_name})) {
132 _pass(context) = false;
133 }
134 }
135};
Václav Kubernát60d6f292018-05-25 09:45:32 +0200136struct nodeup_class {
137 template <typename T, typename Iterator, typename Context>
138 void on_success(Iterator const&, Iterator const&, T&, Context const& context)
139 {
140 auto& parserContext = x3::get<parser_context_tag>(context);
141
Václav Kubernát744f57f2018-06-29 22:46:26 +0200142 if (parserContext.m_curPath.m_nodes.empty())
Václav Kubernát60d6f292018-05-25 09:45:32 +0200143 _pass(context) = false;
Václav Kubernát60d6f292018-05-25 09:45:32 +0200144 }
145};
146
Václav Kubernát0a2a2e82018-05-11 13:59:12 +0200147struct container_class {
148 template <typename T, typename Iterator, typename Context>
149 void on_success(Iterator const&, Iterator const&, T& ast, Context const& context)
150 {
151 auto& parserContext = x3::get<parser_context_tag>(context);
Václav Kubernát48fc3832018-05-28 14:21:22 +0200152 const auto& schema = parserContext.m_schema;
Václav Kubernát0a2a2e82018-05-11 13:59:12 +0200153
Václav Kubernát744f57f2018-06-29 22:46:26 +0200154 if (!schema.isContainer(parserContext.m_curPath, {parserContext.m_curModule, ast.m_name}))
Václav Kubernát0a2a2e82018-05-11 13:59:12 +0200155 _pass(context) = false;
Václav Kubernát0a2a2e82018-05-11 13:59:12 +0200156 }
157};
158
Václav Kubernát07204242018-06-04 18:12:09 +0200159struct leaf_class {
160 template <typename T, typename Iterator, typename Context>
161 void on_success(Iterator const&, Iterator const&, T& ast, Context const& context)
162 {
163 auto& parserContext = x3::get<parser_context_tag>(context);
164 const auto& schema = parserContext.m_schema;
165
Václav Kubernát744f57f2018-06-29 22:46:26 +0200166 if (!schema.isLeaf(parserContext.m_curPath, {parserContext.m_curModule, ast.m_name}))
167 _pass(context) = false;
168 }
169};
170
Václav Kubernát744f57f2018-06-29 22:46:26 +0200171struct module_class {
172 template <typename T, typename Iterator, typename Context>
173 void on_success(Iterator const&, Iterator const&, T& ast, Context const& context)
174 {
175 auto& parserContext = x3::get<parser_context_tag>(context);
176 const auto& schema = parserContext.m_schema;
177
178 if (schema.isModule(parserContext.m_curPath, ast.m_name)) {
179 parserContext.m_curModule = ast.m_name;
180 parserContext.m_topLevelModulePresent = true;
Václav Kubernát07204242018-06-04 18:12:09 +0200181 } else {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200182 parserContext.m_errorMsg = "Invalid module name.";
Václav Kubernát07204242018-06-04 18:12:09 +0200183 _pass(context) = false;
184 }
185 }
186};
187
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200188struct schemaNode_class {
Václav Kubernát0a2a2e82018-05-11 13:59:12 +0200189 template <typename T, typename Iterator, typename Context>
Václav Kubernát744f57f2018-06-29 22:46:26 +0200190 void on_success(Iterator const&, Iterator const&, T& ast, Context const& context)
Václav Kubernát0a2a2e82018-05-11 13:59:12 +0200191 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200192 auto& parserContext = x3::get<parser_context_tag>(context);
193 if (ast.m_suffix.type() == typeid(nodeup_)) {
194 parserContext.m_curPath.m_nodes.pop_back();
195 if (parserContext.m_curPath.m_nodes.empty())
196 parserContext.m_topLevelModulePresent = false;
197 } else {
198 parserContext.m_curPath.m_nodes.push_back(ast);
199 parserContext.m_curModule = boost::none;
200 }
Václav Kubernát0a2a2e82018-05-11 13:59:12 +0200201 }
Václav Kubernát744f57f2018-06-29 22:46:26 +0200202};
Václav Kubernát07204242018-06-04 18:12:09 +0200203
Václav Kubernát39ae9592019-02-05 17:35:16 +0100204struct dataNodeList_class {
205 template <typename T, typename Iterator, typename Context>
206 void on_success(Iterator const&, Iterator const&, T& ast, Context const& context)
207 {
208 auto& parserContext = x3::get<parser_context_tag>(context);
209 parserContext.m_curPath.m_nodes.push_back(dataNodeToSchemaNode(ast));
210 }
211};
Václav Kubernát5c75b252018-10-10 18:33:47 +0200212
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200213struct dataNode_class {
214 template <typename T, typename Iterator, typename Context>
215 void on_success(Iterator const&, Iterator const&, T& ast, Context const& context)
216 {
217 auto& parserContext = x3::get<parser_context_tag>(context);
218 if (ast.m_suffix.type() == typeid(nodeup_)) {
219 parserContext.m_curPath.m_nodes.pop_back();
220 if (parserContext.m_curPath.m_nodes.empty())
221 parserContext.m_topLevelModulePresent = false;
222 } else {
223 parserContext.m_curPath.m_nodes.push_back(dataNodeToSchemaNode(ast));
224 parserContext.m_curModule = boost::none;
225 }
226 }
227};
228
Václav Kubernát37171a12018-08-31 17:01:48 +0200229struct absoluteStart_class {
230 template <typename T, typename Iterator, typename Context>
231 void on_success(Iterator const&, Iterator const&, T&, Context const& context)
232 {
233 auto& parserContext = x3::get<parser_context_tag>(context);
234 parserContext.m_curPath.m_nodes.clear();
235 }
236};
237
Václav Kubernát5c75b252018-10-10 18:33:47 +0200238struct dataNodesListEnd_class;
239
240struct dataPathListEnd_class;
241
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200242struct dataPath_class {
243 template <typename Iterator, typename Exception, typename Context>
244 x3::error_handler_result on_error(Iterator&, Iterator const&, Exception const&, Context const& context)
245 {
246 auto& parserContext = x3::get<parser_context_tag>(context);
247 if (parserContext.m_errorMsg.empty()) {
248 parserContext.m_errorMsg = "Expected path.";
249 return x3::error_handler_result::fail;
250 } else {
251 return x3::error_handler_result::rethrow;
252 }
253 }
254};
255
256struct schemaPath_class {
Václav Kubernát07204242018-06-04 18:12:09 +0200257 template <typename Iterator, typename Exception, typename Context>
Václav Kubernát41378452018-06-06 16:29:40 +0200258 x3::error_handler_result on_error(Iterator&, Iterator const&, Exception const&, Context const& context)
Václav Kubernát07204242018-06-04 18:12:09 +0200259 {
260 auto& parserContext = x3::get<parser_context_tag>(context);
Václav Kubernát41378452018-06-06 16:29:40 +0200261 if (parserContext.m_errorMsg.empty()) {
262 parserContext.m_errorMsg = "Expected path.";
Václav Kubernát07204242018-06-04 18:12:09 +0200263 return x3::error_handler_result::fail;
Václav Kubernát41378452018-06-06 16:29:40 +0200264 } else {
265 return x3::error_handler_result::rethrow;
266 }
Václav Kubernát07204242018-06-04 18:12:09 +0200267 }
268};
269
Václav Kubernát6d791432018-10-25 16:00:35 +0200270struct discard_class;
Václav Kubernát0a2a2e82018-05-11 13:59:12 +0200271
Václav Kubernát11afac72018-07-18 14:59:53 +0200272struct ls_class;
273
Václav Kubernát744f57f2018-06-29 22:46:26 +0200274struct cd_class {
Václav Kubernát0a2a2e82018-05-11 13:59:12 +0200275 template <typename Iterator, typename Exception, typename Context>
276 x3::error_handler_result on_error(Iterator&, Iterator const&, Exception const& x, Context const& context)
277 {
278 auto& parserContext = x3::get<parser_context_tag>(context);
Václav Kubernát41378452018-06-06 16:29:40 +0200279 if (parserContext.m_errorMsg.empty())
280 parserContext.m_errorMsg = "Expected " + x.which() + " here:";
281 return x3::error_handler_result::rethrow;
Václav Kubernát0a2a2e82018-05-11 13:59:12 +0200282 }
283};
Václav Kubernátb61336d2018-05-28 17:35:03 +0200284
285struct presenceContainerPathHandler {
286 template <typename T, typename Iterator, typename Context>
287 void on_success(Iterator const&, Iterator const&, T& ast, Context const& context)
288 {
289 auto& parserContext = x3::get<parser_context_tag>(context);
290 const auto& schema = parserContext.m_schema;
291 try {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200292 boost::optional<std::string> module;
293 if (ast.m_path.m_nodes.back().m_prefix)
294 module = ast.m_path.m_nodes.back().m_prefix.value().m_name;
295 container_ cont = boost::get<container_>(ast.m_path.m_nodes.back().m_suffix);
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200296 schemaPath_ location = pathWithoutLastNode(parserContext.m_curPath);
Václav Kubernátb61336d2018-05-28 17:35:03 +0200297
Václav Kubernát744f57f2018-06-29 22:46:26 +0200298 if (!schema.isPresenceContainer(location, {module, cont.m_name})) {
Václav Kubernát41378452018-06-06 16:29:40 +0200299 parserContext.m_errorMsg = "This container is not a presence container.";
Václav Kubernátb61336d2018-05-28 17:35:03 +0200300 _pass(context) = false;
Václav Kubernátb61336d2018-05-28 17:35:03 +0200301 }
302 } catch (boost::bad_get&) {
Václav Kubernát41378452018-06-06 16:29:40 +0200303 parserContext.m_errorMsg = "This is not a container.";
Václav Kubernátb61336d2018-05-28 17:35:03 +0200304 _pass(context) = false;
Václav Kubernátb61336d2018-05-28 17:35:03 +0200305 }
306 }
307
308 template <typename Iterator, typename Exception, typename Context>
Václav Kubernát41378452018-06-06 16:29:40 +0200309 x3::error_handler_result on_error(Iterator&, Iterator const&, Exception const&, Context const& context)
Václav Kubernátb61336d2018-05-28 17:35:03 +0200310 {
311 auto& parserContext = x3::get<parser_context_tag>(context);
Václav Kubernát41378452018-06-06 16:29:40 +0200312 if (parserContext.m_errorMsg.empty())
313 parserContext.m_errorMsg = "Couldn't parse create/delete command.";
314 return x3::error_handler_result::rethrow;
Václav Kubernátb61336d2018-05-28 17:35:03 +0200315 }
316};
317
318struct create_class : public presenceContainerPathHandler {
319};
320
321struct delete_class : public presenceContainerPathHandler {
322};
323
Václav Kubernát0b0272f2018-06-13 14:13:08 +0200324struct leaf_path_class {
325 template <typename T, typename Iterator, typename Context>
326 void on_success(Iterator const&, Iterator const&, T& ast, Context const& context)
327 {
328 auto& parserContext = x3::get<parser_context_tag>(context);
329 try {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200330 auto leaf = boost::get<leaf_>(ast.m_nodes.back().m_suffix);
Václav Kubernát0b0272f2018-06-13 14:13:08 +0200331 } catch (boost::bad_get&) {
332 parserContext.m_errorMsg = "This is not a path to leaf.";
333 _pass(context) = false;
334 }
335 }
336};
337
Václav Kubernátebca2552018-06-08 19:06:02 +0200338struct leaf_data_class {
Václav Kubernát0b0272f2018-06-13 14:13:08 +0200339 template <typename Iterator, typename Exception, typename Context>
340 x3::error_handler_result on_error(Iterator&, Iterator const&, Exception const&, Context const& context)
341 {
342 auto& parserContext = x3::get<parser_context_tag>(context);
343 auto& schema = parserContext.m_schema;
344 if (parserContext.m_errorMsg.empty()) {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200345 leaf_ leaf = boost::get<leaf_>(parserContext.m_curPath.m_nodes.back().m_suffix);
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200346 schemaPath_ location = pathWithoutLastNode(parserContext.m_curPath);
347 if (location.m_nodes.empty()) {
Václav Kubernát5c75b252018-10-10 18:33:47 +0200348 parserContext.m_curModule = parserContext.m_curPath.m_nodes.back().m_prefix->m_name;
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200349 }
Václav Kubernát744f57f2018-06-29 22:46:26 +0200350 parserContext.m_errorMsg = "Expected " + leafDataTypeToString(schema.leafType(location, {parserContext.m_curModule, leaf.m_name})) + " here:";
Václav Kubernát0b0272f2018-06-13 14:13:08 +0200351 return x3::error_handler_result::fail;
352 }
353 return x3::error_handler_result::rethrow;
354 }
Václav Kubernátebca2552018-06-08 19:06:02 +0200355};
356
357struct leaf_data_base_class {
358 yang::LeafDataTypes m_type;
359
360 leaf_data_base_class(yang::LeafDataTypes type)
361 : m_type(type)
362 {
363 }
364
365 template <typename T, typename Iterator, typename Context>
366 void on_success(Iterator const&, Iterator const&, T&, Context const& context)
367 {
368 auto& parserContext = x3::get<parser_context_tag>(context);
369 auto& schema = parserContext.m_schema;
Václav Kubernát744f57f2018-06-29 22:46:26 +0200370 boost::optional<std::string> module;
371 if (parserContext.m_curPath.m_nodes.back().m_prefix)
372 module = parserContext.m_curPath.m_nodes.back().m_prefix.value().m_name;
Václav Kubernátebca2552018-06-08 19:06:02 +0200373
Václav Kubernát744f57f2018-06-29 22:46:26 +0200374 leaf_ leaf = boost::get<leaf_>(parserContext.m_curPath.m_nodes.back().m_suffix);
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200375 schemaPath_ location = pathWithoutLastNode(parserContext.m_curPath);
Václav Kubernátebca2552018-06-08 19:06:02 +0200376
Václav Kubernát744f57f2018-06-29 22:46:26 +0200377 if (schema.leafType(location, {module, leaf.m_name}) != m_type) {
Václav Kubernátebca2552018-06-08 19:06:02 +0200378 _pass(context) = false;
379 }
380 }
381};
382
383struct leaf_data_enum_class : leaf_data_base_class {
384 leaf_data_enum_class()
385 : leaf_data_base_class(yang::LeafDataTypes::Enum)
386 {
387 }
388
389 template <typename T, typename Iterator, typename Context>
390 void on_success(Iterator const& start, Iterator const& end, T& ast, Context const& context)
391 {
392 leaf_data_base_class::on_success(start, end, ast, context);
393 auto& parserContext = x3::get<parser_context_tag>(context);
394 auto& schema = parserContext.m_schema;
Václav Kubernát744f57f2018-06-29 22:46:26 +0200395 boost::optional<std::string> module;
396 if (parserContext.m_curPath.m_nodes.back().m_prefix)
397 module = parserContext.m_curPath.m_nodes.back().m_prefix.value().m_name;
Václav Kubernátebca2552018-06-08 19:06:02 +0200398
Václav Kubernát744f57f2018-06-29 22:46:26 +0200399 leaf_ leaf = boost::get<leaf_>(parserContext.m_curPath.m_nodes.back().m_suffix);
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200400 schemaPath_ location = pathWithoutLastNode(parserContext.m_curPath);
Václav Kubernátebca2552018-06-08 19:06:02 +0200401
Václav Kubernát744f57f2018-06-29 22:46:26 +0200402 if (!schema.leafEnumHasValue(location, {module, leaf.m_name}, ast.m_value)) {
Václav Kubernátebca2552018-06-08 19:06:02 +0200403 _pass(context) = false;
404 }
405 }
406};
407
408struct leaf_data_decimal_class : leaf_data_base_class {
409 leaf_data_decimal_class()
410 : leaf_data_base_class(yang::LeafDataTypes::Decimal)
411 {
412 }
413};
414
415struct leaf_data_bool_class : leaf_data_base_class {
416 leaf_data_bool_class()
417 : leaf_data_base_class(yang::LeafDataTypes::Bool)
418 {
419 }
420};
421
422struct leaf_data_int_class : leaf_data_base_class {
423 leaf_data_int_class()
424 : leaf_data_base_class(yang::LeafDataTypes::Int)
425 {
426 }
427};
428
429struct leaf_data_uint_class : leaf_data_base_class {
430 leaf_data_uint_class()
431 : leaf_data_base_class(yang::LeafDataTypes::Uint)
432 {
433 }
434};
435
436struct leaf_data_string_class : leaf_data_base_class {
437 leaf_data_string_class()
438 : leaf_data_base_class(yang::LeafDataTypes::String)
439 {
440 }
441};
442
Václav Kubernát07204242018-06-04 18:12:09 +0200443struct set_class {
Václav Kubernát07204242018-06-04 18:12:09 +0200444 template <typename Iterator, typename Exception, typename Context>
445 x3::error_handler_result on_error(Iterator&, Iterator const&, Exception const& x, Context const& context)
446 {
447 auto& parserContext = x3::get<parser_context_tag>(context);
Václav Kubernát41378452018-06-06 16:29:40 +0200448 if (parserContext.m_errorMsg.empty())
449 parserContext.m_errorMsg = "Expected " + x.which() + " here:";
450 return x3::error_handler_result::rethrow;
Václav Kubernát07204242018-06-04 18:12:09 +0200451 }
452};
453
Václav Kubernát812ee282018-08-30 17:10:03 +0200454struct commit_class;
455
Václav Kubernátb6ff0b62018-08-30 16:14:53 +0200456struct get_class;
457
Václav Kubernátb61336d2018-05-28 17:35:03 +0200458struct command_class {
459 template <typename Iterator, typename Exception, typename Context>
460 x3::error_handler_result on_error(Iterator&, Iterator const&, Exception const& x, Context const& context)
461 {
462 auto& parserContext = x3::get<parser_context_tag>(context);
463 auto& error_handler = x3::get<x3::error_handler_tag>(context).get();
Václav Kubernát41378452018-06-06 16:29:40 +0200464 if (parserContext.m_errorMsg.empty()) {
465 parserContext.m_errorMsg = "Unknown command.";
466 }
467 error_handler(x.where(), parserContext.m_errorMsg);
Václav Kubernátb61336d2018-05-28 17:35:03 +0200468 return x3::error_handler_result::fail;
469 }
470};
Václav Kubernát5c75b252018-10-10 18:33:47 +0200471
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100472struct initializePath_class {
Václav Kubernát5c75b252018-10-10 18:33:47 +0200473 template <typename T, typename Iterator, typename Context>
474 void on_success(Iterator const&, Iterator const&, T&, Context const& context)
475 {
476 auto& parserContext = x3::get<parser_context_tag>(context);
477 parserContext.m_curPath = parserContext.m_curPathOrig;
478 parserContext.m_tmpListKeys.clear();
479 parserContext.m_tmpListName.clear();
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100480 parserContext.m_suggestions.clear();
Václav Kubernát5c75b252018-10-10 18:33:47 +0200481 if (!parserContext.m_curPath.m_nodes.empty() && parserContext.m_curPath.m_nodes.at(0).m_prefix)
482 parserContext.m_topLevelModulePresent = true;
483 else
484 parserContext.m_topLevelModulePresent = false;
485 }
486};
Václav Kubernátd6fd2492018-11-19 15:11:16 +0100487
488struct trailingSlash_class;
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100489
490struct createPathSuggestions_class {
491 template <typename T, typename Iterator, typename Context>
492 void on_success(Iterator const& begin, Iterator const&, T&, Context const& context)
493 {
494 auto& parserContext = x3::get<parser_context_tag>(context);
495 const auto& schema = parserContext.m_schema;
496
497 parserContext.m_completionIterator = begin;
498 parserContext.m_suggestions = schema.childNodes(parserContext.m_curPath, Recursion::NonRecursive);
499 }
500};