Coverage Report

Created: 2024-02-29 06:11

/src/libyang/src/parser_common.c
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * @file parser_common.c
3
 * @author Michal Vasko <mvasko@cesnet.cz>
4
 * @brief libyang common parser functions.
5
 *
6
 * Copyright (c) 2015 - 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
#define _GNU_SOURCE
16
#define _POSIX_C_SOURCE 200809L /* strdup, strndup */
17
18
#ifdef __APPLE__
19
#define _DARWIN_C_SOURCE /* F_GETPATH */
20
#endif
21
22
#if defined (__NetBSD__) || defined (__OpenBSD__)
23
/* realpath */
24
#define _XOPEN_SOURCE 1
25
#define _XOPEN_SOURCE_EXTENDED 1
26
#endif
27
28
#include "parser_internal.h"
29
30
#include <assert.h>
31
#include <ctype.h>
32
#include <errno.h>
33
#include <fcntl.h>
34
#include <limits.h>
35
#include <stdint.h>
36
#include <stdio.h>
37
#include <stdlib.h>
38
#include <string.h>
39
#include <unistd.h>
40
41
#include "compat.h"
42
#include "dict.h"
43
#include "in_internal.h"
44
#include "log.h"
45
#include "ly_common.h"
46
#include "parser_data.h"
47
#include "path.h"
48
#include "plugins_exts/metadata.h"
49
#include "schema_compile_node.h"
50
#include "schema_features.h"
51
#include "set.h"
52
#include "tree.h"
53
#include "tree_data.h"
54
#include "tree_data_internal.h"
55
#include "tree_schema.h"
56
#include "tree_schema_internal.h"
57
58
void
59
lyd_ctx_free(struct lyd_ctx *lydctx)
60
9.63k
{
61
9.63k
    ly_set_erase(&lydctx->node_types, NULL);
62
9.63k
    ly_set_erase(&lydctx->meta_types, NULL);
63
9.63k
    ly_set_erase(&lydctx->node_when, NULL);
64
9.63k
    ly_set_erase(&lydctx->ext_node, free);
65
9.63k
    ly_set_erase(&lydctx->ext_val, free);
66
9.63k
}
67
68
LY_ERR
69
lyd_parser_notif_eventtime_validate(const struct lyd_node *node)
70
0
{
71
0
    LY_ERR rc = LY_SUCCESS;
72
0
    struct ly_ctx *ctx = (struct ly_ctx *)LYD_CTX(node);
73
0
    struct lysc_ctx cctx;
74
0
    const struct lys_module *mod;
75
0
    LY_ARRAY_COUNT_TYPE u;
76
0
    struct ly_err_item *err = NULL;
77
0
    struct lysp_type *type_p = NULL;
78
0
    struct lysc_pattern **patterns = NULL;
79
0
    const char *value;
80
81
0
    LYSC_CTX_INIT_CTX(cctx, ctx);
82
83
    /* get date-and-time parsed type */
84
0
    mod = ly_ctx_get_module_latest(ctx, "ietf-yang-types");
85
0
    assert(mod);
86
0
    LY_ARRAY_FOR(mod->parsed->typedefs, u) {
87
0
        if (!strcmp(mod->parsed->typedefs[u].name, "date-and-time")) {
88
0
            type_p = &mod->parsed->typedefs[u].type;
89
0
            break;
90
0
        }
91
0
    }
92
0
    assert(type_p);
93
94
    /* compile patterns */
95
0
    assert(type_p->patterns);
96
0
    LY_CHECK_GOTO(rc = lys_compile_type_patterns(&cctx, type_p->patterns, NULL, &patterns), cleanup);
97
98
    /* validate */
99
0
    value = lyd_get_value(node);
100
0
    rc = lyplg_type_validate_patterns(patterns, value, strlen(value), &err);
101
102
0
cleanup:
103
0
    FREE_ARRAY(&cctx.free_ctx, patterns, lysc_pattern_free);
104
0
    if (rc && err) {
105
0
        ly_err_print(ctx, err);
106
0
        ly_err_free(err);
107
0
        LOGVAL(ctx, LYVE_DATA, "Invalid \"eventTime\" in the notification.");
108
0
    }
109
0
    return rc;
110
0
}
111
112
LY_ERR
113
lyd_parser_find_operation(const struct lyd_node *parent, uint32_t int_opts, struct lyd_node **op)
114
8.25k
{
115
8.25k
    const struct lyd_node *iter;
116
117
8.25k
    *op = NULL;
118
119
8.25k
    if (!parent) {
120
        /* no parent, nothing to look for */
121
8.25k
        return LY_SUCCESS;
122
8.25k
    }
123
124
    /* we need to find the operation node if it already exists */
125
0
    for (iter = parent; iter; iter = lyd_parent(iter)) {
126
0
        if (iter->schema && (iter->schema->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF))) {
127
0
            break;
128
0
        }
129
0
    }
130
131
0
    if (!iter) {
132
        /* no operation found */
133
0
        return LY_SUCCESS;
134
0
    }
135
136
0
    if (!(int_opts & LYD_INTOPT_ANY)) {
137
0
        if (!(int_opts & (LYD_INTOPT_RPC | LYD_INTOPT_ACTION | LYD_INTOPT_NOTIF | LYD_INTOPT_REPLY))) {
138
0
            LOGERR(LYD_CTX(parent), LY_EINVAL, "Invalid parent %s \"%s\" node when not parsing any operation.",
139
0
                    lys_nodetype2str(iter->schema->nodetype), iter->schema->name);
140
0
            return LY_EINVAL;
141
0
        } else if ((iter->schema->nodetype == LYS_RPC) && !(int_opts & (LYD_INTOPT_RPC | LYD_INTOPT_REPLY))) {
142
0
            LOGERR(LYD_CTX(parent), LY_EINVAL, "Invalid parent RPC \"%s\" node when not parsing RPC nor rpc-reply.",
143
0
                    iter->schema->name);
144
0
            return LY_EINVAL;
145
0
        } else if ((iter->schema->nodetype == LYS_ACTION) && !(int_opts & (LYD_INTOPT_ACTION | LYD_INTOPT_REPLY))) {
146
0
            LOGERR(LYD_CTX(parent), LY_EINVAL, "Invalid parent action \"%s\" node when not parsing action nor rpc-reply.",
147
0
                    iter->schema->name);
148
0
            return LY_EINVAL;
149
0
        } else if ((iter->schema->nodetype == LYS_NOTIF) && !(int_opts & LYD_INTOPT_NOTIF)) {
150
0
            LOGERR(LYD_CTX(parent), LY_EINVAL, "Invalid parent notification \"%s\" node when not parsing a notification.",
151
0
                    iter->schema->name);
152
0
            return LY_EINVAL;
153
0
        }
154
0
    }
155
156
0
    *op = (struct lyd_node *)iter;
157
0
    return LY_SUCCESS;
158
0
}
159
160
const struct lysc_node *
161
lyd_parser_node_schema(const struct lyd_node *node)
162
361k
{
163
361k
    uint32_t i;
164
361k
    const struct lyd_node *iter;
165
361k
    const struct lysc_node *schema = NULL;
166
361k
    const struct lys_module *mod;
167
168
361k
    if (!node) {
169
51.9k
        return NULL;
170
309k
    } else if (node->schema) {
171
        /* simplest case */
172
309k
        return node->schema;
173
309k
    }
174
175
    /* find the first schema node in the parsed nodes */
176
0
    i = ly_log_location_dnode_count();
177
0
    if (i) {
178
0
        do {
179
0
            --i;
180
0
            if (ly_log_location_dnode(i)->schema) {
181
                /* this node is processed */
182
0
                schema = ly_log_location_dnode(i)->schema;
183
0
                ++i;
184
0
                break;
185
0
            }
186
0
        } while (i);
187
0
    }
188
189
    /* get schema node of an opaque node */
190
0
    do {
191
        /* get next data node */
192
0
        if (i == ly_log_location_dnode_count()) {
193
0
            iter = node;
194
0
        } else {
195
0
            iter = ly_log_location_dnode(i);
196
0
        }
197
0
        assert(!iter->schema);
198
199
        /* get module */
200
0
        mod = lyd_node_module(iter);
201
0
        if (!mod) {
202
            /* unknown module, no schema node */
203
0
            schema = NULL;
204
0
            break;
205
0
        }
206
207
        /* get schema node */
208
0
        schema = lys_find_child(schema, mod, LYD_NAME(iter), 0, 0, 0);
209
210
        /* move to the descendant */
211
0
        ++i;
212
0
    } while (schema && (iter != node));
213
214
0
    return schema;
215
361k
}
216
217
LY_ERR
218
lyd_parser_check_schema(struct lyd_ctx *lydctx, const struct lysc_node *snode)
219
341k
{
220
341k
    LY_ERR rc = LY_SUCCESS;
221
222
341k
    LOG_LOCSET(snode, NULL);
223
224
341k
    if (lydctx->int_opts & LYD_INTOPT_ANY) {
225
        /* nothing to check, everything is allowed */
226
0
        goto cleanup;
227
0
    }
228
229
341k
    if ((lydctx->parse_opts & LYD_PARSE_NO_STATE) && (snode->flags & LYS_CONFIG_R)) {
230
0
        LOGVAL(lydctx->data_ctx->ctx, LY_VCODE_UNEXPNODE, "state", snode->name);
231
0
        rc = LY_EVALID;
232
0
        goto cleanup;
233
0
    }
234
235
341k
    if (snode->nodetype == LYS_RPC) {
236
0
        if (lydctx->int_opts & (LYD_INTOPT_RPC | LYD_INTOPT_REPLY)) {
237
0
            if (lydctx->op_node) {
238
0
                goto error_node_dup;
239
0
            }
240
0
        } else {
241
0
            goto error_node_inval;
242
0
        }
243
341k
    } else if (snode->nodetype == LYS_ACTION) {
244
0
        if (lydctx->int_opts & (LYD_INTOPT_ACTION | LYD_INTOPT_REPLY)) {
245
0
            if (lydctx->op_node) {
246
0
                goto error_node_dup;
247
0
            }
248
0
        } else {
249
0
            goto error_node_inval;
250
0
        }
251
341k
    } else if (snode->nodetype == LYS_NOTIF) {
252
0
        if (lydctx->int_opts & LYD_INTOPT_NOTIF) {
253
0
            if (lydctx->op_node) {
254
0
                goto error_node_dup;
255
0
            }
256
0
        } else {
257
0
            goto error_node_inval;
258
0
        }
259
0
    }
260
261
    /* success */
262
341k
    goto cleanup;
263
264
341k
error_node_dup:
265
0
    LOGVAL(lydctx->data_ctx->ctx, LYVE_DATA, "Unexpected %s element \"%s\", %s \"%s\" already parsed.",
266
0
            lys_nodetype2str(snode->nodetype), snode->name, lys_nodetype2str(lydctx->op_node->schema->nodetype),
267
0
            lydctx->op_node->schema->name);
268
0
    rc = LY_EVALID;
269
0
    goto cleanup;
270
271
0
error_node_inval:
272
0
    LOGVAL(lydctx->data_ctx->ctx, LYVE_DATA, "Unexpected %s element \"%s\".", lys_nodetype2str(snode->nodetype),
273
0
            snode->name);
274
0
    rc = LY_EVALID;
275
276
341k
cleanup:
277
341k
    LOG_LOCBACK(1, 0);
278
341k
    return rc;
279
0
}
280
281
LY_ERR
282
lyd_parser_create_term(struct lyd_ctx *lydctx, const struct lysc_node *schema, const void *value, size_t value_len,
283
        ly_bool *dynamic, LY_VALUE_FORMAT format, void *prefix_data, uint32_t hints, struct lyd_node **node)
284
447k
{
285
447k
    LY_ERR r;
286
447k
    ly_bool incomplete;
287
447k
    ly_bool store_only = (lydctx->parse_opts & LYD_PARSE_STORE_ONLY) == LYD_PARSE_STORE_ONLY ? 1 : 0;
288
289
447k
    if ((r = lyd_create_term(schema, value, value_len, 1, store_only, dynamic, format, prefix_data,
290
447k
            hints, &incomplete, node))) {
291
2.37k
        if (lydctx->data_ctx->ctx != schema->module->ctx) {
292
            /* move errors to the main context */
293
0
            ly_err_move(schema->module->ctx, (struct ly_ctx *)lydctx->data_ctx->ctx);
294
0
        }
295
2.37k
        return r;
296
2.37k
    }
297
298
445k
    if (incomplete && !(lydctx->parse_opts & LYD_PARSE_ONLY)) {
299
2.09k
        LY_CHECK_RET(ly_set_add(&lydctx->node_types, *node, 1, NULL));
300
2.09k
    }
301
445k
    return LY_SUCCESS;
302
445k
}
303
304
LY_ERR
305
lyd_parser_create_meta(struct lyd_ctx *lydctx, struct lyd_node *parent, struct lyd_meta **meta, const struct lys_module *mod,
306
        const char *name, size_t name_len, const void *value, size_t value_len, ly_bool *dynamic, LY_VALUE_FORMAT format,
307
        void *prefix_data, uint32_t hints, const struct lysc_node *ctx_node)
308
11
{
309
11
    LY_ERR rc = LY_SUCCESS;
310
11
    char *dpath = NULL, *path = NULL;
311
11
    ly_bool incomplete;
312
11
    struct lyd_meta *first = NULL;
313
11
    ly_bool store_only = (lydctx->parse_opts & LYD_PARSE_STORE_ONLY) == LYD_PARSE_STORE_ONLY ? 1 : 0;
314
315
11
    if (meta && *meta) {
316
        /* remember the first metadata */
317
0
        first = *meta;
318
0
    }
319
320
    /* generate path to the metadata */
321
11
    LY_CHECK_RET(ly_vlog_build_data_path(lydctx->data_ctx->ctx, &dpath));
322
11
    if (asprintf(&path, "%s/@%s:%.*s", dpath, mod->name, (int)name_len, name) == -1) {
323
0
        LOGMEM(lydctx->data_ctx->ctx);
324
0
        rc = LY_EMEM;
325
0
        goto cleanup;
326
0
    }
327
11
    ly_log_location(NULL, NULL, path, NULL);
328
329
11
    LY_CHECK_GOTO(rc = lyd_create_meta(parent, meta, mod, name, name_len, value, value_len, 1, store_only, dynamic, format,
330
11
            prefix_data, hints, ctx_node, 0, &incomplete), cleanup);
331
332
0
    if (incomplete && !(lydctx->parse_opts & LYD_PARSE_ONLY)) {
333
0
        LY_CHECK_GOTO(rc = ly_set_add(&lydctx->meta_types, *meta, 1, NULL), cleanup);
334
0
    }
335
336
0
    if (first) {
337
        /* always return the first metadata */
338
0
        *meta = first;
339
0
    }
340
341
11
cleanup:
342
11
    ly_log_location_revert(0, 0, 1, 0);
343
11
    free(dpath);
344
11
    free(path);
345
11
    return rc;
346
0
}
347
348
LY_ERR
349
lyd_parse_check_keys(struct lyd_node *node)
350
13.3k
{
351
13.3k
    const struct lysc_node *skey = NULL;
352
13.3k
    const struct lyd_node *key;
353
354
13.3k
    assert(node->schema->nodetype == LYS_LIST);
355
356
0
    key = lyd_child(node);
357
27.4k
    while ((skey = lys_getnext(skey, node->schema, NULL, 0)) && (skey->flags & LYS_KEY)) {
358
14.2k
        if (!key || (key->schema != skey)) {
359
24
            LOGVAL(LYD_CTX(node), LY_VCODE_NOKEY, skey->name);
360
24
            return LY_EVALID;
361
24
        }
362
363
14.1k
        key = key->next;
364
14.1k
    }
365
366
13.2k
    return LY_SUCCESS;
367
13.3k
}
368
369
LY_ERR
370
lyd_parse_set_data_flags(struct lyd_node *node, struct lyd_meta **meta, struct lyd_ctx *lydctx,
371
        struct lysc_ext_instance *ext)
372
459k
{
373
459k
    struct lyd_meta *meta2, *prev_meta = NULL, *next_meta = NULL;
374
459k
    struct lyd_ctx_ext_val *ext_val;
375
376
459k
    if (lydctx->parse_opts & LYD_PARSE_NO_NEW) {
377
0
        node->flags &= ~LYD_NEW;
378
0
    }
379
380
459k
    if (lysc_has_when(node->schema)) {
381
0
        if (lydctx->parse_opts & LYD_PARSE_WHEN_TRUE) {
382
            /* the condition was true before */
383
0
            node->flags |= LYD_WHEN_TRUE;
384
0
        }
385
0
        if (!(lydctx->parse_opts & LYD_PARSE_ONLY)) {
386
            /* remember we need to evaluate this node's when */
387
0
            LY_CHECK_RET(ly_set_add(&lydctx->node_when, node, 1, NULL));
388
0
        }
389
0
    }
390
391
459k
    LY_LIST_FOR(*meta, meta2) {
392
0
        if (!strcmp(meta2->name, "default") && !strcmp(meta2->annotation->module->name, "ietf-netconf-with-defaults") &&
393
0
                meta2->value.boolean) {
394
            /* node is default according to the metadata */
395
0
            node->flags |= LYD_DEFAULT;
396
397
0
            next_meta = meta2->next;
398
399
            /* delete the metadata */
400
0
            if (meta != &node->meta) {
401
0
                *meta = (*meta)->next;
402
0
            }
403
0
            lyd_free_meta_single(meta2);
404
0
            if (prev_meta) {
405
0
                prev_meta->next = next_meta;
406
0
            }
407
408
            /* update dflt flag for all parent NP containers */
409
0
            lyd_cont_set_dflt(lyd_parent(node));
410
0
            break;
411
0
        }
412
413
0
        prev_meta = meta2;
414
0
    }
415
416
459k
    if (ext) {
417
        /* parsed for an extension */
418
0
        node->flags |= LYD_EXT;
419
420
0
        if (!(lydctx->parse_opts & LYD_PARSE_ONLY)) {
421
            /* rememeber for validation */
422
0
            ext_val = malloc(sizeof *ext_val);
423
0
            LY_CHECK_ERR_RET(!ext_val, LOGMEM(LYD_CTX(node)), LY_EMEM);
424
0
            ext_val->ext = ext;
425
0
            ext_val->sibling = node;
426
0
            LY_CHECK_RET(ly_set_add(&lydctx->ext_val, ext_val, 1, NULL));
427
0
        }
428
0
    }
429
430
459k
    return LY_SUCCESS;
431
459k
}
432
433
void
434
lys_parser_fill_filepath(struct ly_ctx *ctx, struct ly_in *in, const char **filepath)
435
163k
{
436
163k
    char path[PATH_MAX];
437
438
163k
#ifndef __APPLE__
439
163k
    char proc_path[32];
440
163k
    int len;
441
163k
#endif
442
443
326k
    LY_CHECK_ARG_RET(NULL, ctx, in, filepath, );
444
163k
    if (*filepath) {
445
        /* filepath already set */
446
0
        return;
447
0
    }
448
449
163k
    switch (in->type) {
450
0
    case LY_IN_FILEPATH:
451
0
        if (realpath(in->method.fpath.filepath, path) != NULL) {
452
0
            lydict_insert(ctx, path, 0, filepath);
453
0
        } else {
454
0
            lydict_insert(ctx, in->method.fpath.filepath, 0, filepath);
455
0
        }
456
457
0
        break;
458
0
    case LY_IN_FD:
459
#ifdef __APPLE__
460
        if (fcntl(in->method.fd, F_GETPATH, path) != -1) {
461
            lydict_insert(ctx, path, 0, filepath);
462
        }
463
#elif defined _WIN32
464
        HANDLE h = _get_osfhandle(in->method.fd);
465
        FILE_NAME_INFO info;
466
467
        if (GetFileInformationByHandleEx(h, FileNameInfo, &info, sizeof info)) {
468
            char *buf = calloc(info.FileNameLength + 1 /* trailing NULL */, MB_CUR_MAX);
469
470
            len = wcstombs(buf, info.FileName, info.FileNameLength * MB_CUR_MAX);
471
            lydict_insert(ctx, buf, len, filepath);
472
        }
473
#else
474
        /* get URI if there is /proc */
475
0
        sprintf(proc_path, "/proc/self/fd/%d", in->method.fd);
476
0
        if ((len = readlink(proc_path, path, PATH_MAX - 1)) > 0) {
477
0
            lydict_insert(ctx, path, len, filepath);
478
0
        }
479
0
#endif
480
0
        break;
481
163k
    case LY_IN_MEMORY:
482
163k
    case LY_IN_FILE:
483
        /* nothing to do */
484
163k
        break;
485
0
    default:
486
0
        LOGINT(ctx);
487
0
        break;
488
163k
    }
489
163k
}
490
491
static LY_ERR lysp_stmt_container(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
492
        struct lysp_node **siblings);
