schema CHANGE support extension instance top-level in ly_path_compile()

For further support of serching schema nodes in extension instance
instead of the standard module tree, we need to extend internal
ly_path_compile().
diff --git a/src/path.c b/src/path.c
index 778beda..209e460 100644
--- a/src/path.c
+++ b/src/path.c
@@ -782,8 +782,8 @@
 
 LY_ERR
 ly_path_compile(const struct ly_ctx *ctx, const struct lys_module *cur_mod, const struct lysc_node *ctx_node,
-        const struct lyxp_expr *expr, uint8_t lref, uint8_t oper, uint8_t target, LY_PREFIX_FORMAT format,
-        void *prefix_data, struct lys_glob_unres *unres, struct ly_path **path)
+        const struct lysc_ext_instance *ext, const struct lyxp_expr *expr, uint8_t lref, uint8_t oper, uint8_t target,
+        LY_PREFIX_FORMAT format, void *prefix_data, struct lys_glob_unres *unres, struct ly_path **path)
 {
     LY_ERR ret = LY_SUCCESS;
     uint16_t tok_idx = 0;
@@ -861,7 +861,11 @@
         ++tok_idx;
 
         /* find the next node */
-        node2 = lys_find_child(ctx_node, mod, name, name_len, 0, getnext_opts);
+        if (!ctx_node && ext) {
+            node2 = lysc_ext_find_node(ext, mod, name, name_len, 0, getnext_opts);
+        } else {
+            node2 = lys_find_child(ctx_node, mod, name, name_len, 0, getnext_opts);
+        }
         if (!node2 || (op && (node2->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF)) && (node2 != op))) {
             LOGVAL(ctx, LYVE_XPATH, "Not found node \"%.*s\" in path.", (int)name_len, name);
             ret = LY_EVALID;
diff --git a/src/path.h b/src/path.h
index a6e8149..9074191 100644
--- a/src/path.h
+++ b/src/path.h
@@ -149,6 +149,9 @@
  * @param[in] cur_mod Current module of the path (where it was "instantiated"). Used for nodes without a prefix
  * for ::LY_PREF_SCHEMA* format.
  * @param[in] ctx_node Optional context node.
+ * @param[in] ext Extension instance containing the definition of the data being created. It is used to find the top-level
+ * node inside the extension instance instead of a module. Note that this is the case not only if the @p ctx_node is NULL,
+ * but also if the relative path starting in @p ctx_node reaches the document root via double dots.
  * @param[in] expr Parsed path.
  * @param[in] lref Lref option (@ref path_lref_options).
  * @param[in] oper Oper option (@ref path_oper_options).
@@ -160,8 +163,8 @@
  * @return LY_ERR value.
  */
 LY_ERR ly_path_compile(const struct ly_ctx *ctx, const struct lys_module *cur_mod, const struct lysc_node *ctx_node,
-        const struct lyxp_expr *expr, uint8_t lref, uint8_t oper, uint8_t target, LY_PREFIX_FORMAT format,
-        void *prefix_data, struct lys_glob_unres *unres, struct ly_path **path);
+        const struct lysc_ext_instance *ext, const struct lyxp_expr *expr, uint8_t lref, uint8_t oper, uint8_t target,
+        LY_PREFIX_FORMAT format, void *prefix_data, struct lys_glob_unres *unres, struct ly_path **path);
 
 /**
  * @brief Compile predicate into ly_path_predicate structure. Only simple predicates (not leafref) are supported.
diff --git a/src/plugins_types.c b/src/plugins_types.c
index 204b85e..9559608 100644
--- a/src/plugins_types.c
+++ b/src/plugins_types.c
@@ -1706,7 +1706,7 @@
     }
 
     /* resolve it on schema tree */
