structure FEATURE support for augment-structure

WIP
diff --git a/src/plugins_exts.h b/src/plugins_exts.h
index 298557c..2c264a7 100644
--- a/src/plugins_exts.h
+++ b/src/plugins_exts.h
@@ -102,7 +102,7 @@
 /**
  * @brief Extensions API version
  */
-#define LYPLG_EXT_API_VERSION 5
+#define LYPLG_EXT_API_VERSION 6
 
 /**
  * @brief Macro to define plugin information in external plugins
diff --git a/src/plugins_exts/structure.c b/src/plugins_exts/structure.c
index 781cde0..3580ba3 100644
--- a/src/plugins_exts/structure.c
+++ b/src/plugins_exts/structure.c
@@ -16,6 +16,7 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "compat.h"
 #include "libyang.h"
 #include "plugins_exts.h"
 
@@ -29,6 +30,12 @@
     struct lysc_node *child;
 };
 
+struct lysc_ext_instance_augment_structure {
+    uint16_t flags;
+    const char *dsc;
+    const char *ref;
+};
+
 /**
  * @brief Compile structure extension instances.
  *
@@ -37,11 +44,11 @@
 static LY_ERR
 structure_compile(struct lysc_ctx *cctx, const struct lysp_ext_instance *p_ext, struct lysc_ext_instance *c_ext)
 {
-    LY_ERR ret;
+    LY_ERR rc;
     LY_ARRAY_COUNT_TYPE u;
     struct lysc_module *mod_c;
     const struct lysc_node *child;
-    struct lysc_ext_instance_structure *struct_ext;
+    struct lysc_ext_instance_structure *struct_data;
     uint32_t prev_options = *lysc_ctx_get_options(cctx);
 
     /* structure can appear only at the top level of a YANG module or submodule */
@@ -72,90 +79,229 @@
     }
 
     /* allocate the storage */
