Add support for executing RPCs

Creating a temporary YangAccess for RPC input means I need to somehow
give the right libyang schemas. For that reason I supply a callable
which is able to fetch the schema and create a YangAccess instance for
ProxyDatastore.

The ProxyDatastore class now has a simple mechanism for deciding whether
to use the normal datastore and the temporary based on a path prefix.

Change-Id: Ib455f53237598bc2620161a44fb89c48ddfeb6e3
diff --git a/src/path_parser.hpp b/src/path_parser.hpp
index 9fa3db1..00629bb 100644
--- a/src/path_parser.hpp
+++ b/src/path_parser.hpp
@@ -14,6 +14,8 @@
 
 namespace x3 = boost::spirit::x3;
 
+x3::rule<cdPath_class, dataPath_> const cdPath = "cdPath";
+x3::rule<rpcPath_class, dataPath_> const rpcPath = "rpcPath";
 x3::rule<presenceContainerPath_class, dataPath_> const presenceContainerPath = "presenceContainerPath";
 x3::rule<listInstancePath_class, dataPath_> const listInstancePath = "listInstancePath";
 x3::rule<leafListElementPath_class, dataPath_> const leafListElementPath = "leafListElementPath";
@@ -137,10 +139,13 @@
                         parserContext.m_suggestions.emplace(Completion{parseString, "[", Completion::WhenToAdd::IfFullMatch});
                     }
                     break;
+                case yang::NodeTypes::Rpc:
+                    out.m_suffix = rpcNode_{child.second};
+                    parserContext.m_suggestions.emplace(Completion{parseString + "/"});
+                    break;
                 case yang::NodeTypes::Action:
                 case yang::NodeTypes::AnyXml:
                 case yang::NodeTypes::Notification:
-                case yang::NodeTypes::Rpc:
                     continue;
             }
             table.add(parseString, out);
@@ -421,6 +426,20 @@
 auto const writableLeafPath_def =
     PathParser<PathParserMode::DataPath, CompletionMode::Data>{filterConfigFalse};
 
+auto const onlyRpc = [] (const Schema& schema, const std::string& path) {
+    return schema.nodeType(path) == yang::NodeTypes::Rpc;
+};
+
+auto const rpcPath_def =
+    PathParser<PathParserMode::DataPath, CompletionMode::Data>{onlyRpc};
+
+auto const noRpc = [] (const Schema& schema, const std::string& path) {
+    return schema.nodeType(path) != yang::NodeTypes::Rpc;
+};
+
+auto const cdPath_def =
+    PathParser<PathParserMode::DataPath, CompletionMode::Data>{noRpc};
+
 auto const presenceContainerPath_def =
     dataPath;
 
@@ -443,6 +462,8 @@
 BOOST_SPIRIT_DEFINE(keyValue)
 BOOST_SPIRIT_DEFINE(key_identifier)
 BOOST_SPIRIT_DEFINE(listSuffix)
+BOOST_SPIRIT_DEFINE(rpcPath)
+BOOST_SPIRIT_DEFINE(cdPath)
 BOOST_SPIRIT_DEFINE(presenceContainerPath)
 BOOST_SPIRIT_DEFINE(listInstancePath)
 BOOST_SPIRIT_DEFINE(leafListElementPath)