-    ret = ly_path_compile(ctx, NULL, ctx_node, exp, LY_PATH_LREF_FALSE, (ctx_node->flags & LYS_IS_OUTPUT) ?
+    ret = ly_path_compile(ctx, NULL, ctx_node, NULL, exp, LY_PATH_LREF_FALSE, (ctx_node->flags & LYS_IS_OUTPUT) ?
             LY_PATH_OPER_OUTPUT : LY_PATH_OPER_INPUT, LY_PATH_TARGET_SINGLE, format, prefix_data, unres, &path);
     if (ret) {
         *err = ly_err_msg_create(&ret, LYVE_DATA, NULL, NULL, "Invalid instance-identifier \"%.*s\" value - semantic error.", (int)value_len, value);
diff --git a/src/schema_compile.c b/src/schema_compile.c
index 6d9c606..e98e4f7 100644
--- a/src/schema_compile.c
+++ b/src/schema_compile.c
@@ -1018,7 +1018,7 @@
     assert(node->nodetype & (LYS_LEAF | LYS_LEAFLIST));
 
     /* try to find the target */
-    LY_CHECK_RET(ly_path_compile(ctx->ctx, lref->cur_mod, node, lref->path, LY_PATH_LREF_TRUE,
+    LY_CHECK_RET(ly_path_compile(ctx->ctx, lref->cur_mod, node, NULL, lref->path, LY_PATH_LREF_TRUE,
             (node->flags & LYS_IS_OUTPUT) ? LY_PATH_OPER_OUTPUT : LY_PATH_OPER_INPUT, LY_PATH_TARGET_MANY,
             LY_PREF_SCHEMA_RESOLVED, lref->prefixes, unres, &p));
 
diff --git a/src/tree_data.c b/src/tree_data.c
index e94d8d5..0902b31 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -1645,7 +1645,7 @@
             LY_PATH_PREFIX_OPTIONAL, LY_PATH_PRED_SIMPLE, &exp), cleanup);
 
     /* compile path */
-    LY_CHECK_GOTO(ret = ly_path_compile(ctx, NULL, parent ? parent->schema : NULL, exp, LY_PATH_LREF_FALSE,
+    LY_CHECK_GOTO(ret = ly_path_compile(ctx, NULL, parent ? parent->schema : NULL, NULL, exp, LY_PATH_LREF_FALSE,
             options & LYD_NEW_PATH_OUTPUT ? LY_PATH_OPER_OUTPUT : LY_PATH_OPER_INPUT, LY_PATH_TARGET_MANY, LY_PREF_JSON,
             NULL, NULL, &p), cleanup);
 
@@ -3896,7 +3896,7 @@
     LY_CHECK_GOTO(ret, cleanup);
 
     /* compile the path */
-    ret = ly_path_compile(LYD_CTX(ctx_node), NULL, ctx_node->schema, expr, LY_PATH_LREF_FALSE,
+    ret = ly_path_compile(LYD_CTX(ctx_node), NULL, ctx_node->schema, NULL, expr, LY_PATH_LREF_FALSE,
             output ? LY_PATH_OPER_OUTPUT : LY_PATH_OPER_INPUT, LY_PATH_TARGET_SINGLE, LY_PREF_JSON,
             (void *)LYD_CTX(ctx_node), NULL, &lypath);
     LY_CHECK_GOTO(ret, cleanup);
diff --git a/src/tree_schema.c b/src/tree_schema.c
index f6ee17d..67e4804 100644
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -665,7 +665,7 @@
 
     /* compile */
     oper = output ? LY_PATH_OPER_OUTPUT : LY_PATH_OPER_INPUT;
-    ret = ly_path_compile(ctx, NULL, ctx_node, expr, LY_PATH_LREF_FALSE, oper, LY_PATH_TARGET_MANY,
+    ret = ly_path_compile(ctx, NULL, ctx_node, NULL, expr, LY_PATH_LREF_FALSE, oper, LY_PATH_TARGET_MANY,
             LY_PREF_JSON, NULL, NULL, &p);
     LY_CHECK_GOTO(ret, cleanup);
 
@@ -699,7 +699,7 @@
 
     /* compile */
     oper = output ? LY_PATH_OPER_OUTPUT : LY_PATH_OPER_INPUT;
-    ret = ly_path_compile(ctx, NULL, ctx_node, exp, LY_PATH_LREF_FALSE, oper, LY_PATH_TARGET_MANY,
+    ret = ly_path_compile(ctx, NULL, ctx_node, NULL, exp, LY_PATH_LREF_FALSE, oper, LY_PATH_TARGET_MANY,
             LY_PREF_JSON, NULL, NULL, &p);
     LY_CHECK_GOTO(ret, cleanup);
 
diff --git a/src/xpath.c b/src/xpath.c
index d05107f..6846ef7 100644
--- a/src/xpath.c
+++ b/src/xpath.c
@@ -3714,7 +3714,7 @@
             oper = (sleaf->flags & LYS_IS_OUTPUT) ? LY_PATH_OPER_OUTPUT : LY_PATH_OPER_INPUT;
 
             /* it was already evaluated on schema, it must succeed */
-            rc = ly_path_compile(set->ctx, lref->cur_mod, &sleaf->node, lref->path, LY_PATH_LREF_TRUE, oper,
+            rc = ly_path_compile(set->ctx, lref->cur_mod, &sleaf->node, NULL, lref->path, LY_PATH_LREF_TRUE, oper,
                     LY_PATH_TARGET_MANY, LY_PREF_SCHEMA_RESOLVED, lref->prefixes, NULL, &p);
             assert(!rc);
 
diff --git a/tests/utests/data/test_tree_data.c b/tests/utests/data/test_tree_data.c
index 1aab6fc..00cc266 100644
--- a/tests/utests/data/test_tree_data.c
+++ b/tests/utests/data/test_tree_data.c
@@ -227,7 +227,7 @@
     CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
     assert_int_equal(LY_SUCCESS, ly_path_parse(UTEST_LYCTX, NULL, path_str, strlen(path_str), LY_PATH_BEGIN_EITHER, LY_PATH_LREF_FALSE,
             LY_PATH_PREFIX_OPTIONAL, LY_PATH_PRED_SIMPLE, &exp));
-    assert_int_equal(LY_SUCCESS, ly_path_compile(UTEST_LYCTX, NULL, NULL, exp, LY_PATH_LREF_FALSE, LY_PATH_OPER_INPUT,
+    assert_int_equal(LY_SUCCESS, ly_path_compile(UTEST_LYCTX, NULL, NULL, NULL, exp, LY_PATH_LREF_FALSE, LY_PATH_OPER_INPUT,
             LY_PATH_TARGET_SINGLE, LY_PREF_JSON, NULL, NULL, &path));
     term = lyd_target(path, tree);