-    struct_ext = calloc(1, sizeof *struct_ext);
-    if (!struct_ext) {
+    struct_data = calloc(1, sizeof *struct_data);
+    if (!struct_data) {
         goto emem;
     }
-    c_ext->data = struct_ext;
+    c_ext->data = struct_data;
 
     /* compile substatements */
-    LY_ARRAY_CREATE_GOTO(cctx->ctx, c_ext->substmts, 14, ret, emem);
+    LY_ARRAY_CREATE_GOTO(cctx->ctx, c_ext->substmts, 14, rc, emem);
     LY_ARRAY_INCREMENT(c_ext->substmts);
     c_ext->substmts[0].stmt = LY_STMT_MUST;
     c_ext->substmts[0].cardinality = LY_STMT_CARD_ANY;
-    c_ext->substmts[0].storage = &struct_ext->musts;
+    c_ext->substmts[0].storage = &struct_data->musts;
 
     LY_ARRAY_INCREMENT(c_ext->substmts);
     c_ext->substmts[1].stmt = LY_STMT_STATUS;
     c_ext->substmts[1].cardinality = LY_STMT_CARD_OPT;
-    c_ext->substmts[1].storage = &struct_ext->flags;
+    c_ext->substmts[1].storage = &struct_data->flags;
 
     LY_ARRAY_INCREMENT(c_ext->substmts);
     c_ext->substmts[2].stmt = LY_STMT_DESCRIPTION;
     c_ext->substmts[2].cardinality = LY_STMT_CARD_OPT;
-    c_ext->substmts[2].storage = &struct_ext->dsc;
+    c_ext->substmts[2].storage = &struct_data->dsc;
 
     LY_ARRAY_INCREMENT(c_ext->substmts);
     c_ext->substmts[3].stmt = LY_STMT_REFERENCE;
     c_ext->substmts[3].cardinality = LY_STMT_CARD_OPT;
-    c_ext->substmts[3].storage = &struct_ext->ref;
+    c_ext->substmts[3].storage = &struct_data->ref;
 
     LY_ARRAY_INCREMENT(c_ext->substmts);
     c_ext->substmts[4].stmt = LY_STMT_TYPEDEF;
     c_ext->substmts[4].cardinality = LY_STMT_CARD_ANY;
-    c_ext->substmts[4].storage = &struct_ext->typedefs;
+    c_ext->substmts[4].storage = &struct_data->typedefs;
 
     LY_ARRAY_INCREMENT(c_ext->substmts);
     c_ext->substmts[5].stmt = LY_STMT_GROUPING;
     c_ext->substmts[5].cardinality = LY_STMT_CARD_ANY;
-    c_ext->substmts[5].storage = &struct_ext->groupings;
+    c_ext->substmts[5].storage = &struct_data->groupings;
 
     /* data-def-stmt */
     LY_ARRAY_INCREMENT(c_ext->substmts);
     c_ext->substmts[6].stmt = LY_STMT_CONTAINER;
     c_ext->substmts[6].cardinality = LY_STMT_CARD_ANY;
-    c_ext->substmts[6].storage = &struct_ext->child;
+    c_ext->substmts[6].storage = &struct_data->child;
 
     LY_ARRAY_INCREMENT(c_ext->substmts);
     c_ext->substmts[7].stmt = LY_STMT_LEAF;
     c_ext->substmts[7].cardinality = LY_STMT_CARD_ANY;
-    c_ext->substmts[7].storage = &struct_ext->child;
+    c_ext->substmts[7].storage = &struct_data->child;
 
     LY_ARRAY_INCREMENT(c_ext->substmts);
     c_ext->substmts[8].stmt = LY_STMT_LEAF_LIST;
     c_ext->substmts[8].cardinality = LY_STMT_CARD_ANY;
-    c_ext->substmts[8].storage = &struct_ext->child;
+    c_ext->substmts[8].storage = &struct_data->child;
 
     LY_ARRAY_INCREMENT(c_ext->substmts);
     c_ext->substmts[9].stmt = LY_STMT_LIST;
     c_ext->substmts[9].cardinality = LY_STMT_CARD_ANY;
-    c_ext->substmts[9].storage = &struct_ext->child;
+    c_ext->substmts[9].storage = &struct_data->child;
 
     LY_ARRAY_INCREMENT(c_ext->substmts);
     c_ext->substmts[10].stmt = LY_STMT_CHOICE;
     c_ext->substmts[10].cardinality = LY_STMT_CARD_ANY;
-    c_ext->substmts[10].storage = &struct_ext->child;
+    c_ext->substmts[10].storage = &struct_data->child;
 
     LY_ARRAY_INCREMENT(c_ext->substmts);
     c_ext->substmts[11].stmt = LY_STMT_ANYDATA;
     c_ext->substmts[11].cardinality = LY_STMT_CARD_ANY;
-    c_ext->substmts[11].storage = &struct_ext->child;
+    c_ext->substmts[11].storage = &struct_data->child;
 
     LY_ARRAY_INCREMENT(c_ext->substmts);
     c_ext->substmts[12].stmt = LY_STMT_ANYXML;
     c_ext->substmts[12].cardinality = LY_STMT_CARD_ANY;
-    c_ext->substmts[12].storage = &struct_ext->child;
+    c_ext->substmts[12].storage = &struct_data->child;
 
     LY_ARRAY_INCREMENT(c_ext->substmts);
     c_ext->substmts[13].stmt = LY_STMT_USES;
     c_ext->substmts[13].cardinality = LY_STMT_CARD_ANY;
-    c_ext->substmts[13].storage = &struct_ext->child;
+    c_ext->substmts[13].storage = &struct_data->child;
 
     *lysc_ctx_get_options(cctx) |= LYS_COMPILE_NO_CONFIG | LYS_COMPILE_NO_DISABLED;
-    ret = lys_compile_extension_instance(cctx, p_ext, c_ext);
+    rc = lys_compile_extension_instance(cctx, p_ext, c_ext);
     *lysc_ctx_get_options(cctx) = prev_options;
-    if (ret) {
-        return ret;
+    if (rc) {
+        return rc;
+    }
+
+    return LY_SUCCESS;
+
+emem:
+    lyplg_ext_log(c_ext, LY_LLERR, LY_EMEM, lysc_ctx_get_path(cctx), "Memory allocation failed (%s()).", __func__);
+    return LY_EMEM;
+}
+
+/**
+ * @brief Compile augment-structure extension instances.
+ *
+ * Implementation of ::lyplg_ext_compile_clb callback set as lyext_plugin::compile.
+ */
+static LY_ERR
+structure_aug_compile(struct lysc_ctx *cctx, const struct lysp_ext_instance *p_ext, struct lysc_ext_instance *c_ext)
+{
+    LY_ERR rc;
+    struct lysp_stmt *stmt;
+    struct lysc_node *aug_target;
+    struct lysc_ext_instance *target_ext;
+    struct lysc_ext_instance_structure *target_data;
+    struct lysc_ext_instance_augment_structure *aug_data;
+    uint32_t prev_options = *lysc_ctx_get_options(cctx), i;
+
+    /* augment-structure can appear only at the top level of a YANG module or submodule */
+    if ((c_ext->parent_stmt != LY_STMT_MODULE) && (c_ext->parent_stmt != LY_STMT_SUBMODULE)) {
+        lyplg_ext_log(c_ext, LY_LLERR, LY_EVALID, lysc_ctx_get_path(cctx),
+                "Extension %s must not be used as a non top-level statement in \"%s\" statement.",
+                p_ext->name, ly_stmt2str(c_ext->parent_stmt));
+        return LY_EVALID;
+    }
+
+    /* augment-structure must define some data-def-stmt */
+    LY_LIST_FOR(p_ext->child, stmt) {
+        if (LY_STMT_IS_DATA_NODE(stmt->kw)) {
+            break;
+        }
+    }
+    if (!stmt) {
+        lyplg_ext_log(c_ext, LY_LLERR, LY_EVALID, lysc_ctx_get_path(cctx),
+                "Extension %s does not define any data-def-stmt statements.", p_ext->name);
+        return LY_EVALID;
+    }
+
+    /* find the target struct ext instance */
+    if ((rc = lys_compile_extension_instance_find_augment_target(cctx, p_ext->argument, &target_ext, &aug_target))) {
+        return rc;
+    }
+
+    /* check target_ext */
+    if (strcmp(target_ext->def->name, "structure") || strcmp(target_ext->def->module->name, "ietf-yang-structure-ext")) {
+        lyplg_ext_log(c_ext, LY_LLERR, LY_EVALID, lysc_ctx_get_path(cctx),
+                "Extension %s can only target extension instances of \"ietf-yang-structure-ext:structure\".", p_ext->name);
+        return LY_EVALID;
+    }
+    target_data = target_ext->data;
+
+    /* allocate the storage */
+    aug_data = calloc(1, sizeof *aug_data);
+    if (!aug_data) {
+        goto emem;
+    }
+    c_ext->data = aug_data;
+
+    /* compile substatements */
+    LY_ARRAY_CREATE_GOTO(cctx->ctx, c_ext->substmts, 12, rc, emem);
+    LY_ARRAY_INCREMENT(c_ext->substmts);
+    c_ext->substmts[0].stmt = LY_STMT_STATUS;
+    c_ext->substmts[0].cardinality = LY_STMT_CARD_OPT;
+    c_ext->substmts[0].storage = &aug_data->flags;
+
+    LY_ARRAY_INCREMENT(c_ext->substmts);
+    c_ext->substmts[1].stmt = LY_STMT_DESCRIPTION;
+    c_ext->substmts[1].cardinality = LY_STMT_CARD_OPT;
+    c_ext->substmts[1].storage = &aug_data->dsc;
+
+    LY_ARRAY_INCREMENT(c_ext->substmts);
+    c_ext->substmts[2].stmt = LY_STMT_REFERENCE;
+    c_ext->substmts[2].cardinality = LY_STMT_CARD_OPT;
+    c_ext->substmts[2].storage = &aug_data->ref;
+
+    /* data-def-stmt */
+    LY_ARRAY_INCREMENT(c_ext->substmts);
+    c_ext->substmts[3].stmt = LY_STMT_CONTAINER;
+    c_ext->substmts[3].cardinality = LY_STMT_CARD_ANY;
+    c_ext->substmts[3].storage = &target_data->child;
+
+    LY_ARRAY_INCREMENT(c_ext->substmts);
+    c_ext->substmts[4].stmt = LY_STMT_LEAF;
+    c_ext->substmts[4].cardinality = LY_STMT_CARD_ANY;
+    c_ext->substmts[4].storage = &target_data->child;
+
+    LY_ARRAY_INCREMENT(c_ext->substmts);
+    c_ext->substmts[5].stmt = LY_STMT_LEAF_LIST;
+    c_ext->substmts[5].cardinality = LY_STMT_CARD_ANY;
+    c_ext->substmts[5].storage = &target_data->child;
+
+    LY_ARRAY_INCREMENT(c_ext->substmts);
+    c_ext->substmts[6].stmt = LY_STMT_LIST;
+    c_ext->substmts[6].cardinality = LY_STMT_CARD_ANY;
+    c_ext->substmts[6].storage = &target_data->child;
+
+    LY_ARRAY_INCREMENT(c_ext->substmts);
+    c_ext->substmts[7].stmt = LY_STMT_CHOICE;
+    c_ext->substmts[7].cardinality = LY_STMT_CARD_ANY;
+    c_ext->substmts[7].storage = &target_data->child;
+
+    LY_ARRAY_INCREMENT(c_ext->substmts);
+    c_ext->substmts[8].stmt = LY_STMT_ANYDATA;
+    c_ext->substmts[8].cardinality = LY_STMT_CARD_ANY;
+    c_ext->substmts[8].storage = &target_data->child;
+
+    LY_ARRAY_INCREMENT(c_ext->substmts);
+    c_ext->substmts[9].stmt = LY_STMT_ANYXML;
+    c_ext->substmts[9].cardinality = LY_STMT_CARD_ANY;
+    c_ext->substmts[9].storage = &target_data->child;
+
+    LY_ARRAY_INCREMENT(c_ext->substmts);
+    c_ext->substmts[10].stmt = LY_STMT_USES;
+    c_ext->substmts[10].cardinality = LY_STMT_CARD_ANY;
+    c_ext->substmts[10].storage = &target_data->child;
+
+    /* case */
+    LY_ARRAY_INCREMENT(c_ext->substmts);
+    c_ext->substmts[11].stmt = LY_STMT_CASE;
+    c_ext->substmts[11].cardinality = LY_STMT_CARD_ANY;
+    c_ext->substmts[11].storage = &target_data->child;
+
+    *lysc_ctx_get_options(cctx) |= LYS_COMPILE_NO_CONFIG | LYS_COMPILE_NO_DISABLED;
+    rc = lys_compile_extension_instance_augment(cctx, p_ext, c_ext, aug_target);
+    *lysc_ctx_get_options(cctx) = prev_options;
+    if (rc) {
+        return rc;
+    }
+
+    /* data-def-statements are now part of the target extension (do not print nor free them) */
+    for (i = 0; i < 9; ++i) {
+        LY_ARRAY_DECREMENT(c_ext->substmts);
     }
 
     return LY_SUCCESS;
@@ -210,5 +356,18 @@
         .plugin.snode = NULL,
         .plugin.validate = NULL
     },
+    {
+        .module = "ietf-yang-structure-ext",
+        .revision = "2020-06-17",
+        .name = "augment-structure",
+
+        .plugin.id = "libyang 2 - structure, version 1",
+        .plugin.compile = structure_aug_compile,
+        .plugin.sprinter = structure_schema_printer,
+        .plugin.free = structure_free,
+        .plugin.node = NULL,
+        .plugin.snode = NULL,
+        .plugin.validate = NULL
+    },
     {0}     /* terminating zeroed record */
 };