493
static LY_ERR lysp_stmt_choice(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
494
        struct lysp_node **siblings);
495
static LY_ERR lysp_stmt_case(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
496
        struct lysp_node **siblings);
497
static LY_ERR lysp_stmt_uses(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
498
        struct lysp_node **siblings);
499
static LY_ERR lysp_stmt_grouping(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
500
        struct lysp_node_grp **groupings);
501
static LY_ERR lysp_stmt_list(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
502
        struct lysp_node **siblings);
503
504
/**
505
 * @brief Validate stmt string value.
506
 *
507
 * @param[in] ctx Parser context.
508
 * @param[in] val_type String value type.
509
 * @param[in] val Value to validate.
510
 * @return LY_ERR value.
511
 */
512
static LY_ERR
513
lysp_stmt_validate_value(struct lysp_ctx *ctx, enum yang_arg val_type, const char *val)
514
809k
{
515
809k
    uint8_t prefix = 0;
516
809k
    ly_bool first = 1;
517
809k
    uint32_t c;
518
809k
    size_t utf8_char_len;
519
520
809k
    if (!val) {
521
0
        if (val_type == Y_MAYBE_STR_ARG) {
522
            /* fine */
523
0
            return LY_SUCCESS;
524
0
        }
525
526
0
        LOGVAL_PARSER(ctx, LYVE_SYNTAX, "Missing an expected string.");
527
0
        return LY_EVALID;
528
0
    }
529
530
52.2M
    while (*val) {
531
51.4M
        LY_CHECK_ERR_RET(ly_getutf8(&val, &c, &utf8_char_len),
532
51.4M
                LOGVAL_PARSER(ctx, LY_VCODE_INCHAR, (val)[-utf8_char_len]), LY_EVALID);
533
534
51.4M
        switch (val_type) {
535
0
        case Y_IDENTIF_ARG:
536
0
            LY_CHECK_RET(lysp_check_identifierchar(ctx, c, first, NULL));
537
0
            break;
538
2.69M
        case Y_PREF_IDENTIF_ARG:
539
2.69M
            LY_CHECK_RET(lysp_check_identifierchar(ctx, c, first, &prefix));
540
2.69M
            break;
541
48.7M
        case Y_STR_ARG:
542
48.7M
        case Y_MAYBE_STR_ARG:
543
48.7M
            LY_CHECK_RET(lysp_check_stringchar(ctx, c));
544
48.7M
            break;
545
51.4M
        }
546
51.4M
        first = 0;
547
51.4M
    }
548
549
809k
    return LY_SUCCESS;
550
809k
}
551
552
/**
553
 * @brief Duplicate statement siblings, recursively.
554
 *
555
 * @param[in] ctx Parser context.
556
 * @param[in] stmt Statement to duplicate.
557
 * @param[out] first First duplicated statement, the rest follow.
558
 * @return LY_ERR value.
559
 */
560
static LY_ERR
561
lysp_stmt_dup(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_stmt **first)
562
0
{
563
0
    struct lysp_stmt *child, *last = NULL;
564
565
0
    LY_LIST_FOR(stmt, stmt) {
566
0
        child = calloc(1, sizeof *child);
567
0
        LY_CHECK_ERR_RET(!child, LOGMEM(PARSER_CTX(ctx)), LY_EMEM);
568
569
0
        if (last) {
570
0
            last->next = child;
571
0
        } else {
572
0
            assert(!*first);
573
0
            *first = child;
574
0
        }
575
0
        last = child;
576
577
0
        LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->stmt, 0, &child->stmt));
578
0
        LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &child->arg));
579
0
        child->format = stmt->format;
580
0
        LY_CHECK_RET(ly_dup_prefix_data(PARSER_CTX(ctx), stmt->format, stmt->prefix_data, &child->prefix_data));
581
0
        child->flags = stmt->flags;
582
0
        child->kw = stmt->kw;
583
584
        /* recursively */
585
0
        LY_CHECK_RET(lysp_stmt_dup(ctx, stmt->child, &child->child));
586
0
    }
587
588
0
    return LY_SUCCESS;
589
0
}
590
591
/**
592
 * @brief Parse extension instance.
593
 *
594
 * @param[in] ctx parser context.
595
 * @param[in] stmt Source statement data from the parsed extension instance.
596
 * @param[in] insubstmt The statement this extension instance is a substatement of.
597
 * @param[in] insubstmt_index Index of the keyword instance this extension instance is a substatement of.
598
 * @param[in,out] exts Extension instances to add to.
599
 * @return LY_ERR values.
600
 */
601
static LY_ERR
602
lysp_stmt_ext(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, enum ly_stmt insubstmt,
603
        LY_ARRAY_COUNT_TYPE insubstmt_index, struct lysp_ext_instance **exts)
604
0
{
605
0
    struct lysp_ext_instance *e;
606
607
0
    LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *exts, e, LY_EMEM);
608
609
    /* store name and insubstmt info */
610
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->stmt, 0, &e->name));
611
0
    e->parent_stmt = insubstmt;
612
0
    e->parent_stmt_index = insubstmt_index;
613
0
    e->parsed = NULL;
614
0
    LY_CHECK_RET(lysp_stmt_dup(ctx, stmt->child, &e->child));
615
616
    /* get optional argument */
617
0
    if (stmt->arg) {
618
0
        LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &e->argument));
619
0
    }
620
621
0
    return LY_SUCCESS;
622
0
}
623
624
/**
625
 * @brief Parse a generic text field without specific constraints. Those are contact, organization,
626
 * description, etc...
627
 *
628
 * @param[in] ctx parser context.
629
 * @param[in] stmt Source statement data from the parsed extension instance.
630
 * @param[in] substmt_index Index of this substatement.
631
 * @param[in,out] value Place to store the parsed value.
632
 * @param[in] arg Type of the YANG keyword argument (of the value).
633
 * @param[in,out] exts Extension instances to add to.
634
 *
635
 * @return LY_ERR values.
636
 */
637
static LY_ERR
638
lysp_stmt_text_field(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, uint32_t substmt_index, const char **value,
639
        enum yang_arg arg, struct lysp_ext_instance **exts)
640
305k
{
641
305k
    if (*value) {
642
0
        LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, lyplg_ext_stmt2str(stmt->kw));
643
0
        return LY_EVALID;
644
0
    }
645
646
305k
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, arg, stmt->arg));
647
305k
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, value));
648
649
305k
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
650
0
        switch (child->kw) {
651
0
        case LY_STMT_EXTENSION_INSTANCE:
652
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, substmt_index, exts));
653
0
            break;
654
0
        default:
655
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), lyplg_ext_stmt2str(stmt->kw));
656
0
            return LY_EVALID;
657
0
        }
658
0
    }
659
305k
    return LY_SUCCESS;
660
305k
}
661
662
/**
663
 * @brief Parse a qname that can have more instances such as if-feature.
664
 *
665
 * @param[in] ctx parser context.
666
 * @param[in] stmt Source statement data from the parsed extension instance.
667
 * @param[in,out] qnames Parsed qnames to add to.
668
 * @param[in] arg Type of the expected argument.
669
 * @param[in,out] exts Extension instances to add to.
670
 *
671
 * @return LY_ERR values.
672
 */
673
static LY_ERR
674
lysp_stmt_qnames(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_qname **qnames, enum yang_arg arg,
675
        struct lysp_ext_instance **exts)
676
0
{
677
0
    struct lysp_qname *item;
678
679
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, arg, stmt->arg));
680
681
    /* allocate new pointer */
682
0
    LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *qnames, item, LY_EMEM);
683
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &item->str));
684
0
    item->mod = PARSER_CUR_PMOD(ctx);
685
686
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
687
0
        switch (child->kw) {
688
0
        case LY_STMT_EXTENSION_INSTANCE:
689
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, LY_ARRAY_COUNT(*qnames) - 1, exts));
690
0
            break;
691
0
        default:
692
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), lyplg_ext_stmt2str(stmt->kw));
693
0
            return LY_EVALID;
694
0
        }
695
0
    }
696
0
    return LY_SUCCESS;
697
0
}
698
699
/**
700
 * @brief Parse a generic text field that can have more instances such as base.
701
 *
702
 * @param[in] ctx parser context.
703
 * @param[in] stmt Source statement data from the parsed extension instance.
704
 * @param[in,out] texts Parsed values to add to.
705
 * @param[in] arg Type of the expected argument.
706
 * @param[in,out] exts Extension instances to add to.
707
 *
708
 * @return LY_ERR values.
709
 */
710
static LY_ERR
711
lysp_stmt_text_fields(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, const char ***texts, enum yang_arg arg,
712
        struct lysp_ext_instance **exts)
713
0
{
714
0
    const char **item;
715
716
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, arg, stmt->arg));
717
718
    /* allocate new pointer */
719
0
    LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *texts, item, LY_EMEM);
720
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, item));
721
722
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
723
0
        switch (child->kw) {
724
0
        case LY_STMT_EXTENSION_INSTANCE:
725
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, LY_ARRAY_COUNT(*texts) - 1, exts));
726
0
            break;
727
0
        default:
728
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), lyplg_ext_stmt2str(stmt->kw));
729
0
            return LY_EVALID;
730
0
        }
731
0
    }
732
0
    return LY_SUCCESS;
733
0
}
734
735
/**
736
 * @brief Parse the status statement.
737
 *
738
 * @param[in] ctx parser context.
739
 * @param[in] stmt Source statement data from the parsed extension instance.
740
 * @param[in,out] flags Flags to add to.
741
 * @param[in,out] exts Extension instances to add to.
742
 *
743
 * @return LY_ERR values.
744
 */
745
static LY_ERR
746
lysp_stmt_status(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, uint16_t *flags, struct lysp_ext_instance **exts)
747
0
{
748
0
    int arg_len;
749
750
0
    if (*flags & LYS_STATUS_MASK) {
751
0
        LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "status");
752
0
        return LY_EVALID;
753
0
    }
754
755
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
756
0
    arg_len = strlen(stmt->arg);
757
0
    if ((arg_len == ly_strlen_const("current")) && !strncmp(stmt->arg, "current", arg_len)) {
758
0
        *flags |= LYS_STATUS_CURR;
759
0
    } else if ((arg_len == ly_strlen_const("deprecated")) && !strncmp(stmt->arg, "deprecated", arg_len)) {
760
0
        *flags |= LYS_STATUS_DEPRC;
761
0
    } else if ((arg_len == ly_strlen_const("obsolete")) && !strncmp(stmt->arg, "obsolete", arg_len)) {
762
0
        *flags |= LYS_STATUS_OBSLT;
763
0
    } else {
764
0
        LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "status");
765
0
        return LY_EVALID;
766
0
    }
767
768
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
769
0
        switch (child->kw) {
770
0
        case LY_STMT_EXTENSION_INSTANCE:
771
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_STATUS, 0, exts));
772
0
            break;
773
0
        default:
774
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "status");
775
0
            return LY_EVALID;
776
0
        }
777
0
    }
778
0
    return LY_SUCCESS;
779
0
}
780
781
/**
782
 * @brief Parse the when statement.
783
 *
784
 * @param[in] ctx parser context.
785
 * @param[in] stmt Source statement data from the parsed extension instance.
786
 * @param[in,out] when_p When pointer to parse to.
787
 *
788
 * @return LY_ERR values.
789
 */
790
static LY_ERR
791
lysp_stmt_when(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_when **when_p)
792
0
{
793
0
    LY_ERR ret = LY_SUCCESS;
794
0
    struct lysp_when *when;
795
796
0
    if (*when_p) {
797
0
        LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "when");
798
0
        return LY_EVALID;
799
0
    }
800
801
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
802
803
0
    when = calloc(1, sizeof *when);
804
0
    LY_CHECK_ERR_RET(!when, LOGMEM(PARSER_CTX(ctx)), LY_EMEM);
805
0
    *when_p = when;
806
807
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &when->cond));
808
809
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
810
0
        switch (child->kw) {
811
0
        case LY_STMT_DESCRIPTION:
812
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &when->dsc, Y_STR_ARG, &when->exts));
813
0
            break;
814
0
        case LY_STMT_REFERENCE:
815
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &when->ref, Y_STR_ARG, &when->exts));
816
0
            break;
817
0
        case LY_STMT_EXTENSION_INSTANCE:
818
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_WHEN, 0, &when->exts));
819
0
            break;
820
0
        default:
821
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "when");
822
0
            return LY_EVALID;
823
0
        }
824
0
    }
825
0
    return ret;
826
0
}
827
828
/**
829
 * @brief Parse the config statement.
830
 *
831
 * @param[in] ctx parser context.
832
 * @param[in] stmt Source statement data from the parsed extension instance.
833
 * @param[in,out] flags Flags to add to.
834
 * @param[in,out] exts Extension instances to add to.
835
 *
836
 * @return LY_ERR values.
837
 */
838
static LY_ERR
839
lysp_stmt_config(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, uint16_t *flags, struct lysp_ext_instance **exts)
840
0
{
841
0
    int arg_len;
842
843
0
    if (*flags & LYS_CONFIG_MASK) {
844
0
        LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "config");
845
0
        return LY_EVALID;
846
0
    }
847
848
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
849
0
    arg_len = strlen(stmt->arg);
850
0
    if ((arg_len == ly_strlen_const("true")) && !strncmp(stmt->arg, "true", arg_len)) {
851
0
        *flags |= LYS_CONFIG_W;
852
0
    } else if ((arg_len == ly_strlen_const("false")) && !strncmp(stmt->arg, "false", arg_len)) {
853
0
        *flags |= LYS_CONFIG_R;
854
0
    } else {
855
0
        LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "config");
856
0
        return LY_EVALID;
857
0
    }
858
859
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
860
0
        switch (child->kw) {
861
0
        case LY_STMT_EXTENSION_INSTANCE:
862
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_CONFIG, 0, exts));
863
0
            break;
864
0
        default:
865
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "config");
866
0
            return LY_EVALID;
867
0
        }
868
0
    }
869
870
0
    return LY_SUCCESS;
871
0
}
872
873
/**
874
 * @brief Parse the mandatory statement.
875
 *
876
 * @param[in] ctx parser context.
877
 * @param[in] stmt Source statement data from the parsed extension instance.
878
 * @param[in,out] flags Flags to add to.
879
 * @param[in,out] exts Extension instances to add to.
880
 *
881
 * @return LY_ERR values.
882
 */
883
static LY_ERR
884
lysp_stmt_mandatory(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, uint16_t *flags,
885
        struct lysp_ext_instance **exts)
886
0
{
887
0
    int arg_len;
888
889
0
    if (*flags & LYS_MAND_MASK) {
890
0
        LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "mandatory");
891
0
        return LY_EVALID;
892
0
    }
893
894
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
895
0
    arg_len = strlen(stmt->arg);
896
0
    if ((arg_len == ly_strlen_const("true")) && !strncmp(stmt->arg, "true", arg_len)) {
897
0
        *flags |= LYS_MAND_TRUE;
898
0
    } else if ((arg_len == ly_strlen_const("false")) && !strncmp(stmt->arg, "false", arg_len)) {
899
0
        *flags |= LYS_MAND_FALSE;
900
0
    } else {
901
0
        LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "mandatory");
902
0
        return LY_EVALID;
903
0
    }
904
905
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
906
0
        switch (child->kw) {
907
0
        case LY_STMT_EXTENSION_INSTANCE:
908
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_MANDATORY, 0, exts));
909
0
            break;
910
0
        default:
911
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "mandatory");
912
0
            return LY_EVALID;
913
0
        }
914
0
    }
915
916
0
    return LY_SUCCESS;
917
0
}
918
919
/**
920
 * @brief Parse a restriction such as range or length.
921
 *
922
 * @param[in] ctx parser context.
923
 * @param[in] stmt Source statement data from the parsed extension instance.
924
 * @param[in,out] exts Extension instances to add to.
925
 *
926
 * @return LY_ERR values.
927
 */
928
static LY_ERR
929
lysp_stmt_restr(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_restr *restr)
930
35.9k
{
931
35.9k
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
932
35.9k
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &restr->arg.str));
933
35.9k
    restr->arg.mod = PARSER_CUR_PMOD(ctx);
934
935
35.9k
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
936
0
        switch (child->kw) {
937
0
        case LY_STMT_DESCRIPTION:
938
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &restr->dsc, Y_STR_ARG, &restr->exts));
939
0
            break;
940
0
        case LY_STMT_REFERENCE:
941
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &restr->ref, Y_STR_ARG, &restr->exts));
942
0
            break;
943
0
        case LY_STMT_ERROR_APP_TAG:
944
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &restr->eapptag, Y_STR_ARG, &restr->exts));
945
0
            break;
946
0
        case LY_STMT_ERROR_MESSAGE:
947
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &restr->emsg, Y_STR_ARG, &restr->exts));
948
0
            break;
949
0
        case LY_STMT_EXTENSION_INSTANCE:
950
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, &restr->exts));
951
0
            break;
952
0
        default:
953
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), lyplg_ext_stmt2str(stmt->kw));
954
0
            return LY_EVALID;
955
0
        }
956
0
    }
957
35.9k
    return LY_SUCCESS;
958
35.9k
}
959
960
/**
961
 * @brief Parse a restriction that can have more instances such as must.
962
 *
963
 * @param[in] ctx parser context.
964
 * @param[in] stmt Source statement data from the parsed extension instance.
965
 * @param[in,out] restrs Restrictions to add to.
966
 *
967
 * @return LY_ERR values.
968
 */
969
static LY_ERR
970
lysp_stmt_restrs(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_restr **restrs)
971
0
{
972
0
    struct lysp_restr *restr;
973
974
0
    LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *restrs, restr, LY_EMEM);
975
0
    return lysp_stmt_restr(ctx, stmt, restr);
976
0
}
977
978
/**
979
 * @brief Parse the anydata or anyxml statement.
980
 *
981
 * @param[in] ctx parser context.
982
 * @param[in] stmt Source statement data from the parsed extension instance.
983
 * @param[in,out] siblings Siblings to add to.
984
 *
985
 * @return LY_ERR values.
986
 */
987
static LY_ERR
988
lysp_stmt_any(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent, struct lysp_node **siblings)
989
0
{
990
0
    struct lysp_node_anydata *any;
991
992
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
993
994
    /* create new structure and insert into siblings */
995
0
    LY_LIST_NEW_RET(PARSER_CTX(ctx), siblings, any, next, LY_EMEM);
996
997
0
    any->nodetype = stmt->kw == LY_STMT_ANYDATA ? LYS_ANYDATA : LYS_ANYXML;
998
0
    any->parent = parent;
999
1000
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &any->name));
1001
1002
    /* parse substatements */
1003
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1004
0
        switch (child->kw) {
1005
0
        case LY_STMT_CONFIG:
1006
0
            LY_CHECK_RET(lysp_stmt_config(ctx, child, &any->flags, &any->exts));
1007
0
            break;
1008
0
        case LY_STMT_DESCRIPTION:
1009
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &any->dsc, Y_STR_ARG, &any->exts));
1010
0
            break;
1011
0
        case LY_STMT_IF_FEATURE:
1012
0
            LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &any->iffeatures, Y_STR_ARG, &any->exts));
1013
0
            break;
1014
0
        case LY_STMT_MANDATORY:
1015
0
            LY_CHECK_RET(lysp_stmt_mandatory(ctx, child, &any->flags, &any->exts));
1016
0
            break;
1017
0
        case LY_STMT_MUST:
1018
0
            LY_CHECK_RET(lysp_stmt_restrs(ctx, child, &any->musts));
1019
0
            break;
1020
0
        case LY_STMT_REFERENCE:
1021
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &any->ref, Y_STR_ARG, &any->exts));
1022
0
            break;
1023
0
        case LY_STMT_STATUS:
1024
0
            LY_CHECK_RET(lysp_stmt_status(ctx, child, &any->flags, &any->exts));
1025
0
            break;
1026
0
        case LY_STMT_WHEN:
1027
0
            LY_CHECK_RET(lysp_stmt_when(ctx, child, &any->when));
1028
0
            break;
1029
0
        case LY_STMT_EXTENSION_INSTANCE:
1030
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, &any->exts));
1031
0
            break;
1032
0
        default:
1033
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw),
1034
0
                    (any->nodetype & LYS_ANYDATA) == LYS_ANYDATA ? lyplg_ext_stmt2str(LY_STMT_ANYDATA) : lyplg_ext_stmt2str(LY_STMT_ANYXML));
