data FEATURE support extension's data parsing
Make the data parsers to support parsing data corresponding to a
separate schema tree specified in an extension instance.
diff --git a/src/parser_json.c b/src/parser_json.c
index 37b7e68..d64745e 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -26,6 +26,7 @@
#include "json.h"
#include "log.h"
#include "parser_internal.h"
+#include "plugins_exts.h"
#include "set.h"
#include "tree.h"
#include "tree_data.h"
@@ -40,6 +41,7 @@
* Note that the structure maps to the lyd_ctx which is common for all the data parsers
*/
struct lyd_json_ctx {
+ const struct lysc_ext_instance *ext; /**< extension instance possibly changing document root context of the data being parsed */
uint32_t parse_opts; /**< various @ref dataparseroptions. */
uint32_t val_opts; /**< various @ref datavalidationoptions. */
uint32_t int_opts; /**< internal data parser options */
@@ -227,11 +229,25 @@
/* get the schema node */
if (mod && (!parent || parent->schema)) {
- *snode_p = lys_find_child(parent ? parent->schema : NULL, mod, name, name_len, 0, getnext_opts);
+ if (!parent && lydctx->ext) {
+ *snode_p = lys_find_ext_instance_node(lydctx->ext, mod, name, name_len, 0, getnext_opts);
+ } else {
+ *snode_p = lys_find_child(parent ? parent->schema : NULL, mod, name, name_len, 0, getnext_opts);
+ }
if (!*snode_p) {
if (lydctx->parse_opts & LYD_PARSE_STRICT) {
- LOGVAL(lydctx->jsonctx->ctx, LYVE_REFERENCE, "Node \"%.*s\" not found in the \"%s\" module.",
- name_len, name, mod->name);
+ if (lydctx->ext) {
+ if (lydctx->ext->argument) {
+ LOGVAL(lydctx->jsonctx->ctx, LYVE_REFERENCE, "Node \"%.*s\" not found in the \"%s\" %s extension instance.",
+ name_len, name, lydctx->ext->argument, lydctx->ext->def->name);
+ } else {
+ LOGVAL(lydctx->jsonctx->ctx, LYVE_REFERENCE, "Node \"%.*s\" not found in the %s extension instance.",
+ name_len, name, lydctx->ext->def->name);
+ }
+ } else {
+ LOGVAL(lydctx->jsonctx->ctx, LYVE_REFERENCE, "Node \"%.*s\" not found in the \"%s\" module.",
+ name_len, name, mod->name);
+ }
ret = LY_EVALID;
goto cleanup;
} else if (!(lydctx->parse_opts & LYD_PARSE_OPAQ)) {
@@ -1369,8 +1385,9 @@
}
LY_ERR
-lyd_parse_json(const struct ly_ctx *ctx, struct lyd_node *parent, struct lyd_node **first_p, struct ly_in *in,
- uint32_t parse_opts, uint32_t val_opts, enum lyd_type data_type, struct ly_set *parsed, struct lyd_ctx **lydctx_p)
+lyd_parse_json(const struct ly_ctx *ctx, const struct lysc_ext_instance *ext, struct lyd_node *parent,
+ struct lyd_node **first_p, struct ly_in *in, uint32_t parse_opts, uint32_t val_opts, enum lyd_type data_type,
+ struct ly_set *parsed, struct lyd_ctx **lydctx_p)
{
LY_ERR rc = LY_SUCCESS;
struct lyd_json_ctx *lydctx = NULL;
@@ -1401,6 +1418,7 @@
goto cleanup;
}
lydctx->int_opts = int_opts;
+ lydctx->ext = ext;
/* find the operation node if it exists already */
LY_CHECK_GOTO(rc = lyd_parser_find_operation(parent, int_opts, &lydctx->op_node), cleanup);