diff --git a/src/plugins_exts_compile.h b/src/plugins_exts_compile.h
index 5925350..0fbe43b 100644
--- a/src/plugins_exts_compile.h
+++ b/src/plugins_exts_compile.h
@@ -111,7 +111,7 @@
  * supposed to use this function when the extension instance's substatements are supposed to be compiled in a standard way
  * (or if just the @ref scflags are enough to modify the compilation process).
  *
- * @param[in] ctx YANG schema compile context to track the compilation state.
+ * @param[in] ctx Compile context.
  * @param[in] ext_p Parsed representation of the extension instance being processed.
  * @param[in,out] ext Compiled extension instance with the prepared ::lysc_ext_instance.substmts array, which will be updated
  * by storing the compiled data.
@@ -123,6 +123,36 @@
         struct lysc_ext_instance *ext);
 
 /**
+ * @brief Compile substatements of an extension instance but append all schema data nodes as augments.
+ *
+ * Similar to ::lys_compile_extension_instance().
+ *
+ * @param[in] ctx Compile context.
+ * @param[in] ext_p Parsed representation of the extension instance being processed.
+ * @param[in,out] ext Compiled extension instance with the prepared ::lysc_ext_instance.substmts array, which will be updated
+ * by storing the compiled data except for schema data nodes.
+ * @param[in] aug_target Augment target node to append schema data nodes.
+ * @return LY_SUCCESS on success.
+ * @return LY_EVALID if compilation of the substatements fails.
+ * @return LY_ENOT if the extension is disabled (by if-feature) and should be ignored.
+ */
+LIBYANG_API_DECL LY_ERR lys_compile_extension_instance_augment(struct lysc_ctx *ctx, const struct lysp_ext_instance *ext_p,
+        struct lysc_ext_instance *ext, struct lysc_node *aug_target);
+
+/**
+ * @brief Find augment target in an extension.
+ *
+ * @param[in] ctx Compile context.
+ * @param[in] path Absolute-schema-nodeid representing the augment target. The first segment is expected to identify
+ * the specific extension instance.
+ * @param[out] aug_ext Optional augment target extension.
+ * @param[out] aug_target Augment target compiled schema node.
+ * @return LY_ERR value.
+ */
+LIBYANG_API_DECL LY_ERR lys_compile_extension_instance_find_augment_target(struct lysc_ctx *ctx, const char *path,
+        struct lysc_ext_instance **aug_ext, struct lysc_node **aug_target);
+
+/**
  * @brief Update path in the compile context, which is used for logging where the compilation failed.
  *
  * @param[in] ctx Compile context with the path.
diff --git a/src/schema_compile.c b/src/schema_compile.c
index 54428f8..8eb550f 100644
--- a/src/schema_compile.c
+++ b/src/schema_compile.c
@@ -507,11 +507,12 @@
  * @param[in] ext Compiled ext instance.
  * @param[in] substmt Compled ext instance substatement info.
  * @param[in] stmt Parsed statement to process.
+ * @param[in,out] aug_target Optional augment target where to append all schema data nodes.
  * @return LY_ERR value.
  */
 static LY_ERR
 lys_compile_ext_instance_stmt(struct lysc_ctx *ctx, const struct lysp_ext_instance *ext_p, struct lysc_ext_instance *ext,
-        struct lysc_ext_substmt *substmt, struct lysp_stmt *stmt)
+        struct lysc_ext_substmt *substmt, struct lysp_stmt *stmt, struct lysc_node *aug_target)
 {
     LY_ERR rc = LY_SUCCESS;
     struct lysf_ctx fctx = {.ctx = ctx->ctx};
@@ -549,8 +550,16 @@
         }
         *pnodes_p = pnode;
 