1035
0
            return LY_EVALID;
1036
0
        }
1037
0
    }
1038
1039
0
    return LY_SUCCESS;
1040
0
}
1041
1042
/**
1043
 * @brief Parse the value or position statement. Substatement of type enum statement.
1044
 *
1045
 * @param[in] ctx parser context.
1046
 * @param[in] stmt Source statement data from the parsed extension instance.
1047
 * @param[in,out] value Value to write to.
1048
 * @param[in,out] flags Flags to write to.
1049
 * @param[in,out] exts Extension instances to add to.
1050
 *
1051
 * @return LY_ERR values.
1052
 */
1053
static LY_ERR
1054
lysp_stmt_type_enum_value_pos(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, int64_t *value, uint16_t *flags,
1055
        struct lysp_ext_instance **exts)
1056
0
{
1057
0
    int arg_len;
1058
0
    char *ptr = NULL;
1059
0
    long long num = 0;
1060
0
    unsigned long long unum = 0;
1061
1062
0
    if (*flags & LYS_SET_VALUE) {
1063
0
        LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, lyplg_ext_stmt2str(stmt->kw));
1064
0
        return LY_EVALID;
1065
0
    }
1066
0
    *flags |= LYS_SET_VALUE;
1067
1068
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
1069
1070
0
    arg_len = strlen(stmt->arg);
1071
0
    if (!arg_len || (stmt->arg[0] == '+') || ((stmt->arg[0] == '0') && (arg_len > 1)) ||
1072
0
            ((stmt->kw == LY_STMT_POSITION) && !strncmp(stmt->arg, "-0", 2))) {
1073
0
        LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, lyplg_ext_stmt2str(stmt->kw));
1074
0
        goto error;
1075
0
    }
1076
1077
0
    errno = 0;
1078
0
    if (stmt->kw == LY_STMT_VALUE) {
1079
0
        num = strtoll(stmt->arg, &ptr, LY_BASE_DEC);
1080
0
        if ((num < INT64_C(-2147483648)) || (num > INT64_C(2147483647))) {
1081
0
            LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, lyplg_ext_stmt2str(stmt->kw));
1082
0
            goto error;
1083
0
        }
1084
0
    } else {
1085
0
        unum = strtoull(stmt->arg, &ptr, LY_BASE_DEC);
1086
0
        if (unum > UINT64_C(4294967295)) {
1087
0
            LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, lyplg_ext_stmt2str(stmt->kw));
1088
0
            goto error;
1089
0
        }
1090
0
    }
1091
    /* we have not parsed the whole argument */
1092
0
    if (ptr - stmt->arg != arg_len) {
1093
0
        LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, lyplg_ext_stmt2str(stmt->kw));
1094
0
        goto error;
1095
0
    }
1096
0
    if (errno == ERANGE) {
1097
0
        LOGVAL_PARSER(ctx, LY_VCODE_OOB, arg_len, stmt->arg, lyplg_ext_stmt2str(stmt->kw));
1098
0
        goto error;
1099
0
    }
1100
0
    if (stmt->kw == LY_STMT_VALUE) {
1101
0
        *value = num;
1102
0
    } else {
1103
0
        *value = unum;
1104
0
    }
1105
1106
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1107
0
        switch (child->kw) {
1108
0
        case LY_STMT_EXTENSION_INSTANCE:
1109
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw == LY_STMT_VALUE ? LY_STMT_VALUE : LY_STMT_POSITION, 0, exts));
1110
0
            break;
1111
0
        default:
1112
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), lyplg_ext_stmt2str(stmt->kw));
1113
0
            return LY_EVALID;
1114
0
        }
1115
0
    }
1116
0
    return LY_SUCCESS;
1117
1118
0
error:
1119
0
    return LY_EVALID;
1120
0
}
1121
1122
/**
1123
 * @brief Parse the enum or bit statement. Substatement of type statement.
1124
 *
1125
 * @param[in] ctx parser context.
1126
 * @param[in] stmt Source statement data from the parsed extension instance.
1127
 * @param[in,out] enums Enums or bits to add to.
1128
 *
1129
 * @return LY_ERR values.
1130
 */
1131
static LY_ERR
1132
lysp_stmt_type_enum(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_type_enum **enums)
1133
143k
{
1134
143k
    struct lysp_type_enum *enm;
1135
1136
143k
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, stmt->kw == LY_STMT_ENUM ? Y_STR_ARG : Y_IDENTIF_ARG, stmt->arg));
1137
1138
143k
    LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *enums, enm, LY_EMEM);
1139
1140
143k
    if (stmt->kw == LY_STMT_ENUM) {
1141
143k
        LY_CHECK_RET(lysp_check_enum_name(ctx, stmt->arg, strlen(stmt->arg)));
1142
143k
    } /* else nothing specific for YANG_BIT */
1143
1144
143k
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &enm->name));
1145
143k
    CHECK_UNIQUENESS(ctx, *enums, name, lyplg_ext_stmt2str(stmt->kw), enm->name);
1146
1147
215k
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1148
71.9k
        switch (child->kw) {
1149
71.9k
        case LY_STMT_DESCRIPTION:
1150
71.9k
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &enm->dsc, Y_STR_ARG, &enm->exts));
1151
71.9k
            break;
1152
0
        case LY_STMT_IF_FEATURE:
1153
0
            PARSER_CHECK_STMTVER2_RET(ctx, "if-feature", lyplg_ext_stmt2str(stmt->kw));
1154
0
            LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &enm->iffeatures, Y_STR_ARG, &enm->exts));
1155
0
            break;
1156
0
        case LY_STMT_REFERENCE:
1157
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &enm->ref, Y_STR_ARG, &enm->exts));
1158
0
            break;
1159
0
        case LY_STMT_STATUS:
1160
0
            LY_CHECK_RET(lysp_stmt_status(ctx, child, &enm->flags, &enm->exts));
1161
0
            break;
1162
0
        case LY_STMT_VALUE:
1163
0
            LY_CHECK_ERR_RET(stmt->kw == LY_STMT_BIT, LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw),
1164
0
                    lyplg_ext_stmt2str(stmt->kw)), LY_EVALID);
1165
0
            LY_CHECK_RET(lysp_stmt_type_enum_value_pos(ctx, child, &enm->value, &enm->flags, &enm->exts));
1166
0
            break;
1167
0
        case LY_STMT_POSITION:
1168
0
            LY_CHECK_ERR_RET(stmt->kw == LY_STMT_ENUM, LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw),
1169
0
                    lyplg_ext_stmt2str(stmt->kw)), LY_EVALID);
1170
0
            LY_CHECK_RET(lysp_stmt_type_enum_value_pos(ctx, child, &enm->value, &enm->flags, &enm->exts));
1171
0
            break;
1172
0
        case LY_STMT_EXTENSION_INSTANCE:
1173
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, &enm->exts));
1174
0
            break;
1175
0
        default:
1176
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), lyplg_ext_stmt2str(stmt->kw));
1177
0
            return LY_EVALID;
1178
71.9k
        }
1179
71.9k
    }
1180
1181
143k
    return LY_SUCCESS;
1182
143k
}
1183
1184
/**
1185
 * @brief Parse the fraction-digits statement. Substatement of type statement.
1186
 *
1187
 * @param[in] ctx parser context.
1188
 * @param[in] stmt Source statement data from the parsed extension instance.
1189
 * @param[in,out] fracdig Value to write to.
1190
 * @param[in,out] exts Extension instances to add to.
1191
 *
1192
 * @return LY_ERR values.
1193
 */
1194
static LY_ERR
1195
lysp_stmt_type_fracdigits(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, uint8_t *fracdig,
1196
        struct lysp_ext_instance **exts)
1197
0
{
1198
0
    char *ptr;
1199
0
    int arg_len;
1200
0
    unsigned long long num;
1201
1202
0
    if (*fracdig) {
1203
0
        LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "fraction-digits");
1204
0
        return LY_EVALID;
1205
0
    }
1206
1207
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
1208
0
    arg_len = strlen(stmt->arg);
1209
0
    if (!arg_len || (stmt->arg[0] == '0') || !isdigit(stmt->arg[0])) {
1210
0
        LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "fraction-digits");
1211
0
        return LY_EVALID;
1212
0
    }
1213
1214
0
    errno = 0;
1215
0
    num = strtoull(stmt->arg, &ptr, LY_BASE_DEC);
1216
    /* we have not parsed the whole argument */
1217
0
    if (ptr - stmt->arg != arg_len) {
1218
0
        LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "fraction-digits");
1219
0
        return LY_EVALID;
1220
0
    }
1221
0
    if ((errno == ERANGE) || (num > LY_TYPE_DEC64_FD_MAX)) {
1222
0
        LOGVAL_PARSER(ctx, LY_VCODE_OOB, arg_len, stmt->arg, "fraction-digits");
1223
0
        return LY_EVALID;
1224
0
    }
1225
0
    *fracdig = num;
1226
1227
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1228
0
        switch (child->kw) {
1229
0
        case LY_STMT_EXTENSION_INSTANCE:
1230
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_FRACTION_DIGITS, 0, exts));
1231
0
            break;
1232
0
        default:
1233
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "fraction-digits");
1234
0
            return LY_EVALID;
1235
0
        }
1236
0
    }
1237
0
    return LY_SUCCESS;
1238
0
}
1239
1240
/**
1241
 * @brief Parse the require-instance statement. Substatement of type statement.
1242
 *
1243
 * @param[in] ctx parser context.
1244
 * @param[in] stmt Source statement data from the parsed extension instance.
1245
 * @param[in,out] reqinst Value to write to.
1246
 * @param[in,out] flags Flags to write to.
1247
 * @param[in,out] exts Extension instances to add to.
1248
 *
1249
 * @return LY_ERR values.
1250
 */
1251
static LY_ERR
1252
lysp_stmt_type_reqinstance(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, uint8_t *reqinst, uint16_t *flags,
1253
        struct lysp_ext_instance **exts)
1254
0
{
1255
0
    int arg_len;
1256
1257
0
    if (*flags & LYS_SET_REQINST) {
1258
0
        LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "require-instance");
1259
0
        return LY_EVALID;
1260
0
    }
1261
0
    *flags |= LYS_SET_REQINST;
1262
1263
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
1264
0
    arg_len = strlen(stmt->arg);
1265
0
    if ((arg_len == ly_strlen_const("true")) && !strncmp(stmt->arg, "true", arg_len)) {
1266
0
        *reqinst = 1;
1267
0
    } else if ((arg_len != ly_strlen_const("false")) || strncmp(stmt->arg, "false", arg_len)) {
1268
0
        LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "require-instance");
1269
0
        return LY_EVALID;
1270
0
    }
1271
1272
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1273
0
        switch (child->kw) {
1274
0
        case LY_STMT_EXTENSION_INSTANCE:
1275
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_REQUIRE_INSTANCE, 0, exts));
1276
0
            break;
1277
0
        default:
1278
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "require-instance");
1279
0
            return LY_EVALID;
1280
0
        }
1281
0
    }
1282
0
    return LY_SUCCESS;
1283
0
}
1284
1285
/**
1286
 * @brief Parse the modifier statement. Substatement of type pattern statement.
1287
 *
1288
 * @param[in] ctx parser context.
1289
 * @param[in] stmt Source statement data from the parsed extension instance.
1290
 * @param[in,out] pat Value to write to.
1291
 * @param[in,out] exts Extension instances to add to.
1292
 * @return LY_ERR values.
1293
 */
1294
static LY_ERR
1295
lysp_stmt_type_pattern_modifier(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, const char **pat,
1296
        struct lysp_ext_instance **exts)
1297
0
{
1298
0
    int arg_len;
1299
0
    char *buf;
1300
1301
0
    if ((*pat)[0] == LYSP_RESTR_PATTERN_NACK) {
1302
0
        LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "modifier");
1303
0
        return LY_EVALID;
1304
0
    }
1305
1306
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
1307
0
    arg_len = strlen(stmt->arg);
1308
0
    if ((arg_len != ly_strlen_const("invert-match")) || strncmp(stmt->arg, "invert-match", arg_len)) {
1309
0
        LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "modifier");
1310
0
        return LY_EVALID;
1311
0
    }
1312
1313
    /* replace the value in the dictionary */
1314
0
    buf = malloc(strlen(*pat) + 1);
1315
0
    LY_CHECK_ERR_RET(!buf, LOGMEM(PARSER_CTX(ctx)), LY_EMEM);
1316
0
    strcpy(buf, *pat);
1317
0
    lydict_remove(PARSER_CTX(ctx), *pat);
1318
1319
0
    assert(buf[0] == LYSP_RESTR_PATTERN_ACK);
1320
0
    buf[0] = LYSP_RESTR_PATTERN_NACK;
1321
0
    LY_CHECK_RET(lydict_insert_zc(PARSER_CTX(ctx), buf, pat));
1322
1323
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1324
0
        switch (child->kw) {
1325
0
        case LY_STMT_EXTENSION_INSTANCE:
1326
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_MODIFIER, 0, exts));
1327
0
            break;
1328
0
        default:
1329
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "modifier");
1330
0
            return LY_EVALID;
1331
0
        }
1332
0
    }
1333
0
    return LY_SUCCESS;
1334
0
}
1335
1336
/**
1337
 * @brief Parse the pattern statement. Substatement of type statement.
1338
 *
1339
 * @param[in] ctx parser context.
1340
 * @param[in] stmt Source statement data from the parsed extension instance.
1341
 * @param[in,out] patterns Restrictions to add to.
1342
 *
1343
 * @return LY_ERR values.
1344
 */
1345
static LY_ERR
1346
lysp_stmt_type_pattern(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_restr **patterns)
1347
0
{
1348
0
    char *buf;
1349
0
    size_t arg_len;
1350
0
    struct lysp_restr *restr;
1351
1352
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
1353
0
    LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *patterns, restr, LY_EMEM);
1354
0
    arg_len = strlen(stmt->arg);
1355
1356
    /* add special meaning first byte */
1357
0
    buf = malloc(arg_len + 2);
1358
0
    LY_CHECK_ERR_RET(!buf, LOGMEM(PARSER_CTX(ctx)), LY_EMEM);
1359
0
    memmove(buf + 1, stmt->arg, arg_len);
1360
0
    buf[0] = LYSP_RESTR_PATTERN_ACK; /* pattern's default regular-match flag */
1361
0
    buf[arg_len + 1] = '\0'; /* terminating NULL byte */
1362
0
    LY_CHECK_RET(lydict_insert_zc(PARSER_CTX(ctx), buf, &restr->arg.str));
1363
0
    restr->arg.mod = PARSER_CUR_PMOD(ctx);
1364
1365
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1366
0
        switch (child->kw) {
1367
0
        case LY_STMT_DESCRIPTION:
1368
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &restr->dsc, Y_STR_ARG, &restr->exts));
1369
0
            break;
1370
0
        case LY_STMT_REFERENCE:
1371
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &restr->ref, Y_STR_ARG, &restr->exts));
1372
0
            break;
1373
0
        case LY_STMT_ERROR_APP_TAG:
1374
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &restr->eapptag, Y_STR_ARG, &restr->exts));
1375
0
            break;
1376
0
        case LY_STMT_ERROR_MESSAGE:
1377
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &restr->emsg, Y_STR_ARG, &restr->exts));
1378
0
            break;
1379
0
        case LY_STMT_MODIFIER:
1380
0
            PARSER_CHECK_STMTVER2_RET(ctx, "modifier", "pattern");
1381
0
            LY_CHECK_RET(lysp_stmt_type_pattern_modifier(ctx, child, &restr->arg.str, &restr->exts));
1382
0
            break;
1383
0
        case LY_STMT_EXTENSION_INSTANCE:
1384
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_PATTERN, 0, &restr->exts));
1385
0
            break;
1386
0
        default:
1387
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "pattern");
1388
0
            return LY_EVALID;
1389
0
        }
1390
0
    }
1391
0
    return LY_SUCCESS;
1392
0
}
1393
1394
/**
1395
 * @brief Parse the deviate statement. Substatement of deviation statement.
1396
 *
1397
 * @param[in] ctx parser context.
1398
 * @param[in] stmt Source statement data from the parsed extension instance.
1399
 * @param[in,out] devs Array of deviates to add to.
1400
 * @param[in,out] exts Extension instances to add to.
1401
 * @return LY_ERR values.
1402
 */
1403
static LY_ERR
1404
lysp_stmt_deviate(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_deviate **devs, struct lysp_ext_instance **exts)
1405
0
{
1406
0
    (void)stmt;
1407
0
    (void)devs;
1408
0
    (void)exts;
1409
1410
    /* TODO */
1411
0
    LOGERR(PARSER_CTX(ctx), LY_EINVAL, "Extension instance \"deviate\" substatement is not supported.");
1412
0
    return LY_EINVAL;
1413
0
}
1414
1415
/**
1416
 * @brief Parse the deviation statement.
1417
 *
1418
 * @param[in] ctx parser context.
1419
 * @param[in] stmt Source statement data from the parsed extension instance.
1420
 * @param[in,out] deviations Array of deviations to add to.
1421
 * @return LY_ERR values.
1422
 */
1423
static LY_ERR
1424
lysp_stmt_deviation(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_deviation **deviations)
1425
0
{
1426
0
    struct lysp_deviation *dev;
1427
1428
0
    LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *deviations, dev, LY_EMEM);
1429
1430
    /* store nodeid */
1431
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
1432
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &dev->nodeid));
1433
1434
    /* parse substatements */
1435
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1436
0
        switch (child->kw) {
1437
0
        case LY_STMT_DESCRIPTION:
1438
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &dev->dsc, Y_STR_ARG, &dev->exts));
1439
0
            break;
1440
0
        case LY_STMT_DEVIATE:
1441
0
            LY_CHECK_RET(lysp_stmt_deviate(ctx, child, &dev->deviates, &dev->exts));
1442
0
            break;
1443
0
        case LY_STMT_REFERENCE:
1444
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &dev->ref, Y_STR_ARG, &dev->exts));
1445
0
            break;
1446
0
        case LY_STMT_EXTENSION_INSTANCE:
1447
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, &dev->exts));
1448
0
            break;
1449
0
        default:
1450
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), lyplg_ext_stmt2str(LY_STMT_DEVIATION));
1451
0
            return LY_EVALID;
1452
0
        }
1453
0
    }
1454
1455
0
    return LY_SUCCESS;
1456
0
}
1457
1458
/**
1459
 * @brief Parse the yang-version statement.
1460
 *
1461
 * @param[in] ctx parser context.
1462
 * @param[in] stmt Source statement data from the parsed extension instance.
1463
 * @param[out] version Version to write to.
1464
 * @param[in,out] exts Extension instances to add to.
1465
 * @return LY_ERR values.
1466
 */
1467
static LY_ERR
1468
lysp_stmt_yangver(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, uint8_t *version, struct lysp_ext_instance **exts)
1469
0
{
1470
0
    if (*version) {
1471
0
        LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "yin-element");
1472
0
        return LY_EVALID;
1473
0
    }
1474
1475
    /* store flag */
1476
0
    if (!strcmp(stmt->arg, "1")) {
1477
0
        *version = LYS_VERSION_1_0;
1478
0
    } else if (!strcmp(stmt->arg, "1.1")) {
1479
0
        *version = LYS_VERSION_1_1;
1480
0
    } else {
1481
0
        LOGVAL_PARSER(ctx, LY_VCODE_INVAL, (int)strlen(stmt->arg), stmt->arg, "yang-version");
1482
0
        return LY_EVALID;
1483
0
    }
1484
1485
    /* parse substatements */
1486
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1487
0
        switch (child->kw) {
1488
0
        case LY_STMT_EXTENSION_INSTANCE:
1489
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, exts));
1490
0
            break;
1491
0
        default:
1492
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), lyplg_ext_stmt2str(LY_STMT_YANG_VERSION));
1493
0
            return LY_EVALID;
1494
0
        }
1495
0
    }
1496
1497
0
    return LY_SUCCESS;
1498
0
}
1499
1500
/**
1501
 * @brief Parse the module statement.
1502
 *
1503
 * @param[in] ctx parser context.
1504
 * @param[in] stmt Source statement data from the parsed extension instance.
1505
 * @param[in,out] mod Module to fill.
1506
 * @return LY_ERR values.
1507
 */
