blob: 1f01a72dc299c2dd1efa0b10c0ef1347506ebeac [file] [log] [blame]
Václav Kubernát24df80e2018-06-06 15:18:03 +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#include <experimental/iterator>
10#include "ast_path.hpp"
11#include "utils.hpp"
12
13container_::container_(const std::string& name)
14 : m_name(name)
15{
16}
17
18bool container_::operator==(const container_& b) const
19{
20 return this->m_name == b.m_name;
21}
22
23leaf_::leaf_(const std::string& name)
24 : m_name(name)
25{
26}
27
Václav Kubernát744f57f2018-06-29 22:46:26 +020028bool module_::operator==(const module_& b) const
29{
30 return this->m_name == b.m_name;
31}
32
Václav Kubernát2eaceb82018-10-08 19:56:30 +020033dataNode_::dataNode_() = default;
Václav Kubernát744f57f2018-06-29 22:46:26 +020034
Václav Kubernát2eaceb82018-10-08 19:56:30 +020035dataNode_::dataNode_(decltype(m_suffix) node)
Václav Kubernát744f57f2018-06-29 22:46:26 +020036 : m_suffix(node)
37{
38}
39
Václav Kubernát2eaceb82018-10-08 19:56:30 +020040dataNode_::dataNode_(module_ module, decltype(m_suffix) node)
Václav Kubernát744f57f2018-06-29 22:46:26 +020041 : m_prefix(module)
42 , m_suffix(node)
43{
44}
45
Václav Kubernát5c75b252018-10-10 18:33:47 +020046schemaNode_::schemaNode_(decltype(m_suffix) node)
47 : m_suffix(node)
48{
49}
50
Václav Kubernát2eaceb82018-10-08 19:56:30 +020051schemaNode_::schemaNode_(module_ module, decltype(m_suffix) node)
52 : m_prefix(module)
53 , m_suffix(node)
54{
55}
Václav Kubernát744f57f2018-06-29 22:46:26 +020056
Václav Kubernát2eaceb82018-10-08 19:56:30 +020057schemaNode_::schemaNode_() = default;
58
59bool schemaNode_::operator==(const schemaNode_& b) const
60{
61 return this->m_suffix == b.m_suffix && this->m_prefix == b.m_prefix;
62}
63
64bool dataNode_::operator==(const dataNode_& b) const
Václav Kubernát744f57f2018-06-29 22:46:26 +020065{
66 return this->m_suffix == b.m_suffix && this->m_prefix == b.m_prefix;
67}
68
Václav Kubernát24df80e2018-06-06 15:18:03 +020069bool leaf_::operator==(const leaf_& b) const
70{
71 return this->m_name == b.m_name;
72}
73
74listElement_::listElement_(const std::string& listName, const std::map<std::string, std::string>& keys)
75 : m_name(listName)
76 , m_keys(keys)
77{
78}
79
80bool listElement_::operator==(const listElement_& b) const
81{
82 return (this->m_name == b.m_name && this->m_keys == b.m_keys);
83}
84
Václav Kubernát2eaceb82018-10-08 19:56:30 +020085bool list_::operator==(const list_& b) const
86{
87 return (this->m_name == b.m_name);
88}
89
90list_::list_(const std::string& listName)
91 : m_name(listName)
92{
93}
94
95bool schemaPath_::operator==(const schemaPath_& b) const
96{
97 if (this->m_nodes.size() != b.m_nodes.size())
98 return false;
99 return this->m_nodes == b.m_nodes;
100}
101
102bool dataPath_::operator==(const dataPath_& b) const
Václav Kubernát24df80e2018-06-06 15:18:03 +0200103{
104 if (this->m_nodes.size() != b.m_nodes.size())
105 return false;
106 return this->m_nodes == b.m_nodes;
107}
108
109
Václav Kubernát744f57f2018-06-29 22:46:26 +0200110struct nodeToSchemaStringVisitor : public boost::static_visitor<std::string> {
Václav Kubernát24df80e2018-06-06 15:18:03 +0200111 std::string operator()(const nodeup_&) const
112 {
113 return "..";
114 }
115 template <class T>
116 std::string operator()(const T& node) const
117 {
118 return node.m_name;
119 }
120};
Jan Kundrát2a8f4332018-09-14 17:05:31 +0200121
122std::string escapeListKeyString(const std::string& what)
123{
124 // If we have both single and double quote, then we're screwed, but that "shouldn't happen"
125 // in <= YANG 1.1 due to limitations in XPath 1.0.
126 if (what.find('\'') != std::string::npos) {
127 return '\"' + what + '\"';
128 } else {
129 return '\'' + what + '\'';
130 }
131}
132
Václav Kubernát744f57f2018-06-29 22:46:26 +0200133struct nodeToDataStringVisitor : public boost::static_visitor<std::string> {
Václav Kubernát24df80e2018-06-06 15:18:03 +0200134 std::string operator()(const listElement_& node) const
135 {
136 std::ostringstream res;
137 res << node.m_name + "[";
138 std::transform(node.m_keys.begin(), node.m_keys.end(),
139 std::experimental::make_ostream_joiner(res, ' '),
Jan Kundrát2a8f4332018-09-14 17:05:31 +0200140 [] (const auto& it) { return it.first + "=" + escapeListKeyString(it.second); });
Václav Kubernát24df80e2018-06-06 15:18:03 +0200141 res << "]";
Václav Kubernátebca2552018-06-08 19:06:02 +0200142 return res.str();
Václav Kubernát24df80e2018-06-06 15:18:03 +0200143 }
144 std::string operator()(const nodeup_&) const
145 {
146 return "..";
147 }
148 template <class T>
149 std::string operator()(const T& node) const
150 {
151 return node.m_name;
152 }
153};
154
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200155std::string nodeToSchemaString(decltype(dataPath_::m_nodes)::value_type node)
Václav Kubernát744f57f2018-06-29 22:46:26 +0200156{
157 return boost::apply_visitor(nodeToSchemaStringVisitor(), node.m_suffix);
158}
159
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200160std::string pathToDataString(const dataPath_& path)
Václav Kubernát24df80e2018-06-06 15:18:03 +0200161{
162 std::string res;
163 for (const auto it : path.m_nodes)
Václav Kubernát744f57f2018-06-29 22:46:26 +0200164 if (it.m_prefix)
165 res = joinPaths(res, it.m_prefix.value().m_name + ":" + boost::apply_visitor(nodeToDataStringVisitor(), it.m_suffix));
166 else
167 res = joinPaths(res, boost::apply_visitor(nodeToDataStringVisitor(), it.m_suffix));
168
169 return res;
170}
171
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200172std::string pathToAbsoluteSchemaString(const dataPath_& path)
173{
174 return pathToAbsoluteSchemaString(dataPathToSchemaPath(path));
175}
176
177std::string pathToAbsoluteSchemaString(const schemaPath_& path)
Václav Kubernát744f57f2018-06-29 22:46:26 +0200178{
179 std::string res;
180 if (path.m_nodes.empty()) {
181 return "";
182 }
183
184 auto topLevelModule = path.m_nodes.at(0).m_prefix.value();
185 for (const auto it : path.m_nodes) {
186 if (it.m_prefix)
187 res = joinPaths(res, it.m_prefix.value().m_name + ":" + boost::apply_visitor(nodeToSchemaStringVisitor(), it.m_suffix));
188 else
189 res = joinPaths(res, topLevelModule.m_name + ":" + boost::apply_visitor(nodeToSchemaStringVisitor(), it.m_suffix));
190 }
Václav Kubernát24df80e2018-06-06 15:18:03 +0200191 return res;
192}
193
Václav Kubernát5c75b252018-10-10 18:33:47 +0200194std::string pathToSchemaString(const schemaPath_& path)
Václav Kubernát24df80e2018-06-06 15:18:03 +0200195{
196 std::string res;
Václav Kubernát744f57f2018-06-29 22:46:26 +0200197 for (const auto it : path.m_nodes) {
198 if (it.m_prefix)
199 res = joinPaths(res, it.m_prefix.value().m_name + ":" + boost::apply_visitor(nodeToSchemaStringVisitor(), it.m_suffix));
200 else
201 res = joinPaths(res, boost::apply_visitor(nodeToSchemaStringVisitor(), it.m_suffix));
202 }
Václav Kubernát24df80e2018-06-06 15:18:03 +0200203 return res;
204}
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200205
Václav Kubernát5c75b252018-10-10 18:33:47 +0200206std::string pathToSchemaString(const dataPath_& path)
207{
208 return pathToSchemaString(dataPathToSchemaPath(path));
209}
210
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200211struct dataSuffixToSchemaSuffix : boost::static_visitor<decltype(schemaNode_::m_suffix)> {
212 auto operator()(const listElement_& listElement) const
213 {
214 return list_{listElement.m_name};
215 }
216
217 template <typename T>
218 auto operator()(const T& suffix) const
219 {
220 return suffix;
221 }
222};
223
224schemaNode_ dataNodeToSchemaNode(const dataNode_& node)
225{
226 schemaNode_ res;
227 res.m_prefix = node.m_prefix;
228 res.m_suffix = boost::apply_visitor(dataSuffixToSchemaSuffix(), node.m_suffix);
229 return res;
230}
231
232schemaPath_ dataPathToSchemaPath(const dataPath_& path)
233{
234 schemaPath_ res{path.m_scope, {}};
235
236 std::transform(path.m_nodes.begin(), path.m_nodes.end(),
237 std::back_inserter(res.m_nodes),
238 [](const dataNode_& node) { return dataNodeToSchemaNode(node); });
239
240 return res;
241}