-        /* compile, ctx->ext substatement storage is used as the document root */
-        LY_CHECK_GOTO(rc = lys_compile_node(ctx, pnode, NULL, flags, NULL), cleanup);
+        if (aug_target) {
+            /* augment nodes */
+            ((struct lysp_ext_instance *)ext_p)->flags |= LYS_EXT_PARSED_AUGMENT;
+
+            /* compile augmented nodes */
+            LY_CHECK_GOTO(rc = lys_compile_augment_children(ctx, NULL, 0, pnode, aug_target, 0), cleanup);
+        } else {
+            /* compile nodes, ctx->ext substatement storage is used as the document root */
+            LY_CHECK_GOTO(rc = lys_compile_node(ctx, pnode, NULL, flags, NULL), cleanup);
+        }
         break;
     }
     case LY_STMT_GROUPING: {
@@ -700,8 +709,9 @@
     return rc;
 }
 
-LIBYANG_API_DEF LY_ERR
-lys_compile_extension_instance(struct lysc_ctx *ctx, const struct lysp_ext_instance *ext_p, struct lysc_ext_instance *ext)
+static LY_ERR
+lys_compile_extension_instance_(struct lysc_ctx *ctx, const struct lysp_ext_instance *ext_p, struct lysc_ext_instance *ext,
+        struct lysc_node *aug_target)
 {
     LY_ERR rc = LY_SUCCESS;
     LY_ARRAY_COUNT_TYPE u;
@@ -743,7 +753,7 @@
             }
 
             stmt_counter++;
-            if ((rc = lys_compile_ext_instance_stmt(ctx, ext_p, ext, &ext->substmts[u], stmt))) {
+            if ((rc = lys_compile_ext_instance_stmt(ctx, ext_p, ext, &ext->substmts[u], stmt, aug_target))) {
                 goto cleanup;
             }
         }
@@ -763,6 +773,23 @@
     return rc;
 }
 
