parser yang UPDATE automatic parsing of nested extensions

Fixes #2265
diff --git a/src/parser_yang.c b/src/parser_yang.c
index 8511d26..58449ae 100644
--- a/src/parser_yang.c
+++ b/src/parser_yang.c
@@ -982,8 +982,16 @@
     e->parent_stmt_index = parent_stmt_index;
 
     YANG_READ_SUBSTMT_FOR_GOTO(ctx, kw, word, word_len, ret, cleanup) {
-        LY_CHECK_GOTO(ret = parse_ext_substmt(ctx, kw, word, word_len, &e->child), cleanup)
-        YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, NULL, ret, cleanup);
+        switch (kw) {
+        case LY_STMT_EXTENSION_INSTANCE:
+            LY_CHECK_GOTO(parse_ext(ctx, word, word_len, e, LY_STMT_EXTENSION_INSTANCE, 0, &e->exts), cleanup);
+            break;
+        default:
+            /* just store all the statements */
+            LY_CHECK_GOTO(ret = parse_ext_substmt(ctx, kw, word, word_len, &e->child), cleanup)
+            break;
+        }
+        YANG_READ_SUBSTMT_NEXT_ITER(ctx, kw, word, word_len, e->exts, ret, cleanup);
     }
 
 cleanup:
diff --git a/src/parser_yin.c b/src/parser_yin.c
index 3924d0e..eab9c37 100644
--- a/src/parser_yin.c
+++ b/src/parser_yin.c
@@ -4,7 +4,7 @@
  * @author Michal Vasko <mvasko@cesnet.cz>
  * @brief YIN parser.
  *
- * Copyright (c) 2015 - 2022 CESNET, z.s.p.o.
+ * Copyright (c) 2015 - 2024 CESNET, z.s.p.o.
  *
  * This source code is licensed under BSD 3-Clause License (the "License").
  * You may not use this file except in compliance with the License.
@@ -3409,6 +3409,14 @@
     if (ctx->xmlctx->ws_only) {
         LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
         while (ctx->xmlctx->status == LYXML_ELEMENT) {
+            /* BUG nested extensions will not be parsed because we are not able to dinsguish between them
+             * and the argument of this extension, in case there is one and its 'yin-element' is 'true'
+            stmt = yin_match_keyword(ctx, ctx->xmlctx->name, ctx->xmlctx->name_len, ctx->xmlctx->prefix,
+                    ctx->xmlctx->prefix_len, LY_STMT_EXTENSION_INSTANCE);
+            if (stmt == LY_STMT_EXTENSION_INSTANCE) {
+                LY_CHECK_RET(yin_parse_extension_instance(ctx, e, LY_STMT_EXTENSION_INSTANCE, 0, &e->exts));
+            } else { */
+
             LY_CHECK_RET(yin_parse_element_generic(ctx, LY_STMT_EXTENSION_INSTANCE, &new_subelem));
             if (!e->child) {
                 e->child = new_subelem;
@@ -3420,6 +3428,9 @@
             assert(ctx->xmlctx->status == LYXML_ELEM_CLOSE);
             LY_CHECK_RET(lyxml_ctx_next(ctx->xmlctx));
         }
+
+        /* store extension instance array (no realloc anymore) to find the plugin records and finish parsing */
+        LY_CHECK_RET(yin_unres_exts_add(ctx, e->exts));
     } else if (ctx->xmlctx->value_len) {
         /* invalid text content */
         LOGVAL_PARSER(ctx, LYVE_SYNTAX, "Extension instance \"%s\" with unexpected text content \"%.*s\".", ext_name,
diff --git a/src/plugins_exts.h b/src/plugins_exts.h
index 74ce215..d75efae 100644
--- a/src/plugins_exts.h
+++ b/src/plugins_exts.h
@@ -109,7 +109,7 @@
 /**
  * @brief Extensions API version
  */
-#define LYPLG_EXT_API_VERSION 6
+#define LYPLG_EXT_API_VERSION 7
 
 /**
  * @brief Mask for an operation statement.
@@ -419,6 +419,7 @@
                                                  parsed data ([sized array](@ref sizedarrays)) */
     void *parsed;                           /**< private plugin parsed data */
     struct lysp_stmt *child;                /**< list of generic (unknown) YANG statements */
+    struct lysp_ext_instance *exts;         /**< list of the extension instances ([sized array](@ref sizedarrays)) */
 };
 
 /**
diff --git a/src/schema_compile.c b/src/schema_compile.c
index aa9a3d0..bda517c 100644
--- a/src/schema_compile.c
+++ b/src/schema_compile.c
@@ -4,7 +4,7 @@
  * @author Michal Vasko <mvasko@cesnet.cz>
  * @brief Schema compilation.
  *
- * Copyright (c) 2015 - 2022 CESNET, z.s.p.o.
+ * Copyright (c) 2015 - 2024 CESNET, z.s.p.o.
  *
  * This source code is licensed under BSD 3-Clause License (the "License").
  * You may not use this file except in compliance with the License.
@@ -172,7 +172,10 @@
     /* compile extension if not already */
     LY_CHECK_GOTO(ret = lys_compile_extension(ctx, extp, &ext->def), cleanup);
 
-    /* compile */
+    /* compile nested extensions */
+    COMPILE_EXTS_GOTO(ctx, extp->exts, ext->exts, ext, ret, cleanup);
+
+    /* compile this extension */
     if (ext->def->plugin && ext->def->plugin->compile) {
         if (ext->argument) {
             lysc_update_path(ctx, ext->module, ext->argument);
diff --git a/src/tree_schema_free.c b/src/tree_schema_free.c
index 91ba72b..ee05d3c 100644
--- a/src/tree_schema_free.c
+++ b/src/tree_schema_free.c
@@ -80,6 +80,8 @@
     LY_LIST_FOR_SAFE(ext->child, next, stmt) {
         lysp_stmt_free(ctx->ctx, stmt);
     }
+
+    FREE_ARRAY(ctx, ext->exts, lysp_ext_instance_free);
 }
 
 /**