Rework yang::LeafDataType

Before this patch, Schema::leafType was used like this: you called the
method, and it would give you an enum value from which you could tell
the type. In case the type was, for example, yang::LeafDataTypes::Enum,
you would call enumValues to get the valid values from the enum.
However, this approach came up as a problem when implementing the union
yang type. Example: if the union consisted of two different enums, there
was no way to differentiate those two enums (so enumValues wouldn't know
which one to return). The new approach encodes everything inside the
return value of Schema::leafType, so no futher method calls are needed.
This also means, that methods like Schema::leafEnumIsValid and others
are unneeded, since you get all the info from Schema::leafType.

Also, I got rid of all the on_success handlers, and moved the code to
inside to impl_LeafData. This means that enum/identityref validity is
checked inside there. If I wanted to keep the on_success handlers I
would have create another member in ParserContext (which would contain
the values), but it doesn't give any advantage, except that it
automatically rolls back the iterator on fail (I have to do that myself
now, but I don't think it's a huge deal).
createSetSuggestions::on_success was also moved to impl_LeafData.

Change-Id: Ie9a30174094b73f2c25af8cfc88d0aa5e9e882b3
diff --git a/src/static_schema.cpp b/src/static_schema.cpp
index 87d190a..4964e8e 100644
--- a/src/static_schema.cpp
+++ b/src/static_schema.cpp
@@ -71,40 +71,22 @@
     m_nodes.emplace(key, std::unordered_map<std::string, NodeType>());
 }
 
-void StaticSchema::addLeaf(const std::string& location, const std::string& name, const yang::LeafDataTypes& type)
+std::set<identityRef_> StaticSchema::validIdentities(std::string_view module, std::string_view value)
 {
-    m_nodes.at(location).emplace(name, yang::leaf{type, {}, {}, {}});
-    std::string key = joinPaths(location, name);
-    m_nodes.emplace(key, std::unordered_map<std::string, NodeType>());
+    std::set<ModuleValuePair> identities;
+    getIdentSet(ModuleNodePair{boost::optional<std::string>{module}, value}, identities);
+    std::set<identityRef_> res;
+
+    std::transform(identities.begin(), identities.end(), std::inserter(res, res.end()), [](const auto& identity) {
+        return identityRef_{*identity.first, identity.second};
+    });
+
+    return res;
 }
 
-void StaticSchema::addLeafEnum(const std::string& location, const std::string& name, std::set<std::string> enumValues)
+void StaticSchema::addLeaf(const std::string& location, const std::string& name, const yang::LeafDataType& type)
 {
-    yang::leaf toAdd;
-    toAdd.m_type = yang::LeafDataTypes::Enum;
-    toAdd.m_enumValues = enumValues;
-    m_nodes.at(location).emplace(name, toAdd);
-    std::string key = joinPaths(location, name);
-    m_nodes.emplace(key, std::unordered_map<std::string, NodeType>());
-}
-
-void StaticSchema::addLeafIdentityRef(const std::string& location, const std::string& name, const ModuleValuePair& base)
-{
-    assert(base.first); // base identity cannot have an empty module
-    yang::leaf toAdd;
-    toAdd.m_type = yang::LeafDataTypes::IdentityRef;
-    toAdd.m_identBase = base;
-    m_nodes.at(location).emplace(name, toAdd);
-    std::string key = joinPaths(location, name);
-    m_nodes.emplace(key, std::unordered_map<std::string, NodeType>());
-}
-
-void StaticSchema::addLeafRef(const std::string& location, const std::string& name, const std::string& source)
-{
-    yang::leaf toAdd;
-    toAdd.m_type = yang::LeafDataTypes::LeafRef;
-    toAdd.m_leafRefSource = source;
-    m_nodes.at(location).emplace(name, toAdd);
+    m_nodes.at(location).emplace(name, yang::leaf{type});
     std::string key = joinPaths(location, name);
     m_nodes.emplace(key, std::unordered_map<std::string, NodeType>());
 }
@@ -122,12 +104,6 @@
     m_identities.emplace(name, std::set<ModuleValuePair>());
 }
 
-bool StaticSchema::leafEnumHasValue(const schemaPath_& location, const ModuleNodePair& node, const std::string& value) const
-{
-    auto enums = enumValues(location, node);
-    return enums.find(value) != enums.end();
-}
-
 void StaticSchema::getIdentSet(const ModuleValuePair& ident, std::set<ModuleValuePair>& res) const
 {
     res.insert(ident);
@@ -137,41 +113,6 @@
     }
 }
 