+LIBYANG_API_DEF LY_ERR
+lys_compile_extension_instance(struct lysc_ctx *ctx, const struct lysp_ext_instance *ext_p, struct lysc_ext_instance *ext)
+{
+    LY_CHECK_ARG_RET(ctx ? ctx->ctx : NULL, ctx, ext_p, ext, LY_EINVAL);
+
+    return lys_compile_extension_instance_(ctx, ext_p, ext, NULL);
+}
+
+LIBYANG_API_DEF LY_ERR
+lys_compile_extension_instance_augment(struct lysc_ctx *ctx, const struct lysp_ext_instance *ext_p,
+        struct lysc_ext_instance *ext, struct lysc_node *aug_target)
+{
+    LY_CHECK_ARG_RET(ctx ? ctx->ctx : NULL, ctx, ext_p, ext, aug_target, LY_EINVAL);
+
+    return lys_compile_extension_instance_(ctx, ext_p, ext, aug_target);
+}
+
 /**
  * @brief Check when for cyclic dependencies.
  *
diff --git a/src/schema_compile_amend.c b/src/schema_compile_amend.c
index 66d2005..6876ea4 100644
--- a/src/schema_compile_amend.c
+++ b/src/schema_compile_amend.c
@@ -38,8 +38,48 @@
 #include "tree_schema_internal.h"
 #include "xpath.h"
 
-static const struct lys_module *lys_schema_node_get_module(const struct ly_ctx *ctx, const char *nametest,
-        size_t nametest_len, const struct lysp_module *mod, const char **name, size_t *name_len);
+/**
+ * @brief Get module of a single nodeid node name test.
+ *
+ * @param[in] ctx libyang context.
+ * @param[in] nametest Nametest with an optional prefix.
+ * @param[in] nametest_len Length of @p nametest.
+ * @param[in] mod Both current and prefix module for resolving prefixes and to return in case of no prefix.
+ * @param[out] name Optional pointer to the name test without the prefix.
+ * @param[out] name_len Length of @p name.
+ * @return Resolved module.
+ */
+static const struct lys_module *
+lys_schema_node_get_module(const struct ly_ctx *ctx, const char *nametest, size_t nametest_len,
+        const struct lysp_module *mod, const char **name, size_t *name_len)
+{
+    const struct lys_module *target_mod;
+    const char *ptr;
+
+    ptr = ly_strnchr(nametest, ':', nametest_len);
+    if (ptr) {
+        target_mod = ly_resolve_prefix(ctx, nametest, ptr - nametest, LY_VALUE_SCHEMA, (void *)mod);
+        if (!target_mod) {
+            LOGVAL(ctx, LYVE_REFERENCE,
+                    "Invalid absolute-schema-nodeid nametest \"%.*s\" - prefix \"%.*s\" not defined in module \"%s\".",
+                    (int)nametest_len, nametest, (int)(ptr - nametest), nametest, LYSP_MODULE_NAME(mod));
+            return NULL;
+        }
+
+        if (name) {
+            *name = ptr + 1;
+            *name_len = nametest_len - ((ptr - nametest) + 1);
+        }
+    } else {
+        target_mod = mod->mod;
+        if (name) {
+            *name = nametest;
+            *name_len = nametest_len;
+        }
+    }
+
+    return target_mod;
+}
 
 /**
  * @brief Check the syntax of a node-id and collect all the referenced modules.
@@ -1375,49 +1415,6 @@
 }
 
 /**
- * @brief Get module of a single nodeid node name test.
- *
- * @param[in] ctx libyang context.
- * @param[in] nametest Nametest with an optional prefix.
- * @param[in] nametest_len Length of @p nametest.
- * @param[in] mod Both current and prefix module for resolving prefixes and to return in case of no prefix.
- * @param[out] name Optional pointer to the name test without the prefix.
- * @param[out] name_len Length of @p name.
- * @return Resolved module.
- */
-static const struct lys_module *
-lys_schema_node_get_module(const struct ly_ctx *ctx, const char *nametest, size_t nametest_len,
-        const struct lysp_module *mod, const char **name, size_t *name_len)
-{
-    const struct lys_module *target_mod;
-    const char *ptr;
-
-    ptr = ly_strnchr(nametest, ':', nametest_len);
-    if (ptr) {
-        target_mod = ly_resolve_prefix(ctx, nametest, ptr - nametest, LY_VALUE_SCHEMA, (void *)mod);
-        if (!target_mod) {
-            LOGVAL(ctx, LYVE_REFERENCE,
-                    "Invalid absolute-schema-nodeid nametest \"%.*s\" - prefix \"%.*s\" not defined in module \"%s\".",
-                    (int)nametest_len, nametest, (int)(ptr - nametest), nametest, LYSP_MODULE_NAME(mod));
-            return NULL;
-        }
-
-        if (name) {
-            *name = ptr + 1;
-            *name_len = nametest_len - ((ptr - nametest) + 1);
-        }
-    } else {
-        target_mod = mod->mod;
-        if (name) {
-            *name = nametest;
-            *name_len = nametest_len;
-        }
-    }
-
-    return target_mod;
-}
-
-/**
  * @brief Check whether a compiled node matches a single schema nodeid name test.
  *
  * @param[in,out] node Compiled node to consider. On a match it is moved to its parent.
@@ -1732,19 +1729,8 @@
     return ret;
 }
 
-/**
- * @brief Compile augment children.
- *
- * @param[in] ctx Compile context.
- * @param[in] aug_p Parsed augment to compile.
- * @param[in] child First augment child to compile.
- * @param[in] target Target node of the augment.
- * @param[in] child_unres_disabled Whether the children are to be put into unres disabled set or not.
- * @return LY_SUCCESS on success.
- * @return LY_EVALID on failure.
- */
-static LY_ERR
-lys_compile_augment_children(struct lysc_ctx *ctx, struct lysp_node_augment *aug_p, struct lysp_node *child,
+LY_ERR
+lys_compile_augment_children(struct lysc_ctx *ctx, struct lysp_when *aug_when, uint16_t aug_flags, struct lysp_node *child,
         struct lysc_node *target, ly_bool child_unres_disabled)
 {
     LY_ERR rc = LY_SUCCESS;
@@ -1759,7 +1745,7 @@
      * - new cases augmenting some choice can have mandatory nodes
      * - mandatory nodes are allowed only in case the augmentation is made conditional with a when statement
      */
-    if (aug_p->when || (target->nodetype == LYS_CHOICE) || (ctx->cur_mod == target->module)) {
+    if (aug_when || (target->nodetype == LYS_CHOICE) || (ctx->cur_mod == target->module)) {
         allow_mand = 1;
     }
 
@@ -1809,9 +1795,9 @@
                 goto cleanup;
             }
 
-            if (aug_p->when) {
+            if (aug_when) {
                 /* pass augment's when to all the children */
-                rc = lys_compile_when(ctx, aug_p->when, aug_p->flags, target, lysc_data_node(target), node, &when_shared);
+                rc = lys_compile_when(ctx, aug_when, aug_flags, target, lysc_data_node(target), node, &when_shared);
                 LY_CHECK_GOTO(rc, cleanup);
             }
 
@@ -1878,14 +1864,17 @@
     }
 
     /* augment children */
-    LY_CHECK_GOTO(rc = lys_compile_augment_children(ctx, aug_p, aug_p->child, target, child_unres_disabled), cleanup);
+    rc = lys_compile_augment_children(ctx, aug_p->when, aug_p->flags, aug_p->child, target, child_unres_disabled);
+    LY_CHECK_GOTO(rc, cleanup);
 
     /* augment actions */
-    rc = lys_compile_augment_children(ctx, aug_p, (struct lysp_node *)aug_p->actions, target, child_unres_disabled);
+    rc = lys_compile_augment_children(ctx, aug_p->when, aug_p->flags, (struct lysp_node *)aug_p->actions, target,
+            child_unres_disabled);
     LY_CHECK_GOTO(rc, cleanup);
 
     /* augment notifications */
-    rc = lys_compile_augment_children(ctx, aug_p, (struct lysp_node *)aug_p->notifs, target, child_unres_disabled);
+    rc = lys_compile_augment_children(ctx, aug_p->when, aug_p->flags, (struct lysp_node *)aug_p->notifs, target,
+            child_unres_disabled);
     LY_CHECK_GOTO(rc, cleanup);
 
 cleanup:
@@ -2379,3 +2368,73 @@
         }
     }
 }
