Merge Schema::childNodes and Schema::moduleNodes
Change-Id: I30c7120fdba6c0089108599e5ab48d8dcd47f277
diff --git a/src/ast_handlers.hpp b/src/ast_handlers.hpp
index 714657e..5f7b922 100644
--- a/src/ast_handlers.hpp
+++ b/src/ast_handlers.hpp
@@ -458,7 +458,7 @@
const auto& schema = parserContext.m_schema;
parserContext.m_completionIterator = begin;
- auto suggestions = schema.childNodes(parserContext.currentSchemaPath(), Recursion::NonRecursive);
+ auto suggestions = schema.availableNodes(parserContext.currentSchemaPath(), Recursion::NonRecursive);
std::set<Completion> suffixesAdded;
std::transform(suggestions.begin(), suggestions.end(),
std::inserter(suffixesAdded, suffixesAdded.end()),
diff --git a/src/parser.cpp b/src/parser.cpp
index 794cc25..245de1d 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -9,6 +9,7 @@
#include "grammars.hpp"
#include "parser.hpp"
#include "parser_context.hpp"
+#include "utils.hpp"
TooManyArgumentsException::~TooManyArgumentsException() = default;
@@ -100,38 +101,20 @@
return pathToDataString(m_curDir, Prefixes::WhenNeeded);
}
-struct getSchemaPathVisitor : boost::static_visitor<schemaPath_> {
- schemaPath_ operator()(const dataPath_& path) const
- {
- return dataPathToSchemaPath(path);
- }
-
- schemaPath_ operator()(const schemaPath_& path) const
- {
- return path;
- }
-
- [[noreturn]] schemaPath_ operator()([[maybe_unused]] const module_& path) const
- {
- throw std::logic_error("getSchemaPathVisitor: Tried getting a schema path from a module");
- }
-};
-
-
std::set<std::string> Parser::availableNodes(const boost::optional<boost::variant<dataPath_, schemaPath_, module_>>& path, const Recursion& option) const
{
auto pathArg = dataPathToSchemaPath(m_curDir);
if (path) {
if (path->type() == typeid(module_)) {
- return m_schema->moduleNodes(boost::get<module_>(*path), option);
+ return m_schema->availableNodes(*path, option);
}
- auto schemaPath = boost::apply_visitor(getSchemaPathVisitor(), *path);
+ auto schemaPath = anyPathToSchemaPath(*path);
if (schemaPath.m_scope == Scope::Absolute) {
pathArg = schemaPath;
} else {
pathArg.m_nodes.insert(pathArg.m_nodes.end(), schemaPath.m_nodes.begin(), schemaPath.m_nodes.end());
}
}
- return m_schema->childNodes(pathArg, option);
+ return m_schema->availableNodes(pathArg, option);
}
diff --git a/src/schema.hpp b/src/schema.hpp
index 7ce24fb..4dd9a2a 100644
--- a/src/schema.hpp
+++ b/src/schema.hpp
@@ -70,6 +70,5 @@
virtual std::optional<std::string> description(const std::string& location) const = 0;
virtual yang::Status status(const std::string& location) const = 0;
- virtual std::set<std::string> childNodes(const schemaPath_& path, const Recursion recursion) const = 0;
- virtual std::set<std::string> moduleNodes(const module_& module, const Recursion recursion) const = 0;
+ virtual std::set<std::string> availableNodes(const boost::variant<dataPath_, schemaPath_, module_>& path, const Recursion recursion) const = 0;
};
diff --git a/src/static_schema.cpp b/src/static_schema.cpp
index c86b232..2f1dcb2 100644
--- a/src/static_schema.cpp
+++ b/src/static_schema.cpp
@@ -135,12 +135,28 @@
return boost::get<yang::leaf>(children(locationString).at(node)).m_type;
}
-// We do not test StaticSchema, so we don't need to implement recursive childNodes
-// for this class.
-std::set<std::string> StaticSchema::childNodes(const schemaPath_& path, const Recursion) const
+std::set<std::string> StaticSchema::availableNodes(const boost::variant<dataPath_, schemaPath_, module_>& path, const Recursion recursion) const
{
- std::string locationString = pathToSchemaString(path, Prefixes::Always);
+ if (recursion == Recursion::Recursive) {
+ throw std::logic_error("Recursive StaticSchema::availableNodes is not implemented. It shouldn't be used in tests.");
+ }
+
std::set<std::string> res;
+ if (path.type() == typeid(module_)) {
+ auto topLevelNodes = m_nodes.at("");
+ auto modulePlusColon = boost::get<module_>(path).m_name + ":";
+ for (const auto& it : topLevelNodes) {
+ if (boost::algorithm::starts_with(it.first, modulePlusColon)) {
+ res.insert(it.first);
+ }
+ }
+ return res;
+ }
+
+ std::string locationString =
+ path.type() == typeid(schemaPath_) ?
+ pathToSchemaString(boost::get<schemaPath_>(path), Prefixes::Always) :
+ pathToSchemaString(boost::get<dataPath_>(path), Prefixes::Always);
auto childrenRef = children(locationString);
@@ -148,21 +164,6 @@
return res;
}
-// We do not test StaticSchema, so we don't need to implement recursive moduleNodes
-// for this class.
-std::set<std::string> StaticSchema::moduleNodes(const module_& module, const Recursion) const
-{
- std::set<std::string> res;
- auto topLevelNodes = m_nodes.at("");
- auto modulePlusColon = module.m_name + ":";
- for (const auto& it : topLevelNodes) {
- if (boost::algorithm::starts_with(it.first, modulePlusColon)) {
- res.insert(it.first);
- }
- }
- return res;
-}
-
yang::NodeTypes StaticSchema::nodeType(const schemaPath_& location, const ModuleNodePair& node) const
{
std::string locationString = pathToSchemaString(location, Prefixes::Always);
diff --git a/src/static_schema.hpp b/src/static_schema.hpp
index 947cc43..43f7b8d 100644
--- a/src/static_schema.hpp
+++ b/src/static_schema.hpp
@@ -57,8 +57,7 @@
yang::TypeInfo leafType(const std::string& path) const override;
std::optional<std::string> leafTypeName(const std::string& path) const override;
std::string leafrefPath(const std::string& leafrefPath) const override;
- std::set<std::string> childNodes(const schemaPath_& path, const Recursion) const override;
- std::set<std::string> moduleNodes(const module_& module, const Recursion recursion) const override;
+ std::set<std::string> availableNodes(const boost::variant<dataPath_, schemaPath_, module_>& path, const Recursion recursion) const override;
std::optional<std::string> description(const std::string& path) const override;
yang::Status status(const std::string& location) const override;
diff --git a/src/utils.cpp b/src/utils.cpp
index 9496db3..1ed25c7 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -188,3 +188,25 @@
{
return boost::apply_visitor(leafDataToStringVisitor(), value);
}
+
+struct getSchemaPathVisitor : boost::static_visitor<schemaPath_> {
+ schemaPath_ operator()(const dataPath_& path) const
+ {
+ return dataPathToSchemaPath(path);
+ }
+
+ schemaPath_ operator()(const schemaPath_& path) const
+ {
+ return path;
+ }
+
+ [[noreturn]] schemaPath_ operator()([[maybe_unused]] const module_& path) const
+ {
+ throw std::logic_error("getSchemaPathVisitor: Tried getting a schema path from a module");
+ }
+};
+
+schemaPath_ anyPathToSchemaPath(const boost::variant<dataPath_, schemaPath_, module_>& path)
+{
+ return boost::apply_visitor(getSchemaPathVisitor(), path);
+}
diff --git a/src/utils.hpp b/src/utils.hpp
index ef24e60..7e62ae5 100644
--- a/src/utils.hpp
+++ b/src/utils.hpp
@@ -23,3 +23,4 @@
std::string fullNodeName(const schemaPath_& location, const ModuleNodePair& pair);
std::string fullNodeName(const dataPath_& location, const ModuleNodePair& pair);
std::string leafDataToString(const leaf_data_ value);
+schemaPath_ anyPathToSchemaPath(const boost::variant<dataPath_, schemaPath_, module_>& path);
diff --git a/src/yang_schema.cpp b/src/yang_schema.cpp
index b134440..80ec7f3 100644
--- a/src/yang_schema.cpp
+++ b/src/yang_schema.cpp
@@ -320,18 +320,25 @@
return res;
}
-std::set<std::string> YangSchema::childNodes(const schemaPath_& path, const Recursion recursion) const
+std::set<std::string> YangSchema::availableNodes(const boost::variant<dataPath_, schemaPath_, module_>& path, const Recursion recursion) const
{
using namespace std::string_view_literals;
std::set<std::string> res;
std::vector<libyang::S_Schema_Node> nodes;
+ std::string topLevelModule;
- if (path.m_nodes.empty()) {
- nodes = m_context->data_instantiables(0);
+ if (path.type() == typeid(module_)) {
+ nodes = m_context->get_module(boost::get<module_>(path).m_name.c_str())->data_instantiables(0);
} else {
- const auto pathString = pathToSchemaString(path, Prefixes::Always);
- const auto node = getSchemaNode(pathString);
- nodes = node->child_instantiables(0);
+ auto schemaPath = anyPathToSchemaPath(path);
+ if (schemaPath.m_nodes.empty()) {
+ nodes = m_context->data_instantiables(0);
+ } else {
+ const auto pathString = pathToSchemaString(schemaPath, Prefixes::Always);
+ const auto node = getSchemaNode(pathString);
+ nodes = node->child_instantiables(0);
+ topLevelModule = schemaPath.m_nodes.begin()->m_prefix->m_name;
+ }
}
for (const auto& node : nodes) {
@@ -348,7 +355,7 @@
}
} else {
std::string toInsert;
- if (path.m_nodes.empty() || path.m_nodes.front().m_prefix.get().m_name != node->module()->name()) {
+ if (topLevelModule.empty() || topLevelModule != node->module()->name()) {
toInsert += node->module()->name();
toInsert += ":";
}
@@ -360,26 +367,6 @@
return res;
}
-std::set<std::string> YangSchema::moduleNodes(const module_& module, const Recursion recursion) const
-{
- std::set<std::string> res;
- const auto yangModule = m_context->get_module(module.m_name.c_str());
-
- std::vector<libyang::S_Schema_Node> nodes;
-
- for (const auto& node : yangModule->data_instantiables(0)) {
- if (recursion == Recursion::Recursive) {
- for (const auto& it : node->tree_dfs()) {
- res.insert(it->path(LYS_PATH_FIRST_PREFIX));
- }
- } else {
- res.insert(module.m_name + ":" + node->name());
- }
- }
-
- return res;
-}
-
void YangSchema::loadModule(const std::string& moduleName)
{
m_context->load_module(moduleName.c_str());
diff --git a/src/yang_schema.hpp b/src/yang_schema.hpp
index fb0405b..9395ba2 100644
--- a/src/yang_schema.hpp
+++ b/src/yang_schema.hpp
@@ -43,8 +43,7 @@
yang::TypeInfo leafType(const std::string& path) const override;
std::optional<std::string> leafTypeName(const std::string& path) const override;
std::string leafrefPath(const std::string& leafrefPath) const override;
- std::set<std::string> childNodes(const schemaPath_& path, const Recursion recursion) const override;
- std::set<std::string> moduleNodes(const module_& module, const Recursion recursion) const override;
+ std::set<std::string> availableNodes(const boost::variant<dataPath_, schemaPath_, module_>& path, const Recursion recursion) const override;
std::optional<std::string> description(const std::string& path) const override;
yang::Status status(const std::string& location) const override;