blob: b913d0cc22878ce52db40dfebe842950f4ab5782 [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át5b8a8f32020-05-20 00:57:22 +020029bool leafListElement_::operator==(const leafListElement_& b) const
30{
31 return this->m_name == b.m_name && this->m_value == b.m_value;
32}
33
34leafList_::leafList_() = default;
35
36leafList_::leafList_(const std::string& name)
37 : m_name(name)
38{
39}
40
41bool leafList_::operator==(const leafList_& b) const
42{
43 return this->m_name == b.m_name;
44}
45
Václav Kubernát744f57f2018-06-29 22:46:26 +020046bool module_::operator==(const module_& b) const
47{
48 return this->m_name == b.m_name;
49}
50
Václav Kubernát2eaceb82018-10-08 19:56:30 +020051dataNode_::dataNode_() = default;
Václav Kubernát744f57f2018-06-29 22:46:26 +020052
Václav Kubernát2eaceb82018-10-08 19:56:30 +020053dataNode_::dataNode_(decltype(m_suffix) node)
Václav Kubernát744f57f2018-06-29 22:46:26 +020054 : m_suffix(node)
55{
56}
57
Václav Kubernát2eaceb82018-10-08 19:56:30 +020058dataNode_::dataNode_(module_ module, decltype(m_suffix) node)
Václav Kubernát744f57f2018-06-29 22:46:26 +020059 : m_prefix(module)
60 , m_suffix(node)
61{
62}
63
Václav Kubernát2db124c2020-05-28 21:58:36 +020064dataNode_::dataNode_(boost::optional<module_> module, decltype(m_suffix) node)
65 : m_prefix(module)
66 , m_suffix(node)
67{
68
69}
70
Václav Kubernát5c75b252018-10-10 18:33:47 +020071schemaNode_::schemaNode_(decltype(m_suffix) node)
72 : m_suffix(node)
73{
74}
75
Václav Kubernát2eaceb82018-10-08 19:56:30 +020076schemaNode_::schemaNode_(module_ module, decltype(m_suffix) node)
77 : m_prefix(module)
78 , m_suffix(node)
79{
80}
Václav Kubernát744f57f2018-06-29 22:46:26 +020081
Václav Kubernát2eaceb82018-10-08 19:56:30 +020082schemaNode_::schemaNode_() = default;
83
84bool schemaNode_::operator==(const schemaNode_& b) const
85{
86 return this->m_suffix == b.m_suffix && this->m_prefix == b.m_prefix;
87}
88
89bool dataNode_::operator==(const dataNode_& b) const
Václav Kubernát744f57f2018-06-29 22:46:26 +020090{
91 return this->m_suffix == b.m_suffix && this->m_prefix == b.m_prefix;
92}
93
Václav Kubernát24df80e2018-06-06 15:18:03 +020094bool leaf_::operator==(const leaf_& b) const
95{
96 return this->m_name == b.m_name;
97}
98
Václav Kubernátc15fe822020-06-04 11:28:39 +020099listElement_::listElement_(const std::string& listName, const ListInstance& keys)
Václav Kubernát24df80e2018-06-06 15:18:03 +0200100 : m_name(listName)
101 , m_keys(keys)
102{
103}
104
105bool listElement_::operator==(const listElement_& b) const
106{
107 return (this->m_name == b.m_name && this->m_keys == b.m_keys);
108}
109
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200110bool list_::operator==(const list_& b) const
111{
112 return (this->m_name == b.m_name);
113}
114
115list_::list_(const std::string& listName)
116 : m_name(listName)
117{
118}
119
120bool schemaPath_::operator==(const schemaPath_& b) const
121{
122 if (this->m_nodes.size() != b.m_nodes.size())
123 return false;
124 return this->m_nodes == b.m_nodes;
125}
126
127bool dataPath_::operator==(const dataPath_& b) const
Václav Kubernát24df80e2018-06-06 15:18:03 +0200128{
129 if (this->m_nodes.size() != b.m_nodes.size())
130 return false;
131 return this->m_nodes == b.m_nodes;
132}
133
Václav Kubernátb5ca1542020-05-27 01:03:54 +0200134struct nodeToSchemaStringVisitor {
Václav Kubernát24df80e2018-06-06 15:18:03 +0200135 std::string operator()(const nodeup_&) const
136 {
137 return "..";
138 }
139 template <class T>
140 std::string operator()(const T& node) const
141 {
142 return node.m_name;
143 }
144};
Jan Kundrát2a8f4332018-09-14 17:05:31 +0200145
146std::string escapeListKeyString(const std::string& what)
147{
148 // If we have both single and double quote, then we're screwed, but that "shouldn't happen"
149 // in <= YANG 1.1 due to limitations in XPath 1.0.
150 if (what.find('\'') != std::string::npos) {
151 return '\"' + what + '\"';
152 } else {
153 return '\'' + what + '\'';
154 }
155}
156
Václav Kubernátb5ca1542020-05-27 01:03:54 +0200157struct nodeToDataStringVisitor {
Václav Kubernát24df80e2018-06-06 15:18:03 +0200158 std::string operator()(const listElement_& node) const
159 {
160 std::ostringstream res;
161 res << node.m_name + "[";
162 std::transform(node.m_keys.begin(), node.m_keys.end(),
Václav Kubernát5395e712019-12-03 18:24:33 +0100163 std::experimental::make_ostream_joiner(res, "]["),
Václav Kubernát7707cae2020-01-16 12:04:53 +0100164 [] (const auto& it) { return it.first + "=" + escapeListKeyString(leafDataToString(it.second)); });
Václav Kubernát24df80e2018-06-06 15:18:03 +0200165 res << "]";
Václav Kubernátebca2552018-06-08 19:06:02 +0200166 return res.str();
Václav Kubernát24df80e2018-06-06 15:18:03 +0200167 }
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200168 std::string operator()(const leafListElement_& node) const
169 {
170 return node.m_name + "[.=" + escapeListKeyString(leafDataToString(node.m_value)) + "]";
171 }
Václav Kubernát24df80e2018-06-06 15:18:03 +0200172 std::string operator()(const nodeup_&) const
173 {
174 return "..";
175 }
176 template <class T>
177 std::string operator()(const T& node) const
178 {
179 return node.m_name;
180 }
181};
182
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200183std::string nodeToSchemaString(decltype(dataPath_::m_nodes)::value_type node)
Václav Kubernát744f57f2018-06-29 22:46:26 +0200184{
Václav Kubernátb5ca1542020-05-27 01:03:54 +0200185 return std::visit(nodeToSchemaStringVisitor(), node.m_suffix);
Václav Kubernát744f57f2018-06-29 22:46:26 +0200186}
187
Václav Kubernátefcac932020-01-10 15:26:32 +0100188std::string pathToDataString(const dataPath_& path, Prefixes prefixes)
Václav Kubernát24df80e2018-06-06 15:18:03 +0200189{
190 std::string res;
Václav Kubernát5395e712019-12-03 18:24:33 +0100191 if (path.m_scope == Scope::Absolute) {
192 res = "/";
193 }
Václav Kubernátefcac932020-01-10 15:26:32 +0100194
Václav Kubernátef085742020-04-21 09:28:44 +0200195 for (const auto& it : path.m_nodes) {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200196 if (it.m_prefix)
Václav Kubernátb5ca1542020-05-27 01:03:54 +0200197 res = joinPaths(res, it.m_prefix.value().m_name + ":" + std::visit(nodeToDataStringVisitor(), it.m_suffix));
Václav Kubernát744f57f2018-06-29 22:46:26 +0200198 else
Václav Kubernátb5ca1542020-05-27 01:03:54 +0200199 res = joinPaths(res, (prefixes == Prefixes::Always ? path.m_nodes.at(0).m_prefix.value().m_name + ":" : "") + std::visit(nodeToDataStringVisitor(), it.m_suffix));
Václav Kubernátefcac932020-01-10 15:26:32 +0100200 }
Václav Kubernát744f57f2018-06-29 22:46:26 +0200201
202 return res;
203}
204
Václav Kubernátefcac932020-01-10 15:26:32 +0100205std::string pathToSchemaString(const schemaPath_& path, Prefixes prefixes)
Václav Kubernát744f57f2018-06-29 22:46:26 +0200206{
207 std::string res;
Václav Kubernátefcac932020-01-10 15:26:32 +0100208 if (path.m_scope == Scope::Absolute) {
209 res = "/";
Václav Kubernát744f57f2018-06-29 22:46:26 +0200210 }
211
Václav Kubernátef085742020-04-21 09:28:44 +0200212 for (const auto& it : path.m_nodes) {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200213 if (it.m_prefix)
Václav Kubernátb5ca1542020-05-27 01:03:54 +0200214 res = joinPaths(res, it.m_prefix.value().m_name + ":" + std::visit(nodeToSchemaStringVisitor(), it.m_suffix));
Václav Kubernát744f57f2018-06-29 22:46:26 +0200215 else
Václav Kubernátb5ca1542020-05-27 01:03:54 +0200216 res = joinPaths(res, (prefixes == Prefixes::Always ? path.m_nodes.at(0).m_prefix.value().m_name + ":" : "") + std::visit(nodeToSchemaStringVisitor(), it.m_suffix));
Václav Kubernát744f57f2018-06-29 22:46:26 +0200217 }
Václav Kubernát24df80e2018-06-06 15:18:03 +0200218 return res;
219}
220
Václav Kubernátefcac932020-01-10 15:26:32 +0100221std::string pathToSchemaString(const dataPath_& path, Prefixes prefixes)
Václav Kubernát24df80e2018-06-06 15:18:03 +0200222{
Václav Kubernátefcac932020-01-10 15:26:32 +0100223 return pathToSchemaString(dataPathToSchemaPath(path), prefixes);
Václav Kubernát5c75b252018-10-10 18:33:47 +0200224}
225
Václav Kubernátb5ca1542020-05-27 01:03:54 +0200226struct dataSuffixToSchemaSuffix {
227 using ReturnType = decltype(schemaNode_::m_suffix);
228 ReturnType operator()(const listElement_& listElement) const
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200229 {
230 return list_{listElement.m_name};
231 }
232
Václav Kubernátb5ca1542020-05-27 01:03:54 +0200233 ReturnType operator()(const leafListElement_& leafListElement) const
Václav Kubernát5b8a8f32020-05-20 00:57:22 +0200234 {
235 return leafList_{leafListElement.m_name};
236 }
237
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200238 template <typename T>
Václav Kubernátb5ca1542020-05-27 01:03:54 +0200239 ReturnType operator()(const T& suffix) const
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200240 {
241 return suffix;
242 }
243};
244
245schemaNode_ dataNodeToSchemaNode(const dataNode_& node)
246{
247 schemaNode_ res;
248 res.m_prefix = node.m_prefix;
Václav Kubernátb5ca1542020-05-27 01:03:54 +0200249 res.m_suffix = std::visit(dataSuffixToSchemaSuffix(), node.m_suffix);
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200250 return res;
251}
252
253schemaPath_ dataPathToSchemaPath(const dataPath_& path)
254{
Václav Kubernátbf083ec2019-02-19 13:58:09 +0100255 schemaPath_ res{path.m_scope, {}};
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200256
Václav Kubernátbf083ec2019-02-19 13:58:09 +0100257 std::transform(path.m_nodes.begin(), path.m_nodes.end(),
258 std::back_inserter(res.m_nodes),
259 [](const dataNode_& node) { return dataNodeToSchemaNode(node); });
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200260
Václav Kubernátbf083ec2019-02-19 13:58:09 +0100261 return res;
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200262}