+
+LIBYANG_API_DEF LY_ERR
+lys_compile_extension_instance_find_augment_target(struct lysc_ctx *ctx, const char *path,
+        struct lysc_ext_instance **aug_ext, struct lysc_node **aug_target)
+{
+    LY_ERR rc;
+    LY_ARRAY_COUNT_TYPE u;
+    struct lys_module *target_mod;
+    struct lysc_ext_instance *target_ext = NULL, *prev_ext;
+    const struct lysc_node *target;
+    const char *id, *id2, *name;
+    size_t name_len;
+    uint16_t flag;
+
+    LY_CHECK_ARG_RET(ctx ? ctx->ctx : NULL, ctx, path, aug_target, LY_EINVAL);
+
+    /* skip first slash */
+    id = path;
+    if (id[0] != '/') {
+        LOGVAL(ctx->ctx, LYVE_SYNTAX, "Invalid absolute-schema-nodeid \"%s\".", path);
+        return LY_EVALID;
+    }
+    ++id;
+
+    /* find the next slash */
+    id2 = strchr(id, '/');
+    if (!id2) {
+        LOGVAL(ctx->ctx, LYVE_SYNTAX, "Invalid absolute-schema-nodeid \"%s\".", path);
+        return LY_EVALID;
+    }
+
+    /* find the target module */
+    target_mod = (struct lys_module *)lys_schema_node_get_module(ctx->ctx, id, id2 - id, ctx->pmod, &name, &name_len);
+    if (!target_mod) {
+        return LY_ENOTFOUND;
+    } else if (!target_mod->implemented) {
+        LOGVAL(ctx->ctx, LYVE_SEMANTICS, "Augment target extension instance \"%*.s\" in a non-implemented module \"%s\".",
+                (int)name_len, name, target_mod->name);
+        return LY_ENOTFOUND;
+    }
+
+    /* find the extension instance */
+    LY_ARRAY_FOR(target_mod->compiled->exts, u) {
+        if (!ly_strncmp(target_mod->compiled->exts[u].argument, name, name_len)) {
+            target_ext = &target_mod->compiled->exts[u];
+            break;
+        }
+    }
+    if (!target_ext) {
+        LOGVAL(ctx->ctx, LYVE_SEMANTICS, "Augment target extension instance \"%*.s\" not found in module \"%s\".",
+                (int)name_len, name, target_mod->name);
+        return LY_ENOTFOUND;
+    }
+
+    /* find the augment target with the correct compile context */
+    prev_ext = ctx->ext;
+    ctx->ext = target_ext;
+    rc = lysc_resolve_schema_nodeid(ctx, id2, strlen(id2), NULL, LY_VALUE_SCHEMA, ctx->pmod, 0, &target, &flag);
+    ctx->ext = prev_ext;
+    LY_CHECK_RET(rc);
+
+    /* add this module into the target module augmented_by, if not there */
+    lys_array_add_mod_ref(ctx, ctx->cur_mod, &target_mod->augmented_by);
+
+    if (aug_ext) {
+        *aug_ext = target_ext;
+    }
+    *aug_target = (struct lysc_node *)target;
+    return LY_SUCCESS;
+}
diff --git a/src/schema_compile_amend.h b/src/schema_compile_amend.h
index 581dfae..1e47c61 100644
--- a/src/schema_compile_amend.h
+++ b/src/schema_compile_amend.h
@@ -1,9 +1,10 @@
 /**
  * @file schema_compile_amend.h
  * @author Radek Krejci <rkrejci@cesnet.cz>
+ * @author Michal Vasko <mvasko@cesnet.cz>
  * @brief Header for schema compilation of augments, deviations, and refines.
  *
- * Copyright (c) 2015 - 2020 CESNET, z.s.p.o.
+ * Copyright (c) 2015 - 2022 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.
@@ -15,6 +16,8 @@
 #ifndef LY_SCHEMA_COMPILE_AMEND_H_
 #define LY_SCHEMA_COMPILE_AMEND_H_
 
+#include <stddef.h>
+
 #include "log.h"
 
 struct ly_ctx;
@@ -23,6 +26,7 @@
 struct lysc_node;
 struct lysc_ctx;
 struct lysp_node_uses;
+struct lysp_when;
 struct lys_glob_unres;
 struct lys_module;
 
@@ -131,6 +135,21 @@
         const struct lysc_node *parent, struct lysp_node **dev_pnode, ly_bool *not_supported);
 
 /**
+ * @brief Compile augment children.
+ *
+ * @param[in] ctx Compile context.
+ * @param[in] aug_when Parsed augment when to inherit.
+ * @param[in] aug_flags Parsed augment flags.
+ * @param[in] child First augment child to compile.
+ * @param[in] target Target node of the augment.
+ * @param[in] child_unres_disabled Whether the children are to be put into unres disabled set or not.
+ * @return LY_SUCCESS on success.
+ * @return LY_EVALID on failure.
+ */
+LY_ERR lys_compile_augment_children(struct lysc_ctx *ctx, struct lysp_when *aug_when, uint16_t aug_flags,
+        struct lysp_node *child, struct lysc_node *target, ly_bool child_unres_disabled);
+
+/**
  * @brief Compile and apply any precompiled top-level or uses augments targeting a node.
  *
  * @param[in] ctx Compile context.
diff --git a/src/schema_compile_node.c b/src/schema_compile_node.c
index 9263c95..10bcd22 100644
--- a/src/schema_compile_node.c
+++ b/src/schema_compile_node.c
@@ -1,9 +1,10 @@
 /**
  * @file schema_compile_node.c
  * @author Radek Krejci <rkrejci@cesnet.cz>
+ * @author Michal Vasko <mvasko@cesnet.cz>
  * @brief Schema compilation of common nodes.
  *
- * Copyright (c) 2015 - 2020 CESNET, z.s.p.o.
+ * Copyright (c) 2015 - 2022 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.
@@ -2985,25 +2986,7 @@
     return ret;
 }
 
-/**
- * @brief Find the node according to the given descendant/absolute schema nodeid.
- * Used in unique, refine and augment statements.
- *
- * @param[in] ctx Compile context
- * @param[in] nodeid Descendant-schema-nodeid (according to the YANG grammar)
- * @param[in] nodeid_len Length of the given nodeid, if it is not NULL-terminated string.
- * @param[in] ctx_node Context node for a relative nodeid.
- * @param[in] format Format of any prefixes.
- * @param[in] prefix_data Format-specific prefix data (see ::ly_resolve_prefix).
- * @param[in] nodetype Optional (can be 0) restriction for target's nodetype. If target exists, but does not match
- * the given nodetype, LY_EDENIED is returned (and target is provided), but no error message is printed.
- * The value can be even an ORed value to allow multiple nodetypes.
- * @param[out] target Found target node if any.
- * @param[out] result_flag Output parameter to announce if the schema nodeid goes through the action's input/output or a Notification.
- * The LYSC_OPT_RPC_INPUT, LYSC_OPT_RPC_OUTPUT and LYSC_OPT_NOTIFICATION are used as flags.
- * @return LY_ERR values - LY_ENOTFOUND, LY_EVALID, LY_EDENIED or LY_SUCCESS.
- */
-static LY_ERR
+LY_ERR
 lysc_resolve_schema_nodeid(struct lysc_ctx *ctx, const char *nodeid, size_t nodeid_len, const struct lysc_node *ctx_node,
         LY_VALUE_FORMAT format, void *prefix_data, uint16_t nodetype, const struct lysc_node **target, uint16_t *result_flag)
 {
@@ -3096,6 +3079,9 @@
                 /* only input or output is valid */
                 ctx_node = NULL;
             }