-const std::set<std::string> StaticSchema::validIdentities(const schemaPath_& location, const ModuleNodePair& node, const Prefixes prefixes) const
-{
-    std::string locationString = pathToSchemaString(location, Prefixes::Always);
-    assert(isLeaf(location, node));
-
-    const auto& child = children(locationString).at(fullNodeName(location, node));
-    const auto& leaf = boost::get<yang::leaf>(child);
-
-    std::set<ModuleValuePair> identSet;
-    getIdentSet(leaf.m_identBase, identSet);
-
-    std::set<std::string> res;
-    std::transform(identSet.begin(), identSet.end(), std::inserter(res, res.end()), [location, node, prefixes](const auto& it) {
-        auto topLevelModule = location.m_nodes.empty() ? node.first.get() : location.m_nodes.front().m_prefix.get().m_name;
-        std::string stringIdent;
-        if (prefixes == Prefixes::Always || (it.first && it.first.value() != topLevelModule)) {
-            stringIdent += it.first ? it.first.value() : topLevelModule;
-            stringIdent += ":";
-        }
-        stringIdent += it.second;
-        return stringIdent;
-    });
-
-    return res;
-}
-
-bool StaticSchema::leafIdentityIsValid(const schemaPath_& location, const ModuleNodePair& node, const ModuleValuePair& value) const
-{
-    auto identities = validIdentities(location, node, Prefixes::Always);
-
-    auto topLevelModule = location.m_nodes.empty() ? node.first.get() : location.m_nodes.front().m_prefix.get().m_name;
-    auto identModule = value.first ? value.first.value() : topLevelModule;
-    return std::any_of(identities.begin(), identities.end(), [toFind = identModule + ":" + value.second](const auto& x) { return x == toFind; });
-}
-
 std::string lastNodeOfSchemaPath(const std::string& path)
 {
     std::string res = path;
@@ -189,34 +130,17 @@
     return res;
 }
 
-yang::LeafDataTypes StaticSchema::leafrefBaseType(const schemaPath_& location, const ModuleNodePair& node) const
-{
-    std::string locationString = pathToSchemaString(location, Prefixes::Always);
-    auto leaf{boost::get<yang::leaf>(children(locationString).at(fullNodeName(location, node)))};
-    auto locationOfSource = stripLastNodeFromPath(leaf.m_leafRefSource);
-    auto nameOfSource = lastNodeOfSchemaPath(leaf.m_leafRefSource);
-    return boost::get<yang::leaf>(children(locationOfSource).at(nameOfSource)).m_type;
-}
-
-yang::LeafDataTypes StaticSchema::leafType(const schemaPath_& location, const ModuleNodePair& node) const
+yang::LeafDataType StaticSchema::leafType(const schemaPath_& location, const ModuleNodePair& node) const
 {
     std::string locationString = pathToSchemaString(location, Prefixes::Always);
     return boost::get<yang::leaf>(children(locationString).at(fullNodeName(location, node))).m_type;
 }
 
-yang::LeafDataTypes StaticSchema::leafType([[maybe_unused]] const std::string& path) const
+yang::LeafDataType StaticSchema::leafType(const std::string& path) const
 {
-    throw std::runtime_error{"StaticSchema::leafType not implemented"};
-}
-
-const std::set<std::string> StaticSchema::enumValues(const schemaPath_& location, const ModuleNodePair& node) const
-{
-    std::string locationString = pathToSchemaString(location, Prefixes::Always);
-    assert(isLeaf(location, node));
-
-    const auto& child = children(locationString).at(fullNodeName(location, node));
-    const auto& leaf = boost::get<yang::leaf>(child);
-    return leaf.m_enumValues;
+    auto locationString = stripLastNodeFromPath(path);
+    auto node = lastNodeOfSchemaPath(path);
+    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
@@ -291,11 +215,6 @@
     throw std::runtime_error{"Internal error: StaticSchema::nodeType(std::string) not implemented. The tests should not have called this overload."};
 }
 
-yang::LeafDataTypes StaticSchema::leafrefBaseType([[maybe_unused]] const std::string& path) const
-{
-    throw std::runtime_error{"Internal error: StaticSchema::leafrefBaseType(std::string) not implemented. The tests should not have called this overload."};
-}
-
 std::string StaticSchema::leafrefPath([[maybe_unused]] const std::string& leafrefPath) const
 {
     throw std::runtime_error{"Internal error: StaticSchema::leafrefPath(std::string) not implemented. The tests should not have called this overload."};