parser data REFACTOR split NETCONF notification and reply parsing

Because there is never a situation when either of
these messages could be parsed directly, the transport
protocol metadata must first be handled. Also, the
old API did not allow for direct notification
parsing, always only both a reply and notification.
diff --git a/src/parser_data.h b/src/parser_data.h
index c677416..710f6fc 100644
--- a/src/parser_data.h
+++ b/src/parser_data.h
@@ -263,20 +263,21 @@
  * @{
  */
 enum lyd_type {
-    LYD_TYPE_YANG_DATA = 0,         /* generic YANG instance data */
-    LYD_TYPE_YANG_RPC,              /* instance of a YANG RPC/action request with only "input" data children,
-                                       including all parents in case of an action */
-    LYD_TYPE_YANG_NOTIF,            /* instance of a YANG notification , including all parents in case of a nested one */
-    LYD_TYPE_YANG_REPLY,            /* instance of a YANG RPC/action reply with only "output" data children,
-                                       including all parents in case of an action */
-    LYD_TYPE_NETCONF_RPC,           /* complete NETCONF RPC invocation as defined for
-                                       [RPC](https://tools.ietf.org/html/rfc7950#section-7.14.4) and
-                                       [action](https://tools.ietf.org/html/rfc7950#section-7.15.2) */
-    LYD_TYPE_NETCONF_REPLY_OR_NOTIF /* complete NETCONF RPC reply as defined for
-                                       [RPC](https://tools.ietf.org/html/rfc7950#section-7.14.4) and
-                                       [action](https://tools.ietf.org/html/rfc7950#section-7.15.2) or
-                                       [notification](https://tools.ietf.org/html/rfc7950#section-7.16.2), which
-                                       of these is parsed is decided based on the first element name */
+    LYD_TYPE_DATA_YANG = 0, /* generic YANG instance data */
+    LYD_TYPE_RPC_YANG,      /* instance of a YANG RPC/action request with only "input" data children,
+                               including all parents in case of an action */
+    LYD_TYPE_NOTIF_YANG,    /* instance of a YANG notification , including all parents in case of a nested one */
+    LYD_TYPE_REPLY_YANG,    /* instance of a YANG RPC/action reply with only "output" data children,
+                               including all parents in case of an action */
+
+    LYD_TYPE_RPC_NETCONF,   /* complete NETCONF RPC invocation as defined for
+                               [RPC](https://tools.ietf.org/html/rfc7950#section-7.14.4) and
+                               [action](https://tools.ietf.org/html/rfc7950#section-7.15.2) */
+    LYD_TYPE_NOTIF_NETCONF, /* complete NETCONF notification message as defined for
+                               [notification](https://tools.ietf.org/html/rfc7950#section-7.16.2) */
+    LYD_TYPE_REPLY_NETCONF  /* complete NETCONF RPC reply as defined for
+                               [RPC](https://tools.ietf.org/html/rfc7950#section-7.14.4) and
+                               [action](https://tools.ietf.org/html/rfc7950#section-7.15.2) */
 };
 /** @} datatype */
 
@@ -286,20 +287,27 @@
  * At least one of @p parent, @p tree, or @p op must always be set.
  *
  * Specific @p data_type values have different parameter meaning as follows:
- * - ::LYD_TYPE_NETCONF_RPC:
+ * - ::LYD_TYPE_RPC_NETCONF:
  *   - @p parent - must be NULL, the whole RPC is expected;
  *   - @p format - must be ::LYD_XML, NETCONF supports only this format;
  *   - @p tree - must be provided, all the NETCONF-specific XML envelopes will be returned here as
  *               a separate opaque data tree, even if the function fails, this may be returned;
  *   - @p op - must be provided, the RPC/action data tree itself will be returned here, pointing to the operation;
  *
- * - ::LYD_TYPE_NETCONF_REPLY_OR_NOTIF:
+ * - ::LYD_TYPE_NOTIF_NETCONF:
+ *   - @p parent - must be NULL, the whole notification is expected;
+ *   - @p format - must be ::LYD_XML, NETCONF supports only this format;
+ *   - @p tree - must be provided, all the NETCONF-specific XML envelopes will be returned here as
+ *               a separate opaque data tree;
+ *   - @p op - must be provided, the notification data tree itself will be returned here, pointing to the operation;
+ *
+ * - ::LYD_TYPE_REPLY_NETCONF:
  *   - @p parent - must be set, pointing to the invoked RPC operation (RPC or action) node;
  *   - @p format - must be ::LYD_XML, NETCONF supports only this format;
  *   - @p tree - must be provided, all the NETCONF-specific XML envelopes will be returned here as
  *               a separate opaque data tree;
- *   - @p op - must be provided, the notification data tree itself will be returned here, pointing to the operation,
- *             it will be set to NULL if no data nodes were parsed in the reply (ok or rpc-error);
+ *   - @p op - must be NULL, the reply is appended to the RPC;
+ *   Note that there are 3 kinds of NETCONF replies - ok, error, and data. Only data reply appends any nodes to the RPC.
  *
  * @param[in] ctx libyang context.
  * @param[in] parent Optional parent to connect the parsed nodes to.
diff --git a/src/parser_json.c b/src/parser_json.c
index bccd286..37b7e68 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -1383,16 +1383,16 @@
     assert(status == LYJSON_OBJECT);
 
     switch (data_type) {
-    case LYD_TYPE_YANG_DATA:
+    case LYD_TYPE_DATA_YANG:
         int_opts = LYD_INTOPT_WITH_SIBLINGS;
         break;
-    case LYD_TYPE_YANG_RPC:
+    case LYD_TYPE_RPC_YANG:
         int_opts = LYD_INTOPT_RPC | LYD_INTOPT_ACTION | LYD_INTOPT_NO_SIBLINGS;
         break;
-    case LYD_TYPE_YANG_NOTIF:
+    case LYD_TYPE_NOTIF_YANG:
         int_opts = LYD_INTOPT_NOTIF | LYD_INTOPT_NO_SIBLINGS;
         break;
-    case LYD_TYPE_YANG_REPLY:
+    case LYD_TYPE_REPLY_YANG:
         int_opts = LYD_INTOPT_REPLY | LYD_INTOPT_NO_SIBLINGS;
         break;
     default:
diff --git a/src/parser_lyb.c b/src/parser_lyb.c
index e755160..05f410c 100644
--- a/src/parser_lyb.c
+++ b/src/parser_lyb.c
@@ -1040,16 +1040,16 @@
     lybctx->free = lyd_lyb_ctx_free;
 
     switch (data_type) {
-    case LYD_TYPE_YANG_DATA:
+    case LYD_TYPE_DATA_YANG:
         int_opts = LYD_INTOPT_WITH_SIBLINGS;
         break;
-    case LYD_TYPE_YANG_RPC:
+    case LYD_TYPE_RPC_YANG:
         int_opts = LYD_INTOPT_RPC | LYD_INTOPT_ACTION | LYD_INTOPT_NO_SIBLINGS;
         break;
-    case LYD_TYPE_YANG_NOTIF:
+    case LYD_TYPE_NOTIF_YANG:
         int_opts = LYD_INTOPT_NOTIF | LYD_INTOPT_NO_SIBLINGS;
         break;
-    case LYD_TYPE_YANG_REPLY:
+    case LYD_TYPE_REPLY_YANG:
         int_opts = LYD_INTOPT_REPLY | LYD_INTOPT_NO_SIBLINGS;
         break;
     default:
diff --git a/src/parser_xml.c b/src/parser_xml.c
index 887305f..7773db1 100644
--- a/src/parser_xml.c
+++ b/src/parser_xml.c
@@ -1298,39 +1298,6 @@
     return rc;
 }
 
-/**
- * @brief Parse all expected non-data XML elements of a NETCONF rpc-reply or notification message.
- *
- * @param[in] xmlctx XML parser context.
- * @param[out] evnp Parsed envelope(s) (opaque node).
- * @param[out] int_opts Internal options for parsing the rest of YANG data.
- * @param[out] close_elem Number of parsed opened elements that need to be closed.
- * @param[out] parent_p Parent to append to the rest of YANG data, may be unset.
- * @return LY_SUCCESS on success.
- * @return LY_ERR value on error.
- */
-static LY_ERR
-lydxml_env_netconf_reply_or_notif(struct lyxml_ctx *xmlctx, struct lyd_node **envp, uint32_t *int_opts,
-        uint32_t *close_elem, struct lyd_node **parent_p)
-{
-    /* is it a "rpc-reply" or a "notification"? */
-    assert(xmlctx->status == LYXML_ELEMENT);
-    if (!ly_strncmp("rpc-reply", xmlctx->name, xmlctx->name_len)) {
-        LY_CHECK_RET(lydxml_env_netconf_reply(xmlctx, envp, int_opts, close_elem));
-    } else if (!ly_strncmp("notification", xmlctx->name, xmlctx->name_len)) {
-        LY_CHECK_RET(lydxml_env_netconf_notif(xmlctx, envp, int_opts, close_elem));
-
-        /* unset parent, the notification starts from top-level */
-        *parent_p = NULL;
-    } else {
-        LOGVAL(xmlctx->ctx, LYVE_REFERENCE, "Unexpected element \"%.*s\" instead of \"rpc-reply\" or \"notification\".",
-                xmlctx->name_len, xmlctx->name);
-        return LY_EVALID;
-    }
-
-    return LY_SUCCESS;
-}
-
 LY_ERR
 lyd_parse_xml(const struct ly_ctx *ctx, struct lyd_node *parent, struct lyd_node **first_p, struct ly_in *in,
         uint32_t parse_opts, uint32_t val_opts, enum lyd_type data_type, struct lyd_node **envp, struct ly_set *parsed,
@@ -1354,26 +1321,29 @@
     lydctx->free = lyd_xml_ctx_free;
 
     switch (data_type) {
-    case LYD_TYPE_YANG_DATA:
+    case LYD_TYPE_DATA_YANG:
         int_opts = LYD_INTOPT_WITH_SIBLINGS;
         break;
-    case LYD_TYPE_YANG_RPC:
+    case LYD_TYPE_RPC_YANG:
         int_opts = LYD_INTOPT_RPC | LYD_INTOPT_ACTION | LYD_INTOPT_NO_SIBLINGS;
         break;
-    case LYD_TYPE_YANG_NOTIF:
+    case LYD_TYPE_NOTIF_YANG:
         int_opts = LYD_INTOPT_NOTIF | LYD_INTOPT_NO_SIBLINGS;
         break;
-    case LYD_TYPE_YANG_REPLY:
+    case LYD_TYPE_REPLY_YANG:
         int_opts = LYD_INTOPT_REPLY | LYD_INTOPT_NO_SIBLINGS;
         break;
-    case LYD_TYPE_NETCONF_RPC:
+    case LYD_TYPE_RPC_NETCONF:
         assert(!parent);
         LY_CHECK_GOTO(rc = lydxml_env_netconf_rpc(lydctx->xmlctx, envp, &int_opts, &close_elem), cleanup);
         break;
-    case LYD_TYPE_NETCONF_REPLY_OR_NOTIF:
+    case LYD_TYPE_NOTIF_NETCONF:
+        assert(!parent);
+        LY_CHECK_GOTO(rc = lydxml_env_netconf_notif(lydctx->xmlctx, envp, &int_opts, &close_elem), cleanup);
+        break;
+    case LYD_TYPE_REPLY_NETCONF:
         assert(parent);
-        LY_CHECK_GOTO(rc = lydxml_env_netconf_reply_or_notif(lydctx->xmlctx, envp, &int_opts, &close_elem, &parent),
-                cleanup);
+        LY_CHECK_GOTO(rc = lydxml_env_netconf_reply(lydctx->xmlctx, envp, &int_opts, &close_elem), cleanup);
         break;
     }
     lydctx->int_opts = int_opts;
diff --git a/src/tree_data.c b/src/tree_data.c
index a2f0506..e633297 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -331,13 +331,13 @@
     /* parse the data */
     switch (format) {
     case LYD_XML:
-        rc = lyd_parse_xml(ctx, parent, first_p, in, parse_opts, val_opts, LYD_TYPE_YANG_DATA, NULL, &parsed, &lydctx);
+        rc = lyd_parse_xml(ctx, parent, first_p, in, parse_opts, val_opts, LYD_TYPE_DATA_YANG, NULL, &parsed, &lydctx);
         break;
     case LYD_JSON:
-        rc = lyd_parse_json(ctx, parent, first_p, in, parse_opts, val_opts, LYD_TYPE_YANG_DATA, &parsed, &lydctx);
+        rc = lyd_parse_json(ctx, parent, first_p, in, parse_opts, val_opts, LYD_TYPE_DATA_YANG, &parsed, &lydctx);
         break;
     case LYD_LYB:
-        rc = lyd_parse_lyb(ctx, parent, first_p, in, parse_opts, val_opts, LYD_TYPE_YANG_DATA, &parsed, &lydctx);
+        rc = lyd_parse_lyb(ctx, parent, first_p, in, parse_opts, val_opts, LYD_TYPE_DATA_YANG, &parsed, &lydctx);
         break;
     case LYD_UNKNOWN:
         LOGARG(ctx, format);
@@ -462,10 +462,11 @@
     in->func_start = in->current;
 
     /* check params based on the data type */
-    if (data_type == LYD_TYPE_NETCONF_RPC) {
+    if ((data_type == LYD_TYPE_RPC_NETCONF) || (data_type == LYD_TYPE_NOTIF_NETCONF)) {
         LY_CHECK_ARG_RET(ctx, format == LYD_XML, !parent, tree, op, LY_EINVAL);
-    } else if (data_type == LYD_TYPE_NETCONF_REPLY_OR_NOTIF) {
-        LY_CHECK_ARG_RET(ctx, format == LYD_XML, parent, parent->schema->nodetype & (LYS_RPC | LYS_ACTION), tree, op, LY_EINVAL);
+    } else if (data_type == LYD_TYPE_REPLY_NETCONF) {
+        LY_CHECK_ARG_RET(ctx, format == LYD_XML, parent, parent->schema->nodetype & (LYS_RPC | LYS_ACTION), tree, !op,
+                LY_EINVAL);
     }
     parse_opts = LYD_PARSE_ONLY | LYD_PARSE_STRICT;
     val_opts = 0;
diff --git a/src/validation.c b/src/validation.c
index c970ffa..824fe7d 100644
--- a/src/validation.c
+++ b/src/validation.c
@@ -1608,14 +1608,14 @@
     struct lyd_node *op_node;
     uint32_t int_opts;
 
-    LY_CHECK_ARG_RET(NULL, op_tree, !op_tree->parent, !dep_tree || !dep_tree->parent, (data_type == LYD_TYPE_YANG_RPC) ||
-            (data_type == LYD_TYPE_YANG_NOTIF) || (data_type == LYD_TYPE_YANG_REPLY), LY_EINVAL);
+    LY_CHECK_ARG_RET(NULL, op_tree, !op_tree->parent, !dep_tree || !dep_tree->parent, (data_type == LYD_TYPE_RPC_YANG) ||
+            (data_type == LYD_TYPE_NOTIF_YANG) || (data_type == LYD_TYPE_REPLY_YANG), LY_EINVAL);
     if (diff) {
         *diff = NULL;
     }
-    if (data_type == LYD_TYPE_YANG_RPC) {
+    if (data_type == LYD_TYPE_RPC_YANG) {
         int_opts = LYD_INTOPT_RPC | LYD_INTOPT_ACTION;
-    } else if (data_type == LYD_TYPE_YANG_NOTIF) {
+    } else if (data_type == LYD_TYPE_NOTIF_YANG) {
         int_opts = LYD_INTOPT_NOTIF;
     } else {
         int_opts = LYD_INTOPT_REPLY;