+        } else if (ctx->ext && !ctx_node) {
+            /* top-level extension nodes */
+            ctx_node = lysc_ext_find_node(ctx->ext, mod, name, name_len, 0, LYS_GETNEXT_WITHCHOICE | LYS_GETNEXT_WITHCASE);
         } else {
             ctx_node = lys_find_child(ctx_node, mod, name, name_len, 0,
                     getnext_extra_flag | LYS_GETNEXT_WITHCHOICE | LYS_GETNEXT_WITHCASE);
diff --git a/src/schema_compile_node.h b/src/schema_compile_node.h
index 3b1eb6b..d1f050d 100644
--- a/src/schema_compile_node.h
+++ b/src/schema_compile_node.h
@@ -95,6 +95,27 @@
         struct lysp_qname **dflt);
 
 /**
+ * @brief Find the node according to the given descendant/absolute schema nodeid.
+ * Used in unique, refine and augment statements.
+ *
+ * @param[in] ctx Compile context
+ * @param[in] nodeid Descendant-schema-nodeid (according to the YANG grammar)
+ * @param[in] nodeid_len Length of the given nodeid, if it is not NULL-terminated string.
+ * @param[in] ctx_node Context node for a relative nodeid.
+ * @param[in] format Format of any prefixes.
+ * @param[in] prefix_data Format-specific prefix data (see ::ly_resolve_prefix).
+ * @param[in] nodetype Optional (can be 0) restriction for target's nodetype. If target exists, but does not match
+ * the given nodetype, LY_EDENIED is returned (and target is provided), but no error message is printed.
+ * The value can be even an ORed value to allow multiple nodetypes.
+ * @param[out] target Found target node if any.
+ * @param[out] result_flag Output parameter to announce if the schema nodeid goes through the action's input/output or a Notification.
+ * The LYSC_OPT_RPC_INPUT, LYSC_OPT_RPC_OUTPUT and LYSC_OPT_NOTIFICATION are used as flags.
+ * @return LY_ERR values - LY_ENOTFOUND, LY_EVALID, LY_EDENIED or LY_SUCCESS.
+ */
+LY_ERR lysc_resolve_schema_nodeid(struct lysc_ctx *ctx, const char *nodeid, size_t nodeid_len, const struct lysc_node *ctx_node,
+        LY_VALUE_FORMAT format, void *prefix_data, uint16_t nodetype, const struct lysc_node **target, uint16_t *result_flag);
+
+/**
  * @brief Compile choice children.
  *
  * @param[in] ctx Compile context
diff --git a/src/tree_schema.h b/src/tree_schema.h
index 892bb81..c6d9eec 100644
--- a/src/tree_schema.h
+++ b/src/tree_schema.h
@@ -515,7 +515,7 @@
 struct lysp_stmt {
     const char *stmt;                /**< identifier of the statement */
     const char *arg;                 /**< statement's argument */
-    LY_VALUE_FORMAT format;         /**< prefix format of the identifier/argument (::LY_VALUE_XML is YIN format) */
+    LY_VALUE_FORMAT format;          /**< prefix format of the identifier/argument (::LY_VALUE_XML is YIN format) */
     void *prefix_data;               /**< Format-specific data for prefix resolution (see ly_resolve_prefix()) */
 
     struct lysp_stmt *next;          /**< link to the next statement */
@@ -775,56 +775,57 @@
  *     1 - container    6 - anydata/anyxml    11 - output       16 - grouping   21 - enum
  *     2 - choice       7 - case              12 - feature      17 - uses       22 - type
  *     3 - leaf         8 - notification      13 - identity     18 - refine     23 - stmt
- *     4 - leaflist     9 - rpc               14 - extension    19 - augment
+ *     4 - leaflist     9 - rpc               14 - extension    19 - augment    24 - extension instance
  *     5 - list        10 - input             15 - typedef      20 - deviate
  *
  *                                             1 1 1 1 1 1 1 1 1 1 2 2 2 2
  *     bit name              1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
