blob: 0aa839c54355be36adc5dceb2fa42766fcc66fc0 [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>
Václav Kubernát509ce652019-05-29 19:46:44 +020010#include <sstream>
Václav Kubernát24df80e2018-06-06 15:18:03 +020011#include "ast_path.hpp"
12#include "utils.hpp"
13
14container_::container_(const std::string& name)
15 : m_name(name)
16{
17}
18
19bool container_::operator==(const container_& b) const
20{
21 return this->m_name == b.m_name;
22}
23
24leaf_::leaf_(const std::string& name)
25 : m_name(name)
26{
27}
28
Václav Kubernát744f57f2018-06-29 22:46:26 +020029bool module_::operator==(const module_& b) const
30{
31 return this->m_name == b.m_name;
32}
33
Václav Kubernát2eaceb82018-10-08 19:56:30 +020034dataNode_::dataNode_() = default;
Václav Kubernát744f57f2018-06-29 22:46:26 +020035
Václav Kubernát2eaceb82018-10-08 19:56:30 +020036dataNode_::dataNode_(decltype(m_suffix) node)
Václav Kubernát744f57f2018-06-29 22:46:26 +020037 : m_suffix(node)
38{
39}
40
Václav Kubernát2eaceb82018-10-08 19:56:30 +020041dataNode_::dataNode_(module_ module, decltype(m_suffix) node)
Václav Kubernát744f57f2018-06-29 22:46:26 +020042 : m_prefix(module)
43 , m_suffix(node)
44{
45}
46
Václav Kubernát5c75b252018-10-10 18:33:47 +020047schemaNode_::schemaNode_(decltype(m_suffix) node)
48 : m_suffix(node)
49{
50}
51
Václav Kubernát2eaceb82018-10-08 19:56:30 +020052schemaNode_::schemaNode_(module_ module, decltype(m_suffix) node)
53 : m_prefix(module)
54 , m_suffix(node)
55{
56}
Václav Kubernát744f57f2018-06-29 22:46:26 +020057
Václav Kubernát2eaceb82018-10-08 19:56:30 +020058schemaNode_::schemaNode_() = default;
59
60bool schemaNode_::operator==(const schemaNode_& b) const
61{
62 return this->m_suffix == b.m_suffix && this->m_prefix == b.m_prefix;
63}
64
65bool dataNode_::operator==(const dataNode_& b) const
Václav Kubernát744f57f2018-06-29 22:46:26 +020066{
67 return this->m_suffix == b.m_suffix && this->m_prefix == b.m_prefix;
68}
69
Václav Kubernát24df80e2018-06-06 15:18:03 +020070bool leaf_::operator==(const leaf_& b) const
71{
72 return this->m_name == b.m_name;
73}
74
Václav Kubernát7707cae2020-01-16 12:04:53 +010075listElement_::listElement_(const std::string& listName, const std::map<std::string, leaf_data_>& keys)
Václav Kubernát24df80e2018-06-06 15:18:03 +020076 : m_name(listName)
77 , m_keys(keys)
78{
79}
80
81bool listElement_::operator==(const listElement_& b) const
82{
83 return (this->m_name == b.m_name && this->m_keys == b.m_keys);
84}
85
Václav Kubernát2eaceb82018-10-08 19:56:30 +020086bool list_::operator==(const list_& b) const
87{
88 return (this->m_name == b.m_name);
89}
90
91list_::list_(const std::string& listName)
92 : m_name(listName)
93{
94}
95
96bool schemaPath_::operator==(const schemaPath_& b) const
97{
98 if (this->m_nodes.size() != b.m_nodes.size())
99 return false;
100 return this->m_nodes == b.m_nodes;
101}
102
103bool dataPath_::operator==(const dataPath_& b) const
Václav Kubernát24df80e2018-06-06 15:18:03 +0200104{
105 if (this->m_nodes.size() != b.m_nodes.size())
106 return false;
107 return this->m_nodes == b.m_nodes;
108}
109
110
Václav Kubernát744f57f2018-06-29 22:46:26 +0200111struct nodeToSchemaStringVisitor : public boost::static_visitor<std::string> {
Václav Kubernát24df80e2018-06-06 15:18:03 +0200112 std::string operator()(const nodeup_&) const
113 {
114 return "..";
115 }
116 template <class T>
117 std::string operator()(const T& node) const
118 {
119 return node.m_name;
120 }
121};
Jan Kundrát2a8f4332018-09-14 17:05:31 +0200122
123std::string escapeListKeyString(const std::string& what)
124{
125 // If we have both single and double quote, then we're screwed, but that "shouldn't happen"
126 // in <= YANG 1.1 due to limitations in XPath 1.0.
127 if (what.find('\'') != std::string::npos) {
128 return '\"' + what + '\"';
129 } else {
130 return '\'' + what + '\'';
131 }
132}
133
Václav Kubernát744f57f2018-06-29 22:46:26 +0200134struct nodeToDataStringVisitor : public boost::static_visitor<std::string> {
Václav Kubernát24df80e2018-06-06 15:18:03 +0200135 std::string operator()(const listElement_& node) const
136 {
137 std::ostringstream res;
138 res << node.m_name + "[";
139 std::transform(node.m_keys.begin(), node.m_keys.end(),
Václav Kubernát5395e712019-12-03 18:24:33 +0100140 std::experimental::make_ostream_joiner(res, "]["),
Václav Kubernát7707cae2020-01-16 12:04:53 +0100141 [] (const auto& it) { return it.first + "=" + escapeListKeyString(leafDataToString(it.second)); });
Václav Kubernát24df80e2018-06-06 15:18:03 +0200142 res << "]";
Václav Kubernátebca2552018-06-08 19:06:02 +0200143 return res.str();
Václav Kubernát24df80e2018-06-06 15:18:03 +0200144 }
145 std::string operator()(const nodeup_&) const
146 {
147 return "..";
148 }
149 template <class T>
150 std::string operator()(const T& node) const
151 {
152 return node.m_name;
153 }
154};
155
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200156std::string nodeToSchemaString(decltype(dataPath_::m_nodes)::value_type node)
Václav Kubernát744f57f2018-06-29 22:46:26 +0200157{
158 return boost::apply_visitor(nodeToSchemaStringVisitor(), node.m_suffix);
159}
160
Václav Kubernátefcac932020-01-10 15:26:32 +0100161std::string pathToDataString(const dataPath_& path, Prefixes prefixes)
Václav Kubernát24df80e2018-06-06 15:18:03 +0200162{
163 std::string res;
Václav Kubernát5395e712019-12-03 18:24:33 +0100164 if (path.m_scope == Scope::Absolute) {
165 res = "/";
166 }
Václav Kubernátefcac932020-01-10 15:26:32 +0100167
Václav Kubernátef085742020-04-21 09:28:44 +0200168 for (const auto& it : path.m_nodes) {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200169 if (it.m_prefix)
170 res = joinPaths(res, it.m_prefix.value().m_name + ":" + boost::apply_visitor(nodeToDataStringVisitor(), it.m_suffix));
171 else
Václav Kubernátefcac932020-01-10 15:26:32 +0100172 res = joinPaths(res, (prefixes == Prefixes::Always ? path.m_nodes.at(0).m_prefix.value().m_name + ":" : "") + boost::apply_visitor(nodeToDataStringVisitor(), it.m_suffix));
173 }
Václav Kubernát744f57f2018-06-29 22:46:26 +0200174
175 return res;
176}
177
Václav Kubernátefcac932020-01-10 15:26:32 +0100178std::string pathToSchemaString(const schemaPath_& path, Prefixes prefixes)
Václav Kubernát744f57f2018-06-29 22:46:26 +0200179{
180 std::string res;
Václav Kubernátefcac932020-01-10 15:26:32 +0100181 if (path.m_scope == Scope::Absolute) {
182 res = "/";
Václav Kubernát744f57f2018-06-29 22:46:26 +0200183 }
184
Václav Kubernátef085742020-04-21 09:28:44 +0200185 for (const auto& it : path.m_nodes) {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200186 if (it.m_prefix)
187 res = joinPaths(res, it.m_prefix.value().m_name + ":" + boost::apply_visitor(nodeToSchemaStringVisitor(), it.m_suffix));
188 else
Václav Kubernátefcac932020-01-10 15:26:32 +0100189 res = joinPaths(res, (prefixes == Prefixes::Always ? path.m_nodes.at(0).m_prefix.value().m_name + ":" : "") + boost::apply_visitor(nodeToSchemaStringVisitor(), it.m_suffix));
Václav Kubernát744f57f2018-06-29 22:46:26 +0200190 }
Václav Kubernát24df80e2018-06-06 15:18:03 +0200191 return res;
192}
193
Václav Kubernátefcac932020-01-10 15:26:32 +0100194std::string pathToSchemaString(const dataPath_& path, Prefixes prefixes)
Václav Kubernát24df80e2018-06-06 15:18:03 +0200195{
Václav Kubernátefcac932020-01-10 15:26:32 +0100196 return pathToSchemaString(dataPathToSchemaPath(path), prefixes);
Václav Kubernát5c75b252018-10-10 18:33:47 +0200197}
198
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200199struct dataSuffixToSchemaSuffix : boost::static_visitor<decltype(schemaNode_::m_suffix)> {
200 auto operator()(const listElement_& listElement) const
201 {
202 return list_{listElement.m_name};
203 }
204
205 template <typename T>
206 auto operator()(const T& suffix) const
207 {
208 return suffix;
209 }
210};
211
212schemaNode_ dataNodeToSchemaNode(const dataNode_& node)
213{
214 schemaNode_ res;
215 res.m_prefix = node.m_prefix;
216 res.m_suffix = boost::apply_visitor(dataSuffixToSchemaSuffix(), node.m_suffix);
217 return res;
218}
219
220schemaPath_ dataPathToSchemaPath(const dataPath_& path)
221{
Václav Kubernátbf083ec2019-02-19 13:58:09 +0100222 schemaPath_ res{path.m_scope, {}};
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200223
Václav Kubernátbf083ec2019-02-19 13:58:09 +0100224 std::transform(path.m_nodes.begin(), path.m_nodes.end(),
225 std::back_inserter(res.m_nodes),
226 [](const dataNode_& node) { return dataNodeToSchemaNode(node); });
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200227
Václav Kubernátbf083ec2019-02-19 13:58:09 +0100228 return res;
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200229}