Make create/delete accept list instance paths

Change-Id: I5991e1377ebc0edcfc3f8dbc60066a580314a51a
diff --git a/src/ast_commands.hpp b/src/ast_commands.hpp
index 634a190..5015787 100644
--- a/src/ast_commands.hpp
+++ b/src/ast_commands.hpp
@@ -86,12 +86,13 @@
     static constexpr auto name = "create";
     static constexpr auto shortHelp = "create - Create a presence container.";
     static constexpr auto longHelp = R"(
-    create path_to_presence_container
+    create path
 
-    Creates a presence container specified by a path.
+    Creates a presence container or a list instance specified by path.
 
     Usage:
-        /> create /module:pContainer)";
+        /> create /module:pContainer
+        /> create /module:list[key=value][anotherKey=value])";
     bool operator==(const create_& b) const;
     dataPath_ m_path;
 };
@@ -100,12 +101,13 @@
     static constexpr auto name = "delete";
     static constexpr auto shortHelp = "delete - Delete a presence container.";
     static constexpr auto longHelp = R"(
-    delete path_to_presence_container
+    delete path
 
-    Delete a presence container specified by a path.
+    Deletes a presence container or a list instance specified by path.
 
     Usage:
-        /> delete /module:pContainer)";
+        /> delete /module:pContainer
+        /> delete /module:list[key=value][anotherKey=value])";
     bool operator==(const delete_& b) const;
     dataPath_ m_path;
 };
diff --git a/src/ast_handlers.hpp b/src/ast_handlers.hpp
index c937eee..d365641 100644
--- a/src/ast_handlers.hpp
+++ b/src/ast_handlers.hpp
@@ -312,6 +312,18 @@
     }
 };
 
+struct listInstancePath_class {
+    template <typename T, typename Iterator, typename Context>
+    void on_success(Iterator const&, Iterator const&, T& ast, Context const& context)
+    {
+        auto& parserContext = x3::get<parser_context_tag>(context);
+        if (ast.m_nodes.back().m_suffix.type() != typeid(listElement_)) {
+            parserContext.m_errorMsg = "This is not a list instance.";
+            _pass(context) = false;
+        }
+    }
+};
+
 struct create_class {
     template <typename Iterator, typename Exception, typename Context>
     x3::error_handler_result on_error(Iterator&, Iterator const&, Exception const&, Context const& context)
diff --git a/src/datastore_access.hpp b/src/datastore_access.hpp
index 7972523..2f75e51 100644
--- a/src/datastore_access.hpp
+++ b/src/datastore_access.hpp
@@ -24,6 +24,8 @@
     virtual void setLeaf(const std::string& path, leaf_data_ value) = 0;
     virtual void createPresenceContainer(const std::string& path) = 0;
     virtual void deletePresenceContainer(const std::string& path) = 0;
+    virtual void createListInstance(const std::string& path) = 0;
+    virtual void deleteListInstance(const std::string& path) = 0;
 
     virtual void commitChanges() = 0;
     virtual void discardChanges() = 0;
diff --git a/src/grammars.hpp b/src/grammars.hpp
index abdd9ce..a2e68fc 100644
--- a/src/grammars.hpp
+++ b/src/grammars.hpp
@@ -35,6 +35,7 @@
 x3::rule<dataPath_class, dataPath_> const dataPath = "dataPath";
 x3::rule<leaf_path_class, dataPath_> const leafPath = "leafPath";
 x3::rule<presenceContainerPath_class, dataPath_> const presenceContainerPath = "presenceContainerPath";
+x3::rule<listInstancePath_class, dataPath_> const listInstancePath = "listInstancePath";
 
 x3::rule<leaf_data_class, leaf_data_> const leaf_data = "leaf_data";
 x3::rule<leaf_data_enum_class, enum_> const leaf_data_enum = "leaf_data_enum";
@@ -182,6 +183,9 @@
 auto const presenceContainerPath_def =
     dataPath;
 
+auto const listInstancePath_def =
+    dataPath;
+
 auto const createEnumSuggestions_def =
     x3::eps;
 
@@ -244,10 +248,10 @@
     cd_::name >> space_separator > dataPath;
 
 auto const create_def =
-    create_::name >> space_separator > presenceContainerPath;
+    create_::name >> space_separator > (presenceContainerPath | listInstancePath);
 
 auto const delete_rule_def =
-    delete_::name >> space_separator > presenceContainerPath;
+    delete_::name >> space_separator > (presenceContainerPath | listInstancePath);
 
 auto const get_def =
     get_::name >> -(space_separator >> (dataPathListEnd | dataPath));
@@ -298,6 +302,7 @@
 BOOST_SPIRIT_DEFINE(leaf)
 BOOST_SPIRIT_DEFINE(leafPath)
 BOOST_SPIRIT_DEFINE(presenceContainerPath)
+BOOST_SPIRIT_DEFINE(listInstancePath)
 BOOST_SPIRIT_DEFINE(schemaPath)
 BOOST_SPIRIT_DEFINE(dataPath)
 BOOST_SPIRIT_DEFINE(dataNodeList)
diff --git a/src/interpreter.cpp b/src/interpreter.cpp
index aff5bcc..44177b6 100644
--- a/src/interpreter.cpp
+++ b/src/interpreter.cpp
@@ -65,7 +65,10 @@
 
 void Interpreter::operator()(const delete_& delet) const
 {
-    m_datastore.deletePresenceContainer(absolutePathFromCommand(delet));
+    if (delet.m_path.m_nodes.back().m_suffix.type() == typeid(container_))
+        m_datastore.deletePresenceContainer(absolutePathFromCommand(delet));
+    else
+        m_datastore.deleteListInstance(absolutePathFromCommand(delet));
 }
 
 void Interpreter::operator()(const ls_& ls) const
diff --git a/src/sysrepo_access.cpp b/src/sysrepo_access.cpp
index a6388db..d514203 100644
--- a/src/sysrepo_access.cpp
+++ b/src/sysrepo_access.cpp
@@ -117,6 +117,16 @@
     m_session->delete_item(path.c_str());
 }
 
+void SysrepoAccess::createListInstance(const std::string& path)
+{
+    m_session->set_item(path.c_str());
+}
+
+void SysrepoAccess::deleteListInstance(const std::string& path)
+{
+    m_session->delete_item(path.c_str());
+}
+
 void SysrepoAccess::commitChanges()
 {
     m_session->commit();
diff --git a/src/sysrepo_access.hpp b/src/sysrepo_access.hpp
index 13b4ace..76e9088 100644
--- a/src/sysrepo_access.hpp
+++ b/src/sysrepo_access.hpp
@@ -32,6 +32,8 @@
     void setLeaf(const std::string& path, leaf_data_ value) override;
     void createPresenceContainer(const std::string& path) override;
     void deletePresenceContainer(const std::string& path) override;
+    void createListInstance(const std::string& path) override;
+    void deleteListInstance(const std::string& path) override;
     std::string fetchSchema(const char* module, const char* revision, const char* submodule);
     std::vector<std::string> listImplementedSchemas();