Skip to content

Commit 58838ec

Browse files
committed
structure UPDATE top-level augment support
Required plugins ext API change. Fixes #2430
1 parent ef60310 commit 58838ec

File tree

8 files changed

+125
-121
lines changed

8 files changed

+125
-121
lines changed

src/plugins_exts.c

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -77,18 +77,43 @@ lyplg_ext_parse_extension_instance(struct lysp_ctx *pctx, struct lysp_ext_instan
7777
return rc;
7878
}
7979

80+
LIBYANG_API_DEF struct ly_ctx *
81+
lyplg_ext_compile_get_ctx(const struct lysc_ctx *ctx)
82+
{
83+
return ctx->ctx;
84+
}
85+
86+
LIBYANG_API_DEF uint32_t *
87+
lyplg_ext_compile_get_options(const struct lysc_ctx *ctx)
88+
{
89+
return &((struct lysc_ctx *)ctx)->compile_opts;
90+
}
91+
92+
LIBYANG_API_DEF const struct lys_module *
93+
lyplg_ext_compile_get_cur_mod(const struct lysc_ctx *ctx)
94+
{
95+
return ctx->cur_mod;
96+
}
97+
98+
LIBYANG_API_DEF struct lysp_module *
99+
lyplg_ext_compile_get_pmod(const struct lysc_ctx *ctx)
100+
{
101+
return ctx->pmod;
102+
}
103+
80104
/**
81105
* @brief Compile an instance extension statement.
82106
*
83107
* @param[in] ctx Compile context.
84108
* @param[in] parsed_p Parsed ext instance substatement structure.
85109
* @param[in] ext Compiled ext instance.
110+
* @param[in] parent Optional parent of all the compiled schema nodes.
86111
* @param[in] substmt Compled ext instance substatement info.
87112
* @return LY_ERR value.
88113
*/
89114
static LY_ERR
90115
lys_compile_ext_instance_stmt(struct lysc_ctx *ctx, void **parsed_p, struct lysc_ext_instance *ext,
91-
struct lysc_ext_substmt *substmt)
116+
struct lysc_node *parent, struct lysc_ext_substmt *substmt)
92117
{
93118
LY_ERR rc = LY_SUCCESS;
94119
ly_bool length_restr = 0;
@@ -144,8 +169,8 @@ lys_compile_ext_instance_stmt(struct lysc_ctx *ctx, void **parsed_p, struct lysc
144169
LY_CHECK_GOTO(rc = lys_compile_node_action_inout(ctx, pnode, node), cleanup);
145170
LY_CHECK_GOTO(rc = lys_compile_node_connect(ctx, NULL, node), cleanup);
146171
} else {
147-
/* ctx->ext substatement storage is used as the document root */
148-
LY_CHECK_GOTO(rc = lys_compile_node(ctx, pnode, NULL, flags, NULL), cleanup);
172+
/* if parent is NULL, ctx->ext substatement storage is used as the document root */
173+
LY_CHECK_GOTO(rc = lys_compile_node(ctx, pnode, parent, flags, NULL), cleanup);
149174
}
150175
}
151176
break;
@@ -325,7 +350,7 @@ lys_compile_ext_instance_stmt(struct lysc_ctx *ctx, void **parsed_p, struct lysc
325350

326351
LIBYANG_API_DEF LY_ERR
327352
lyplg_ext_compile_extension_instance(struct lysc_ctx *ctx, const struct lysp_ext_instance *extp,
328-
struct lysc_ext_instance *ext)
353+
struct lysc_ext_instance *ext, struct lysc_node *parent)
329354
{
330355
LY_ERR rc = LY_SUCCESS;
331356
LY_ARRAY_COUNT_TYPE u, v;
@@ -352,7 +377,7 @@ lyplg_ext_compile_extension_instance(struct lysc_ctx *ctx, const struct lysp_ext
352377
continue;
353378
}
354379

355-
if ((rc = lys_compile_ext_instance_stmt(ctx, storagep, ext, &ext->substmts[v]))) {
380+
if ((rc = lys_compile_ext_instance_stmt(ctx, storagep, ext, parent, &ext->substmts[v]))) {
356381
goto cleanup;
357382
}
358383

@@ -370,28 +395,24 @@ lyplg_ext_compile_extension_instance(struct lysc_ctx *ctx, const struct lysp_ext
370395
return rc;
371396
}
372397

373-
LIBYANG_API_DEF struct ly_ctx *
374-
lyplg_ext_compile_get_ctx(const struct lysc_ctx *ctx)
398+
LIBYANG_API_DEF LY_ERR
399+
lyplg_ext_compiled_node_augments(struct lysc_ctx *ctx, struct lysc_ext_instance *ext, struct lysc_node *node)
375400
{
376-
return ctx->ctx;
377-
}
401+
LY_ERR rc = LY_SUCCESS;
378402

379-
LIBYANG_API_DEF uint32_t *
380-
lyplg_ext_compile_get_options(const struct lysc_ctx *ctx)
381-
{
382-
return &((struct lysc_ctx *)ctx)->compile_opts;
383-
}
403+
LY_CHECK_ARG_RET(ctx ? ctx->ctx : NULL, ctx, ext, node, LY_EINVAL);
384404

385-
LIBYANG_API_DEF const struct lys_module *
386-
lyplg_ext_compile_get_cur_mod(const struct lysc_ctx *ctx)
387-
{
388-
return ctx->cur_mod;
389-
}
405+
assert(!ctx->ext);
390406

391-
LIBYANG_API_DEF struct lysp_module *
392-
lyplg_ext_compile_get_pmod(const struct lysc_ctx *ctx)
393-
{
394-
return ctx->pmod;
407+
/* note into the compile context that we are processing extension now */
408+
ctx->ext = ext;
409+
410+
/* connect any augments */
411+
LY_CHECK_GOTO(rc = lys_compile_node_augments(ctx, node), cleanup);
412+
413+
cleanup:
414+
ctx->ext = NULL;
415+
return rc;
395416
}
396417

397418
LIBYANG_API_DEF struct ly_out **

src/plugins_exts.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ extern "C" {
109109
/**
110110
* @brief Extensions API version
111111
*/
112-
#define LYPLG_EXT_API_VERSION 9
112+
#define LYPLG_EXT_API_VERSION 10
113113

114114
/**
115115
* @brief Mask for an operation statement.
@@ -644,12 +644,27 @@ LIBYANG_API_DECL struct lysp_module *lyplg_ext_compile_get_pmod(const struct lys
644644
* @param[in] extp Parsed representation of the extension instance being processed.
645645
* @param[in,out] ext Compiled extension instance with the prepared ::lysc_ext_instance.substmts array, which will be updated
646646
* by storing the compiled data.
647+
* @param[in] parent Optional parent of all the compiled schema nodes.
647648
* @return LY_SUCCESS on success.
648649
* @return LY_EVALID if compilation of the substatements fails.
649650
* @return LY_ENOT if the extension is disabled (by if-feature) and should be ignored.
650651
*/
651652
LIBYANG_API_DECL LY_ERR lyplg_ext_compile_extension_instance(struct lysc_ctx *ctx, const struct lysp_ext_instance *extp,
652-
struct lysc_ext_instance *ext);
653+
struct lysc_ext_instance *ext, struct lysc_node *parent);
654+
655+
/**
656+
* @brief Compile augments for a specific node in an extension instance.
657+
*
658+
* May be useful for cases when there are virtual nodes that cannot be compiled using
659+
* ::lyplg_ext_compile_extension_instance().
660+
*
661+
* @param[in] ctx Compile context.
662+
* @param[in] ext Compiled extension instance.
663+
* @param[in,out] node Compiled schema node to apply any matching augments for.
664+
* @return LY_ERR value.
665+
*/
666+
LIBYANG_API_DECL LY_ERR lyplg_ext_compiled_node_augments(struct lysc_ctx *ctx, struct lysc_ext_instance *ext,
667+
struct lysc_node *node);
653668

654669
/** @} pluginsExtensionsCompile */
655670

src/plugins_exts/metadata.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ annotation_compile(struct lysc_ctx *cctx, const struct lysp_ext_instance *extp,
162162
ext->substmts[5].stmt = LY_STMT_REFERENCE;
163163
ext->substmts[5].storage_p = (void **)&ann_cdata->ref;
164164

165-
ret = lyplg_ext_compile_extension_instance(cctx, extp, ext);
165+
ret = lyplg_ext_compile_extension_instance(cctx, extp, ext, NULL);
166166
return ret;
167167

168168
emem:

src/plugins_exts/structure.c

Lines changed: 44 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,6 @@ struct lysp_ext_instance_structure {
3535
};
3636

3737
struct lysc_ext_instance_structure {
38-
struct lysc_must *musts;
39-
uint16_t flags;
40-
const char *dsc;
41-
const char *ref;
42-
struct lysc_node *child;
4338
struct lysc_node_container *top_cont;
4439
};
4540

@@ -192,23 +187,34 @@ structure_compile(struct lysc_ctx *cctx, const struct lysp_ext_instance *extp, s
192187
}
193188
ext->compiled = struct_cdata;
194189

190+
/* add the top-level container with the extension instance name, connect all the other substatements into it */
191+
struct_cdata->top_cont = calloc(1, sizeof *struct_cdata->top_cont);
192+
if (!struct_cdata->top_cont) {
193+
goto emem;
194+
}
195+
196+
struct_cdata->top_cont->name = ext->argument;
197+
struct_cdata->top_cont->nodetype = LYS_CONTAINER;
198+
struct_cdata->top_cont->module = (struct lys_module *)lyplg_ext_compile_get_cur_mod(cctx);
199+
struct_cdata->top_cont->prev = &struct_cdata->top_cont->node;
200+
195201
/* compile substatements */
196202
LY_ARRAY_CREATE_GOTO(cctx->ctx, ext->substmts, 14, rc, emem);
197203
LY_ARRAY_INCREMENT(ext->substmts);
198204
ext->substmts[0].stmt = LY_STMT_MUST;
199-
ext->substmts[0].storage_p = (void **)&struct_cdata->musts;
205+
ext->substmts[0].storage_p = (void **)&struct_cdata->top_cont->musts;
200206

201207
LY_ARRAY_INCREMENT(ext->substmts);
202208
ext->substmts[1].stmt = LY_STMT_STATUS;
203-
ext->substmts[1].storage_p = (void **)&struct_cdata->flags;
209+
ext->substmts[1].storage_p = (void **)&struct_cdata->top_cont->flags;
204210

205211
LY_ARRAY_INCREMENT(ext->substmts);
206212
ext->substmts[2].stmt = LY_STMT_DESCRIPTION;
207-
ext->substmts[2].storage_p = (void **)&struct_cdata->dsc;
213+
ext->substmts[2].storage_p = (void **)&struct_cdata->top_cont->dsc;
208214

209215
LY_ARRAY_INCREMENT(ext->substmts);
210216
ext->substmts[3].stmt = LY_STMT_REFERENCE;
211-
ext->substmts[3].storage_p = (void **)&struct_cdata->ref;
217+
ext->substmts[3].storage_p = (void **)&struct_cdata->top_cont->ref;
212218

213219
LY_ARRAY_INCREMENT(ext->substmts);
214220
ext->substmts[4].stmt = LY_STMT_TYPEDEF;
@@ -221,59 +227,50 @@ structure_compile(struct lysc_ctx *cctx, const struct lysp_ext_instance *extp, s
221227
/* data-def-stmt */
222228
LY_ARRAY_INCREMENT(ext->substmts);
223229
ext->substmts[6].stmt = LY_STMT_CONTAINER;
224-
ext->substmts[6].storage_p = (void **)&struct_cdata->child;
230+
ext->substmts[6].storage_p = (void **)&struct_cdata->top_cont->child;
225231

226232
LY_ARRAY_INCREMENT(ext->substmts);
227233
ext->substmts[7].stmt = LY_STMT_LEAF;
228-
ext->substmts[7].storage_p = (void **)&struct_cdata->child;
234+
ext->substmts[7].storage_p = (void **)&struct_cdata->top_cont->child;
229235

230236
LY_ARRAY_INCREMENT(ext->substmts);
231237
ext->substmts[8].stmt = LY_STMT_LEAF_LIST;
232-
ext->substmts[8].storage_p = (void **)&struct_cdata->child;
238+
ext->substmts[8].storage_p = (void **)&struct_cdata->top_cont->child;
233239

234240
LY_ARRAY_INCREMENT(ext->substmts);
235241
ext->substmts[9].stmt = LY_STMT_LIST;
236-
ext->substmts[9].storage_p = (void **)&struct_cdata->child;
242+
ext->substmts[9].storage_p = (void **)&struct_cdata->top_cont->child;
237243

238244
LY_ARRAY_INCREMENT(ext->substmts);
239245
ext->substmts[10].stmt = LY_STMT_CHOICE;
240-
ext->substmts[10].storage_p = (void **)&struct_cdata->child;
246+
ext->substmts[10].storage_p = (void **)&struct_cdata->top_cont->child;
241247

242248
LY_ARRAY_INCREMENT(ext->substmts);
243249
ext->substmts[11].stmt = LY_STMT_ANYDATA;
244-
ext->substmts[11].storage_p = (void **)&struct_cdata->child;
250+
ext->substmts[11].storage_p = (void **)&struct_cdata->top_cont->child;
245251

246252
LY_ARRAY_INCREMENT(ext->substmts);
247253
ext->substmts[12].stmt = LY_STMT_ANYXML;
248-
ext->substmts[12].storage_p = (void **)&struct_cdata->child;
254+
ext->substmts[12].storage_p = (void **)&struct_cdata->top_cont->child;
249255

250256
LY_ARRAY_INCREMENT(ext->substmts);
251257
ext->substmts[13].stmt = LY_STMT_USES;
252-
ext->substmts[13].storage_p = (void **)&struct_cdata->child;
258+
ext->substmts[13].storage_p = (void **)&struct_cdata->top_cont->child;
253259

254260
*lyplg_ext_compile_get_options(cctx) |= LYS_COMPILE_NO_CONFIG | LYS_COMPILE_NO_DISABLED;
255-
rc = lyplg_ext_compile_extension_instance(cctx, extp, ext);
261+
rc = lyplg_ext_compile_extension_instance(cctx, extp, ext, (struct lysc_node *)struct_cdata->top_cont);
256262
*lyplg_ext_compile_get_options(cctx) = prev_options;
257263
if (rc) {
258264
return rc;
259265
}
260266

261-
/* add the top-level container with the extension instance name, connect all the other substatements into it */
262-
struct_cdata->top_cont = calloc(1, sizeof *struct_cdata->top_cont);
263-
if (!struct_cdata->top_cont) {
264-
goto emem;
267+
/* compile config properly even though it is ignored */
268+
if (!(struct_cdata->top_cont->flags & LYS_CONFIG_MASK)) {
269+
struct_cdata->top_cont->flags |= LYS_CONFIG_W;
265270
}
266271

267-
struct_cdata->top_cont->name = ext->argument;
268-
struct_cdata->top_cont->nodetype = LYS_CONTAINER;
269-
struct_cdata->top_cont->flags = struct_cdata->flags;
270-
struct_cdata->top_cont->module = (struct lys_module *)lyplg_ext_compile_get_cur_mod(cctx);
271-
struct_cdata->top_cont->prev = &struct_cdata->top_cont->node;
272-
struct_cdata->top_cont->child = struct_cdata->child;
273-
LY_LIST_FOR(struct_cdata->child, child) {
274-
child->parent = (struct lysc_node *)struct_cdata->top_cont;
275-
}
276-
struct_cdata->top_cont->musts = struct_cdata->musts;
272+
/* connect any augments */
273+
LY_CHECK_RET(lyplg_ext_compiled_node_augments(cctx, ext, (struct lysc_node *)struct_cdata->top_cont));
277274

278275
return LY_SUCCESS;
279276

@@ -360,37 +357,33 @@ structure_compiled_print(const struct lysc_ext_instance *orig_ext, struct lysc_e
360357
memset(struct_cdata->top_cont, 0, sizeof *struct_cdata->top_cont);
361358

362359
/* substatements */
363-
ext->substmts[0].storage_p = (void **)&struct_cdata->musts;
364-
ext->substmts[1].storage_p = (void **)&struct_cdata->flags;
365-
ext->substmts[2].storage_p = (void **)&struct_cdata->dsc;
366-
ext->substmts[3].storage_p = (void **)&struct_cdata->ref;
367-
368-
ext->substmts[6].storage_p = (void **)&struct_cdata->child;
369-
ext->substmts[7].storage_p = (void **)&struct_cdata->child;
370-
ext->substmts[8].storage_p = (void **)&struct_cdata->child;
371-
ext->substmts[9].storage_p = (void **)&struct_cdata->child;
372-
ext->substmts[10].storage_p = (void **)&struct_cdata->child;
373-
ext->substmts[11].storage_p = (void **)&struct_cdata->child;
374-
ext->substmts[12].storage_p = (void **)&struct_cdata->child;
375-
ext->substmts[13].storage_p = (void **)&struct_cdata->child;
360+
ext->substmts[0].storage_p = (void **)&struct_cdata->top_cont->musts;
361+
ext->substmts[1].storage_p = (void **)&struct_cdata->top_cont->flags;
362+
ext->substmts[2].storage_p = (void **)&struct_cdata->top_cont->dsc;
363+
ext->substmts[3].storage_p = (void **)&struct_cdata->top_cont->ref;
364+
365+
ext->substmts[6].storage_p = (void **)&struct_cdata->top_cont->child;
366+
ext->substmts[7].storage_p = (void **)&struct_cdata->top_cont->child;
367+
ext->substmts[8].storage_p = (void **)&struct_cdata->top_cont->child;
368+
ext->substmts[9].storage_p = (void **)&struct_cdata->top_cont->child;
369+
ext->substmts[10].storage_p = (void **)&struct_cdata->top_cont->child;
370+
ext->substmts[11].storage_p = (void **)&struct_cdata->top_cont->child;
371+
ext->substmts[12].storage_p = (void **)&struct_cdata->top_cont->child;
372+
ext->substmts[13].storage_p = (void **)&struct_cdata->top_cont->child;
376373

377374
r = lyplg_ext_compiled_stmts_storage_print(orig_ext->substmts, ext->substmts, addr_ht, ptr_set, mem);
378375
if (r) {
379376
return r;
380377
}
381378

382-
/* top_cont substatements that are now in addr_ht (except for musts which are not shared normally) */
379+
/* top_cont substatements that are now in addr_ht */
383380
struct_cdata->top_cont->name = lyplg_ext_compiled_print_get_addr(addr_ht, orig_cdata->top_cont->name);
384381
assert(struct_cdata->top_cont->name);
385382
struct_cdata->top_cont->nodetype = orig_cdata->top_cont->nodetype;
386-
struct_cdata->top_cont->flags = orig_cdata->top_cont->flags;
387383
struct_cdata->top_cont->module = lyplg_ext_compiled_print_get_addr(addr_ht, orig_cdata->top_cont->module);
388384
assert(struct_cdata->top_cont->module);
389385
struct_cdata->top_cont->prev = lyplg_ext_compiled_print_get_addr(addr_ht, orig_cdata->top_cont->prev);
390386
assert(struct_cdata->top_cont->prev);
391-
struct_cdata->top_cont->child = lyplg_ext_compiled_print_get_addr(addr_ht, orig_cdata->top_cont->child);
392-
assert(struct_cdata->top_cont->child);
393-
struct_cdata->top_cont->musts = struct_cdata->musts;
394387

395388
return LY_SUCCESS;
396389
}
@@ -602,7 +595,7 @@ structure_snode(struct lysc_ext_instance *ext, const struct lyd_node *parent, co
602595

603596
if (in_xpath) {
604597
/* XPath starts at the substatements */
605-
*snode = struct_cdata->child;
598+
*snode = struct_cdata->top_cont->child;
606599
} else {
607600
/* data tree start at the top-level virtual container */
608601
*snode = &struct_cdata->top_cont->node;

src/plugins_exts/yangdata.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ yangdata_compile(struct lysc_ctx *cctx, const struct lysp_ext_instance *extp, st
107107
ext->substmts[2].storage_p = (void **)&ext->compiled;
108108

109109
*lyplg_ext_compile_get_options(cctx) |= LYS_COMPILE_NO_CONFIG | LYS_COMPILE_NO_DISABLED;
110-
ret = lyplg_ext_compile_extension_instance(cctx, extp, ext);
110+
ret = lyplg_ext_compile_extension_instance(cctx, extp, ext, NULL);
111111
*lyplg_ext_compile_get_options(cctx) = prev_options;
112112
if (ret) {
113113
return ret;

0 commit comments

Comments
 (0)