1508
static LY_ERR
1509
lysp_stmt_module(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_module *mod)
1510
0
{
1511
0
    (void)stmt;
1512
0
    (void)mod;
1513
1514
    /* TODO */
1515
0
    LOGERR(PARSER_CTX(ctx), LY_EINVAL, "Extension instance \"module\" substatement is not supported.");
1516
0
    return LY_EINVAL;
1517
0
}
1518
1519
/**
1520
 * @brief Parse the submodule statement.
1521
 *
1522
 * @param[in] ctx parser context.
1523
 * @param[in] stmt Source statement data from the parsed extension instance.
1524
 * @param[in,out] submod Module to fill.
1525
 * @return LY_ERR values.
1526
 */
1527
static LY_ERR
1528
lysp_stmt_submodule(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_submodule *submod)
1529
0
{
1530
0
    (void)stmt;
1531
0
    (void)submod;
1532
1533
    /* TODO */
1534
0
    LOGERR(PARSER_CTX(ctx), LY_EINVAL, "Extension instance \"submodule\" substatement is not supported.");
1535
0
    return LY_EINVAL;
1536
0
}
1537
1538
/**
1539
 * @brief Parse the yin-element statement. Substatement of argument statement.
1540
 *
1541
 * @param[in] ctx parser context.
1542
 * @param[in] stmt Source statement data from the parsed extension instance.
1543
 * @param[in,out] flags Flags to write to.
1544
 * @param[in,out] exts Extension instances to add to.
1545
 * @return LY_ERR values.
1546
 */
1547
static LY_ERR
1548
lysp_stmt_yinelem(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, uint16_t *flags, struct lysp_ext_instance **exts)
1549
0
{
1550
0
    if (*flags & LYS_YINELEM_MASK) {
1551
0
        LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "yin-element");
1552
0
        return LY_EVALID;
1553
0
    }
1554
1555
    /* store flag */
1556
0
    if (!strcmp(stmt->arg, "true")) {
1557
0
        *flags |= LYS_YINELEM_TRUE;
1558
0
    } else if (!strcmp(stmt->arg, "false")) {
1559
0
        *flags |= LYS_YINELEM_FALSE;
1560
0
    } else {
1561
0
        LOGVAL_PARSER(ctx, LY_VCODE_INVAL, (int)strlen(stmt->arg), stmt->arg, "yin-element");
1562
0
        return LY_EVALID;
1563
0
    }
1564
1565
    /* parse substatements */
1566
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1567
0
        switch (child->kw) {
1568
0
        case LY_STMT_EXTENSION_INSTANCE:
1569
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, exts));
1570
0
            break;
1571
0
        default:
1572
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), lyplg_ext_stmt2str(LY_STMT_YIN_ELEMENT));
1573
0
            return LY_EVALID;
1574
0
        }
1575
0
    }
1576
1577
0
    return LY_SUCCESS;
1578
0
}
1579
1580
/**
1581
 * @brief Parse the argument statement. Substatement of extension statement.
1582
 *
1583
 * @param[in] ctx parser context.
1584
 * @param[in] stmt Source statement data from the parsed extension instance.
1585
 * @param[in,out] ex Extension to fill.
1586
 * @return LY_ERR values.
1587
 */
1588
static LY_ERR
1589
lysp_stmt_argument(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_ext *ex)
1590
0
{
1591
0
    if (ex->argname) {
1592
0
        LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "argument");
1593
0
        return LY_EVALID;
1594
0
    }
1595
1596
    /* store argument name */
1597
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_PREF_IDENTIF_ARG, stmt->arg));
1598
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &ex->argname));
1599
1600
    /* parse substatements */
1601
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1602
0
        switch (child->kw) {
1603
0
        case LY_STMT_YIN_ELEMENT:
1604
0
            LY_CHECK_RET(lysp_stmt_yinelem(ctx, child, &ex->flags, &ex->exts));
1605
0
            break;
1606
0
        case LY_STMT_EXTENSION_INSTANCE:
1607
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, &ex->exts));
1608
0
            break;
1609
0
        default:
1610
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), lyplg_ext_stmt2str(LY_STMT_ARGUMENT));
1611
0
            return LY_EVALID;
1612
0
        }
1613
0
    }
1614
1615
0
    return LY_SUCCESS;
1616
0
}
1617
1618
/**
1619
 * @brief Parse the extension statement.
1620
 *
1621
 * @param[in] ctx parser context.
1622
 * @param[in] stmt Source statement data from the parsed extension instance.
1623
 * @param[in,out] extensions Array of extensions to add to.
1624
 * @return LY_ERR values.
1625
 */
1626
static LY_ERR
1627
lysp_stmt_extension(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_ext **extensions)
1628
0
{
1629
0
    struct lysp_ext *ex;
1630
1631
0
    LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *extensions, ex, LY_EMEM);
1632
1633
    /* store name */
1634
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
1635
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &ex->name));
1636
1637
    /* parse substatements */
1638
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1639
0
        switch (child->kw) {
1640
0
        case LY_STMT_DESCRIPTION:
1641
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &ex->dsc, Y_STR_ARG, &ex->exts));
1642
0
            break;
1643
0
        case LY_STMT_REFERENCE:
1644
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &ex->ref, Y_STR_ARG, &ex->exts));
1645
0
            break;
1646
0
        case LY_STMT_STATUS:
1647
0
            LY_CHECK_RET(lysp_stmt_status(ctx, child, &ex->flags, &ex->exts));
1648
0
            break;
1649
0
        case LY_STMT_ARGUMENT:
1650
0
            LY_CHECK_RET(lysp_stmt_argument(ctx, child, ex));
1651
0
            break;
1652
0
        case LY_STMT_EXTENSION_INSTANCE:
1653
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, &ex->exts));
1654
0
            break;
1655
0
        default:
1656
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), lyplg_ext_stmt2str(LY_STMT_EXTENSION));
1657
0
            return LY_EVALID;
1658
0
        }
1659
0
    }
1660
1661
0
    return LY_SUCCESS;
1662
0
}
1663
1664
/**
1665
 * @brief Parse the feature statement.
1666
 *
1667
 * @param[in] ctx parser context.
1668
 * @param[in] stmt Source statement data from the parsed extension instance.
1669
 * @param[in,out] features Array of features to add to.
1670
 * @return LY_ERR values.
1671
 */
1672
static LY_ERR
1673
lysp_stmt_feature(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_feature **features)
1674
0
{
1675
0
    struct lysp_feature *feat;
1676
1677
0
    LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *features, feat, LY_EMEM);
1678
1679
    /* store name */
1680
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
1681
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &feat->name));
1682
1683
    /* parse substatements */
1684
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1685
0
        switch (child->kw) {
1686
0
        case LY_STMT_DESCRIPTION:
1687
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &feat->dsc, Y_STR_ARG, &feat->exts));
1688
0
            break;
1689
0
        case LY_STMT_IF_FEATURE:
1690
0
            LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &feat->iffeatures, Y_STR_ARG, &feat->exts));
1691
0
            break;
1692
0
        case LY_STMT_REFERENCE:
1693
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &feat->ref, Y_STR_ARG, &feat->exts));
1694
0
            break;
1695
0
        case LY_STMT_STATUS:
1696
0
            LY_CHECK_RET(lysp_stmt_status(ctx, child, &feat->flags, &feat->exts));
1697
0
            break;
1698
0
        case LY_STMT_EXTENSION_INSTANCE:
1699
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, &feat->exts));
1700
0
            break;
1701
0
        default:
1702
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), lyplg_ext_stmt2str(LY_STMT_FEATURE));
1703
0
            return LY_EVALID;
1704
0
        }
1705
0
    }
1706
1707
0
    return LY_SUCCESS;
1708
0
}
1709
1710
/**
1711
 * @brief Parse the identity statement.
1712
 *
1713
 * @param[in] ctx parser context.
1714
 * @param[in] stmt Source statement data from the parsed extension instance.
1715
 * @param[in,out] identities Array of identities to add to.
1716
 * @return LY_ERR values.
1717
 */
1718
static LY_ERR
1719
lysp_stmt_identity(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_ident **identities)
1720
0
{
1721
0
    struct lysp_ident *ident;
1722
1723
0
    LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *identities, ident, LY_EMEM);
1724
1725
    /* store name */
1726
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
1727
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &ident->name));
1728
1729
    /* parse substatements */
1730
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1731
0
        switch (child->kw) {
1732
0
        case LY_STMT_DESCRIPTION:
1733
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &ident->dsc, Y_STR_ARG, &ident->exts));
1734
0
            break;
1735
0
        case LY_STMT_IF_FEATURE:
1736
0
            LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &ident->iffeatures, Y_STR_ARG, &ident->exts));
1737
0
            break;
1738
0
        case LY_STMT_REFERENCE:
1739
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &ident->ref, Y_STR_ARG, &ident->exts));
1740
0
            break;
1741
0
        case LY_STMT_STATUS:
1742
0
            LY_CHECK_RET(lysp_stmt_status(ctx, child, &ident->flags, &ident->exts));
1743
0
            break;
1744
0
        case LY_STMT_BASE:
1745
0
            LY_CHECK_RET(lysp_stmt_text_fields(ctx, child, &ident->bases, Y_PREF_IDENTIF_ARG, &ident->exts));
1746
0
            break;
1747
0
        case LY_STMT_EXTENSION_INSTANCE:
1748
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, &ident->exts));
1749
0
            break;
1750
0
        default:
1751
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), lyplg_ext_stmt2str(LY_STMT_IDENTITY));
1752
0
            return LY_EVALID;
1753
0
        }
1754
0
    }
1755
1756
0
    return LY_SUCCESS;
1757
0
}
1758
1759
/**
1760
 * @brief Parse the import statement.
1761
 *
1762
 * @param[in] ctx parser context.
1763
 * @param[in] stmt Source statement data from the parsed extension instance.
1764
 * @param[in,out] imports Array of imports to add to.
1765
 * @return LY_ERR values.
1766
 */
1767
static LY_ERR
1768
lysp_stmt_import(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_import **imports)
1769
0
{
1770
0
    struct lysp_import *imp;
1771
0
    const char *str = NULL;
1772
1773
0
    LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *imports, imp, LY_EMEM);
1774
1775
    /* store name */
1776
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
1777
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &imp->name));
1778
1779
    /* parse substatements */
1780
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1781
0
        switch (child->kw) {
1782
0
        case LY_STMT_PREFIX:
1783
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &imp->prefix, Y_IDENTIF_ARG, &imp->exts));
1784
0
            LY_CHECK_RET(lysp_check_prefix(ctx, *imports, NULL, &imp->prefix), LY_EVALID);
1785
0
            break;
1786
0
        case LY_STMT_DESCRIPTION:
1787
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &imp->dsc, Y_STR_ARG, &imp->exts));
1788
0
            break;
1789
0
        case LY_STMT_REFERENCE:
1790
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &imp->ref, Y_STR_ARG, &imp->exts));
1791
0
            break;
1792
0
        case LY_STMT_REVISION_DATE:
1793
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, stmt, 0, &str, Y_STR_ARG, &imp->exts));
1794
0
            strcpy(imp->rev, str);
1795
0
            lydict_remove(PARSER_CTX(ctx), str);
1796
0
            LY_CHECK_RET(lysp_check_date(ctx, imp->rev, LY_REV_SIZE - 1, "revision-date"));
1797
0
            break;
1798
0
        case LY_STMT_EXTENSION_INSTANCE:
1799
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, &imp->exts));
1800
0
            break;
1801
0
        default:
1802
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), lyplg_ext_stmt2str(LY_STMT_IMPORT));
1803
0
            return LY_EVALID;
1804
0
        }
1805
0
    }
1806
1807
0
    return LY_SUCCESS;
1808
0
}
1809
1810
/**
1811
 * @brief Parse the include statement.
1812
 *
1813
 * @param[in] ctx parser context.
1814
 * @param[in] stmt Source statement data from the parsed extension instance.
1815
 * @param[in,out] includes Array of identities to add to.
1816
 * @return LY_ERR values.
1817
 */
1818
static LY_ERR
1819
lysp_stmt_include(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_include **includes)
1820
0
{
1821
0
    struct lysp_include *inc;
1822
0
    const char *str = NULL;
1823
1824
0
    LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *includes, inc, LY_EMEM);
1825
1826
    /* store name */
1827
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
1828
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &inc->name));
1829
1830
    /* parse substatements */
1831
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1832
0
        switch (child->kw) {
1833
0
        case LY_STMT_DESCRIPTION:
1834
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &inc->dsc, Y_STR_ARG, &inc->exts));
1835
0
            break;
1836
0
        case LY_STMT_REFERENCE:
1837
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &inc->ref, Y_STR_ARG, &inc->exts));
1838
0
            break;
1839
0
        case LY_STMT_REVISION_DATE:
1840
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, stmt, 0, &str, Y_STR_ARG, &inc->exts));
1841
0
            strcpy(inc->rev, str);
1842
0
            lydict_remove(PARSER_CTX(ctx), str);
1843
0
            LY_CHECK_RET(lysp_check_date(ctx, inc->rev, LY_REV_SIZE - 1, "revision-date"));
1844
0
            break;
1845
0
        case LY_STMT_EXTENSION_INSTANCE:
1846
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, &inc->exts));
1847
0
            break;
1848
0
        default:
1849
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), lyplg_ext_stmt2str(LY_STMT_INCLUDE));
1850
0
            return LY_EVALID;
1851
0
        }
1852
0
    }
1853
1854
0
    return LY_SUCCESS;
1855
0
}
1856
1857
/**
1858
 * @brief Parse the revision statement.
1859
 *
1860
 * @param[in] ctx parser context.
1861
 * @param[in] stmt Source statement data from the parsed extension instance.
1862
 * @param[in,out] includes Array of identities to add to.
1863
 * @return LY_ERR values.
1864
 */
1865
static LY_ERR
1866
lysp_stmt_revision(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_revision **revs)
1867
0
{
1868
0
    struct lysp_revision *rev;
1869
1870
0
    LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *revs, rev, LY_EMEM);
1871
1872
    /* store date */
1873
0
    LY_CHECK_RET(lysp_check_date(ctx, stmt->arg, strlen(stmt->arg), "revision"));
1874
0
    strncpy(rev->date, stmt->arg, LY_REV_SIZE - 1);
1875
1876
    /* parse substatements */
1877
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1878
0
        switch (child->kw) {
1879
0
        case LY_STMT_DESCRIPTION:
1880
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &rev->dsc, Y_STR_ARG, &rev->exts));
1881
0
            break;
1882
0
        case LY_STMT_REFERENCE:
1883
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &rev->ref, Y_STR_ARG, &rev->exts));
1884
0
            break;
1885
0
        case LY_STMT_EXTENSION_INSTANCE:
1886
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, &rev->exts));
1887
0
            break;
1888
0
        default:
1889
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), lyplg_ext_stmt2str(LY_STMT_REVISION));
1890
0
            return LY_EVALID;
1891
0
        }
1892
0
    }
1893
1894
0
    return LY_SUCCESS;
1895
0
}
1896
1897
/**
1898
 * @brief Parse the type statement.
1899
 *
1900
 * @param[in] ctx parser context.
1901
 * @param[in] stmt Source statement data from the parsed extension instance.
1902
 * @param[in,out] type Type to wrote to.
1903
 *
1904
 * @return LY_ERR values.
1905
 */
1906
static LY_ERR
1907
lysp_stmt_type(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_type *type)
1908
323k
{
1909
323k
    struct lysp_type *nest_type;
1910
323k
    const char *str_path = NULL;
1911
323k
    LY_ERR ret;
1912
1913
323k
    if (type->name) {
1914
0
        LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "type");
1915
0
        return LY_EVALID;
1916
0
    }
1917
1918
323k
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_PREF_IDENTIF_ARG, stmt->arg));
1919
323k
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &type->name));
1920
323k
    type->pmod = PARSER_CUR_PMOD(ctx);
1921
1922
647k
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
1923
323k
        switch (child->kw) {
1924
0
        case LY_STMT_BASE:
1925
0
            LY_CHECK_RET(lysp_stmt_text_fields(ctx, child, &type->bases, Y_PREF_IDENTIF_ARG, &type->exts));
1926
0
            type->flags |= LYS_SET_BASE;
1927
0
            break;
1928
0
        case LY_STMT_BIT:
1929
0
            LY_CHECK_RET(lysp_stmt_type_enum(ctx, child, &type->bits));
1930
0
            type->flags |= LYS_SET_BIT;
1931
0
            break;
1932
143k
        case LY_STMT_ENUM:
1933
143k
            LY_CHECK_RET(lysp_stmt_type_enum(ctx, child, &type->enums));
1934
143k
            type->flags |= LYS_SET_ENUM;
1935
143k
            break;
1936
0
        case LY_STMT_FRACTION_DIGITS:
1937
0
            LY_CHECK_RET(lysp_stmt_type_fracdigits(ctx, child, &type->fraction_digits, &type->exts));
1938
0
            type->flags |= LYS_SET_FRDIGITS;
1939
0
            break;
1940
0
        case LY_STMT_LENGTH:
1941
0
            if (type->length) {
1942
0
                LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, lyplg_ext_stmt2str(child->kw));
1943
0
                return LY_EVALID;
1944
0
            }
1945
0
            type->length = calloc(1, sizeof *type->length);
1946
0
            LY_CHECK_ERR_RET(!type->length, LOGMEM(PARSER_CTX(ctx)), LY_EMEM);
1947
1948
0
            LY_CHECK_RET(lysp_stmt_restr(ctx, child, type->length));
1949
0
            type->flags |= LYS_SET_LENGTH;
1950
0
            break;
1951
0
        case LY_STMT_PATH:
1952
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &str_path, Y_STR_ARG, &type->exts));
1953
0
            ret = ly_path_parse(PARSER_CTX(ctx), NULL, str_path, 0, 1, LY_PATH_BEGIN_EITHER,
1954
0
                    LY_PATH_PREFIX_OPTIONAL, LY_PATH_PRED_LEAFREF, &type->path);
1955
0
            lydict_remove(PARSER_CTX(ctx), str_path);
1956
0
            LY_CHECK_RET(ret);
1957
0
            type->flags |= LYS_SET_PATH;
1958
0
            break;
1959
0
        case LY_STMT_PATTERN:
1960
0
            LY_CHECK_RET(lysp_stmt_type_pattern(ctx, child, &type->patterns));
1961
0
            type->flags |= LYS_SET_PATTERN;
1962
0
            break;
1963
35.9k
        case LY_STMT_RANGE:
1964
35.9k
            if (type->range) {
1965
0
                LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, lyplg_ext_stmt2str(child->kw));
1966
0
                return LY_EVALID;
1967
0
            }
1968
35.9k
            type->range = calloc(1, sizeof *type->range);
1969
35.9k
            LY_CHECK_ERR_RET(!type->range, LOGMEM(PARSER_CTX(ctx)), LY_EMEM);
1970
1971
35.9k
            LY_CHECK_RET(lysp_stmt_restr(ctx, child, type->range));
1972
35.9k
            type->flags |= LYS_SET_RANGE;
1973
35.9k
            break;
1974
0
        case LY_STMT_REQUIRE_INSTANCE:
1975
0
            LY_CHECK_RET(lysp_stmt_type_reqinstance(ctx, child, &type->require_instance, &type->flags, &type->exts));
1976
            /* LYS_SET_REQINST checked and set inside lysp_stmt_type_reqinstance() */
1977
0
            break;
1978
143k
        case LY_STMT_TYPE:
1979
143k
            LY_ARRAY_NEW_RET(PARSER_CTX(ctx), type->types, nest_type, LY_EMEM);
1980
143k
            LY_CHECK_RET(lysp_stmt_type(ctx, child, nest_type));
1981
143k
            type->flags |= LYS_SET_TYPE;
1982
143k
            break;
1983
0
        case LY_STMT_EXTENSION_INSTANCE:
1984
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_TYPE, 0, &type->exts));
1985
0
            break;
1986
0
        default:
1987
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "type");
1988
0
            return LY_EVALID;
1989
323k
        }
1990
323k
    }
1991
323k
    return LY_SUCCESS;
1992
323k
}
1993
1994
/**
1995
 * @brief Parse the leaf statement.
1996
 *
1997
 * @param[in] ctx parser context.
1998
 * @param[in] stmt Source statement data from the parsed extension instance.
1999
 * @param[in] parent Parent node to connect to (not into).
2000
 * @param[in,out] siblings Siblings to add to.
2001
 *
2002
 * @return LY_ERR values.
2003
 */
2004
static LY_ERR
2005
lysp_stmt_leaf(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent, struct lysp_node **siblings)
2006
0
{
2007
0
    struct lysp_node_leaf *leaf;
2008
2009
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
2010
2011
    /* create new leaf structure */
2012
0
    LY_LIST_NEW_RET(PARSER_CTX(ctx), siblings, leaf, next, LY_EMEM);
2013
0
    leaf->nodetype = LYS_LEAF;
2014
0
    leaf->parent = parent;
2015
2016
    /* get name */
2017
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &leaf->name));
2018
2019
    /* parse substatements */
