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);
}
/**