data FEATURE support extension's data parsing

Make the data parsers to support parsing data corresponding to a
separate schema tree specified in an extension instance.
diff --git a/src/parser_json.c b/src/parser_json.c
index 37b7e68..d64745e 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -26,6 +26,7 @@
 #include "json.h"
 #include "log.h"
 #include "parser_internal.h"
+#include "plugins_exts.h"
 #include "set.h"
 #include "tree.h"
 #include "tree_data.h"
@@ -40,6 +41,7 @@
  * Note that the structure maps to the lyd_ctx which is common for all the data parsers
  */
 struct lyd_json_ctx {
+    const struct lysc_ext_instance *ext; /**< extension instance possibly changing document root context of the data being parsed */
     uint32_t parse_opts;           /**< various @ref dataparseroptions. */
     uint32_t val_opts;             /**< various @ref datavalidationoptions. */
     uint32_t int_opts;             /**< internal data parser options */
@@ -227,11 +229,25 @@
 
     /* get the schema node */
     if (mod && (!parent || parent->schema)) {
-        *snode_p = lys_find_child(parent ? parent->schema : NULL, mod, name, name_len, 0, getnext_opts);
+        if (!parent && lydctx->ext) {
+            *snode_p = lys_find_ext_instance_node(lydctx->ext, mod, name, name_len, 0, getnext_opts);
+        } else {
+            *snode_p = lys_find_child(parent ? parent->schema : NULL, mod, name, name_len, 0, getnext_opts);
+        }
         if (!*snode_p) {
             if (lydctx->parse_opts & LYD_PARSE_STRICT) {
-                LOGVAL(lydctx->jsonctx->ctx, LYVE_REFERENCE, "Node \"%.*s\" not found in the \"%s\" module.",
-                        name_len, name, mod->name);
+                if (lydctx->ext) {
+                    if (lydctx->ext->argument) {
+                        LOGVAL(lydctx->jsonctx->ctx, LYVE_REFERENCE, "Node \"%.*s\" not found in the \"%s\" %s extension instance.",
+                                name_len, name, lydctx->ext->argument, lydctx->ext->def->name);
+                    } else {
+                        LOGVAL(lydctx->jsonctx->ctx, LYVE_REFERENCE, "Node \"%.*s\" not found in the %s extension instance.",
+                                name_len, name, lydctx->ext->def->name);
+                    }
+                } else {
+                    LOGVAL(lydctx->jsonctx->ctx, LYVE_REFERENCE, "Node \"%.*s\" not found in the \"%s\" module.",
+                            name_len, name, mod->name);
+                }
                 ret = LY_EVALID;
                 goto cleanup;
             } else if (!(lydctx->parse_opts & LYD_PARSE_OPAQ)) {
@@ -1369,8 +1385,9 @@
 }
 
 LY_ERR
-lyd_parse_json(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 ly_set *parsed, struct lyd_ctx **lydctx_p)
+lyd_parse_json(const struct ly_ctx *ctx, const struct lysc_ext_instance *ext, 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 ly_set *parsed, struct lyd_ctx **lydctx_p)
 {
     LY_ERR rc = LY_SUCCESS;
     struct lyd_json_ctx *lydctx = NULL;
@@ -1401,6 +1418,7 @@
         goto cleanup;
     }
     lydctx->int_opts = int_opts;
+    lydctx->ext = ext;
 
     /* find the operation node if it exists already */
     LY_CHECK_GOTO(rc = lyd_parser_find_operation(parent, int_opts, &lydctx->op_node), cleanup);