2020
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
2021
0
        switch (child->kw) {
2022
0
        case LY_STMT_CONFIG:
2023
0
            LY_CHECK_RET(lysp_stmt_config(ctx, child, &leaf->flags, &leaf->exts));
2024
0
            break;
2025
0
        case LY_STMT_DEFAULT:
2026
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &leaf->dflt.str, Y_STR_ARG, &leaf->exts));
2027
0
            leaf->dflt.mod = PARSER_CUR_PMOD(ctx);
2028
0
            break;
2029
0
        case LY_STMT_DESCRIPTION:
2030
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &leaf->dsc, Y_STR_ARG, &leaf->exts));
2031
0
            break;
2032
0
        case LY_STMT_IF_FEATURE:
2033
0
            LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &leaf->iffeatures, Y_STR_ARG, &leaf->exts));
2034
0
            break;
2035
0
        case LY_STMT_MANDATORY:
2036
0
            LY_CHECK_RET(lysp_stmt_mandatory(ctx, child, &leaf->flags, &leaf->exts));
2037
0
            break;
2038
0
        case LY_STMT_MUST:
2039
0
            LY_CHECK_RET(lysp_stmt_restrs(ctx, child, &leaf->musts));
2040
0
            break;
2041
0
        case LY_STMT_REFERENCE:
2042
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &leaf->ref, Y_STR_ARG, &leaf->exts));
2043
0
            break;
2044
0
        case LY_STMT_STATUS:
2045
0
            LY_CHECK_RET(lysp_stmt_status(ctx, child, &leaf->flags, &leaf->exts));
2046
0
            break;
2047
0
        case LY_STMT_TYPE:
2048
0
            LY_CHECK_RET(lysp_stmt_type(ctx, child, &leaf->type));
2049
0
            break;
2050
0
        case LY_STMT_UNITS:
2051
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &leaf->units, Y_STR_ARG, &leaf->exts));
2052
0
            break;
2053
0
        case LY_STMT_WHEN:
2054
0
            LY_CHECK_RET(lysp_stmt_when(ctx, child, &leaf->when));
2055
0
            break;
2056
0
        case LY_STMT_EXTENSION_INSTANCE:
2057
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_LEAF, 0, &leaf->exts));
2058
0
            break;
2059
0
        default:
2060
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "leaf");
2061
0
            return LY_EVALID;
2062
0
        }
2063
0
    }
2064
2065
    /* mandatory substatements */
2066
0
    if (!leaf->type.name) {
2067
0
        LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "type", "leaf");
2068
0
        return LY_EVALID;
2069
0
    }
2070
2071
0
    return LY_SUCCESS;
2072
0
}
2073
2074
/**
2075
 * @brief Parse the max-elements statement.
2076
 *
2077
 * @param[in] ctx parser context.
2078
 * @param[in] stmt Source statement data from the parsed extension instance.
2079
 * @param[in,out] max Value to write to.
2080
 * @param[in,out] flags Flags to write to.
2081
 * @param[in,out] exts Extension instances to add to.
2082
 *
2083
 * @return LY_ERR values.
2084
 */
2085
static LY_ERR
2086
lysp_stmt_maxelements(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, uint32_t *max, uint16_t *flags,
2087
        struct lysp_ext_instance **exts)
2088
0
{
2089
0
    int arg_len;
2090
0
    char *ptr;
2091
0
    unsigned long long num;
2092
2093
0
    if (*flags & LYS_SET_MAX) {
2094
0
        LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "max-elements");
2095
0
        return LY_EVALID;
2096
0
    }
2097
0
    *flags |= LYS_SET_MAX;
2098
2099
    /* get value */
2100
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
2101
0
    arg_len = strlen(stmt->arg);
2102
2103
0
    if (!arg_len || (stmt->arg[0] == '0') || ((stmt->arg[0] != 'u') && !isdigit(stmt->arg[0]))) {
2104
0
        LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "max-elements");
2105
0
        return LY_EVALID;
2106
0
    }
2107
2108
0
    if ((arg_len != ly_strlen_const("unbounded")) || strncmp(stmt->arg, "unbounded", arg_len)) {
2109
0
        errno = 0;
2110
0
        num = strtoull(stmt->arg, &ptr, LY_BASE_DEC);
2111
        /* we have not parsed the whole argument */
2112
0
        if (ptr - stmt->arg != arg_len) {
2113
0
            LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "max-elements");
2114
0
            return LY_EVALID;
2115
0
        }
2116
0
        if ((errno == ERANGE) || (num > UINT32_MAX)) {
2117
0
            LOGVAL_PARSER(ctx, LY_VCODE_OOB, arg_len, stmt->arg, "max-elements");
2118
0
            return LY_EVALID;
2119
0
        }
2120
2121
0
        *max = num;
2122
0
    } else {
2123
        /* unbounded */
2124
0
        *max = 0;
2125
0
    }
2126
2127
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
2128
0
        switch (child->kw) {
2129
0
        case LY_STMT_EXTENSION_INSTANCE:
2130
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_MAX_ELEMENTS, 0, exts));
2131
0
            break;
2132
0
        default:
2133
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "max-elements");
2134
0
            return LY_EVALID;
2135
0
        }
2136
0
    }
2137
2138
0
    return LY_SUCCESS;
2139
0
}
2140
2141
/**
2142
 * @brief Parse the min-elements statement.
2143
 *
2144
 * @param[in] ctx parser context.
2145
 * @param[in] stmt Source statement data from the parsed extension instance.
2146
 * @param[in,out] min Value to write to.
2147
 * @param[in,out] flags Flags to write to.
2148
 * @param[in,out] exts Extension instances to add to.
2149
 * @return LY_ERR values.
2150
 */
2151
static LY_ERR
2152
lysp_stmt_minelements(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, uint32_t *min, uint16_t *flags,
2153
        struct lysp_ext_instance **exts)
2154
0
{
2155
0
    int arg_len;
2156
0
    char *ptr;
2157
0
    unsigned long long num;
2158
2159
0
    if (*flags & LYS_SET_MIN) {
2160
0
        LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "min-elements");
2161
0
        return LY_EVALID;
2162
0
    }
2163
0
    *flags |= LYS_SET_MIN;
2164
2165
    /* get value */
2166
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
2167
0
    arg_len = strlen(stmt->arg);
2168
2169
0
    if (!arg_len || !isdigit(stmt->arg[0]) || ((stmt->arg[0] == '0') && (arg_len > 1))) {
2170
0
        LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "min-elements");
2171
0
        return LY_EVALID;
2172
0
    }
2173
2174
0
    errno = 0;
2175
0
    num = strtoull(stmt->arg, &ptr, LY_BASE_DEC);
2176
    /* we have not parsed the whole argument */
2177
0
    if (ptr - stmt->arg != arg_len) {
2178
0
        LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "min-elements");
2179
0
        return LY_EVALID;
2180
0
    }
2181
0
    if ((errno == ERANGE) || (num > UINT32_MAX)) {
2182
0
        LOGVAL_PARSER(ctx, LY_VCODE_OOB, arg_len, stmt->arg, "min-elements");
2183
0
        return LY_EVALID;
2184
0
    }
2185
0
    *min = num;
2186
2187
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
2188
0
        switch (child->kw) {
2189
0
        case LY_STMT_EXTENSION_INSTANCE:
2190
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_MIN_ELEMENTS, 0, exts));
2191
0
            break;
2192
0
        default:
2193
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "min-elements");
2194
0
            return LY_EVALID;
2195
0
        }
2196
0
    }
2197
2198
0
    return LY_SUCCESS;
2199
0
}
2200
2201
/**
2202
 * @brief Parse the ordered-by statement.
2203
 *
2204
 * @param[in] ctx parser context.
2205
 * @param[in] stmt Source statement data from the parsed extension instance.
2206
 * @param[in,out] flags Flags to write to.
2207
 * @param[in,out] exts Extension instances to add to.
2208
 * @return LY_ERR values.
2209
 */
2210
static LY_ERR
2211
lysp_stmt_orderedby(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, uint16_t *flags, struct lysp_ext_instance **exts)
2212
0
{
2213
0
    int arg_len;
2214
2215
0
    if (*flags & LYS_ORDBY_MASK) {
2216
0
        LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, "ordered-by");
2217
0
        return LY_EVALID;
2218
0
    }
2219
2220
    /* get value */
2221
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
2222
0
    arg_len = strlen(stmt->arg);
2223
0
    if ((arg_len == ly_strlen_const("system")) && !strncmp(stmt->arg, "system", arg_len)) {
2224
0
        *flags |= LYS_MAND_TRUE;
2225
0
    } else if ((arg_len == ly_strlen_const("user")) && !strncmp(stmt->arg, "user", arg_len)) {
2226
0
        *flags |= LYS_MAND_FALSE;
2227
0
    } else {
2228
0
        LOGVAL_PARSER(ctx, LY_VCODE_INVAL, arg_len, stmt->arg, "ordered-by");
2229
0
        return LY_EVALID;
2230
0
    }
2231
2232
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
2233
0
        switch (child->kw) {
2234
0
        case LY_STMT_EXTENSION_INSTANCE:
2235
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_ORDERED_BY, 0, exts));
2236
0
            break;
2237
0
        default:
2238
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "ordered-by");
2239
0
            return LY_EVALID;
2240
0
        }
2241
0
    }
2242
2243
0
    return LY_SUCCESS;
2244
0
}
2245
2246
/**
2247
 * @brief Parse the leaf-list statement.
2248
 *
2249
 * @param[in] ctx parser context.
2250
 * @param[in] stmt Source statement data from the parsed extension instance.
2251
 * @param[in] parent Parent node to connect to (not into).
2252
 * @param[in,out] siblings Siblings to add to.
2253
 * @return LY_ERR values.
2254
 */
2255
static LY_ERR
2256
lysp_stmt_leaflist(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
2257
        struct lysp_node **siblings)
2258
0
{
2259
0
    struct lysp_node_leaflist *llist;
2260
2261
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
2262
2263
    /* create new leaf-list structure */
2264
0
    LY_LIST_NEW_RET(PARSER_CTX(ctx), siblings, llist, next, LY_EMEM);
2265
0
    llist->nodetype = LYS_LEAFLIST;
2266
0
    llist->parent = parent;
2267
2268
    /* get name */
2269
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &llist->name));
2270
2271
    /* parse substatements */
2272
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
2273
0
        switch (child->kw) {
2274
0
        case LY_STMT_CONFIG:
2275
0
            LY_CHECK_RET(lysp_stmt_config(ctx, child, &llist->flags, &llist->exts));
2276
0
            break;
2277
0
        case LY_STMT_DEFAULT:
2278
0
            PARSER_CHECK_STMTVER2_RET(ctx, "default", "leaf-list");
2279
0
            LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &llist->dflts, Y_STR_ARG, &llist->exts));
2280
0
            break;
2281
0
        case LY_STMT_DESCRIPTION:
2282
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &llist->dsc, Y_STR_ARG, &llist->exts));
2283
0
            break;
2284
0
        case LY_STMT_IF_FEATURE:
2285
0
            LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &llist->iffeatures, Y_STR_ARG, &llist->exts));
2286
0
            break;
2287
0
        case LY_STMT_MAX_ELEMENTS:
2288
0
            LY_CHECK_RET(lysp_stmt_maxelements(ctx, child, &llist->max, &llist->flags, &llist->exts));
2289
0
            break;
2290
0
        case LY_STMT_MIN_ELEMENTS:
2291
0
            LY_CHECK_RET(lysp_stmt_minelements(ctx, child, &llist->min, &llist->flags, &llist->exts));
2292
0
            break;
2293
0
        case LY_STMT_MUST:
2294
0
            LY_CHECK_RET(lysp_stmt_restrs(ctx, child, &llist->musts));
2295
0
            break;
2296
0
        case LY_STMT_ORDERED_BY:
2297
0
            LY_CHECK_RET(lysp_stmt_orderedby(ctx, child, &llist->flags, &llist->exts));
2298
0
            break;
2299
0
        case LY_STMT_REFERENCE:
2300
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &llist->ref, Y_STR_ARG, &llist->exts));
2301
0
            break;
2302
0
        case LY_STMT_STATUS:
2303
0
            LY_CHECK_RET(lysp_stmt_status(ctx, child, &llist->flags, &llist->exts));
2304
0
            break;
2305
0
        case LY_STMT_TYPE:
2306
0
            LY_CHECK_RET(lysp_stmt_type(ctx, child, &llist->type));
2307
0
            break;
2308
0
        case LY_STMT_UNITS:
2309
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &llist->units, Y_STR_ARG, &llist->exts));
2310
0
            break;
2311
0
        case LY_STMT_WHEN:
2312
0
            LY_CHECK_RET(lysp_stmt_when(ctx, child, &llist->when));
2313
0
            break;
2314
0
        case LY_STMT_EXTENSION_INSTANCE:
2315
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_LEAF_LIST, 0, &llist->exts));
2316
0
            break;
2317
0
        default:
2318
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "llist");
2319
0
            return LY_EVALID;
2320
0
        }
2321
0
    }
2322
2323
    /* mandatory substatements */
2324
0
    if (!llist->type.name) {
2325
0
        LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "type", "leaf-list");
2326
0
        return LY_EVALID;
2327
0
    }
2328
2329
0
    return LY_SUCCESS;
2330
0
}
2331
2332
/**
2333
 * @brief Parse the refine statement.
2334
 *
2335
 * @param[in] ctx parser context.
2336
 * @param[in] stmt Source statement data from the parsed extension instance.
2337
 * @param[in,out] refines Refines to add to.
2338
 * @return LY_ERR values.
2339
 */
2340
static LY_ERR
2341
lysp_stmt_refine(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_refine **refines)
2342
0
{
2343
0
    struct lysp_refine *rf;
2344
2345
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
2346
2347
0
    LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *refines, rf, LY_EMEM);
2348
2349
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &rf->nodeid));
2350
2351
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
2352
0
        switch (child->kw) {
2353
0
        case LY_STMT_CONFIG:
2354
0
            LY_CHECK_RET(lysp_stmt_config(ctx, child, &rf->flags, &rf->exts));
2355
0
            break;
2356
0
        case LY_STMT_DEFAULT:
2357
0
            LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &rf->dflts, Y_STR_ARG, &rf->exts));
2358
0
            break;
2359
0
        case LY_STMT_DESCRIPTION:
2360
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &rf->dsc, Y_STR_ARG, &rf->exts));
2361
0
            break;
2362
0
        case LY_STMT_IF_FEATURE:
2363
0
            PARSER_CHECK_STMTVER2_RET(ctx, "if-feature", "refine");
2364
0
            LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &rf->iffeatures, Y_STR_ARG, &rf->exts));
2365
0
            break;
2366
0
        case LY_STMT_MAX_ELEMENTS:
2367
0
            LY_CHECK_RET(lysp_stmt_maxelements(ctx, child, &rf->max, &rf->flags, &rf->exts));
2368
0
            break;
2369
0
        case LY_STMT_MIN_ELEMENTS:
2370
0
            LY_CHECK_RET(lysp_stmt_minelements(ctx, child, &rf->min, &rf->flags, &rf->exts));
2371
0
            break;
2372
0
        case LY_STMT_MUST:
2373
0
            LY_CHECK_RET(lysp_stmt_restrs(ctx, child, &rf->musts));
2374
0
            break;
2375
0
        case LY_STMT_MANDATORY:
2376
0
            LY_CHECK_RET(lysp_stmt_mandatory(ctx, child, &rf->flags, &rf->exts));
2377
0
            break;
2378
0
        case LY_STMT_REFERENCE:
2379
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &rf->ref, Y_STR_ARG, &rf->exts));
2380
0
            break;
2381
0
        case LY_STMT_PRESENCE:
2382
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &rf->presence, Y_STR_ARG, &rf->exts));
2383
0
            break;
2384
0
        case LY_STMT_EXTENSION_INSTANCE:
2385
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_REFINE, 0, &rf->exts));
2386
0
            break;
2387
0
        default:
2388
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "refine");
2389
0
            return LY_EVALID;
2390
0
        }
2391
0
    }
2392
2393
0
    return LY_SUCCESS;
2394
0
}
2395
2396
/**
2397
 * @brief Parse the typedef statement.
2398
 *
2399
 * @param[in] ctx parser context.
2400
 * @param[in] stmt Source statement data from the parsed extension instance.
2401
 * @param[in] parent Parent node to connect to (not into).
2402
 * @param[in,out] typedefs Typedefs to add to.
2403
 *
2404
 * @return LY_ERR values.
2405
 */
2406
static LY_ERR
2407
lysp_stmt_typedef(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
2408
        struct lysp_tpdf **typedefs)
2409
0
{
2410
0
    struct lysp_tpdf *tpdf;
2411
2412
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
2413
2414
0
    LY_ARRAY_NEW_RET(PARSER_CTX(ctx), *typedefs, tpdf, LY_EMEM);
2415
2416
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &tpdf->name));
2417
2418
    /* parse substatements */
2419
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
2420
0
        switch (child->kw) {
2421
0
        case LY_STMT_DEFAULT:
2422
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &tpdf->dflt.str, Y_STR_ARG, &tpdf->exts));
2423
0
            tpdf->dflt.mod = PARSER_CUR_PMOD(ctx);
2424
0
            break;
2425
0
        case LY_STMT_DESCRIPTION:
2426
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &tpdf->dsc, Y_STR_ARG, &tpdf->exts));
2427
0
            break;
2428
0
        case LY_STMT_REFERENCE:
2429
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &tpdf->ref, Y_STR_ARG, &tpdf->exts));
2430
0
            break;
2431
0
        case LY_STMT_STATUS:
2432
0
            LY_CHECK_RET(lysp_stmt_status(ctx, child, &tpdf->flags, &tpdf->exts));
2433
0
            break;
2434
0
        case LY_STMT_TYPE:
2435
0
            LY_CHECK_RET(lysp_stmt_type(ctx, child, &tpdf->type));
2436
0
            break;
2437
0
        case LY_STMT_UNITS:
2438
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &tpdf->units, Y_STR_ARG, &tpdf->exts));
2439
0
            break;
2440
0
        case LY_STMT_EXTENSION_INSTANCE:
2441
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_TYPEDEF, 0, &tpdf->exts));
2442
0
            break;
2443
0
        default:
2444
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "typedef");
2445
0
            return LY_EVALID;
2446
0
        }
2447
0
    }
2448
2449
    /* mandatory substatements */
2450
0
    if (!tpdf->type.name) {
2451
0
        LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "type", "typedef");
2452
0
        return LY_EVALID;
2453
0
    }
2454
2455
    /* store data for collision check */
2456
0
    if (parent && !(parent->nodetype & (LYS_GROUPING | LYS_RPC | LYS_ACTION | LYS_INPUT | LYS_OUTPUT | LYS_NOTIF))) {
2457
0
        LY_CHECK_RET(ly_set_add(&ctx->tpdfs_nodes, parent, 0, NULL));
2458
0
    }
2459
2460
0
    return LY_SUCCESS;
2461
0
}
2462
2463
/**
2464
 * @brief Parse the input or output statement.
2465
 *
2466
 * @param[in] ctx parser context.
2467
 * @param[in] stmt Source statement data from the parsed extension instance.
2468
 * @param[in] parent Parent node to connect to (not into).
2469
 * @param[in,out] inout_p Input/output pointer to write to.
2470
 *
2471
 * @return LY_ERR values.
2472
 */
2473
static LY_ERR
2474
lysp_stmt_inout(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
2475
        struct lysp_node_action_inout *inout_p)
2476
0
{
2477
0
    if (inout_p->nodetype) {
2478
0
        LOGVAL_PARSER(ctx, LY_VCODE_DUPSTMT, lyplg_ext_stmt2str(stmt->kw));
2479
0
        return LY_EVALID;
2480
0
    }
2481
2482
    /* initiate structure */
2483
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->kw == LY_STMT_INPUT ? "input" : "output", 0, &inout_p->name));
2484
0
    inout_p->nodetype = stmt->kw == LY_STMT_INPUT ? LYS_INPUT : LYS_OUTPUT;
2485
0
    inout_p->parent = parent;
2486
2487
    /* parse substatements */
