schema tree FEATURE add internal standard module metadata
diff --git a/src/schema_compile.c b/src/schema_compile.c
index 3dcc175..0a44157 100644
--- a/src/schema_compile.c
+++ b/src/schema_compile.c
@@ -1139,54 +1139,6 @@
return LY_SUCCESS;
}
-static LY_ERR
-lys_compile_ietf_netconf_wd_annotation(struct lysc_ctx *ctx, struct lys_module *mod)
-{
- struct lysc_ext_instance *ext;
- struct lysp_ext_instance *ext_p = NULL;
- struct lysp_stmt *stmt;
- const struct lys_module *ext_mod;
- LY_ERR ret = LY_SUCCESS;
-
- /* create the parsed extension instance manually */
- ext_p = calloc(1, sizeof *ext_p);
- LY_CHECK_ERR_GOTO(!ext_p, LOGMEM(ctx->ctx); ret = LY_EMEM, cleanup);
- LY_CHECK_GOTO(ret = lydict_insert(ctx->ctx, "md:annotation", 0, &ext_p->name), cleanup);
- LY_CHECK_GOTO(ret = lydict_insert(ctx->ctx, "default", 0, &ext_p->argument), cleanup);
- ext_p->insubstmt = LYEXT_SUBSTMT_SELF;
- ext_p->insubstmt_index = 0;
-
- ext_p->child = stmt = calloc(1, sizeof *ext_p->child);
- LY_CHECK_ERR_GOTO(!stmt, LOGMEM(ctx->ctx); ret = LY_EMEM, cleanup);
- LY_CHECK_GOTO(ret = lydict_insert(ctx->ctx, "type", 0, &stmt->stmt), cleanup);
- LY_CHECK_GOTO(ret = lydict_insert(ctx->ctx, "boolean", 0, &stmt->arg), cleanup);
- stmt->kw = LY_STMT_TYPE;
-
- /* allocate new extension instance */
- LY_ARRAY_NEW_GOTO(mod->ctx, mod->compiled->exts, ext, ret, cleanup);
-
- /* manually get extension definition module */
- ext_mod = ly_ctx_get_module_latest(ctx->ctx, "ietf-yang-metadata");
-
- /* compile the extension instance */
- ret = lys_compile_ext(ctx, ext_p, ext, mod->compiled, LYEXT_PAR_MODULE, ext_mod);
- if (ret == LY_ENOT) {
- /* free the extension */
- lysc_ext_instance_free(ctx->ctx, ext);
- LY_ARRAY_DECREMENT_FREE(mod->compiled->exts);
-
- ret = LY_SUCCESS;
- goto cleanup;
- } else if (ret) {
- goto cleanup;
- }
-
-cleanup:
- lysp_ext_instance_free(ctx->ctx, ext_p);
- free(ext_p);
- return ret;
-}
-
/**
* @brief Compile default value(s) for leaf or leaf-list expecting a complete compiled schema tree.
*
@@ -1726,24 +1678,6 @@
}
ctx.pmod = sp;
-#if 0
- /* hack for NETCONF's edit-config's operation attribute. It is not defined in the schema, but since libyang
- * implements YANG metadata (annotations), we need its definition. Because the ietf-netconf schema is not the
- * internal part of libyang, we cannot add the annotation into the schema source, but we do it here to have
- * the anotation definitions available in the internal schema structure. */
- if (ly_strequal(mod->name, "ietf-netconf", 0)) {
- if (lyp_add_ietf_netconf_annotations(mod)) {
- lys_free(mod, NULL, 1, 1);
- return NULL;
- }
- }
-#endif
-
- /* add ietf-netconf-with-defaults "default" metadata to the compiled module */
- if (!strcmp(mod->name, "ietf-netconf-with-defaults")) {
- LY_CHECK_GOTO(ret = lys_compile_ietf_netconf_wd_annotation(&ctx, mod), error);
- }
-
/* there can be no leftover deviations or augments */
LY_CHECK_ERR_GOTO(ctx.augs.count, LOGINT(ctx.ctx); ret = LY_EINT, error);
LY_CHECK_ERR_GOTO(ctx.devs.count, LOGINT(ctx.ctx); ret = LY_EINT, error);
diff --git a/src/tree_schema.c b/src/tree_schema.c
index 4ba3827..e933995 100644
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -778,6 +778,187 @@
return ret;
}
+/**
+ * @brief Add ietf-netconf metadata to the parsed module. Operation, filter, and select are added.
+ *
+ * @param[in] mod Parsed module to add to.
+ * @return LY_SUCCESS on success.
+ * @return LY_ERR on error.
+ */
+static LY_ERR
+lys_parsed_add_internal_ietf_netconf(struct lysp_module *mod)
+{
+ struct lysp_ext_instance *ext_p;
+ struct lysp_stmt *stmt;
+ struct lysp_import *imp;
+
+ /*
+ * 1) edit-config's operation
+ */
+ LY_ARRAY_NEW_RET(mod->mod->ctx, mod->exts, ext_p, LY_EMEM);
+ LY_CHECK_ERR_RET(!ext_p, LOGMEM(mod->mod->ctx), LY_EMEM);
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "md_:annotation", 0, &ext_p->name));
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "operation", 0, &ext_p->argument));
+ ext_p->flags = LYS_INTERNAL;
+ ext_p->insubstmt = LYEXT_SUBSTMT_SELF;
+ ext_p->insubstmt_index = 0;
+
+ ext_p->child = stmt = calloc(1, sizeof *ext_p->child);
+ LY_CHECK_ERR_RET(!stmt, LOGMEM(mod->mod->ctx), LY_EMEM);
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "type", 0, &stmt->stmt));
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "enumeration", 0, &stmt->arg));
+ stmt->kw = LY_STMT_TYPE;
+
+ stmt->child = calloc(1, sizeof *stmt->child);
+ stmt = stmt->child;
+ LY_CHECK_ERR_RET(!stmt, LOGMEM(mod->mod->ctx), LY_EMEM);
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "enum", 0, &stmt->stmt));
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "merge", 0, &stmt->arg));
+ stmt->kw = LY_STMT_ENUM;
+
+ stmt->next = calloc(1, sizeof *stmt->child);
+ stmt = stmt->next;
+ LY_CHECK_ERR_RET(!stmt, LOGMEM(mod->mod->ctx), LY_EMEM);
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "enum", 0, &stmt->stmt));
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "replace", 0, &stmt->arg));
+ stmt->kw = LY_STMT_ENUM;
+
+ stmt->next = calloc(1, sizeof *stmt->child);
+ stmt = stmt->next;
+ LY_CHECK_ERR_RET(!stmt, LOGMEM(mod->mod->ctx), LY_EMEM);
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "enum", 0, &stmt->stmt));
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "create", 0, &stmt->arg));
+ stmt->kw = LY_STMT_ENUM;
+
+ stmt->next = calloc(1, sizeof *stmt->child);
+ stmt = stmt->next;
+ LY_CHECK_ERR_RET(!stmt, LOGMEM(mod->mod->ctx), LY_EMEM);
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "enum", 0, &stmt->stmt));
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "delete", 0, &stmt->arg));
+ stmt->kw = LY_STMT_ENUM;
+
+ stmt->next = calloc(1, sizeof *stmt->child);
+ stmt = stmt->next;
+ LY_CHECK_ERR_RET(!stmt, LOGMEM(mod->mod->ctx), LY_EMEM);
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "enum", 0, &stmt->stmt));
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "remove", 0, &stmt->arg));
+ stmt->kw = LY_STMT_ENUM;
+
+ /*
+ * 2) filter's type
+ */
+ LY_ARRAY_NEW_RET(mod->mod->ctx, mod->exts, ext_p, LY_EMEM);
+ LY_CHECK_ERR_RET(!ext_p, LOGMEM(mod->mod->ctx), LY_EMEM);
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "md_:annotation", 0, &ext_p->name));
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "type", 0, &ext_p->argument));
+ ext_p->flags = LYS_INTERNAL;
+ ext_p->insubstmt = LYEXT_SUBSTMT_SELF;
+ ext_p->insubstmt_index = 0;
+
+ ext_p->child = stmt = calloc(1, sizeof *ext_p->child);
+ LY_CHECK_ERR_RET(!stmt, LOGMEM(mod->mod->ctx), LY_EMEM);
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "type", 0, &stmt->stmt));
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "enumeration", 0, &stmt->arg));
+ stmt->kw = LY_STMT_TYPE;
+
+ stmt->child = calloc(1, sizeof *stmt->child);
+ stmt = stmt->child;
+ LY_CHECK_ERR_RET(!stmt, LOGMEM(mod->mod->ctx), LY_EMEM);
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "enum", 0, &stmt->stmt));
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "subtree", 0, &stmt->arg));
+ stmt->kw = LY_STMT_ENUM;
+
+ stmt->next = calloc(1, sizeof *stmt->child);
+ stmt = stmt->next;
+ LY_CHECK_ERR_RET(!stmt, LOGMEM(mod->mod->ctx), LY_EMEM);
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "enum", 0, &stmt->stmt));
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "xpath", 0, &stmt->arg));
+ stmt->kw = LY_STMT_ENUM;
+
+ /* if-feature for enum allowed only for YANG 1.1 modules */
+ if (mod->version >= LYS_VERSION_1_1) {
+ stmt->child = calloc(1, sizeof *stmt->child);
+ stmt = stmt->child;
+ LY_CHECK_ERR_RET(!stmt, LOGMEM(mod->mod->ctx), LY_EMEM);
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "if-feature", 0, &stmt->stmt));
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "xpath", 0, &stmt->arg));
+ stmt->kw = LY_STMT_IF_FEATURE;
+ }
+
+ /*
+ * 3) filter's select
+ */
+ LY_ARRAY_NEW_RET(mod->mod->ctx, mod->exts, ext_p, LY_EMEM);
+ LY_CHECK_ERR_RET(!ext_p, LOGMEM(mod->mod->ctx), LY_EMEM);
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "md_:annotation", 0, &ext_p->name));
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "select", 0, &ext_p->argument));
+ ext_p->flags = LYS_INTERNAL;
+ ext_p->insubstmt = LYEXT_SUBSTMT_SELF;
+ ext_p->insubstmt_index = 0;
+
+ ext_p->child = stmt = calloc(1, sizeof *ext_p->child);
+ LY_CHECK_ERR_RET(!stmt, LOGMEM(mod->mod->ctx), LY_EMEM);
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "type", 0, &stmt->stmt));
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "yang_:xpath1.0", 0, &stmt->arg));
+ stmt->kw = LY_STMT_TYPE;
+
+ /* create new imports for the used prefixes */
+ LY_ARRAY_NEW_RET(mod->mod->ctx, mod->imports, imp, LY_EMEM);
+
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "ietf-yang-metadata", 0, &imp->name));
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "md_", 0, &imp->prefix));
+ imp->flags = LYS_INTERNAL;
+
+ LY_ARRAY_NEW_RET(mod->mod->ctx, mod->imports, imp, LY_EMEM);
+
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "ietf-yang-types", 0, &imp->name));
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "yang_", 0, &imp->prefix));
+ imp->flags = LYS_INTERNAL;
+
+ return LY_SUCCESS;
+}
+
+/**
+ * @brief Add ietf-netconf-with-defaults "default" metadata to the parsed module.
+ *
+ * @param[in] mod Parsed module to add to.
+ * @return LY_SUCCESS on success.
+ * @return LY_ERR on error.
+ */
+static LY_ERR
+lys_parsed_add_internal_ietf_netconf_with_defaults(struct lysp_module *mod)
+{
+ struct lysp_ext_instance *ext_p;
+ struct lysp_stmt *stmt;
+ struct lysp_import *imp;
+
+ /* add new extension instance */
+ LY_ARRAY_NEW_RET(mod->mod->ctx, mod->exts, ext_p, LY_EMEM);
+
+ /* fill in the extension instance fields */
+ LY_CHECK_ERR_RET(!ext_p, LOGMEM(mod->mod->ctx), LY_EMEM);
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "md_:annotation", 0, &ext_p->name));
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "default", 0, &ext_p->argument));
+ ext_p->flags = LYS_INTERNAL;
+ ext_p->insubstmt = LYEXT_SUBSTMT_SELF;
+ ext_p->insubstmt_index = 0;
+
+ ext_p->child = stmt = calloc(1, sizeof *ext_p->child);
+ LY_CHECK_ERR_RET(!stmt, LOGMEM(mod->mod->ctx), LY_EMEM);
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "type", 0, &stmt->stmt));
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "boolean", 0, &stmt->arg));
+ stmt->kw = LY_STMT_TYPE;
+
+ /* create new import for the used prefix */
+ LY_ARRAY_NEW_RET(mod->mod->ctx, mod->imports, imp, LY_EMEM);
+
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "ietf-yang-metadata", 0, &imp->name));
+ LY_CHECK_RET(lydict_insert(mod->mod->ctx, "md_", 0, &imp->prefix));
+ imp->flags = LYS_INTERNAL;
+
+ return LY_SUCCESS;
+}
+
LY_ERR
lys_create_module(struct ly_ctx *ctx, struct ly_in *in, LYS_INFORMAT format, ly_bool implement,
LY_ERR (*custom_check)(const struct ly_ctx *ctx, struct lysp_module *mod, struct lysp_submodule *submod, void *data),
@@ -911,6 +1092,13 @@
latest->latest_revision = 0;
}
+ /* add internal data in case specific modules were parsed */
+ if (!strcmp(mod->name, "ietf-netconf")) {
+ LY_CHECK_GOTO(ret = lys_parsed_add_internal_ietf_netconf(mod->parsed), error);
+ } else if (!strcmp(mod->name, "ietf-netconf-with-defaults")) {
+ LY_CHECK_GOTO(ret = lys_parsed_add_internal_ietf_netconf_with_defaults(mod->parsed), error);
+ }
+
/* add into context */
ret = ly_set_add(&ctx->list, mod, 1, NULL);
LY_CHECK_GOTO(ret, error);