- *     ---------------------+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *       1 LYS_CONFIG_W     |x|x|x|x|x|x| | | | | | | | | | | |x| |x| | | |
- *         LYS_SET_BASE     | | | | | | | | | | | | | | | | | | | | | |x| |
- *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *       2 LYS_CONFIG_R     |x|x|x|x|x|x| | | | | | | | | | | |x| |x| | | |
- *         LYS_SET_BIT      | | | | | | | | | | | | | | | | | | | | | |x| |
- *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *       3 LYS_STATUS_CURR  |x|x|x|x|x|x|x|x|x| | |x|x|x|x|x|x| |x|x|x| | |
- *         LYS_SET_ENUM     | | | | | | | | | | | | | | | | | | | | | |x| |
- *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *       4 LYS_STATUS_DEPRC |x|x|x|x|x|x|x|x|x| | |x|x|x|x|x|x| |x|x|x| | |
- *         LYS_SET_FRDIGITS | | | | | | | | | | | | | | | | | | | | | |x| |
- *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *       5 LYS_STATUS_OBSLT |x|x|x|x|x|x|x|x|x| | |x|x|x|x|x|x| |x|x|x| | |
- *         LYS_SET_LENGTH   | | | | | | | | | | | | | | | | | | | | | |x| |
- *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *       6 LYS_MAND_TRUE    | |x|x| | |x| | | | | | | | | | | |x| |x| | | |
- *         LYS_SET_PATH     | | | | | | | | | | | | | | | | | | | | | |x| |
- *         LYS_FENABLED     | | | | | | | | | | | |x| | | | | | | | | | | |
- *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *       7 LYS_MAND_FALSE   | |x|x| | |x| | | | | | | | | | | |x| |x| | | |
- *         LYS_ORDBY_USER   | | | |x|x| | | | | | | | | | | | | | | | | | |
- *         LYS_SET_PATTERN  | | | | | | | | | | | | | | | | | | | | | |x| |
- *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *       8 LYS_ORDBY_SYSTEM | | | |x|x| | | | | | | | | | | | | | | | | | |
- *         LYS_YINELEM_TRUE | | | | | | | | | | | | | |x| | | | | | | | | |
- *         LYS_SET_RANGE    | | | | | | | | | | | | | | | | | | | | | |x| |
- *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *       9 LYS_YINELEM_FALSE| | | | | | | | | | | | | |x| | | | | | | | | |
- *         LYS_SET_TYPE     | | | | | | | | | | | | | | | | | | | | | |x| |
- *         LYS_SINGLEQUOTED | | | | | | | | | | | | | | | | | | | | | | |x|
- *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *      10 LYS_SET_VALUE    | | | | | | | | | | | | | | | | | | | | |x| | |
- *         LYS_SET_REQINST  | | | | | | | | | | | | | | | | | | | | | |x| |
- *         LYS_SET_MIN      | | | |x|x| | | | | | | | | | | | |x| |x| | | |
- *         LYS_DOUBLEQUOTED | | | | | | | | | | | | | | | | | | | | | | |x|
- *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *      11 LYS_SET_MAX      | | | |x|x| | | | | | | | | | | | |x| |x| | | |
- *         LYS_USED_GRP     | | | | | | | | | | | | | | | |x| | | | | | | |
- *         LYS_YIN_ATTR     | | | | | | | | | | | | | | | | | | | | | | |x|
- *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *      12 LYS_YIN_ARGUMENT | | | | | | | | | | | | | | | | | | | | | | |x|
- *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *      13 LYS_INTERNAL     |x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|
- *     ---------------------+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *     ---------------------+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *       1 LYS_CONFIG_W     |x|x|x|x|x|x| | | | | | | | | | | |x| |x| | | | |
+ *         LYS_SET_BASE     | | | | | | | | | | | | | | | | | | | | | |x| | |
+ *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *       2 LYS_CONFIG_R     |x|x|x|x|x|x| | | | | | | | | | | |x| |x| | | | |
+ *         LYS_SET_BIT      | | | | | | | | | | | | | | | | | | | | | |x| | |
+ *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *       3 LYS_STATUS_CURR  |x|x|x|x|x|x|x|x|x| | |x|x|x|x|x|x| |x|x|x| | | |
+ *         LYS_SET_ENUM     | | | | | | | | | | | | | | | | | | | | | |x| | |
+ *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *       4 LYS_STATUS_DEPRC |x|x|x|x|x|x|x|x|x| | |x|x|x|x|x|x| |x|x|x| | | |
+ *         LYS_SET_FRDIGITS | | | | | | | | | | | | | | | | | | | | | |x| | |
+ *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *       5 LYS_STATUS_OBSLT |x|x|x|x|x|x|x|x|x| | |x|x|x|x|x|x| |x|x|x| | | |
+ *         LYS_SET_LENGTH   | | | | | | | | | | | | | | | | | | | | | |x| | |
+ *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *       6 LYS_MAND_TRUE    | |x|x| | |x| | | | | | | | | | | |x| |x| | | | |
+ *         LYS_SET_PATH     | | | | | | | | | | | | | | | | | | | | | |x| | |
+ *         LYS_FENABLED     | | | | | | | | | | | |x| | | | | | | | | | | | |
+ *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *       7 LYS_MAND_FALSE   | |x|x| | |x| | | | | | | | | | | |x| |x| | | | |
+ *         LYS_ORDBY_USER   | | | |x|x| | | | | | | | | | | | | | | | | | | |
+ *         LYS_SET_PATTERN  | | | | | | | | | | | | | | | | | | | | | |x| | |
+ *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *       8 LYS_ORDBY_SYSTEM | | | |x|x| | | | | | | | | | | | | | | | | | | |
+ *         LYS_YINELEM_TRUE | | | | | | | | | | | | | |x| | | | | | | | | | |
+ *         LYS_SET_RANGE    | | | | | | | | | | | | | | | | | | | | | |x| | |
+ *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *       9 LYS_YINELEM_FALSE| | | | | | | | | | | | | |x| | | | | | | | | | |
+ *         LYS_SET_TYPE     | | | | | | | | | | | | | | | | | | | | | |x| | |
+ *         LYS_SINGLEQUOTED | | | | | | | | | | | | | | | | | | | | | | |x| |
+ *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *      10 LYS_SET_VALUE    | | | | | | | | | | | | | | | | | | | | |x| | | |
+ *         LYS_SET_REQINST  | | | | | | | | | | | | | | | | | | | | | |x| | |
+ *         LYS_SET_MIN      | | | |x|x| | | | | | | | | | | | |x| |x| | | | |
+ *         LYS_DOUBLEQUOTED | | | | | | | | | | | | | | | | | | | | | | |x| |
+ *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *      11 LYS_SET_MAX      | | | |x|x| | | | | | | | | | | | |x| |x| | | | |
+ *         LYS_USED_GRP     | | | | | | | | | | | | | | | |x| | | | | | | | |
+ *         LYS_YIN_ATTR     | | | | | | | | | | | | | | | | | | | | | | |x| |
+ *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *      12 LYS_YIN_ARGUMENT | | | | | | | | | | | | | | | | | | | | | | |x| |
+ *   LYS_EXT_PARSED_AUGMENT | | | | | | | | | | | | | | | | | | | | | | | |x|
+ *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *      13 LYS_INTERNAL     |x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|
+ *     ---------------------+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  *
  */
 
@@ -951,6 +952,7 @@
 
 #define LYS_YIN_ATTR     0x0400      /**< flag to identify YIN attribute parsed as extension's substatement, only when the source is YIN */
 #define LYS_YIN_ARGUMENT 0x0800      /**< flag to identify statement representing extension's argument, only when the source is YIN */
+#define LYS_EXT_PARSED_AUGMENT 0x0800   /**< flag to mark an extension instance whose parsed nodes are augment nodes */
 
 #define LYS_INTERNAL     0x1000      /**< flag to identify internal parsed statements that should not be printed */