2488
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
2489
0
        switch (child->kw) {
2490
0
        case LY_STMT_ANYDATA:
2491
0
            PARSER_CHECK_STMTVER2_RET(ctx, "anydata", lyplg_ext_stmt2str(stmt->kw));
2492
        /* fall through */
2493
0
        case LY_STMT_ANYXML:
2494
0
            LY_CHECK_RET(lysp_stmt_any(ctx, child, &inout_p->node, &inout_p->child));
2495
0
            break;
2496
0
        case LY_STMT_CHOICE:
2497
0
            LY_CHECK_RET(lysp_stmt_choice(ctx, child, &inout_p->node, &inout_p->child));
2498
0
            break;
2499
0
        case LY_STMT_CONTAINER:
2500
0
            LY_CHECK_RET(lysp_stmt_container(ctx, child, &inout_p->node, &inout_p->child));
2501
0
            break;
2502
0
        case LY_STMT_LEAF:
2503
0
            LY_CHECK_RET(lysp_stmt_leaf(ctx, child, &inout_p->node, &inout_p->child));
2504
0
            break;
2505
0
        case LY_STMT_LEAF_LIST:
2506
0
            LY_CHECK_RET(lysp_stmt_leaflist(ctx, child, &inout_p->node, &inout_p->child));
2507
0
            break;
2508
0
        case LY_STMT_LIST:
2509
0
            LY_CHECK_RET(lysp_stmt_list(ctx, child, &inout_p->node, &inout_p->child));
2510
0
            break;
2511
0
        case LY_STMT_USES:
2512
0
            LY_CHECK_RET(lysp_stmt_uses(ctx, child, &inout_p->node, &inout_p->child));
2513
0
            break;
2514
0
        case LY_STMT_TYPEDEF:
2515
0
            LY_CHECK_RET(lysp_stmt_typedef(ctx, child, &inout_p->node, &inout_p->typedefs));
2516
0
            break;
2517
0
        case LY_STMT_MUST:
2518
0
            PARSER_CHECK_STMTVER2_RET(ctx, "must", lyplg_ext_stmt2str(stmt->kw));
2519
0
            LY_CHECK_RET(lysp_stmt_restrs(ctx, child, &inout_p->musts));
2520
0
            break;
2521
0
        case LY_STMT_GROUPING:
2522
0
            LY_CHECK_RET(lysp_stmt_grouping(ctx, child, &inout_p->node, &inout_p->groupings));
2523
0
            break;
2524
0
        case LY_STMT_EXTENSION_INSTANCE:
2525
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, stmt->kw, 0, &inout_p->exts));
2526
0
            break;
2527
0
        default:
2528
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), lyplg_ext_stmt2str(stmt->kw));
2529
0
            return LY_EVALID;
2530
0
        }
2531
0
    }
2532
2533
0
    if (!inout_p->child) {
2534
0
        LOGVAL_PARSER(ctx, LY_VCODE_MISSTMT, "data-def-stmt", lyplg_ext_stmt2str(stmt->kw));
2535
0
        return LY_EVALID;
2536
0
    }
2537
2538
0
    return LY_SUCCESS;
2539
0
}
2540
2541
/**
2542
 * @brief Parse the action statement.
2543
 *
2544
 * @param[in] ctx parser context.
2545
 * @param[in] stmt Source statement data from the parsed extension instance.
2546
 * @param[in] parent Parent node to connect to (not into).
2547
 * @param[in,out] actions Actions to add to.
2548
 *
2549
 * @return LY_ERR values.
2550
 */
2551
static LY_ERR
2552
lysp_stmt_action(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
2553
        struct lysp_node_action **actions)
2554
0
{
2555
0
    struct lysp_node_action *act;
2556
2557
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
2558
2559
0
    LY_LIST_NEW_RET(PARSER_CTX(ctx), actions, act, next, LY_EMEM);
2560
2561
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &act->name));
2562
0
    act->nodetype = parent ? LYS_ACTION : LYS_RPC;
2563
0
    act->parent = parent;
2564
2565
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
2566
0
        switch (child->kw) {
2567
0
        case LY_STMT_DESCRIPTION:
2568
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &act->dsc, Y_STR_ARG, &act->exts));
2569
0
            break;
2570
0
        case LY_STMT_IF_FEATURE:
2571
0
            LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &act->iffeatures, Y_STR_ARG, &act->exts));
2572
0
            break;
2573
0
        case LY_STMT_REFERENCE:
2574
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &act->ref, Y_STR_ARG, &act->exts));
2575
0
            break;
2576
0
        case LY_STMT_STATUS:
2577
0
            LY_CHECK_RET(lysp_stmt_status(ctx, child, &act->flags, &act->exts));
2578
0
            break;
2579
2580
0
        case LY_STMT_INPUT:
2581
0
            LY_CHECK_RET(lysp_stmt_inout(ctx, child, &act->node, &act->input));
2582
0
            break;
2583
0
        case LY_STMT_OUTPUT:
2584
0
            LY_CHECK_RET(lysp_stmt_inout(ctx, child, &act->node, &act->output));
2585
0
            break;
2586
2587
0
        case LY_STMT_TYPEDEF:
2588
0
            LY_CHECK_RET(lysp_stmt_typedef(ctx, child, &act->node, &act->typedefs));
2589
0
            break;
2590
0
        case LY_STMT_GROUPING:
2591
0
            LY_CHECK_RET(lysp_stmt_grouping(ctx, child, &act->node, &act->groupings));
2592
0
            break;
2593
0
        case LY_STMT_EXTENSION_INSTANCE:
2594
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, parent ? LY_STMT_ACTION : LY_STMT_RPC, 0, &act->exts));
2595
0
            break;
2596
0
        default:
2597
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), parent ? "action" : "rpc");
2598
0
            return LY_EVALID;
2599
0
        }
2600
0
    }
2601
2602
    /* always initialize inout, they are technically present (needed for later deviations/refines) */
2603
0
    if (!act->input.nodetype) {
2604
0
        act->input.nodetype = LYS_INPUT;
2605
0
        act->input.parent = &act->node;
2606
0
        LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), "input", 0, &act->input.name));
2607
0
    }
2608
0
    if (!act->output.nodetype) {
2609
0
        act->output.nodetype = LYS_OUTPUT;
2610
0
        act->output.parent = &act->node;
2611
0
        LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), "output", 0, &act->output.name));
2612
0
    }
2613
2614
0
    return LY_SUCCESS;
2615
0
}
2616
2617
/**
2618
 * @brief Parse the notification statement.
2619
 *
2620
 * @param[in] ctx parser context.
2621
 * @param[in] stmt Source statement data from the parsed extension instance.
2622
 * @param[in] parent Parent node to connect to (not into).
2623
 * @param[in,out] notifs Notifications to add to.
2624
 *
2625
 * @return LY_ERR values.
2626
 */
2627
static LY_ERR
2628
lysp_stmt_notif(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
2629
        struct lysp_node_notif **notifs)
2630
0
{
2631
0
    struct lysp_node_notif *notif;
2632
2633
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
2634
2635
0
    LY_LIST_NEW_RET(PARSER_CTX(ctx), notifs, notif, next, LY_EMEM);
2636
2637
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &notif->name));
2638
0
    notif->nodetype = LYS_NOTIF;
2639
0
    notif->parent = parent;
2640
2641
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
2642
0
        switch (child->kw) {
2643
0
        case LY_STMT_DESCRIPTION:
2644
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &notif->dsc, Y_STR_ARG, &notif->exts));
2645
0
            break;
2646
0
        case LY_STMT_IF_FEATURE:
2647
0
            LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &notif->iffeatures, Y_STR_ARG, &notif->exts));
2648
0
            break;
2649
0
        case LY_STMT_REFERENCE:
2650
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &notif->ref, Y_STR_ARG, &notif->exts));
2651
0
            break;
2652
0
        case LY_STMT_STATUS:
2653
0
            LY_CHECK_RET(lysp_stmt_status(ctx, child, &notif->flags, &notif->exts));
2654
0
            break;
2655
2656
0
        case LY_STMT_ANYDATA:
2657
0
            PARSER_CHECK_STMTVER2_RET(ctx, "anydata", "notification");
2658
        /* fall through */
2659
0
        case LY_STMT_ANYXML:
2660
0
            LY_CHECK_RET(lysp_stmt_any(ctx, child, &notif->node, &notif->child));
2661
0
            break;
2662
0
        case LY_STMT_CHOICE:
2663
0
            LY_CHECK_RET(lysp_stmt_case(ctx, child, &notif->node, &notif->child));
2664
0
            break;
2665
0
        case LY_STMT_CONTAINER:
2666
0
            LY_CHECK_RET(lysp_stmt_container(ctx, child, &notif->node, &notif->child));
2667
0
            break;
2668
0
        case LY_STMT_LEAF:
2669
0
            LY_CHECK_RET(lysp_stmt_leaf(ctx, child, &notif->node, &notif->child));
2670
0
            break;
2671
0
        case LY_STMT_LEAF_LIST:
2672
0
            LY_CHECK_RET(lysp_stmt_leaflist(ctx, child, &notif->node, &notif->child));
2673
0
            break;
2674
0
        case LY_STMT_LIST:
2675
0
            LY_CHECK_RET(lysp_stmt_list(ctx, child, &notif->node, &notif->child));
2676
0
            break;
2677
0
        case LY_STMT_USES:
2678
0
            LY_CHECK_RET(lysp_stmt_uses(ctx, child, &notif->node, &notif->child));
2679
0
            break;
2680
2681
0
        case LY_STMT_MUST:
2682
0
            PARSER_CHECK_STMTVER2_RET(ctx, "must", "notification");
2683
0
            LY_CHECK_RET(lysp_stmt_restrs(ctx, child, &notif->musts));
2684
0
            break;
2685
0
        case LY_STMT_TYPEDEF:
2686
0
            LY_CHECK_RET(lysp_stmt_typedef(ctx, child, &notif->node, &notif->typedefs));
2687
0
            break;
2688
0
        case LY_STMT_GROUPING:
2689
0
            LY_CHECK_RET(lysp_stmt_grouping(ctx, child, &notif->node, &notif->groupings));
2690
0
            break;
2691
0
        case LY_STMT_EXTENSION_INSTANCE:
2692
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_NOTIFICATION, 0, &notif->exts));
2693
0
            break;
2694
0
        default:
2695
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "notification");
2696
0
            return LY_EVALID;
2697
0
        }
2698
0
    }
2699
2700
0
    return LY_SUCCESS;
2701
0
}
2702
2703
/**
2704
 * @brief Parse the grouping statement.
2705
 *
2706
 * @param[in] ctx parser context.
2707
 * @param[in] stmt Source statement data from the parsed extension instance.
2708
 * @param[in] parent Parent node to connect to (not into).
2709
 * @param[in,out] groupings Groupings to add to.
2710
 *
2711
 * @return LY_ERR values.
2712
 */
2713
static LY_ERR
2714
lysp_stmt_grouping(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
2715
        struct lysp_node_grp **groupings)
2716
0
{
2717
0
    struct lysp_node_grp *grp;
2718
2719
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
2720
2721
0
    LY_LIST_NEW_RET(PARSER_CTX(ctx), groupings, grp, next, LY_EMEM);
2722
2723
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &grp->name));
2724
0
    grp->nodetype = LYS_GROUPING;
2725
0
    grp->parent = parent;
2726
2727
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
2728
0
        switch (child->kw) {
2729
0
        case LY_STMT_DESCRIPTION:
2730
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &grp->dsc, Y_STR_ARG, &grp->exts));
2731
0
            break;
2732
0
        case LY_STMT_REFERENCE:
2733
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &grp->ref, Y_STR_ARG, &grp->exts));
2734
0
            break;
2735
0
        case LY_STMT_STATUS:
2736
0
            LY_CHECK_RET(lysp_stmt_status(ctx, child, &grp->flags, &grp->exts));
2737
0
            break;
2738
2739
0
        case LY_STMT_ANYDATA:
2740
0
            PARSER_CHECK_STMTVER2_RET(ctx, "anydata", "grouping");
2741
        /* fall through */
2742
0
        case LY_STMT_ANYXML:
2743
0
            LY_CHECK_RET(lysp_stmt_any(ctx, child, &grp->node, &grp->child));
2744
0
            break;
2745
0
        case LY_STMT_CHOICE:
2746
0
            LY_CHECK_RET(lysp_stmt_choice(ctx, child, &grp->node, &grp->child));
2747
0
            break;
2748
0
        case LY_STMT_CONTAINER:
2749
0
            LY_CHECK_RET(lysp_stmt_container(ctx, child, &grp->node, &grp->child));
2750
0
            break;
2751
0
        case LY_STMT_LEAF:
2752
0
            LY_CHECK_RET(lysp_stmt_leaf(ctx, child, &grp->node, &grp->child));
2753
0
            break;
2754
0
        case LY_STMT_LEAF_LIST:
2755
0
            LY_CHECK_RET(lysp_stmt_leaflist(ctx, child, &grp->node, &grp->child));
2756
0
            break;
2757
0
        case LY_STMT_LIST:
2758
0
            LY_CHECK_RET(lysp_stmt_list(ctx, child, &grp->node, &grp->child));
2759
0
            break;
2760
0
        case LY_STMT_USES:
2761
0
            LY_CHECK_RET(lysp_stmt_uses(ctx, child, &grp->node, &grp->child));
2762
0
            break;
2763
2764
0
        case LY_STMT_TYPEDEF:
2765
0
            LY_CHECK_RET(lysp_stmt_typedef(ctx, child, &grp->node, &grp->typedefs));
2766
0
            break;
2767
0
        case LY_STMT_ACTION:
2768
0
            PARSER_CHECK_STMTVER2_RET(ctx, "action", "grouping");
2769
0
            LY_CHECK_RET(lysp_stmt_action(ctx, child, &grp->node, &grp->actions));
2770
0
            break;
2771
0
        case LY_STMT_GROUPING:
2772
0
            LY_CHECK_RET(lysp_stmt_grouping(ctx, child, &grp->node, &grp->groupings));
2773
0
            break;
2774
0
        case LY_STMT_NOTIFICATION:
2775
0
            PARSER_CHECK_STMTVER2_RET(ctx, "notification", "grouping");
2776
0
            LY_CHECK_RET(lysp_stmt_notif(ctx, child, &grp->node, &grp->notifs));
2777
0
            break;
2778
0
        case LY_STMT_EXTENSION_INSTANCE:
2779
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_GROUPING, 0, &grp->exts));
2780
0
            break;
2781
0
        default:
2782
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "grouping");
2783
0
            return LY_EVALID;
2784
0
        }
2785
0
    }
2786
2787
0
    return LY_SUCCESS;
2788
0
}
2789
2790
/**
2791
 * @brief Parse the augment statement.
2792
 *
2793
 * @param[in] ctx parser context.
2794
 * @param[in] stmt Source statement data from the parsed extension instance.
2795
 * @param[in] parent Parent node to connect to (not into).
2796
 * @param[in,out] augments Augments to add to.
2797
 *
2798
 * @return LY_ERR values.
2799
 */
2800
static LY_ERR
2801
lysp_stmt_augment(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
2802
        struct lysp_node_augment **augments)
2803
0
{
2804
0
    struct lysp_node_augment *aug;
2805
2806
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_STR_ARG, stmt->arg));
2807
2808
0
    LY_LIST_NEW_RET(PARSER_CTX(ctx), augments, aug, next, LY_EMEM);
2809
2810
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &aug->nodeid));
2811
0
    aug->nodetype = LYS_AUGMENT;
2812
0
    aug->parent = parent;
2813
2814
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
2815
0
        switch (child->kw) {
2816
0
        case LY_STMT_DESCRIPTION:
2817
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &aug->dsc, Y_STR_ARG, &aug->exts));
2818
0
            break;
2819
0
        case LY_STMT_IF_FEATURE:
2820
0
            LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &aug->iffeatures, Y_STR_ARG, &aug->exts));
2821
0
            break;
2822
0
        case LY_STMT_REFERENCE:
2823
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &aug->ref, Y_STR_ARG, &aug->exts));
2824
0
            break;
2825
0
        case LY_STMT_STATUS:
2826
0
            LY_CHECK_RET(lysp_stmt_status(ctx, child, &aug->flags, &aug->exts));
2827
0
            break;
2828
0
        case LY_STMT_WHEN:
2829
0
            LY_CHECK_RET(lysp_stmt_when(ctx, child, &aug->when));
2830
0
            break;
2831
2832
0
        case LY_STMT_ANYDATA:
2833
0
            PARSER_CHECK_STMTVER2_RET(ctx, "anydata", "augment");
2834
        /* fall through */
2835
0
        case LY_STMT_ANYXML:
2836
0
            LY_CHECK_RET(lysp_stmt_any(ctx, child, &aug->node, &aug->child));
2837
0
            break;
2838
0
        case LY_STMT_CASE:
2839
0
            LY_CHECK_RET(lysp_stmt_case(ctx, child, &aug->node, &aug->child));
2840
0
            break;
2841
0
        case LY_STMT_CHOICE:
2842
0
            LY_CHECK_RET(lysp_stmt_choice(ctx, child, &aug->node, &aug->child));
2843
0
            break;
2844
0
        case LY_STMT_CONTAINER:
2845
0
            LY_CHECK_RET(lysp_stmt_container(ctx, child, &aug->node, &aug->child));
2846
0
            break;
2847
0
        case LY_STMT_LEAF:
2848
0
            LY_CHECK_RET(lysp_stmt_leaf(ctx, child, &aug->node, &aug->child));
2849
0
            break;
2850
0
        case LY_STMT_LEAF_LIST:
2851
0
            LY_CHECK_RET(lysp_stmt_leaflist(ctx, child, &aug->node, &aug->child));
2852
0
            break;
2853
0
        case LY_STMT_LIST:
2854
0
            LY_CHECK_RET(lysp_stmt_list(ctx, child, &aug->node, &aug->child));
2855
0
            break;
2856
0
        case LY_STMT_USES:
2857
0
            LY_CHECK_RET(lysp_stmt_uses(ctx, child, &aug->node, &aug->child));
2858
0
            break;
2859
2860
0
        case LY_STMT_ACTION:
2861
0
            PARSER_CHECK_STMTVER2_RET(ctx, "action", "augment");
2862
0
            LY_CHECK_RET(lysp_stmt_action(ctx, child, &aug->node, &aug->actions));
2863
0
            break;
2864
0
        case LY_STMT_NOTIFICATION:
2865
0
            PARSER_CHECK_STMTVER2_RET(ctx, "notification", "augment");
2866
0
            LY_CHECK_RET(lysp_stmt_notif(ctx, child, &aug->node, &aug->notifs));
2867
0
            break;
2868
0
        case LY_STMT_EXTENSION_INSTANCE:
2869
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_AUGMENT, 0, &aug->exts));
2870
0
            break;
2871
0
        default:
2872
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "augment");
2873
0
            return LY_EVALID;
2874
0
        }
2875
0
    }
2876
2877
0
    return LY_SUCCESS;
2878
0
}
2879
2880
/**
2881
 * @brief Parse the uses statement.
2882
 *
2883
 * @param[in] ctx parser context.
2884
 * @param[in] stmt Source statement data from the parsed extension instance.
2885
 * @param[in] parent Parent node to connect to (not into).
2886
 * @param[in,out] siblings Siblings to add to.
2887
 *
2888
 * @return LY_ERR values.
2889
 */
2890
static LY_ERR
2891
lysp_stmt_uses(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
2892
        struct lysp_node **siblings)
2893
0
{
2894
0
    struct lysp_node_uses *uses;
2895
2896
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_PREF_IDENTIF_ARG, stmt->arg));
2897
2898
    /* create uses structure */
2899
0
    LY_LIST_NEW_RET(PARSER_CTX(ctx), siblings, uses, next, LY_EMEM);
2900
2901
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &uses->name));
2902
0
    uses->nodetype = LYS_USES;
2903
0
    uses->parent = parent;
2904
2905
    /* parse substatements */
2906
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
2907
0
        switch (child->kw) {
2908
0
        case LY_STMT_DESCRIPTION:
2909
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &uses->dsc, Y_STR_ARG, &uses->exts));
2910
0
            break;
2911
0
        case LY_STMT_IF_FEATURE:
2912
0
            LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &uses->iffeatures, Y_STR_ARG, &uses->exts));
2913
0
            break;
2914
0
        case LY_STMT_REFERENCE:
2915
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &uses->ref, Y_STR_ARG, &uses->exts));
2916
0
            break;
2917
0
        case LY_STMT_STATUS:
2918
0
            LY_CHECK_RET(lysp_stmt_status(ctx, child, &uses->flags, &uses->exts));
2919
0
            break;
2920
0
        case LY_STMT_WHEN:
2921
0
            LY_CHECK_RET(lysp_stmt_when(ctx, child, &uses->when));
