blob: c09698c159efe2a161908bf586e03a258bc875c6 [file] [log] [blame]
Michal Vaskoedb0fa52022-10-04 10:36:00 +02001/**
2 * @file structure.c
3 * @author Michal Vasko <mvasko@cesnet.cz>
Michal Vasko193dacd2022-10-13 08:43:05 +02004 * @brief libyang extension plugin - structure (RFC 8791)
Michal Vaskoedb0fa52022-10-04 10:36:00 +02005 *
6 * Copyright (c) 2022 CESNET, z.s.p.o.
7 *
8 * This source code is licensed under BSD 3-Clause License (the "License").
9 * You may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * https://opensource.org/licenses/BSD-3-Clause
13 */
14
15#include <stdint.h>
16#include <stdlib.h>
17#include <string.h>
18
Michal Vasko0b50f6b2022-10-05 15:07:55 +020019#include "compat.h"
Michal Vaskoedb0fa52022-10-04 10:36:00 +020020#include "libyang.h"
21#include "plugins_exts.h"
22
Michal Vasko193dacd2022-10-13 08:43:05 +020023struct lysp_ext_instance_structure {
24 struct lysp_restr *musts;
Michal Vaskoedb0fa52022-10-04 10:36:00 +020025 uint16_t flags;
26 const char *dsc;
27 const char *ref;
28 struct lysp_tpdf *typedefs;
29 struct lysp_node_grp *groupings;
Michal Vasko193dacd2022-10-13 08:43:05 +020030 struct lysp_node *child;
31};
32
33struct lysc_ext_instance_structure {
34 struct lysc_must *musts;
35 uint16_t flags;
36 const char *dsc;
37 const char *ref;
Michal Vaskoedb0fa52022-10-04 10:36:00 +020038 struct lysc_node *child;
39};
40
Michal Vasko193dacd2022-10-13 08:43:05 +020041struct lysp_ext_instance_augment_structure {
42 uint16_t flags;
43 const char *dsc;
44 const char *ref;
45 struct lysp_node *child;
46};
47
Michal Vasko0b50f6b2022-10-05 15:07:55 +020048struct lysc_ext_instance_augment_structure {
49 uint16_t flags;
50 const char *dsc;
51 const char *ref;
52};
53
Michal Vaskoedb0fa52022-10-04 10:36:00 +020054/**
Michal Vasko193dacd2022-10-13 08:43:05 +020055 * @brief Parse structure extension instances.
56 *
57 * Implementation of ::lyplg_ext_parse_clb callback set as lyext_plugin::parse.
58 */
59static LY_ERR
60structure_parse(struct lysp_ctx *pctx, struct lysp_ext_instance *ext)
61{
62 LY_ERR rc;
63 LY_ARRAY_COUNT_TYPE u;
64 struct lysp_module *pmod;
65 struct lysp_ext_instance_structure *struct_pdata;
66
67 /* structure can appear only at the top level of a YANG module or submodule */
68 if ((ext->parent_stmt != LY_STMT_MODULE) && (ext->parent_stmt != LY_STMT_SUBMODULE)) {
69 lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EVALID,
70 "Extension %s must not be used as a non top-level statement in \"%s\" statement.", ext->name,
71 lyplg_ext_stmt2str(ext->parent_stmt));
72 return LY_EVALID;
73 }
74
75 pmod = ext->parent;
76
77 /* check for duplication */
78 LY_ARRAY_FOR(pmod->exts, u) {
79 if ((&pmod->exts[u] != ext) && (pmod->exts[u].name == ext->name) && !strcmp(pmod->exts[u].argument, ext->argument)) {
80 /* duplication of the same structure extension in a single module */
81 lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EVALID, "Extension %s is instantiated multiple times.", ext->name);
82 return LY_EVALID;
83 }
84 }
85
86 /* allocate the storage */
87 struct_pdata = calloc(1, sizeof *struct_pdata);
88 if (!struct_pdata) {
89 goto emem;
90 }
91 ext->parsed = struct_pdata;
92 LY_ARRAY_CREATE_GOTO(lyplg_extp_cur_pmod(pctx)->mod->ctx, ext->substmts, 14, rc, emem);
93
94 /* parse substatements */
95 LY_ARRAY_INCREMENT(ext->substmts);
96 ext->substmts[0].stmt = LY_STMT_MUST;
97 ext->substmts[0].storage = &struct_pdata->musts;
98
99 LY_ARRAY_INCREMENT(ext->substmts);
100 ext->substmts[1].stmt = LY_STMT_STATUS;
101 ext->substmts[1].storage = &struct_pdata->flags;
102
103 LY_ARRAY_INCREMENT(ext->substmts);
104 ext->substmts[2].stmt = LY_STMT_DESCRIPTION;
105 ext->substmts[2].storage = &struct_pdata->dsc;
106
107 LY_ARRAY_INCREMENT(ext->substmts);
108 ext->substmts[3].stmt = LY_STMT_REFERENCE;
109 ext->substmts[3].storage = &struct_pdata->ref;
110
111 LY_ARRAY_INCREMENT(ext->substmts);
112 ext->substmts[4].stmt = LY_STMT_TYPEDEF;
113 ext->substmts[4].storage = &struct_pdata->typedefs;
114
115 LY_ARRAY_INCREMENT(ext->substmts);
116 ext->substmts[5].stmt = LY_STMT_GROUPING;
117 ext->substmts[5].storage = &struct_pdata->groupings;
118
119 /* data-def-stmt */
120 LY_ARRAY_INCREMENT(ext->substmts);
121 ext->substmts[6].stmt = LY_STMT_CONTAINER;
122 ext->substmts[6].storage = &struct_pdata->child;
123
124 LY_ARRAY_INCREMENT(ext->substmts);
125 ext->substmts[7].stmt = LY_STMT_LEAF;
126 ext->substmts[7].storage = &struct_pdata->child;
127
128 LY_ARRAY_INCREMENT(ext->substmts);
129 ext->substmts[8].stmt = LY_STMT_LEAF_LIST;
130 ext->substmts[8].storage = &struct_pdata->child;
131
132 LY_ARRAY_INCREMENT(ext->substmts);
133 ext->substmts[9].stmt = LY_STMT_LIST;
134 ext->substmts[9].storage = &struct_pdata->child;
135
136 LY_ARRAY_INCREMENT(ext->substmts);
137 ext->substmts[10].stmt = LY_STMT_CHOICE;
138 ext->substmts[10].storage = &struct_pdata->child;
139
140 LY_ARRAY_INCREMENT(ext->substmts);
141 ext->substmts[11].stmt = LY_STMT_ANYDATA;
142 ext->substmts[11].storage = &struct_pdata->child;
143
144 LY_ARRAY_INCREMENT(ext->substmts);
145 ext->substmts[12].stmt = LY_STMT_ANYXML;
146 ext->substmts[12].storage = &struct_pdata->child;
147
148 LY_ARRAY_INCREMENT(ext->substmts);
149 ext->substmts[13].stmt = LY_STMT_USES;
150 ext->substmts[13].storage = &struct_pdata->child;
151
152 rc = lyplg_ext_parse_extension_instance(pctx, ext);
153 return rc;
154
155emem:
156 lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EMEM, "Memory allocation failed (%s()).", __func__);
157 return LY_EMEM;
158}
159
160/**
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200161 * @brief Compile structure extension instances.
162 *
163 * Implementation of ::lyplg_ext_compile_clb callback set as lyext_plugin::compile.
164 */
165static LY_ERR
Michal Vasko193dacd2022-10-13 08:43:05 +0200166structure_compile(struct lysc_ctx *cctx, const struct lysp_ext_instance *extp, struct lysc_ext_instance *ext)
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200167{
Michal Vasko0b50f6b2022-10-05 15:07:55 +0200168 LY_ERR rc;
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200169 struct lysc_module *mod_c;
170 const struct lysc_node *child;
Michal Vasko193dacd2022-10-13 08:43:05 +0200171 struct lysc_ext_instance_structure *struct_cdata;
172 uint32_t prev_options = *lyplg_ext_compile_get_options(cctx);
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200173
Michal Vasko193dacd2022-10-13 08:43:05 +0200174 mod_c = ext->parent;
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200175
Michal Vasko193dacd2022-10-13 08:43:05 +0200176 /* check identifier namespace with the compiled nodes */
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200177 LY_LIST_FOR(mod_c->data, child) {
Michal Vasko193dacd2022-10-13 08:43:05 +0200178 if (!strcmp(child->name, ext->argument)) {
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200179 /* identifier collision */
Michal Vasko193dacd2022-10-13 08:43:05 +0200180 lyplg_ext_compile_log(cctx, ext, LY_LLERR, LY_EVALID, "Extension %s collides with a %s with the same identifier.",
181 extp->name, lys_nodetype2str(child->nodetype));
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200182 return LY_EVALID;
183 }
184 }
185
186 /* allocate the storage */
Michal Vasko193dacd2022-10-13 08:43:05 +0200187 struct_cdata = calloc(1, sizeof *struct_cdata);
188 if (!struct_cdata) {
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200189 goto emem;
190 }
Michal Vasko193dacd2022-10-13 08:43:05 +0200191 ext->compiled = struct_cdata;
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200192
193 /* compile substatements */
Michal Vasko193dacd2022-10-13 08:43:05 +0200194 LY_ARRAY_CREATE_GOTO(cctx->ctx, ext->substmts, 14, rc, emem);
195 LY_ARRAY_INCREMENT(ext->substmts);
196 ext->substmts[0].stmt = LY_STMT_MUST;
197 ext->substmts[0].storage = &struct_cdata->musts;
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200198
Michal Vasko193dacd2022-10-13 08:43:05 +0200199 LY_ARRAY_INCREMENT(ext->substmts);
200 ext->substmts[1].stmt = LY_STMT_STATUS;
201 ext->substmts[1].storage = &struct_cdata->flags;
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200202
Michal Vasko193dacd2022-10-13 08:43:05 +0200203 LY_ARRAY_INCREMENT(ext->substmts);
204 ext->substmts[2].stmt = LY_STMT_DESCRIPTION;
205 ext->substmts[2].storage = &struct_cdata->dsc;
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200206
Michal Vasko193dacd2022-10-13 08:43:05 +0200207 LY_ARRAY_INCREMENT(ext->substmts);
208 ext->substmts[3].stmt = LY_STMT_REFERENCE;
209 ext->substmts[3].storage = &struct_cdata->ref;
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200210
Michal Vasko193dacd2022-10-13 08:43:05 +0200211 LY_ARRAY_INCREMENT(ext->substmts);
212 ext->substmts[4].stmt = LY_STMT_TYPEDEF;
213 ext->substmts[4].storage = NULL;
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200214
Michal Vasko193dacd2022-10-13 08:43:05 +0200215 LY_ARRAY_INCREMENT(ext->substmts);
216 ext->substmts[5].stmt = LY_STMT_GROUPING;
217 ext->substmts[5].storage = NULL;
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200218
219 /* data-def-stmt */
Michal Vasko193dacd2022-10-13 08:43:05 +0200220 LY_ARRAY_INCREMENT(ext->substmts);
221 ext->substmts[6].stmt = LY_STMT_CONTAINER;
222 ext->substmts[6].storage = &struct_cdata->child;
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200223
Michal Vasko193dacd2022-10-13 08:43:05 +0200224 LY_ARRAY_INCREMENT(ext->substmts);
225 ext->substmts[7].stmt = LY_STMT_LEAF;
226 ext->substmts[7].storage = &struct_cdata->child;
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200227
Michal Vasko193dacd2022-10-13 08:43:05 +0200228 LY_ARRAY_INCREMENT(ext->substmts);
229 ext->substmts[8].stmt = LY_STMT_LEAF_LIST;
230 ext->substmts[8].storage = &struct_cdata->child;
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200231
Michal Vasko193dacd2022-10-13 08:43:05 +0200232 LY_ARRAY_INCREMENT(ext->substmts);
233 ext->substmts[9].stmt = LY_STMT_LIST;
234 ext->substmts[9].storage = &struct_cdata->child;
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200235
Michal Vasko193dacd2022-10-13 08:43:05 +0200236 LY_ARRAY_INCREMENT(ext->substmts);
237 ext->substmts[10].stmt = LY_STMT_CHOICE;
238 ext->substmts[10].storage = &struct_cdata->child;
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200239
Michal Vasko193dacd2022-10-13 08:43:05 +0200240 LY_ARRAY_INCREMENT(ext->substmts);
241 ext->substmts[11].stmt = LY_STMT_ANYDATA;
242 ext->substmts[11].storage = &struct_cdata->child;
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200243
Michal Vasko193dacd2022-10-13 08:43:05 +0200244 LY_ARRAY_INCREMENT(ext->substmts);
245 ext->substmts[12].stmt = LY_STMT_ANYXML;
246 ext->substmts[12].storage = &struct_cdata->child;
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200247
Michal Vasko193dacd2022-10-13 08:43:05 +0200248 LY_ARRAY_INCREMENT(ext->substmts);
249 ext->substmts[13].stmt = LY_STMT_USES;
250 ext->substmts[13].storage = &struct_cdata->child;
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200251
Michal Vasko193dacd2022-10-13 08:43:05 +0200252 *lyplg_ext_compile_get_options(cctx) |= LYS_COMPILE_NO_CONFIG | LYS_COMPILE_NO_DISABLED;
253 rc = lyplg_ext_compile_extension_instance(cctx, extp, ext);
254 *lyplg_ext_compile_get_options(cctx) = prev_options;
Michal Vasko0b50f6b2022-10-05 15:07:55 +0200255 if (rc) {
256 return rc;
257 }
258
259 return LY_SUCCESS;
260
261emem:
Michal Vasko193dacd2022-10-13 08:43:05 +0200262 lyplg_ext_compile_log(cctx, ext, LY_LLERR, LY_EMEM, "Memory allocation failed (%s()).", __func__);
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200263 return LY_EMEM;
264}
265
266/**
267 * @brief INFO printer
268 *
Michal Vasko941e0562022-10-18 10:35:00 +0200269 * Implementation of ::lyplg_ext_sprinter_info_clb set as ::lyext_plugin::printer_info
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200270 */
271static LY_ERR
Michal Vasko941e0562022-10-18 10:35:00 +0200272structure_printer_info(struct lyspr_ctx *ctx, struct lysc_ext_instance *ext, ly_bool *flag)
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200273{
Michal Vasko941e0562022-10-18 10:35:00 +0200274 lyplg_ext_print_info_extension_instance(ctx, ext, flag);
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200275 return LY_SUCCESS;
276}
277
278/**
Michal Vasko193dacd2022-10-13 08:43:05 +0200279 * @brief Free parsed structure extension instance data.
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200280 *
Michal Vasko193dacd2022-10-13 08:43:05 +0200281 * Implementation of ::lyplg_clb_parse_free_clb callback set as lyext_plugin::pfree.
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200282 */
283static void
Michal Vasko193dacd2022-10-13 08:43:05 +0200284structure_pfree(const struct ly_ctx *ctx, struct lysp_ext_instance *ext)
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200285{
Michal Vasko193dacd2022-10-13 08:43:05 +0200286 lyplg_ext_pfree_instance_substatements(ctx, ext->substmts);
287 free(ext->parsed);
288}
289
290/**
291 * @brief Free compiled structure extension instance data.
292 *
293 * Implementation of ::lyplg_clb_compile_free_clb callback set as lyext_plugin::cfree.
294 */
295static void
296structure_cfree(const struct ly_ctx *ctx, struct lysc_ext_instance *ext)
297{
298 lyplg_ext_cfree_instance_substatements(ctx, ext->substmts);
299 free(ext->compiled);
300}
301
302/**
303 * @brief Parse augment-structure extension instances.
304 *
305 * Implementation of ::lyplg_ext_parse_clb callback set as lyext_plugin::parse.
306 */
307static LY_ERR
308structure_aug_parse(struct lysp_ctx *pctx, struct lysp_ext_instance *ext)
309{
310 LY_ERR rc;
311 struct lysp_stmt *stmt;
312 struct lysp_ext_instance_augment_structure *aug_pdata;
313
314 /* augment-structure can appear only at the top level of a YANG module or submodule */
315 if ((ext->parent_stmt != LY_STMT_MODULE) && (ext->parent_stmt != LY_STMT_SUBMODULE)) {
316 lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EVALID,
317 "Extension %s must not be used as a non top-level statement in \"%s\" statement.", ext->name,
318 lyplg_ext_stmt2str(ext->parent_stmt));
319 return LY_EVALID;
320 }
321
322 /* augment-structure must define some data-def-stmt */
323 LY_LIST_FOR(ext->child, stmt) {
324 if (stmt->kw & LY_STMT_DATA_NODE_MASK) {
325 break;
326 }
327 }
328 if (!stmt) {
329 lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EVALID, "Extension %s does not define any data-def-stmt statements.",
330 ext->name);
331 return LY_EVALID;
332 }
333
334 /* allocate the storage */
335 aug_pdata = calloc(1, sizeof *aug_pdata);
336 if (!aug_pdata) {
337 goto emem;
338 }
339 ext->parsed = aug_pdata;
340 LY_ARRAY_CREATE_GOTO(lyplg_extp_cur_pmod(pctx)->mod->ctx, ext->substmts, 12, rc, emem);
341
342 /* parse substatements */
343 LY_ARRAY_INCREMENT(ext->substmts);
344 ext->substmts[0].stmt = LY_STMT_STATUS;
345 ext->substmts[0].storage = &aug_pdata->flags;
346
347 LY_ARRAY_INCREMENT(ext->substmts);
348 ext->substmts[1].stmt = LY_STMT_DESCRIPTION;
349 ext->substmts[1].storage = &aug_pdata->dsc;
350
351 LY_ARRAY_INCREMENT(ext->substmts);
352 ext->substmts[2].stmt = LY_STMT_REFERENCE;
353 ext->substmts[2].storage = &aug_pdata->ref;
354
355 /* data-def-stmt */
356 LY_ARRAY_INCREMENT(ext->substmts);
357 ext->substmts[3].stmt = LY_STMT_CONTAINER;
358 ext->substmts[3].storage = &aug_pdata->child;
359
360 LY_ARRAY_INCREMENT(ext->substmts);
361 ext->substmts[4].stmt = LY_STMT_LEAF;
362 ext->substmts[4].storage = &aug_pdata->child;
363
364 LY_ARRAY_INCREMENT(ext->substmts);
365 ext->substmts[5].stmt = LY_STMT_LEAF_LIST;
366 ext->substmts[5].storage = &aug_pdata->child;
367
368 LY_ARRAY_INCREMENT(ext->substmts);
369 ext->substmts[6].stmt = LY_STMT_LIST;
370 ext->substmts[6].storage = &aug_pdata->child;
371
372 LY_ARRAY_INCREMENT(ext->substmts);
373 ext->substmts[7].stmt = LY_STMT_CHOICE;
374 ext->substmts[7].storage = &aug_pdata->child;
375
376 LY_ARRAY_INCREMENT(ext->substmts);
377 ext->substmts[8].stmt = LY_STMT_ANYDATA;
378 ext->substmts[8].storage = &aug_pdata->child;
379
380 LY_ARRAY_INCREMENT(ext->substmts);
381 ext->substmts[9].stmt = LY_STMT_ANYXML;
382 ext->substmts[9].storage = &aug_pdata->child;
383
384 LY_ARRAY_INCREMENT(ext->substmts);
385 ext->substmts[10].stmt = LY_STMT_USES;
386 ext->substmts[10].storage = &aug_pdata->child;
387
388 /* case */
389 LY_ARRAY_INCREMENT(ext->substmts);
390 ext->substmts[11].stmt = LY_STMT_CASE;
391 ext->substmts[11].storage = &aug_pdata->child;
392
393 rc = lyplg_ext_parse_extension_instance(pctx, ext);
394 return rc;
395
396emem:
397 lyplg_ext_parse_log(pctx, ext, LY_LLERR, LY_EMEM, "Memory allocation failed (%s()).", __func__);
398 return LY_EMEM;
399}
400
401/**
402 * @brief Compile augment-structure extension instances.
403 *
404 * Implementation of ::lyplg_ext_compile_clb callback set as lyext_plugin::compile.
405 */
406static LY_ERR
407structure_aug_compile(struct lysc_ctx *cctx, const struct lysp_ext_instance *extp, struct lysc_ext_instance *ext)
408{
409 LY_ERR rc;
410 struct lysc_node *aug_target;
411 struct lysc_ext_instance *target_ext;
412 struct lysc_ext_instance_structure *target_cdata;
413 struct lysc_ext_instance_augment_structure *aug_cdata;
414 uint32_t prev_options = *lyplg_ext_compile_get_options(cctx), i;
415
416 /* find the target struct ext instance */
417 if ((rc = lys_compile_extension_instance_find_augment_target(cctx, extp->argument, &target_ext, &aug_target))) {
418 return rc;
419 }
420
421 /* check target_ext */
422 if (strcmp(target_ext->def->name, "structure") || strcmp(target_ext->def->module->name, "ietf-yang-structure-ext")) {
423 lyplg_ext_compile_log(cctx, ext, LY_LLERR, LY_EVALID,
424 "Extension %s can only target extension instances of \"ietf-yang-structure-ext:structure\".", extp->name);
425 return LY_EVALID;
426 }
427 target_cdata = target_ext->compiled;
428
429 /* allocate the storage */
430 aug_cdata = calloc(1, sizeof *aug_cdata);
431 if (!aug_cdata) {
432 goto emem;
433 }
434 ext->compiled = aug_cdata;
435
436 /* compile substatements */
437 LY_ARRAY_CREATE_GOTO(cctx->ctx, ext->substmts, 12, rc, emem);
438 LY_ARRAY_INCREMENT(ext->substmts);
439 ext->substmts[0].stmt = LY_STMT_STATUS;
440 ext->substmts[0].storage = &aug_cdata->flags;
441
442 LY_ARRAY_INCREMENT(ext->substmts);
443 ext->substmts[1].stmt = LY_STMT_DESCRIPTION;
444 ext->substmts[1].storage = &aug_cdata->dsc;
445
446 LY_ARRAY_INCREMENT(ext->substmts);
447 ext->substmts[2].stmt = LY_STMT_REFERENCE;
448 ext->substmts[2].storage = &aug_cdata->ref;
449
450 /* data-def-stmt */
451 LY_ARRAY_INCREMENT(ext->substmts);
452 ext->substmts[3].stmt = LY_STMT_CONTAINER;
453 ext->substmts[3].storage = &target_cdata->child;
454
455 LY_ARRAY_INCREMENT(ext->substmts);
456 ext->substmts[4].stmt = LY_STMT_LEAF;
457 ext->substmts[4].storage = &target_cdata->child;
458
459 LY_ARRAY_INCREMENT(ext->substmts);
460 ext->substmts[5].stmt = LY_STMT_LEAF_LIST;
461 ext->substmts[5].storage = &target_cdata->child;
462
463 LY_ARRAY_INCREMENT(ext->substmts);
464 ext->substmts[6].stmt = LY_STMT_LIST;
465 ext->substmts[6].storage = &target_cdata->child;
466
467 LY_ARRAY_INCREMENT(ext->substmts);
468 ext->substmts[7].stmt = LY_STMT_CHOICE;
469 ext->substmts[7].storage = &target_cdata->child;
470
471 LY_ARRAY_INCREMENT(ext->substmts);
472 ext->substmts[8].stmt = LY_STMT_ANYDATA;
473 ext->substmts[8].storage = &target_cdata->child;
474
475 LY_ARRAY_INCREMENT(ext->substmts);
476 ext->substmts[9].stmt = LY_STMT_ANYXML;
477 ext->substmts[9].storage = &target_cdata->child;
478
479 LY_ARRAY_INCREMENT(ext->substmts);
480 ext->substmts[10].stmt = LY_STMT_USES;
481 ext->substmts[10].storage = &target_cdata->child;
482
483 /* case */
484 LY_ARRAY_INCREMENT(ext->substmts);
485 ext->substmts[11].stmt = LY_STMT_CASE;
486 ext->substmts[11].storage = &target_cdata->child;
487
488 *lyplg_ext_compile_get_options(cctx) |= LYS_COMPILE_NO_CONFIG | LYS_COMPILE_NO_DISABLED;
489 rc = lyplg_ext_compile_extension_instance_augment(cctx, extp, ext, aug_target);
490 *lyplg_ext_compile_get_options(cctx) = prev_options;
491 if (rc) {
492 return rc;
493 }
494
495 /* data-def-statements are now part of the target extension (do not print nor free them) */
496 for (i = 0; i < 9; ++i) {
497 LY_ARRAY_DECREMENT(ext->substmts);
498 }
499
500 return LY_SUCCESS;
501
502emem:
503 lyplg_ext_compile_log(cctx, ext, LY_LLERR, LY_EMEM, "Memory allocation failed (%s()).", __func__);
504 return LY_EMEM;
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200505}
506
507/**
508 * @brief Plugin descriptions for the structure extension
509 *
510 * Note that external plugins are supposed to use:
511 *
512 * LYPLG_EXTENSIONS = {
513 */
514const struct lyplg_ext_record plugins_structure[] = {
515 {
516 .module = "ietf-yang-structure-ext",
517 .revision = "2020-06-17",
518 .name = "structure",
519
Michal Vasko193dacd2022-10-13 08:43:05 +0200520 .plugin.id = "ly2 structure v1",
521 .plugin.parse = structure_parse,
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200522 .plugin.compile = structure_compile,
Michal Vasko941e0562022-10-18 10:35:00 +0200523 .plugin.printer_info = structure_printer_info,
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200524 .plugin.node = NULL,
525 .plugin.snode = NULL,
Michal Vasko193dacd2022-10-13 08:43:05 +0200526 .plugin.validate = NULL,
527 .plugin.pfree = structure_pfree,
528 .plugin.cfree = structure_cfree
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200529 },
Michal Vasko0b50f6b2022-10-05 15:07:55 +0200530 {
531 .module = "ietf-yang-structure-ext",
532 .revision = "2020-06-17",
533 .name = "augment-structure",
534
Michal Vasko193dacd2022-10-13 08:43:05 +0200535 .plugin.id = "ly2 structure v1",
536 .plugin.parse = structure_aug_parse,
Michal Vasko0b50f6b2022-10-05 15:07:55 +0200537 .plugin.compile = structure_aug_compile,
Michal Vasko941e0562022-10-18 10:35:00 +0200538 .plugin.printer_info = structure_printer_info,
Michal Vasko0b50f6b2022-10-05 15:07:55 +0200539 .plugin.node = NULL,
540 .plugin.snode = NULL,
Michal Vasko193dacd2022-10-13 08:43:05 +0200541 .plugin.validate = NULL,
542 .plugin.pfree = NULL,
543 .plugin.cfree = structure_cfree
Michal Vasko0b50f6b2022-10-05 15:07:55 +0200544 },
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200545 {0} /* terminating zeroed record */
546};