2922
0
            break;
2923
2924
0
        case LY_STMT_REFINE:
2925
0
            LY_CHECK_RET(lysp_stmt_refine(ctx, child, &uses->refines));
2926
0
            break;
2927
0
        case LY_STMT_AUGMENT:
2928
0
            LY_CHECK_RET(lysp_stmt_augment(ctx, child, &uses->node, &uses->augments));
2929
0
            break;
2930
0
        case LY_STMT_EXTENSION_INSTANCE:
2931
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_USES, 0, &uses->exts));
2932
0
            break;
2933
0
        default:
2934
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "uses");
2935
0
            return LY_EVALID;
2936
0
        }
2937
0
    }
2938
2939
0
    return LY_SUCCESS;
2940
0
}
2941
2942
/**
2943
 * @brief Parse the case statement.
2944
 *
2945
 * @param[in] ctx parser context.
2946
 * @param[in] stmt Source statement data from the parsed extension instance.
2947
 * @param[in] parent Parent node to connect to (not into).
2948
 * @param[in,out] siblings Siblings to add to.
2949
 *
2950
 * @return LY_ERR values.
2951
 */
2952
static LY_ERR
2953
lysp_stmt_case(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
2954
        struct lysp_node **siblings)
2955
0
{
2956
0
    struct lysp_node_case *cas;
2957
2958
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
2959
2960
    /* create new case structure */
2961
0
    LY_LIST_NEW_RET(PARSER_CTX(ctx), siblings, cas, next, LY_EMEM);
2962
2963
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &cas->name));
2964
0
    cas->nodetype = LYS_CASE;
2965
0
    cas->parent = parent;
2966
2967
    /* parse substatements */
2968
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
2969
0
        switch (child->kw) {
2970
0
        case LY_STMT_DESCRIPTION:
2971
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &cas->dsc, Y_STR_ARG, &cas->exts));
2972
0
            break;
2973
0
        case LY_STMT_IF_FEATURE:
2974
0
            LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &cas->iffeatures, Y_STR_ARG, &cas->exts));
2975
0
            break;
2976
0
        case LY_STMT_REFERENCE:
2977
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &cas->ref, Y_STR_ARG, &cas->exts));
2978
0
            break;
2979
0
        case LY_STMT_STATUS:
2980
0
            LY_CHECK_RET(lysp_stmt_status(ctx, child, &cas->flags, &cas->exts));
2981
0
            break;
2982
0
        case LY_STMT_WHEN:
2983
0
            LY_CHECK_RET(lysp_stmt_when(ctx, child, &cas->when));
2984
0
            break;
2985
2986
0
        case LY_STMT_ANYDATA:
2987
0
            PARSER_CHECK_STMTVER2_RET(ctx, "anydata", "case");
2988
        /* fall through */
2989
0
        case LY_STMT_ANYXML:
2990
0
            LY_CHECK_RET(lysp_stmt_any(ctx, child, &cas->node, &cas->child));
2991
0
            break;
2992
0
        case LY_STMT_CHOICE:
2993
0
            LY_CHECK_RET(lysp_stmt_choice(ctx, child, &cas->node, &cas->child));
2994
0
            break;
2995
0
        case LY_STMT_CONTAINER:
2996
0
            LY_CHECK_RET(lysp_stmt_container(ctx, child, &cas->node, &cas->child));
2997
0
            break;
2998
0
        case LY_STMT_LEAF:
2999
0
            LY_CHECK_RET(lysp_stmt_leaf(ctx, child, &cas->node, &cas->child));
3000
0
            break;
3001
0
        case LY_STMT_LEAF_LIST:
3002
0
            LY_CHECK_RET(lysp_stmt_leaflist(ctx, child, &cas->node, &cas->child));
3003
0
            break;
3004
0
        case LY_STMT_LIST:
3005
0
            LY_CHECK_RET(lysp_stmt_list(ctx, child, &cas->node, &cas->child));
3006
0
            break;
3007
0
        case LY_STMT_USES:
3008
0
            LY_CHECK_RET(lysp_stmt_uses(ctx, child, &cas->node, &cas->child));
3009
0
            break;
3010
0
        case LY_STMT_EXTENSION_INSTANCE:
3011
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_CASE, 0, &cas->exts));
3012
0
            break;
3013
0
        default:
3014
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "case");
3015
0
            return LY_EVALID;
3016
0
        }
3017
0
    }
3018
0
    return LY_SUCCESS;
3019
0
}
3020
3021
/**
3022
 * @brief Parse the choice statement.
3023
 *
3024
 * @param[in] ctx parser context.
3025
 * @param[in] stmt Source statement data from the parsed extension instance.
3026
 * @param[in] parent Parent node to connect to (not into).
3027
 * @param[in,out] siblings Siblings to add to.
3028
 *
3029
 * @return LY_ERR values.
3030
 */
3031
static LY_ERR
3032
lysp_stmt_choice(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
3033
        struct lysp_node **siblings)
3034
0
{
3035
0
    struct lysp_node_choice *choice;
3036
3037
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
3038
3039
    /* create new choice structure */
3040
0
    LY_LIST_NEW_RET(PARSER_CTX(ctx), siblings, choice, next, LY_EMEM);
3041
3042
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &choice->name));
3043
0
    choice->nodetype = LYS_CHOICE;
3044
0
    choice->parent = parent;
3045
3046
    /* parse substatements */
3047
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
3048
0
        switch (child->kw) {
3049
0
        case LY_STMT_CONFIG:
3050
0
            LY_CHECK_RET(lysp_stmt_config(ctx, child, &choice->flags, &choice->exts));
3051
0
            break;
3052
0
        case LY_STMT_DESCRIPTION:
3053
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &choice->dsc, Y_STR_ARG, &choice->exts));
3054
0
            break;
3055
0
        case LY_STMT_IF_FEATURE:
3056
0
            LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &choice->iffeatures, Y_STR_ARG, &choice->exts));
3057
0
            break;
3058
0
        case LY_STMT_MANDATORY:
3059
0
            LY_CHECK_RET(lysp_stmt_mandatory(ctx, child, &choice->flags, &choice->exts));
3060
0
            break;
3061
0
        case LY_STMT_REFERENCE:
3062
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &choice->ref, Y_STR_ARG, &choice->exts));
3063
0
            break;
3064
0
        case LY_STMT_STATUS:
3065
0
            LY_CHECK_RET(lysp_stmt_status(ctx, child, &choice->flags, &choice->exts));
3066
0
            break;
3067
0
        case LY_STMT_WHEN:
3068
0
            LY_CHECK_RET(lysp_stmt_when(ctx, child, &choice->when));
3069
0
            break;
3070
0
        case LY_STMT_DEFAULT:
3071
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &choice->dflt.str, Y_PREF_IDENTIF_ARG, &choice->exts));
3072
0
            choice->dflt.mod = PARSER_CUR_PMOD(ctx);
3073
0
            break;
3074
0
        case LY_STMT_ANYDATA:
3075
0
            PARSER_CHECK_STMTVER2_RET(ctx, "anydata", "choice");
3076
        /* fall through */
3077
0
        case LY_STMT_ANYXML:
3078
0
            LY_CHECK_RET(lysp_stmt_any(ctx, child, &choice->node, &choice->child));
3079
0
            break;
3080
0
        case LY_STMT_CASE:
3081
0
            LY_CHECK_RET(lysp_stmt_case(ctx, child, &choice->node, &choice->child));
3082
0
            break;
3083
0
        case LY_STMT_CHOICE:
3084
0
            PARSER_CHECK_STMTVER2_RET(ctx, "choice", "choice");
3085
0
            LY_CHECK_RET(lysp_stmt_choice(ctx, child, &choice->node, &choice->child));
3086
0
            break;
3087
0
        case LY_STMT_CONTAINER:
3088
0
            LY_CHECK_RET(lysp_stmt_container(ctx, child, &choice->node, &choice->child));
3089
0
            break;
3090
0
        case LY_STMT_LEAF:
3091
0
            LY_CHECK_RET(lysp_stmt_leaf(ctx, child, &choice->node, &choice->child));
3092
0
            break;
3093
0
        case LY_STMT_LEAF_LIST:
3094
0
            LY_CHECK_RET(lysp_stmt_leaflist(ctx, child, &choice->node, &choice->child));
3095
0
            break;
3096
0
        case LY_STMT_LIST:
3097
0
            LY_CHECK_RET(lysp_stmt_list(ctx, child, &choice->node, &choice->child));
3098
0
            break;
3099
0
        case LY_STMT_EXTENSION_INSTANCE:
3100
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_CHOICE, 0, &choice->exts));
3101
0
            break;
3102
0
        default:
3103
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "choice");
3104
0
            return LY_EVALID;
3105
0
        }
3106
0
    }
3107
0
    return LY_SUCCESS;
3108
0
}
3109
3110
/**
3111
 * @brief Parse the container statement.
3112
 *
3113
 * @param[in] ctx parser context.
3114
 * @param[in] stmt Source statement data from the parsed extension instance.
3115
 * @param[in] parent Parent node to connect to (not into).
3116
 * @param[in,out] siblings Siblings to add to.
3117
 *
3118
 * @return LY_ERR values.
3119
 */
3120
static LY_ERR
3121
lysp_stmt_container(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
3122
        struct lysp_node **siblings)
3123
0
{
3124
0
    struct lysp_node_container *cont;
3125
3126
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
3127
3128
    /* create new container structure */
3129
0
    LY_LIST_NEW_RET(PARSER_CTX(ctx), siblings, cont, next, LY_EMEM);
3130
3131
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &cont->name));
3132
0
    cont->nodetype = LYS_CONTAINER;
3133
0
    cont->parent = parent;
3134
3135
    /* parse substatements */
3136
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
3137
0
        switch (child->kw) {
3138
0
        case LY_STMT_CONFIG:
3139
0
            LY_CHECK_RET(lysp_stmt_config(ctx, child, &cont->flags, &cont->exts));
3140
0
            break;
3141
0
        case LY_STMT_DESCRIPTION:
3142
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &cont->dsc, Y_STR_ARG, &cont->exts));
3143
0
            break;
3144
0
        case LY_STMT_IF_FEATURE:
3145
0
            LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &cont->iffeatures, Y_STR_ARG, &cont->exts));
3146
0
            break;
3147
0
        case LY_STMT_REFERENCE:
3148
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &cont->ref, Y_STR_ARG, &cont->exts));
3149
0
            break;
3150
0
        case LY_STMT_STATUS:
3151
0
            LY_CHECK_RET(lysp_stmt_status(ctx, child, &cont->flags, &cont->exts));
3152
0
            break;
3153
0
        case LY_STMT_WHEN:
3154
0
            LY_CHECK_RET(lysp_stmt_when(ctx, child, &cont->when));
3155
0
            break;
3156
0
        case LY_STMT_PRESENCE:
3157
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &cont->presence, Y_STR_ARG, &cont->exts));
3158
0
            break;
3159
0
        case LY_STMT_ANYDATA:
3160
0
            PARSER_CHECK_STMTVER2_RET(ctx, "anydata", "container");
3161
        /* fall through */
3162
0
        case LY_STMT_ANYXML:
3163
0
            LY_CHECK_RET(lysp_stmt_any(ctx, child, &cont->node, &cont->child));
3164
0
            break;
3165
0
        case LY_STMT_CHOICE:
3166
0
            LY_CHECK_RET(lysp_stmt_choice(ctx, child, &cont->node, &cont->child));
3167
0
            break;
3168
0
        case LY_STMT_CONTAINER:
3169
0
            LY_CHECK_RET(lysp_stmt_container(ctx, child, &cont->node, &cont->child));
3170
0
            break;
3171
0
        case LY_STMT_LEAF:
3172
0
            LY_CHECK_RET(lysp_stmt_leaf(ctx, child, &cont->node, &cont->child));
3173
0
            break;
3174
0
        case LY_STMT_LEAF_LIST:
3175
0
            LY_CHECK_RET(lysp_stmt_leaflist(ctx, child, &cont->node, &cont->child));
3176
0
            break;
3177
0
        case LY_STMT_LIST:
3178
0
            LY_CHECK_RET(lysp_stmt_list(ctx, child, &cont->node, &cont->child));
3179
0
            break;
3180
0
        case LY_STMT_USES:
3181
0
            LY_CHECK_RET(lysp_stmt_uses(ctx, child, &cont->node, &cont->child));
3182
0
            break;
3183
3184
0
        case LY_STMT_TYPEDEF:
3185
0
            LY_CHECK_RET(lysp_stmt_typedef(ctx, child, &cont->node, &cont->typedefs));
3186
0
            break;
3187
0
        case LY_STMT_MUST:
3188
0
            LY_CHECK_RET(lysp_stmt_restrs(ctx, child, &cont->musts));
3189
0
            break;
3190
0
        case LY_STMT_ACTION:
3191
0
            PARSER_CHECK_STMTVER2_RET(ctx, "action", "container");
3192
0
            LY_CHECK_RET(lysp_stmt_action(ctx, child, &cont->node, &cont->actions));
3193
0
            break;
3194
0
        case LY_STMT_GROUPING:
3195
0
            LY_CHECK_RET(lysp_stmt_grouping(ctx, child, &cont->node, &cont->groupings));
3196
0
            break;
3197
0
        case LY_STMT_NOTIFICATION:
3198
0
            PARSER_CHECK_STMTVER2_RET(ctx, "notification", "container");
3199
0
            LY_CHECK_RET(lysp_stmt_notif(ctx, child, &cont->node, &cont->notifs));
3200
0
            break;
3201
0
        case LY_STMT_EXTENSION_INSTANCE:
3202
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_CONTAINER, 0, &cont->exts));
3203
0
            break;
3204
0
        default:
3205
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "container");
3206
0
            return LY_EVALID;
3207
0
        }
3208
0
    }
3209
3210
0
    return LY_SUCCESS;
3211
0
}
3212
3213
/**
3214
 * @brief Parse the list statement.
3215
 *
3216
 * @param[in] ctx parser context.
3217
 * @param[in] stmt Source statement data from the parsed extension instance.
3218
 * @param[in] parent Parent node to connect to (not into).
3219
 * @param[in,out] siblings Siblings to add to.
3220
 *
3221
 * @return LY_ERR values.
3222
 */
3223
static LY_ERR
3224
lysp_stmt_list(struct lysp_ctx *ctx, const struct lysp_stmt *stmt, struct lysp_node *parent,
3225
        struct lysp_node **siblings)
3226
0
{
3227
0
    struct lysp_node_list *list;
3228
3229
0
    LY_CHECK_RET(lysp_stmt_validate_value(ctx, Y_IDENTIF_ARG, stmt->arg));
3230
3231
    /* create new list structure */
3232
0
    LY_LIST_NEW_RET(PARSER_CTX(ctx), siblings, list, next, LY_EMEM);
3233
3234
0
    LY_CHECK_RET(lydict_insert(PARSER_CTX(ctx), stmt->arg, 0, &list->name));
3235
0
    list->nodetype = LYS_LIST;
3236
0
    list->parent = parent;
3237
3238
    /* parse substatements */
3239
0
    for (const struct lysp_stmt *child = stmt->child; child; child = child->next) {
3240
0
        switch (child->kw) {
3241
0
        case LY_STMT_CONFIG:
3242
0
            LY_CHECK_RET(lysp_stmt_config(ctx, child, &list->flags, &list->exts));
3243
0
            break;
3244
0
        case LY_STMT_DESCRIPTION:
3245
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &list->dsc, Y_STR_ARG, &list->exts));
3246
0
            break;
3247
0
        case LY_STMT_IF_FEATURE:
3248
0
            LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &list->iffeatures, Y_STR_ARG, &list->exts));
3249
0
            break;
3250
0
        case LY_STMT_REFERENCE:
3251
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &list->ref, Y_STR_ARG, &list->exts));
3252
0
            break;
3253
0
        case LY_STMT_STATUS:
3254
0
            LY_CHECK_RET(lysp_stmt_status(ctx, child, &list->flags, &list->exts));
3255
0
            break;
3256
0
        case LY_STMT_WHEN:
3257
0
            LY_CHECK_RET(lysp_stmt_when(ctx, child, &list->when));
3258
0
            break;
3259
0
        case LY_STMT_KEY:
3260
0
            LY_CHECK_RET(lysp_stmt_text_field(ctx, child, 0, &list->key, Y_STR_ARG, &list->exts));
3261
0
            break;
3262
0
        case LY_STMT_MAX_ELEMENTS:
3263
0
            LY_CHECK_RET(lysp_stmt_maxelements(ctx, child, &list->max, &list->flags, &list->exts));
3264
0
            break;
3265
0
        case LY_STMT_MIN_ELEMENTS:
3266
0
            LY_CHECK_RET(lysp_stmt_minelements(ctx, child, &list->min, &list->flags, &list->exts));
3267
0
            break;
3268
0
        case LY_STMT_ORDERED_BY:
3269
0
            LY_CHECK_RET(lysp_stmt_orderedby(ctx, child, &list->flags, &list->exts));
3270
0
            break;
3271
0
        case LY_STMT_UNIQUE:
3272
0
            LY_CHECK_RET(lysp_stmt_qnames(ctx, child, &list->uniques, Y_STR_ARG, &list->exts));
3273
0
            break;
3274
3275
0
        case LY_STMT_ANYDATA:
3276
0
            PARSER_CHECK_STMTVER2_RET(ctx, "anydata", "list");
3277
        /* fall through */
3278
0
        case LY_STMT_ANYXML:
3279
0
            LY_CHECK_RET(lysp_stmt_any(ctx, child, &list->node, &list->child));
3280
0
            break;
3281
0
        case LY_STMT_CHOICE:
3282
0
            LY_CHECK_RET(lysp_stmt_choice(ctx, child, &list->node, &list->child));
3283
0
            break;
3284
0
        case LY_STMT_CONTAINER:
3285
0
            LY_CHECK_RET(lysp_stmt_container(ctx, child, &list->node, &list->child));
3286
0
            break;
3287
0
        case LY_STMT_LEAF:
3288
0
            LY_CHECK_RET(lysp_stmt_leaf(ctx, child, &list->node, &list->child));
3289
0
            break;
3290
0
        case LY_STMT_LEAF_LIST:
3291
0
            LY_CHECK_RET(lysp_stmt_leaflist(ctx, child, &list->node, &list->child));
3292
0
            break;
3293
0
        case LY_STMT_LIST:
3294
0
            LY_CHECK_RET(lysp_stmt_list(ctx, child, &list->node, &list->child));
3295
0
            break;
3296
0
        case LY_STMT_USES:
3297
0
            LY_CHECK_RET(lysp_stmt_uses(ctx, child, &list->node, &list->child));
3298
0
            break;
3299
3300
0
        case LY_STMT_TYPEDEF:
3301
0
            LY_CHECK_RET(lysp_stmt_typedef(ctx, child, &list->node, &list->typedefs));
3302
0
            break;
3303
0
        case LY_STMT_MUST:
3304
0
            LY_CHECK_RET(lysp_stmt_restrs(ctx, child, &list->musts));
3305
0
            break;
3306
0
        case LY_STMT_ACTION:
3307
0
            PARSER_CHECK_STMTVER2_RET(ctx, "action", "list");
3308
0
            LY_CHECK_RET(lysp_stmt_action(ctx, child, &list->node, &list->actions));
3309
0
            break;
3310
0
        case LY_STMT_GROUPING:
3311
0
            LY_CHECK_RET(lysp_stmt_grouping(ctx, child, &list->node, &list->groupings));
3312
0
            break;
3313
0
        case LY_STMT_NOTIFICATION:
3314
0
            PARSER_CHECK_STMTVER2_RET(ctx, "notification", "list");
3315
0
            LY_CHECK_RET(lysp_stmt_notif(ctx, child, &list->node, &list->notifs));
3316
0
            break;
3317
0
        case LY_STMT_EXTENSION_INSTANCE:
3318
0
            LY_CHECK_RET(lysp_stmt_ext(ctx, child, LY_STMT_LIST, 0, &list->exts));
3319
0
            break;
3320
0
        default:
3321
0
            LOGVAL_PARSER(ctx, LY_VCODE_INCHILDSTMT, lyplg_ext_stmt2str(child->kw), "list");
3322
0
            return LY_EVALID;
3323
0
        }
3324
0
    }
3325
3326
0
    return LY_SUCCESS;
3327
0
}
3328
3329
/**
3330
 * @brief Parse generic statement structure into a specific parsed-schema structure.
3331
 *
3332
 * @param[in] pctx Parse context of the @p stmt being processed.
3333
 * @param[in] stmt Generic statement structure to process.
3334
 * @param[out] result Specific parsed-schema structure for the given statement. For the specific type for the particular statement, check the function code.
3335
 * @param[in,out] exts [sized array](@ref sizedarrays) For extension instances in case of statements that do not store extension instances in their own list.
3336
 * @return LY_ERR value.
3337
 */
3338
static LY_ERR
3339
lysp_stmt_parse(struct lysp_ctx *pctx, const struct lysp_stmt *stmt, void **result, struct lysp_ext_instance **exts)
3340
413k
{
3341
413k
    LY_ERR ret = LY_SUCCESS;
3342
413k
    uint16_t flags;
3343
3344
413k
    switch (stmt->kw) {
3345
0
    case LY_STMT_NOTIFICATION:
3346
0
        ret = lysp_stmt_notif(pctx, stmt, NULL, (struct lysp_node_notif **)result);
3347
0
        break;
3348
0
    case LY_STMT_INPUT:
3349
0
    case LY_STMT_OUTPUT: {
3350
0
        struct lysp_node_action_inout *inout;
3351
3352
0
        *result = inout = calloc(1, sizeof *inout);
3353
0
        LY_CHECK_ERR_RET(!inout, LOGMEM(PARSER_CTX(pctx)), LY_EMEM);
3354
0
        ret = lysp_stmt_inout(pctx, stmt, NULL, inout);
3355
0
        break;
3356
0
    }
3357
0
    case LY_STMT_ACTION:
3358
0
    case LY_STMT_RPC:
3359
0
        ret = lysp_stmt_action(pctx, stmt, NULL, (struct lysp_node_action **)result);
3360
0
        break;
3361
0
    case LY_STMT_ANYDATA:
3362
0
    case LY_STMT_ANYXML:
3363
0
        ret = lysp_stmt_any(pctx, stmt, NULL, (struct lysp_node **)result);
3364
0
        break;
3365
0
    case LY_STMT_AUGMENT:
3366
0
        ret = lysp_stmt_augment(pctx, stmt, NULL, (struct lysp_node_augment **)result);
3367
0
        break;
3368
0
    case LY_STMT_CASE:
3369
0
        ret = lysp_stmt_case(pctx, stmt, NULL, (struct lysp_node **)result);
3370
0
        break;
3371
0
    case LY_STMT_CHOICE:
3372
0
        ret = lysp_stmt_choice(pctx, stmt, NULL, (struct lysp_node **)result);
3373
0
        break;
3374
0
    case LY_STMT_CONTAINER:
3375
0
        ret = lysp_stmt_container(pctx, stmt, NULL, (struct lysp_node **)result);
3376
0
        break;
3377
0
    case LY_STMT_GROUPING:
3378
0
        ret = lysp_stmt_grouping(pctx, stmt, NULL, (struct lysp_node_grp **)result);
3379
0
        break;
3380
0
    case LY_STMT_LEAF:
3381
0
        ret = lysp_stmt_leaf(pctx, stmt, NULL, (struct lysp_node **)result);
3382
0
        break;
3383
0
    case LY_STMT_LEAF_LIST:
3384
0
        ret = lysp_stmt_leaflist(pctx, stmt, NULL, (struct lysp_node **)result);
3385
0
        break;
3386
0
    case LY_STMT_LIST:
3387
0
        ret = lysp_stmt_list(pctx, stmt, NULL, (struct lysp_node **)result);
3388
0
        break;
3389
0
    case LY_STMT_USES:
3390
0
        ret = lysp_stmt_uses(pctx, stmt, NULL, (struct lysp_node **)result);
3391
0
        break;
3392
0
    case LY_STMT_BASE:
3393
0
        ret = lysp_stmt_text_fields(pctx, stmt, (const char ***)result, Y_PREF_IDENTIF_ARG, exts);
3394
0
        break;
3395
0
    case LY_STMT_ARGUMENT:
3396
0
    case LY_STMT_BELONGS_TO:
3397
0
    case LY_STMT_CONTACT:
3398
161k
    case LY_STMT_DESCRIPTION:
3399
161k
    case LY_STMT_ERROR_APP_TAG:
3400
161k
    case LY_STMT_ERROR_MESSAGE:
3401
161k
    case LY_STMT_KEY:
3402
161k
    case LY_STMT_NAMESPACE:
3403
161k
    case LY_STMT_ORGANIZATION:
3404
161k
    case LY_STMT_PRESENCE:
3405
233k
    case LY_STMT_REFERENCE:
3406
233k
    case LY_STMT_REVISION_DATE:
3407
233k
    case LY_STMT_UNITS:
3408
233k
        ret = lysp_stmt_text_field(pctx, stmt, 0, (const char **)result, Y_STR_ARG, exts);
3409
233k
        break;
3410
0
    case LY_STMT_BIT:
3411
0
    case LY_STMT_ENUM:
3412
0
        ret = lysp_stmt_type_enum(pctx, stmt, (struct lysp_type_enum **)result);
3413
0
        break;
3414
0
    case LY_STMT_CONFIG:
3415
0
        assert(*result);
3416
0
        ret = lysp_stmt_config(pctx, stmt, *(uint16_t **)result, exts);
3417
0
        break;
3418
0
    case LY_STMT_DEFAULT:
3419
0
    case LY_STMT_IF_FEATURE:
3420
0
    case LY_STMT_UNIQUE:
3421
0
        ret = lysp_stmt_qnames(pctx, stmt, (struct lysp_qname **)result, Y_STR_ARG, exts);
3422
0
        break;
3423
0
    case LY_STMT_DEVIATE:
3424
0
        ret = lysp_stmt_deviate(pctx, stmt, (struct lysp_deviate **)result, exts);
3425
0
        break;
3426
0
    case LY_STMT_DEVIATION:
3427
0
        ret = lysp_stmt_deviation(pctx, stmt, (struct lysp_deviation **)result);
3428
0
        break;
3429
0
    case LY_STMT_EXTENSION:
3430
0
        ret = lysp_stmt_extension(pctx, stmt, (struct lysp_ext **)result);
3431
0
        break;
3432
0
    case LY_STMT_EXTENSION_INSTANCE:
3433
0
        ret = lysp_stmt_ext(pctx, stmt, LY_STMT_EXTENSION_INSTANCE, 0, (struct lysp_ext_instance **)result);
3434
0
        break;
3435
0
    case LY_STMT_FEATURE:
3436
0
        ret = lysp_stmt_feature(pctx, stmt, (struct lysp_feature **)result);
3437
0
        break;
3438
0
    case LY_STMT_FRACTION_DIGITS:
3439
0
        ret = lysp_stmt_type_fracdigits(pctx, stmt, *(uint8_t **)result, exts);
3440
0
        break;
3441
0
    case LY_STMT_LENGTH:
3442
0
    case LY_STMT_RANGE: {
3443
0
        struct lysp_restr *restr;
3444
3445
0
        *result = restr = calloc(1, sizeof *restr);
3446
0
        LY_CHECK_ERR_RET(!restr, LOGMEM(PARSER_CTX(pctx)), LY_EMEM);
3447
3448
0
        ret = lysp_stmt_restr(pctx, stmt, restr);
3449
0
        break;
3450
0
    }
3451
0
    case LY_STMT_MUST:
3452
0
        ret = lysp_stmt_restrs(pctx, stmt, (struct lysp_restr **)result);
3453
0
        break;
3454
0
    case LY_STMT_IDENTITY:
3455
0
        ret = lysp_stmt_identity(pctx, stmt, (struct lysp_ident **)result);
3456
0
        break;
3457
0
    case LY_STMT_IMPORT:
3458
0
        ret = lysp_stmt_import(pctx, stmt, (struct lysp_import **)result);
3459
0
        break;
3460
0
    case LY_STMT_INCLUDE:
3461
0
        ret = lysp_stmt_include(pctx, stmt, (struct lysp_include **)result);
3462
0
        break;
3463
0
    case LY_STMT_MANDATORY:
3464
0
        ret = lysp_stmt_mandatory(pctx, stmt, *(uint16_t **)result, exts);
3465
0
        break;
3466
0
    case LY_STMT_MAX_ELEMENTS:
3467
0
        flags = 0;
3468
0
        ret = lysp_stmt_maxelements(pctx, stmt, *(uint32_t **)result, &flags, exts);
3469
0
        break;
3470
0
    case LY_STMT_MIN_ELEMENTS:
3471
0
        flags = 0;
3472
0
        ret = lysp_stmt_minelements(pctx, stmt, *(uint32_t **)result, &flags, exts);
3473
0
        break;
3474
0
    case LY_STMT_MODIFIER:
3475
0
        ret = lysp_stmt_type_pattern_modifier(pctx, stmt, (const char **)result, exts);
3476
0
        break;
3477
0
    case LY_STMT_MODULE: {
3478
0
        struct lysp_module *mod;
3479
3480
0
        *result = mod = calloc(1, sizeof *mod);
3481
0
        LY_CHECK_ERR_RET(!mod, LOGMEM(PARSER_CTX(pctx)), LY_EMEM);
3482
0
        ret = lysp_stmt_module(pctx, stmt, mod);
3483
0
        break;
3484
0
    }
3485
0
    case LY_STMT_ORDERED_BY:
3486
0
        ret = lysp_stmt_orderedby(pctx, stmt, *(uint16_t **)result, exts);
3487
0
        break;
3488
0
    case LY_STMT_PATH: {
3489
0
        const char *str_path = NULL;
3490
3491
0
        LY_CHECK_RET(lysp_stmt_text_field(pctx, stmt, 0, &str_path, Y_STR_ARG, exts));
3492
0
        ret = ly_path_parse(PARSER_CTX(pctx), NULL, str_path, 0, 1, LY_PATH_BEGIN_EITHER,
3493
0
                LY_PATH_PREFIX_OPTIONAL, LY_PATH_PRED_LEAFREF, (struct lyxp_expr **)result);
3494
0
        lydict_remove(PARSER_CTX(pctx), str_path);
3495
0
        break;
3496
0
    }
3497
0
    case LY_STMT_PATTERN:
3498
0
        ret = lysp_stmt_type_pattern(pctx, stmt, (struct lysp_restr **)result);
3499
0
        break;
3500
0
    case LY_STMT_POSITION:
3501
0
    case LY_STMT_VALUE:
3502
0
        flags = 0;
3503
0
        ret = lysp_stmt_type_enum_value_pos(pctx, stmt, *(int64_t **)result, &flags, exts);
3504
0
        break;
3505
0
    case LY_STMT_PREFIX:
3506
0
        ret = lysp_stmt_text_field(pctx, stmt, 0, (const char **)result, Y_IDENTIF_ARG, exts);
3507
0
        break;
3508
0
    case LY_STMT_REFINE:
3509
0
        ret = lysp_stmt_refine(pctx, stmt, (struct lysp_refine **)result);
3510
0
        break;
3511
0
    case LY_STMT_REQUIRE_INSTANCE:
3512
0
        flags = 0;
3513
0
        ret = lysp_stmt_type_reqinstance(pctx, stmt, *(uint8_t **)result, &flags, exts);
3514
0
        break;
3515
0
    case LY_STMT_REVISION:
3516
0
        ret = lysp_stmt_revision(pctx, stmt, (struct lysp_revision **)result);
3517
0
        break;
3518
0
    case LY_STMT_STATUS:
3519
0
        ret = lysp_stmt_status(pctx, stmt, (uint16_t *)result, exts);
3520
0
        break;
3521
0
    case LY_STMT_SUBMODULE: {
3522
0
        struct lysp_submodule *submod;
3523
3524
0
        *result = submod = calloc(1, sizeof *submod);
3525
0
        LY_CHECK_ERR_RET(!submod, LOGMEM(PARSER_CTX(pctx)), LY_EMEM);
3526
0
        ret = lysp_stmt_submodule(pctx, stmt, submod);
3527
0
        break;
3528
0
    }
3529
179k
    case LY_STMT_TYPE: {
3530
179k
        struct lysp_type *type;
3531
3532
179k
        *result = type = calloc(1, sizeof *type);
3533
179k
        LY_CHECK_ERR_RET(!type, LOGMEM(PARSER_CTX(pctx)), LY_EMEM);
3534
179k
        ret = lysp_stmt_type(pctx, stmt, type);
3535
179k
        break;
3536
179k
    }
3537
0
    case LY_STMT_TYPEDEF:
3538
0
        ret = lysp_stmt_typedef(pctx, stmt, NULL, (struct lysp_tpdf **)result);
3539
0
        break;
3540
0
    case LY_STMT_WHEN:
3541
0
        ret = lysp_stmt_when(pctx, stmt, (struct lysp_when **)result);
3542
0
        break;
3543
0
    case LY_STMT_YANG_VERSION:
3544
0
        ret = lysp_stmt_yangver(pctx, stmt, *(uint8_t **)result, exts);
3545
0
        break;
3546
0
    case LY_STMT_YIN_ELEMENT:
3547
0
        ret = lysp_stmt_yinelem(pctx, stmt, *(uint16_t **)result, exts);
3548
0
        break;
3549
0
    default:
3550
0
        LOGINT(PARSER_CTX(pctx));
3551
0
        return LY_EINT;
3552
413k
    }
3553
3554
413k
    return ret;
3555
413k
}
3556
3557
LY_ERR
3558
lys_parse_ext_instance_stmt(struct lysp_ctx *pctx, struct lysp_ext_substmt *substmt, struct lysp_stmt *stmt)
3559
413k
{
3560
413k
    LY_ERR rc = LY_SUCCESS;
3561
3562
413k
    if (!substmt->storage) {
3563
        /* nothing to parse, ignored */
3564
0
        goto cleanup;
3565
0
    }
3566
3567
413k
    switch (stmt->kw) {
3568
0
    case LY_STMT_NOTIFICATION:
3569
0
    case LY_STMT_INPUT:
3570
0
    case LY_STMT_OUTPUT:
3571
0
    case LY_STMT_ACTION:
3572
0
    case LY_STMT_RPC:
3573
0
    case LY_STMT_ANYDATA:
3574
0
    case LY_STMT_ANYXML:
3575
0
    case LY_STMT_AUGMENT:
3576
0
    case LY_STMT_CASE:
3577
0
    case LY_STMT_CHOICE:
3578
0
    case LY_STMT_CONTAINER:
3579
0
    case LY_STMT_GROUPING:
3580
0
    case LY_STMT_LEAF:
3581
0
    case LY_STMT_LEAF_LIST:
3582
0
    case LY_STMT_LIST:
3583
0
    case LY_STMT_USES: {
3584
0
        struct lysp_node **pnodes_p, *pnode = NULL;
3585
3586
        /* parse the node */
3587
0
        LY_CHECK_GOTO(rc = lysp_stmt_parse(pctx, stmt, (void **)&pnode, NULL), cleanup);
3588
3589
        /* usually is a linked-list of all the parsed schema nodes */
3590
0
        pnodes_p = substmt->storage;
3591
0
        while (*pnodes_p) {
3592
0
            pnodes_p = &(*pnodes_p)->next;
3593
0
        }
3594
0
        *pnodes_p = pnode;
3595
3596
0
        break;
3597
0
    }
3598
0
    case LY_STMT_BASE:
3599
0
    case LY_STMT_BIT:
3600
0
    case LY_STMT_DEFAULT:
3601
0
    case LY_STMT_DEVIATE:
3602
0
    case LY_STMT_DEVIATION:
3603
0
    case LY_STMT_ENUM:
3604
0
    case LY_STMT_EXTENSION:
3605
0
    case LY_STMT_EXTENSION_INSTANCE:
3606
0
    case LY_STMT_FEATURE:
3607
0
    case LY_STMT_IDENTITY:
3608
0
    case LY_STMT_IF_FEATURE:
3609
0
    case LY_STMT_IMPORT:
3610
0
    case LY_STMT_INCLUDE:
3611
0
    case LY_STMT_MUST:
3612
0
    case LY_STMT_PATTERN:
3613
0
    case LY_STMT_REFINE:
3614
0
    case LY_STMT_REVISION:
3615
0
    case LY_STMT_TYPEDEF:
3616
0
    case LY_STMT_UNIQUE:
3617
        /* parse, sized array */
3618
0
        LY_CHECK_GOTO(rc = lysp_stmt_parse(pctx, stmt, substmt->storage, NULL), cleanup);
3619
0
        break;
3620
3621
0
    case LY_STMT_ARGUMENT:
3622
0
    case LY_STMT_BELONGS_TO:
3623
0
    case LY_STMT_CONTACT:
3624
161k
    case LY_STMT_DESCRIPTION:
3625
161k
    case LY_STMT_ERROR_APP_TAG:
3626
161k
    case LY_STMT_ERROR_MESSAGE:
3627
161k
    case LY_STMT_FRACTION_DIGITS:
3628
161k
    case LY_STMT_KEY:
3629
161k
    case LY_STMT_LENGTH:
3630
161k
    case LY_STMT_MANDATORY:
3631
161k
    case LY_STMT_MAX_ELEMENTS:
3632
161k
    case LY_STMT_MIN_ELEMENTS:
3633
161k
    case LY_STMT_MODIFIER:
3634
161k
    case LY_STMT_MODULE:
3635
161k
    case LY_STMT_NAMESPACE:
3636
161k
    case LY_STMT_ORGANIZATION:
3637
161k
    case LY_STMT_PATH:
3638
161k
    case LY_STMT_POSITION:
3639
161k
    case LY_STMT_PREFIX:
3640
161k
    case LY_STMT_PRESENCE:
3641
161k
    case LY_STMT_RANGE:
3642
233k
    case LY_STMT_REFERENCE:
3643
233k
    case LY_STMT_REQUIRE_INSTANCE:
3644
233k
    case LY_STMT_REVISION_DATE:
3645
233k
    case LY_STMT_SUBMODULE:
3646
413k
    case LY_STMT_TYPE:
3647
413k
    case LY_STMT_UNITS:
3648
413k
    case LY_STMT_VALUE:
3649
413k
    case LY_STMT_WHEN:
3650
413k
    case LY_STMT_YANG_VERSION:
3651
413k
    case LY_STMT_YIN_ELEMENT:
3652
        /* single item */
3653
413k
        if (*(void **)substmt->storage) {
3654
0
            LOGVAL(PARSER_CTX(pctx), LY_VCODE_DUPSTMT, stmt->stmt);
3655
0
            rc = LY_EVALID;
3656
0
            goto cleanup;
3657
0
        }
3658
3659
        /* parse */
3660
413k
        LY_CHECK_GOTO(rc = lysp_stmt_parse(pctx, stmt, substmt->storage, NULL), cleanup);
3661
413k
        break;
3662
3663
0
    case LY_STMT_CONFIG:
3664
        /* single item */
3665
0
        if ((*(uint16_t *)substmt->storage) & LYS_CONFIG_MASK) {
3666
0
            LOGVAL(PARSER_CTX(pctx), LY_VCODE_DUPSTMT, stmt->stmt);
3667
0
            rc = LY_EVALID;
3668
0
            goto cleanup;
3669
0
        }
3670
3671
        /* parse */
3672
0
        LY_CHECK_GOTO(rc = lysp_stmt_parse(pctx, stmt, substmt->storage, NULL), cleanup);
3673
0
        break;
3674
3675
0
    case LY_STMT_ORDERED_BY:
3676
        /* single item */
3677
0
        if ((*(uint16_t *)substmt->storage) & LYS_ORDBY_MASK) {
3678
0
            LOGVAL(PARSER_CTX(pctx), LY_VCODE_DUPSTMT, stmt->stmt);
3679
0
            rc = LY_EVALID;
3680
0
            goto cleanup;
3681
0
        }
3682
3683
        /* parse */
3684
0
        LY_CHECK_GOTO(rc = lysp_stmt_parse(pctx, stmt, substmt->storage, NULL), cleanup);
3685
0
        break;
3686
3687
0
    case LY_STMT_STATUS:
3688
        /* single item */
3689
0
        if ((*(uint16_t *)substmt->storage) & LYS_STATUS_MASK) {
3690
0
            LOGVAL(PARSER_CTX(pctx), LY_VCODE_DUPSTMT, stmt->stmt);
3691
0
            rc = LY_EVALID;
3692
0
            goto cleanup;
3693
0
        }
3694
3695
        /* parse */
3696
0
        LY_CHECK_GOTO(rc = lysp_stmt_parse(pctx, stmt, substmt->storage, NULL), cleanup);
3697
0
        break;
3698
3699
0
    default:
3700
0
        LOGINT(PARSER_CTX(pctx));
3701
0
        rc = LY_EINT;
3702
0
        goto cleanup;
3703
413k
    }
3704
3705
413k
cleanup:
3706
413k
    return rc;
3707
413k
}