/**
 * @file tree_schema.c
 * @author Radek Krejci <rkrejci@cesnet.cz>
 * @brief Schema tree implementation
 *
 * Copyright (c) 2015 - 2018 CESNET, z.s.p.o.
 *
 * This source code is licensed under BSD 3-Clause License (the "License").
 * You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://opensource.org/licenses/BSD-3-Clause
 */

#define _GNU_SOURCE /* asprintf, strdup */

#include "tree_schema.h"

#include <assert.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

#include "common.h"
#include "compat.h"
#include "context.h"
#include "dict.h"
#include "in.h"
#include "in_internal.h"
#include "log.h"
#include "parser_internal.h"
#include "parser_schema.h"
#include "path.h"
#include "plugins_internal.h"
#include "schema_compile.h"
#include "schema_compile_amend.h"
#include "schema_features.h"
#include "set.h"
#include "tree.h"
#include "tree_edit.h"
#include "tree_schema_free.h"
#include "tree_schema_internal.h"
#include "xpath.h"

const char * const ly_devmod_list[] = {
    [LYS_DEV_NOT_SUPPORTED] = "not-supported",
    [LYS_DEV_ADD] = "add",
    [LYS_DEV_DELETE] = "delete",
    [LYS_DEV_REPLACE] = "replace",
};

LIBYANG_API_DEF LY_ERR
lysc_tree_dfs_full(const struct lysc_node *root, lysc_dfs_clb dfs_clb, void *data)
{
    struct lysc_node *elem, *elem2;
    const struct lysc_node_action *action;
    const struct lysc_node_notif *notif;

    LY_CHECK_ARG_RET(NULL, root, dfs_clb, LY_EINVAL);

    LYSC_TREE_DFS_BEGIN(root, elem) {
        /* schema node */
        LY_CHECK_RET(dfs_clb(elem, data, &LYSC_TREE_DFS_continue));

        LY_LIST_FOR(lysc_node_actions(elem), action) {
            LYSC_TREE_DFS_BEGIN(action, elem2) {
                /* action subtree */
                LY_CHECK_RET(dfs_clb(elem2, data, &LYSC_TREE_DFS_continue));

                LYSC_TREE_DFS_END(action, elem2);
            }
        }

        LY_LIST_FOR(lysc_node_notifs(elem), notif) {
            LYSC_TREE_DFS_BEGIN(notif, elem2) {
                /* notification subtree */
                LY_CHECK_RET(dfs_clb(elem2, data, &LYSC_TREE_DFS_continue));

                LYSC_TREE_DFS_END(notif, elem2);
            }
        }

        LYSC_TREE_DFS_END(root, elem);
    }

    return LY_SUCCESS;
}

LIBYANG_API_DEF LY_ERR
lysc_module_dfs_full(const struct lys_module *mod, lysc_dfs_clb dfs_clb, void *data)
{
    const struct lysc_node *root;

    LY_CHECK_ARG_RET(NULL, mod, mod->compiled, dfs_clb, LY_EINVAL);

    /* schema nodes */
    LY_LIST_FOR(mod->compiled->data, root) {
        LY_CHECK_RET(lysc_tree_dfs_full(root, dfs_clb, data));
    }

    /* RPCs */
    LY_LIST_FOR((const struct lysc_node *)mod->compiled->rpcs, root) {
        LY_CHECK_RET(lysc_tree_dfs_full(root, dfs_clb, data));
    }

    /* notifications */
    LY_LIST_FOR((const struct lysc_node *)mod->compiled->notifs, root) {
        LY_CHECK_RET(lysc_tree_dfs_full(root, dfs_clb, data));
    }

    return LY_SUCCESS;
}

static void
lys_getnext_into_case(const struct lysc_node_case *first_case, const struct lysc_node **last, const struct lysc_node **next)
{
    for ( ; first_case; first_case = (const struct lysc_node_case *)first_case->next) {
        if (first_case->child) {
            /* there is something to return */
            (*next) = first_case->child;
            return;
        }
    }

    /* no children in choice's cases, so go to the choice's sibling instead of into it */
    (*last) = (*next);
    (*next) = (*next)->next;
}

/**
 * @brief Generic getnext function for ::lys_getnext() and ::lys_getnext_ext().
 *
 * Gets next schema tree (sibling) node element that can be instantiated in a data tree. Returned node can
 * be from an augment. If the @p ext is provided, the function is locked inside the schema tree defined in the
 * extension instance.
 *
 * ::lys_getnext_() is supposed to be called sequentially. In the first call, the @p last parameter is usually NULL
 * and function starts returning i) the first @p parent's child or ii) the first top level element specified in the
 * given extension (if provided) or iii) the first top level element of the @p module.
 * Consequent calls suppose to provide the previously returned node as the @p last parameter and still the same
 * @p parent and @p module parameters.
 *
 * Without options, the function is used to traverse only the schema nodes that can be paired with corresponding
 * data nodes in a data tree. By setting some @p options the behavior can be modified to the extent that
 * all the schema nodes are iteratively returned.
 *
 * @param[in] last Previously returned schema tree node, or NULL in case of the first call.
 * @param[in] parent Parent of the subtree where the function starts processing.
 * @param[in] module In case of iterating on top level elements, the @p parent is NULL and
 * module must be specified.
 * @param[in] ext The extension instance to provide a separate schema tree. To consider the top level elements in the tree,
 * the @p parent must be NULL. Anyway, at least one of @p parent, @p module and @p ext parameters must be specified.
 * @param[in] options [ORed options](@ref sgetnextflags).
 * @return Next schema tree node that can be instantiated in a data tree, NULL in case there is no such element.
 */
static const struct lysc_node *
lys_getnext_(const struct lysc_node *last, const struct lysc_node *parent, const struct lysc_module *module,
        const struct lysc_ext_instance *ext, uint32_t options)
{
    const struct lysc_node *next = NULL;
    ly_bool action_flag = 0, notif_flag = 0;

    LY_CHECK_ARG_RET(NULL, parent || module || ext, NULL);

next:
    if (!last) {
        /* first call */

        /* get know where to start */
        if (parent) {
            /* schema subtree */
            next = last = lysc_node_child(parent);
        } else {
            /* top level data */
            if (ext) {
                lyplg_ext_get_storage(ext, LY_STMT_DATA_NODE_MASK, sizeof last, (const void **)&last);
                next = last;
            } else {
                next = last = module->data;
            }
        }
        if (!next) {
            /* try to get action or notification */
            goto repeat;
        }
        /* test if the next can be returned */
        goto check;

    } else if (last->nodetype & (LYS_RPC | LYS_ACTION)) {
        action_flag = 1;
        next = last->next;
    } else if (last->nodetype == LYS_NOTIF) {
        action_flag = notif_flag = 1;
        next = last->next;
    } else {
        next = last->next;
    }

repeat:
    if (!next) {
        /* possibly go back to parent */
        if (last && (last->parent != parent)) {
            last = last->parent;
            goto next;
        } else if (!action_flag) {
            action_flag = 1;
            if (ext) {
                lyplg_ext_get_storage(ext, LY_STMT_OP_MASK, sizeof next, (const void **)&next);
            } else if (parent) {
                next = (struct lysc_node *)lysc_node_actions(parent);
            } else {
                next = (struct lysc_node *)module->rpcs;
            }
        } else if (!notif_flag) {
            notif_flag = 1;
            if (ext) {
                lyplg_ext_get_storage(ext, LY_STMT_NOTIFICATION, sizeof next, (const void **)&next);
            } else if (parent) {
                next = (struct lysc_node *)lysc_node_notifs(parent);
            } else {
                next = (struct lysc_node *)module->notifs;
            }
        } else {
            return NULL;
        }
        goto repeat;
    }
check:
    switch (next->nodetype) {
    case LYS_RPC:
    case LYS_ACTION:
    case LYS_NOTIF:
    case LYS_LEAF:
    case LYS_ANYXML:
    case LYS_ANYDATA:
    case LYS_LIST:
    case LYS_LEAFLIST:
        break;
    case LYS_CASE:
        if (options & LYS_GETNEXT_WITHCASE) {
            break;
        } else {
            /* go into */
            lys_getnext_into_case((const struct lysc_node_case *)next, &last, &next);
        }
        goto repeat;
    case LYS_CONTAINER:
        if (!(next->flags & LYS_PRESENCE) && (options & LYS_GETNEXT_INTONPCONT)) {
            if (lysc_node_child(next)) {
                /* go into */
                next = lysc_node_child(next);
            } else {
                last = next;
                next = next->next;
            }
            goto repeat;
        }
        break;
    case LYS_CHOICE:
        if (options & LYS_GETNEXT_WITHCHOICE) {
            break;
        } else if ((options & LYS_GETNEXT_NOCHOICE) || !lysc_node_child(next)) {
            next = next->next;
        } else {
            if (options & LYS_GETNEXT_WITHCASE) {
                next = lysc_node_child(next);
            } else {
                /* go into */
                lys_getnext_into_case(((struct lysc_node_choice *)next)->cases, &last, &next);
            }
        }
        goto repeat;
    case LYS_INPUT:
        if (options & LYS_GETNEXT_OUTPUT) {
            /* skip */
            next = next->next;
        } else {
            /* go into */
            next = lysc_node_child(next);
        }
        goto repeat;
    case LYS_OUTPUT:
        if (!(options & LYS_GETNEXT_OUTPUT)) {
            /* skip */
            next = next->next;
        } else {
            /* go into */
            next = lysc_node_child(next);
        }
        goto repeat;
    default:
        /* we should not be here */
        LOGINT(module ? module->mod->ctx : parent ? parent->module->ctx : ext->module->ctx);
        return NULL;
    }

    return next;
}

LIBYANG_API_DEF const struct lysc_node *
lys_getnext(const struct lysc_node *last, const struct lysc_node *parent, const struct lysc_module *module, uint32_t options)
{
    return lys_getnext_(last, parent, module, NULL, options);
}

LIBYANG_API_DEF const struct lysc_node *
lys_getnext_ext(const struct lysc_node *last, const struct lysc_node *parent, const struct lysc_ext_instance *ext, uint32_t options)
{
    return lys_getnext_(last, parent, NULL, ext, options);
}

const struct lysc_node *
lysc_ext_find_node(const struct lysc_ext_instance *ext, const struct lys_module *module, const char *name, size_t name_len,
        uint16_t nodetype, uint32_t options)
{
    const struct lysc_node *node = NULL;

    LY_CHECK_ARG_RET(NULL, ext, name, NULL);
    if (!nodetype) {
        nodetype = LYS_NODETYPE_MASK;
    }

    if (module && (module != ext->module)) {
        return NULL;
    }

    while ((node = lys_getnext_ext(node, NULL, ext, options))) {
        if (!(node->nodetype & nodetype)) {
            continue;
        }

        if (name_len) {
            if (!ly_strncmp(node->name, name, name_len)) {
                return node;
            }
        } else {
            if (!strcmp(node->name, name)) {
                return node;
            }
        }
    }
    return NULL;
}

LIBYANG_API_DEF const struct lysc_node *
lys_find_child(const struct lysc_node *parent, const struct lys_module *module, const char *name, size_t name_len,
        uint16_t nodetype, uint32_t options)
{
    const struct lysc_node *node = NULL;

    LY_CHECK_ARG_RET(NULL, module, name, NULL);
    LY_CHECK_CTX_EQUAL_RET(parent ? parent->module->ctx : NULL, module->ctx, NULL);
    if (!nodetype) {
        nodetype = LYS_NODETYPE_MASK;
    }

    while ((node = lys_getnext(node, parent, module->compiled, options))) {
        if (!(node->nodetype & nodetype)) {
            continue;
        }
        if (node->module != module) {
            continue;
        }

        if (name_len) {
            if (!ly_strncmp(node->name, name, name_len)) {
                return node;
            }
        } else {
            if (!strcmp(node->name, name)) {
                return node;
            }
        }
    }

    return NULL;
}

LIBYANG_API_DEF LY_ERR
lys_find_xpath_atoms(const struct ly_ctx *ctx, const struct lysc_node *ctx_node, const char *xpath, uint32_t options,
        struct ly_set **set)
{
    LY_ERR ret = LY_SUCCESS;
    struct lyxp_set xp_set;
    struct lyxp_expr *exp = NULL;
    uint32_t i;

    LY_CHECK_ARG_RET(NULL, ctx || ctx_node, xpath, set, LY_EINVAL);
    LY_CHECK_CTX_EQUAL_RET(ctx, ctx_node ? ctx_node->module->ctx : NULL, LY_EINVAL);
    if (!(options & LYXP_SCNODE_ALL)) {
        options |= LYXP_SCNODE;
    }
    if (!ctx) {
        ctx = ctx_node->module->ctx;
    }

    memset(&xp_set, 0, sizeof xp_set);

    /* compile expression */
    ret = lyxp_expr_parse(ctx, xpath, 0, 1, &exp);
    LY_CHECK_GOTO(ret, cleanup);

    /* atomize expression */
    ret = lyxp_atomize(ctx, exp, NULL, LY_VALUE_JSON, NULL, ctx_node, ctx_node, &xp_set, options);
    LY_CHECK_GOTO(ret, cleanup);

    /* allocate return set */
    ret = ly_set_new(set);
    LY_CHECK_GOTO(ret, cleanup);

    /* transform into ly_set */
    (*set)->objs = malloc(xp_set.used * sizeof *(*set)->objs);
    LY_CHECK_ERR_GOTO(!(*set)->objs, LOGMEM(ctx); ret = LY_EMEM, cleanup);
    (*set)->size = xp_set.used;

    for (i = 0; i < xp_set.used; ++i) {
        if (xp_set.val.scnodes[i].type == LYXP_NODE_ELEM) {
            ret = ly_set_add(*set, xp_set.val.scnodes[i].scnode, 1, NULL);
            LY_CHECK_GOTO(ret, cleanup);
        }
    }

cleanup:
    lyxp_set_free_content(&xp_set);
    lyxp_expr_free(ctx, exp);
    return ret;
}

LIBYANG_API_DEF LY_ERR
lys_find_expr_atoms(const struct lysc_node *ctx_node, const struct lys_module *cur_mod, const struct lyxp_expr *expr,
        const struct lysc_prefix *prefixes, uint32_t options, struct ly_set **set)
{
    LY_ERR ret = LY_SUCCESS;
    struct lyxp_set xp_set = {0};
    uint32_t i;

    LY_CHECK_ARG_RET(NULL, cur_mod, expr, prefixes, set, LY_EINVAL);
    LY_CHECK_CTX_EQUAL_RET(ctx_node ? ctx_node->module->ctx : NULL, cur_mod->ctx, LY_EINVAL);
    if (!(options & LYXP_SCNODE_ALL)) {
        options = LYXP_SCNODE;
    }

    /* atomize expression */
    ret = lyxp_atomize(cur_mod->ctx, expr, cur_mod, LY_VALUE_SCHEMA_RESOLVED, (void *)prefixes, ctx_node, ctx_node,
            &xp_set, options);
    LY_CHECK_GOTO(ret, cleanup);

    /* allocate return set */
    ret = ly_set_new(set);
    LY_CHECK_GOTO(ret, cleanup);

    /* transform into ly_set */
    (*set)->objs = malloc(xp_set.used * sizeof *(*set)->objs);
    LY_CHECK_ERR_GOTO(!(*set)->objs, LOGMEM(cur_mod->ctx); ret = LY_EMEM, cleanup);
    (*set)->size = xp_set.used;

    for (i = 0; i < xp_set.used; ++i) {
        if ((xp_set.val.scnodes[i].type == LYXP_NODE_ELEM) && (xp_set.val.scnodes[i].in_ctx >= LYXP_SET_SCNODE_ATOM_NODE)) {
            assert((xp_set.val.scnodes[i].in_ctx == LYXP_SET_SCNODE_ATOM_NODE) ||
                    (xp_set.val.scnodes[i].in_ctx == LYXP_SET_SCNODE_ATOM_VAL) ||
                    (xp_set.val.scnodes[i].in_ctx == LYXP_SET_SCNODE_ATOM_CTX));
            ret = ly_set_add(*set, xp_set.val.scnodes[i].scnode, 1, NULL);
            LY_CHECK_GOTO(ret, cleanup);
        }
    }

cleanup:
    lyxp_set_free_content(&xp_set);
    if (ret) {
        ly_set_free(*set, NULL);
        *set = NULL;
    }
    return ret;
}

LIBYANG_API_DEF LY_ERR
lys_find_xpath(const struct ly_ctx *ctx, const struct lysc_node *ctx_node, const char *xpath, uint32_t options,
        struct ly_set **set)
{
    LY_ERR ret = LY_SUCCESS;
    struct lyxp_set xp_set = {0};
    struct lyxp_expr *exp = NULL;
    uint32_t i;

    LY_CHECK_ARG_RET(NULL, ctx || ctx_node, xpath, set, LY_EINVAL);
    LY_CHECK_CTX_EQUAL_RET(ctx, ctx_node ? ctx_node->module->ctx : NULL, LY_EINVAL);
    if (!(options & LYXP_SCNODE_ALL)) {
        options = LYXP_SCNODE;
    }
    if (!ctx) {
        ctx = ctx_node->module->ctx;
    }

    /* compile expression */
    ret = lyxp_expr_parse(ctx, xpath, 0, 1, &exp);
    LY_CHECK_GOTO(ret, cleanup);

    /* atomize expression */
    ret = lyxp_atomize(ctx, exp, NULL, LY_VALUE_JSON, NULL, ctx_node, ctx_node, &xp_set, options);
    LY_CHECK_GOTO(ret, cleanup);

    /* allocate return set */
    ret = ly_set_new(set);
    LY_CHECK_GOTO(ret, cleanup);

    /* transform into ly_set */
    (*set)->objs = malloc(xp_set.used * sizeof *(*set)->objs);
    LY_CHECK_ERR_GOTO(!(*set)->objs, LOGMEM(ctx); ret = LY_EMEM, cleanup);
    (*set)->size = xp_set.used;

    for (i = 0; i < xp_set.used; ++i) {
        if ((xp_set.val.scnodes[i].type == LYXP_NODE_ELEM) && (xp_set.val.scnodes[i].in_ctx == LYXP_SET_SCNODE_ATOM_CTX)) {
            ret = ly_set_add(*set, xp_set.val.scnodes[i].scnode, 1, NULL);
            LY_CHECK_GOTO(ret, cleanup);
        }
    }

cleanup:
    lyxp_set_free_content(&xp_set);
    lyxp_expr_free(ctx, exp);
    if (ret) {
        ly_set_free(*set, NULL);
        *set = NULL;
    }
    return ret;
}

LIBYANG_API_DEF LY_ERR
lys_find_lypath_atoms(const struct ly_path *path, struct ly_set **set)
{
    LY_ERR ret = LY_SUCCESS;
    LY_ARRAY_COUNT_TYPE u, v;

    LY_CHECK_ARG_RET(NULL, path, set, LY_EINVAL);

    /* allocate return set */
    LY_CHECK_RET(ly_set_new(set));

    LY_ARRAY_FOR(path, u) {
        /* add nodes from the path */
        LY_CHECK_GOTO(ret = ly_set_add(*set, (void *)path[u].node, 0, NULL), cleanup);
        if (path[u].pred_type == LY_PATH_PREDTYPE_LIST) {
            LY_ARRAY_FOR(path[u].predicates, v) {
                /* add all the keys in a predicate */
                LY_CHECK_GOTO(ret = ly_set_add(*set, (void *)path[u].predicates[v].key, 0, NULL), cleanup);
            }
        }
    }

cleanup:
    if (ret) {
        ly_set_free(*set, NULL);
        *set = NULL;
    }
    return ret;
}

LIBYANG_API_DEF LY_ERR
lys_find_path_atoms(const struct ly_ctx *ctx, const struct lysc_node *ctx_node, const char *path, ly_bool output,
        struct ly_set **set)
{
    LY_ERR ret = LY_SUCCESS;
    uint8_t oper;
    struct lyxp_expr *expr = NULL;
    struct ly_path *p = NULL;

    LY_CHECK_ARG_RET(ctx, ctx || ctx_node, path, set, LY_EINVAL);
    LY_CHECK_CTX_EQUAL_RET(ctx, ctx_node ? ctx_node->module->ctx : NULL, LY_EINVAL);

    if (!ctx) {
        ctx = ctx_node->module->ctx;
    }

    /* parse */
    ret = lyxp_expr_parse(ctx, path, strlen(path), 0, &expr);
    LY_CHECK_GOTO(ret, cleanup);

    /* compile */
    oper = output ? LY_PATH_OPER_OUTPUT : LY_PATH_OPER_INPUT;
    ret = ly_path_compile(ctx, NULL, ctx_node, NULL, expr, oper, LY_PATH_TARGET_MANY, 0, LY_VALUE_JSON, NULL, &p);
    LY_CHECK_GOTO(ret, cleanup);

    /* resolve */
    ret = lys_find_lypath_atoms(p, set);

cleanup:
    ly_path_free(ctx, p);
    lyxp_expr_free(ctx, expr);
    return ret;
}

LIBYANG_API_DEF const struct lysc_node *
lys_find_path(const struct ly_ctx *ctx, const struct lysc_node *ctx_node, const char *path, ly_bool output)
{
    const struct lysc_node *snode = NULL;
    struct lyxp_expr *exp = NULL;
    struct ly_path *p = NULL;
    LY_ERR ret;
    uint8_t oper;

    LY_CHECK_ARG_RET(ctx, ctx || ctx_node, NULL);
    LY_CHECK_CTX_EQUAL_RET(ctx, ctx_node ? ctx_node->module->ctx : NULL, NULL);

    if (!ctx) {
        ctx = ctx_node->module->ctx;
    }

    /* parse */
    ret = lyxp_expr_parse(ctx, path, strlen(path), 0, &exp);
    LY_CHECK_GOTO(ret, cleanup);

    /* compile */
    oper = output ? LY_PATH_OPER_OUTPUT : LY_PATH_OPER_INPUT;
    ret = ly_path_compile(ctx, NULL, ctx_node, NULL, exp, oper, LY_PATH_TARGET_MANY, 0, LY_VALUE_JSON, NULL, &p);
    LY_CHECK_GOTO(ret, cleanup);

    /* get last node */
    snode = p[LY_ARRAY_COUNT(p) - 1].node;

cleanup:
    ly_path_free(ctx, p);
    lyxp_expr_free(ctx, exp);
    return snode;
}

char *
lysc_path_until(const struct lysc_node *node, const struct lysc_node *parent, LYSC_PATH_TYPE pathtype, char *buffer,
        size_t buflen)
{
    const struct lysc_node *iter, *par, *key;
    char *path = NULL;
    int len = 0;
    ly_bool skip_schema;

    if (buffer) {
        LY_CHECK_ARG_RET(node->module->ctx, buflen > 1, NULL);
        buffer[0] = '\0';
    }

    if ((pathtype == LYSC_PATH_DATA) || (pathtype == LYSC_PATH_DATA_PATTERN)) {
        /* skip schema-only nodes */
        skip_schema = 1;
    } else {
        skip_schema = 0;
    }

    for (iter = node; iter && (iter != parent) && (len >= 0); iter = iter->parent) {
        char *s;
        const char *slash;

        if (skip_schema && (iter->nodetype & (LYS_CHOICE | LYS_CASE | LYS_INPUT | LYS_OUTPUT))) {
            /* schema-only node */
            continue;
        }

        if ((pathtype == LYSC_PATH_DATA_PATTERN) && (iter->nodetype == LYS_LIST)) {
            key = NULL;
            while ((key = lys_getnext(key, iter, NULL, 0)) && lysc_is_key(key)) {
                s = buffer ? strdup(buffer) : path;

                /* print key predicate */
                if (buffer) {
                    len = snprintf(buffer, buflen, "[%s='%%s']%s", key->name, s ? s : "");
                } else {
                    len = asprintf(&path, "[%s='%%s']%s", key->name, s ? s : "");
                }
                free(s);

                if (buffer && (buflen <= (size_t)len)) {
                    /* not enough space in buffer */
                    break;
                }
            }
        }

        s = buffer ? strdup(buffer) : path;
        if (parent && (iter->parent == parent)) {
            slash = "";
        } else {
            slash = "/";
        }

        if (skip_schema) {
            par = lysc_data_parent(iter);
        } else {
            par = iter->parent;
        }

        if (!par || (par->module != iter->module)) {
            /* print prefix */
            if (buffer) {
                len = snprintf(buffer, buflen, "%s%s:%s%s", slash, iter->module->name, iter->name, s ? s : "");
            } else {
                len = asprintf(&path, "%s%s:%s%s", slash, iter->module->name, iter->name, s ? s : "");
            }
        } else {
            /* prefix is the same as in parent */
            if (buffer) {
                len = snprintf(buffer, buflen, "%s%s%s", slash, iter->name, s ? s : "");
            } else {
                len = asprintf(&path, "%s%s%s", slash, iter->name, s ? s : "");
            }
        }
        free(s);

        if (buffer && (buflen <= (size_t)len)) {
            /* not enough space in buffer */
            break;
        }
    }

    if (len < 0) {
        free(path);
        path = NULL;
    } else if (len == 0) {
        if (buffer) {
            strcpy(buffer, "/");
        } else {
            path = strdup("/");
        }
    }

    if (buffer) {
        return buffer;
    } else {
        return path;
    }
}

LIBYANG_API_DEF char *
lysc_path(const struct lysc_node *node, LYSC_PATH_TYPE pathtype, char *buffer, size_t buflen)
{
    return lysc_path_until(node, NULL, pathtype, buffer, buflen);
}

LY_ERR
_lys_set_implemented(struct lys_module *mod, const char **features, struct lys_glob_unres *unres)
{
    LY_ERR ret = LY_SUCCESS, r;
    struct lys_module *mod_iter;
    const char **imp_f, *all_f[] = {"*", NULL};
    uint32_t i;

    if (mod->implemented) {
        /* mod is already implemented, set the features */
        r = lys_set_features(mod->parsed, features);
        if (r == LY_EEXIST) {
            /* no changes */
            return LY_SUCCESS;
        } else if (!r) {
            /* mark the module as changed */
            mod->to_compile = 1;
        }

        return r;
    }

    /* implement, ignore recompilation because it must always take place later */
    r = lys_implement(mod, features, unres);
    LY_CHECK_ERR_GOTO(r && (r != LY_ERECOMPILE), ret = r, cleanup);

    if (mod->ctx->flags & LY_CTX_ALL_IMPLEMENTED) {
        /* implement all the imports as well */
        for (i = 0; i < unres->creating.count; ++i) {
            mod = unres->creating.objs[i];
            if (mod->implemented) {
                continue;
            }

            imp_f = (mod->ctx->flags & LY_CTX_ENABLE_IMP_FEATURES) ? all_f : NULL;
            r = lys_implement(mod, imp_f, unres);
            LY_CHECK_ERR_GOTO(r && (r != LY_ERECOMPILE), ret = r, cleanup);
        }
    }

    /* Try to find module with LYS_MOD_IMPORTED_REV flag. */
    i = 0;
    while ((mod_iter = ly_ctx_get_module_iter(mod->ctx, &i))) {
        if (!strcmp(mod_iter->name, mod->name) && (mod_iter != mod) && (mod_iter->latest_revision & LYS_MOD_IMPORTED_REV)) {
            LOGVRB("Implemented module \"%s@%s\" was not and will not be imported if the revision-date is missing"
                    " in the import statement. Instead, the revision \"%s\" is imported.", mod->name, mod->revision,
                    mod_iter->revision);
            break;
        }
    }

cleanup:
    return ret;
}

/**
 * @brief Check whether it may be needed to (re)compile a module from a particular dependency set
 * and if so, add it into its dep set.
 *
 * Dependency set includes all modules that need to be (re)compiled in case any of the module(s)
 * in the dep set are (re)compiled.
 *
 * The reason for recompilation is possible disabled nodes and updating
 * leafref targets to point to the newly compiled modules. Using the import relation, the
 * dependency is reflexive because of possible foreign augments and deviations, which are compiled
 * during the target module compilation.
 *
 * - every module must belong to exactly one dep set
 * - implement flag must be ignored because it can be changed during dep set compilation
 *
 * @param[in] mod Module to process.
 * @param[in,out] ctx_set Set with all not-yet-processed modules.
 * @param[in,out] dep_set Current dependency set to update.
 * @param[in] aux_set Set of traversed non-compiled modules, should be empty on first call.
 * @return LY_ERR value.
 */
static LY_ERR
lys_unres_dep_sets_create_mod_r(struct lys_module *mod, struct ly_set *ctx_set, struct ly_set *dep_set,
        struct ly_set *aux_set)
{
    struct lys_module *mod2;
    struct lysp_import *imports;
    uint32_t i;
    LY_ARRAY_COUNT_TYPE u, v;
    ly_bool found;

    if (LYS_IS_SINGLE_DEP_SET(mod)) {
        /* is already in a separate dep set */
        if (!lys_has_dep_mods(mod)) {
            /* break the dep set here, no modules depend on this one */
            return LY_SUCCESS;
        }

        if (ly_set_contains(aux_set, mod, NULL)) {
            /* it was traversed */
            return LY_SUCCESS;
        }

        /* add a new auxiliary module */
        LY_CHECK_RET(ly_set_add(aux_set, mod, 1, NULL));
    } else {
        if (!ly_set_contains(ctx_set, mod, &i)) {
            /* it was already processed */
            return LY_SUCCESS;
        }

        /* remove it from the set, we are processing it now */
        ly_set_rm_index(ctx_set, i, NULL);

        /* add a new dependent module into the dep set */
        LY_CHECK_RET(ly_set_add(dep_set, mod, 1, NULL));
    }

    /* process imports of the module and submodules */
    imports = mod->parsed->imports;
    LY_ARRAY_FOR(imports, u) {
        mod2 = imports[u].module;
        LY_CHECK_RET(lys_unres_dep_sets_create_mod_r(mod2, ctx_set, dep_set, aux_set));
    }
    LY_ARRAY_FOR(mod->parsed->includes, v) {
        imports = mod->parsed->includes[v].submodule->imports;
        LY_ARRAY_FOR(imports, u) {
            mod2 = imports[u].module;
            if (LYS_IS_SINGLE_DEP_SET(mod2) && !lys_has_dep_mods(mod2)) {
                /* break the dep set here, no modules depend on this one */
                continue;
            }

            LY_CHECK_RET(lys_unres_dep_sets_create_mod_r(imports[u].module, ctx_set, dep_set, aux_set));
        }
    }

    /* process modules and submodules importing this module */
    for (i = 0; i < mod->ctx->list.count; ++i) {
        mod2 = mod->ctx->list.objs[i];
        found = 0;

        imports = mod2->parsed->imports;
        LY_ARRAY_FOR(imports, u) {
            if (imports[u].module == mod) {
                found = 1;
                break;
            }
        }

        if (!found) {
            LY_ARRAY_FOR(mod2->parsed->includes, v) {
                imports = mod2->parsed->includes[v].submodule->imports;
                LY_ARRAY_FOR(imports, u) {
                    if (imports[u].module == mod) {
                        found = 1;
                        break;
                    }
                }

                if (found) {
                    break;
                }
            }
        }

        if (found) {
            LY_CHECK_RET(lys_unres_dep_sets_create_mod_r(mod2, ctx_set, dep_set, aux_set));
        }
    }

    return LY_SUCCESS;
}

/**
 * @brief Add all simple modules (that have nothing to (re)compile) into separate dep sets.
 *
 * @param[in,out] ctx_set Set with all not-yet-processed modules.
 * @param[in,out] main_set Set of dependency module sets.
 * @return LY_ERR value.
 */
static LY_ERR
lys_unres_dep_sets_create_single(struct ly_set *ctx_set, struct ly_set *main_set)
{
    LY_ERR ret = LY_SUCCESS;
    struct lys_module *m;
    uint32_t i = 0;
    struct ly_set *dep_set = NULL;

    while (i < ctx_set->count) {
        m = ctx_set->objs[i];
        if (LYS_IS_SINGLE_DEP_SET(m)) {
            /* remove it from the set, we are processing it now */
            ly_set_rm_index(ctx_set, i, NULL);

            /* this module can be in a separate dep set (but there still may be modules importing this one
             * that depend on imports of this one in case it defines groupings) */
            LY_CHECK_GOTO(ret = ly_set_new(&dep_set), cleanup);
            LY_CHECK_GOTO(ret = ly_set_add(dep_set, m, 1, NULL), cleanup);
            LY_CHECK_GOTO(ret = ly_set_add(main_set, dep_set, 1, NULL), cleanup);
            dep_set = NULL;
        } else {
            ++i;
        }
    }

cleanup:
    ly_set_free(dep_set, NULL);
    return ret;
}

LY_ERR
lys_unres_dep_sets_create(struct ly_ctx *ctx, struct ly_set *main_set, struct lys_module *mod)
{
    LY_ERR ret = LY_SUCCESS;
    struct lys_module *m;
    struct ly_set *dep_set = NULL, *ctx_set = NULL, aux_set = {0};
    uint32_t i;
    ly_bool found;

    assert(!main_set->count);

    /* start with a duplicate set of modules that we will remove from */
    LY_CHECK_GOTO(ret = ly_set_dup(&ctx->list, NULL, &ctx_set), cleanup);

    /* first create all dep sets with single modules */
    LY_CHECK_GOTO(ret = lys_unres_dep_sets_create_single(ctx_set, main_set), cleanup);

    if (mod && !ly_set_contains(ctx_set, mod, NULL)) {
        /* dep set for this module has already been created, nothing else to do */
        goto cleanup;
    }

    while (ctx_set->count) {
        /* create new dep set */
        LY_CHECK_GOTO(ret = ly_set_new(&dep_set), cleanup);

        if (mod) {
            /* use the module create a dep set with the rest of its dependent modules */
            LY_CHECK_GOTO(ret = lys_unres_dep_sets_create_mod_r(mod, ctx_set, dep_set, &aux_set), cleanup);
        } else {
            /* use first ctx mod to create a dep set with the rest of its dependent modules */
            LY_CHECK_GOTO(ret = lys_unres_dep_sets_create_mod_r(ctx_set->objs[0], ctx_set, dep_set, &aux_set), cleanup);
        }
        ly_set_erase(&aux_set, NULL);
        assert(dep_set->count);

        /* check whether there is any module that will be (re)compiled */
        found = 0;
        for (i = 0; i < dep_set->count; ++i) {
            m = dep_set->objs[i];
            if (m->to_compile) {
                found = 1;
                break;
            }
        }

        if (found) {
            /* if there is, all the implemented modules need to be recompiled */
            for (i = 0; i < dep_set->count; ++i) {
                m = dep_set->objs[i];
                if (m->implemented) {
                    m->to_compile = 1;
                }
            }
        }

        /* add the dep set into main set */
        LY_CHECK_GOTO(ret = ly_set_add(main_set, dep_set, 1, NULL), cleanup);
        dep_set = NULL;

        if (mod) {
            /* we need dep set only for this module */
            break;
        }
    }

#ifndef NDEBUG
    LOGDBG(LY_LDGDEPSETS, "dep sets created (%" PRIu32 "):", main_set->count);
    for (i = 0; i < main_set->count; ++i) {
        struct ly_set *iter_set = main_set->objs[i];

        LOGDBG(LY_LDGDEPSETS, "dep set #%" PRIu32 ":", i);
        for (uint32_t j = 0; j < iter_set->count; ++j) {
            m = iter_set->objs[j];
            LOGDBG(LY_LDGDEPSETS, "\t%s", m->name);
        }
    }
#endif

cleanup:
    assert(ret || main_set->objs);
    ly_set_erase(&aux_set, NULL);
    ly_set_free(dep_set, NULL);
    ly_set_free(ctx_set, NULL);
    return ret;
}

void
lys_unres_glob_revert(struct ly_ctx *ctx, struct lys_glob_unres *unres)
{
    uint32_t i, j, idx, prev_lo;
    struct lysf_ctx fctx = {.ctx = ctx};
    struct ly_set *dep_set;
    LY_ERR ret;

    for (i = 0; i < unres->implementing.count; ++i) {
        fctx.mod = unres->implementing.objs[i];
        assert(fctx.mod->implemented);

        /* make the module correctly non-implemented again */
        fctx.mod->implemented = 0;
        lys_precompile_augments_deviations_revert(ctx, fctx.mod);
        lysc_module_free(&fctx, fctx.mod->compiled);
        fctx.mod->compiled = NULL;

        /* should not be made implemented */
        fctx.mod->to_compile = 0;
    }

    for (i = 0; i < unres->creating.count; ++i) {
        fctx.mod = unres->creating.objs[i];

        /* remove the module from the context */
        ly_set_rm(&ctx->list, fctx.mod, NULL);

        /* remove it also from dep sets */
        for (j = 0; j < unres->dep_sets.count; ++j) {
            dep_set = unres->dep_sets.objs[j];
            if (ly_set_contains(dep_set, fctx.mod, &idx)) {
                ly_set_rm_index(dep_set, idx, NULL);
                break;
            }
        }

        /* free the module */
        lys_module_free(&fctx, fctx.mod, 1);
    }

    /* remove the extensions as well */
    lysf_ctx_erase(&fctx);

    if (unres->implementing.count) {
        /* recompile previous context because some implemented modules are no longer implemented,
         * we can reuse the current to_compile flags */
        prev_lo = ly_log_options(0);
        ret = lys_compile_depset_all(ctx, &ctx->unres);
        ly_log_options(prev_lo);
        if (ret) {
            LOGINT(ctx);
        }
    }
}

void
lys_unres_glob_erase(struct lys_glob_unres *unres)
{
    uint32_t i;

    for (i = 0; i < unres->dep_sets.count; ++i) {
        ly_set_free(unres->dep_sets.objs[i], NULL);
    }
    ly_set_erase(&unres->dep_sets, NULL);
    ly_set_erase(&unres->implementing, NULL);
    ly_set_erase(&unres->creating, NULL);

    assert(!unres->ds_unres.whens.count);
    assert(!unres->ds_unres.musts.count);
    assert(!unres->ds_unres.leafrefs.count);
    assert(!unres->ds_unres.disabled_leafrefs.count);
    assert(!unres->ds_unres.dflts.count);
    assert(!unres->ds_unres.disabled.count);
}

LIBYANG_API_DEF LY_ERR
lys_set_implemented(struct lys_module *mod, const char **features)
{
    LY_ERR ret = LY_SUCCESS;
    struct lys_glob_unres *unres = &mod->ctx->unres;

    LY_CHECK_ARG_RET(NULL, mod, LY_EINVAL);

    /* implement */
    ret = _lys_set_implemented(mod, features, unres);
    LY_CHECK_GOTO(ret, cleanup);

    if (!(mod->ctx->flags & LY_CTX_EXPLICIT_COMPILE)) {
        /* create dep set for the module and mark all the modules that will be (re)compiled */
        LY_CHECK_GOTO(ret = lys_unres_dep_sets_create(mod->ctx, &unres->dep_sets, mod), cleanup);

        /* (re)compile the whole dep set (other dep sets will have no modules marked for compilation) */
        LY_CHECK_GOTO(ret = lys_compile_depset_all(mod->ctx, unres), cleanup);

        /* unres resolved */
        lys_unres_glob_erase(unres);
    }

cleanup:
    if (ret) {
        lys_unres_glob_revert(mod->ctx, unres);
        lys_unres_glob_erase(unres);
    }
    return ret;
}

/**
 * @brief Resolve (find) all imported and included modules.
 *
 * @param[in] pctx Parser context.
 * @param[in] pmod Parsed module to resolve.
 * @param[out] new_mods Set with all the newly loaded modules.
 * @return LY_ERR value.
 */
static LY_ERR
lysp_resolve_import_include(struct lysp_ctx *pctx, struct lysp_module *pmod, struct ly_set *new_mods)
{
    struct lysp_import *imp;
    LY_ARRAY_COUNT_TYPE u, v;

    pmod->parsing = 1;
    LY_ARRAY_FOR(pmod->imports, u) {
        imp = &pmod->imports[u];
        if (!imp->module) {
            LY_CHECK_RET(lys_parse_load(PARSER_CTX(pctx), imp->name, imp->rev[0] ? imp->rev : NULL, new_mods, &imp->module));

            if (!imp->rev[0]) {
                /* This module must be selected for the next similar
                 * import without revision-date to avoid incorrect
                 * derived identities in the ::lys_module.identities.
                 */
                imp->module->latest_revision |= LYS_MOD_IMPORTED_REV;
            }
        }
        /* check for importing the same module twice */
        for (v = 0; v < u; ++v) {
            if (imp->module == pmod->imports[v].module) {
                LOGWRN(PARSER_CTX(pctx), "Single revision of the module \"%s\" imported twice.", imp->name);
            }
        }
    }
    LY_CHECK_RET(lysp_load_submodules(pctx, pmod, new_mods));

    pmod->parsing = 0;

    return LY_SUCCESS;
}

/**
 * @brief Generate path of the given paresed node.
 *
 * @param[in] node Schema path of this node will be generated.
 * @param[in] parent Build relative path only until this parent is found. If NULL, the full absolute path is printed.
 * @return NULL in case of memory allocation error, path of the node otherwise.
 * In case the @p buffer is NULL, the returned string is dynamically allocated and caller is responsible to free it.
 */
static char *
lysp_path_until(const struct lysp_node *node, const struct lysp_node *parent, const struct lysp_module *pmod)
{
    const struct lysp_node *iter, *par;
    char *path = NULL, *s;
    const char *slash;
    int len = 0;

    for (iter = node; iter && (iter != parent) && (len >= 0); iter = iter->parent) {
        if (parent && (iter->parent == parent)) {
            slash = "";
        } else {
            slash = "/";
        }

        s = path;
        par = iter->parent;
        if (!par) {
            /* print prefix */
            len = asprintf(&path, "%s%s:%s%s", slash, pmod->mod->name, iter->name, s ? s : "");
        } else {
            /* prefix is the same as in parent */
            len = asprintf(&path, "%s%s%s", slash, iter->name, s ? s : "");
        }
        free(s);
    }

    if (len < 0) {
        free(path);
        path = NULL;
    } else if (len == 0) {
        path = strdup("/");
    }

    return path;
}

/**
 * @brief Build log path for a parsed extension instance.
 *
 * @param[in] pcxt Parse context.
 * @param[in] ext Parsed extension instance.
 * @param[out] path Generated path.
 * @return LY_ERR value.
 */
static LY_ERR
lysp_resolve_ext_instance_log_path(const struct lysp_ctx *pctx, const struct lysp_ext_instance *ext, char **path)
{
    char *buf = NULL;
    uint32_t used = 0, size = 0;

    if (ext->parent_stmt & LY_STMT_NODE_MASK) {
        /* parsed node path */
        buf = lysp_path_until(ext->parent, NULL, PARSER_CUR_PMOD(pctx));
        LY_CHECK_ERR_RET(!buf, LOGMEM(PARSER_CTX(pctx)), LY_EMEM);
        size = used = strlen(buf);

        /* slash */
        size += 1;
        buf = realloc(buf, size + 1);
        LY_CHECK_ERR_RET(!buf, LOGMEM(PARSER_CTX(pctx)), LY_EMEM);
        used += sprintf(buf + used, "/");
    } else {
        /* module */
        size += 1 + strlen(PARSER_CUR_PMOD(pctx)->mod->name) + 1;
        buf = realloc(buf, size + 1);
        LY_CHECK_ERR_RET(!buf, LOGMEM(PARSER_CTX(pctx)), LY_EMEM);
        used += sprintf(buf + used, "/%s:", PARSER_CUR_PMOD(pctx)->mod->name);
    }

    /* extension name */
    size += 12 + strlen(ext->name) + 2;
    buf = realloc(buf, size + 1);
    LY_CHECK_ERR_RET(!buf, LOGMEM(PARSER_CTX(pctx)), LY_EMEM);
    used += sprintf(buf + used, "{extension='%s'}", ext->name);

    /* extension argument */
    if (ext->argument) {
        size += 1 + strlen(ext->argument);
        buf = realloc(buf, size + 1);
        LY_CHECK_ERR_RET(!buf, LOGMEM(PARSER_CTX(pctx)), LY_EMEM);
        used += sprintf(buf + used, "/%s", ext->argument);
    }

    *path = buf;
    return LY_SUCCESS;
}

/**
 * @brief Resolve (find) all extension instance records and finish their parsing.
 *
 * @param[in] pctx Parse context with all the parsed extension instances.
 * @return LY_ERR value.
 */
static LY_ERR
lysp_resolve_ext_instance_records(struct lysp_ctx *pctx)
{
    LY_ERR r;
    struct lysf_ctx fctx = {.ctx = PARSER_CTX(pctx)};
    struct lysp_ext_instance *exts, *ext;
    const struct lys_module *mod;
    uint32_t i;
    LY_ARRAY_COUNT_TYPE u;
    char *path = NULL;

    /* first finish parsing all extension instances ... */
    for (i = 0; i < pctx->ext_inst.count; ++i) {
        exts = pctx->ext_inst.objs[i];
        LY_ARRAY_FOR(exts, u) {
            ext = &exts[u];

            /* find the extension definition */
            LY_CHECK_RET(lysp_ext_find_definition(PARSER_CTX(pctx), ext, &mod, &ext->def));

            /* resolve the argument, if needed */
            LY_CHECK_RET(lysp_ext_instance_resolve_argument(PARSER_CTX(pctx), ext));

            /* find the extension record, if any */
            ext->record = lyplg_ext_record_find(mod->name, mod->revision, ext->def->name);
        }
    }

    /* ... then call the parse callback */
    for (i = 0; i < pctx->ext_inst.count; ++i) {
        exts = pctx->ext_inst.objs[i];
        u = 0;
        while (u < LY_ARRAY_COUNT(exts)) {
            ext = &exts[u];
            if (!ext->record || !ext->record->plugin.parse) {
                goto next_iter;
            }

            /* set up log path */
            if ((r = lysp_resolve_ext_instance_log_path(pctx, ext, &path))) {
                return r;
            }
            LOG_LOCSET(NULL, NULL, path, NULL);

            /* parse */
            r = ext->record->plugin.parse(pctx, ext);

            LOG_LOCBACK(0, 0, 1, 0);
            free(path);

            if (r == LY_ENOT) {
                /* instance should be ignored, remove it */
                lysp_ext_instance_free(&fctx, ext);
                LY_ARRAY_DECREMENT(exts);
                if (u < LY_ARRAY_COUNT(exts)) {
                    /* replace by the last item */
                    *ext = exts[LY_ARRAY_COUNT(exts)];
                } /* else if there are no more items, leave the empty array, we are not able to free it */
                continue;
            } else if (r) {
                /* error */
                return r;
            }

next_iter:
            ++u;
        }
    }

    return LY_SUCCESS;
}

LY_ERR
lys_parse_submodule(struct ly_ctx *ctx, struct ly_in *in, LYS_INFORMAT format, struct lysp_ctx *main_ctx,
        LY_ERR (*custom_check)(const struct ly_ctx *, struct lysp_module *, struct lysp_submodule *, void *),
        void *check_data, struct ly_set *new_mods, struct lysp_submodule **submodule)
{
    LY_ERR ret;
    struct lysp_submodule *submod = NULL, *latest_sp;
    struct lysp_yang_ctx *yangctx = NULL;
    struct lysp_yin_ctx *yinctx = NULL;
    struct lysp_ctx *pctx;
    struct lysf_ctx fctx = {.ctx = ctx};

    LY_CHECK_ARG_RET(ctx, ctx, in, LY_EINVAL);

    switch (format) {
    case LYS_IN_YIN:
        ret = yin_parse_submodule(&yinctx, ctx, main_ctx, in, &submod);
        pctx = (struct lysp_ctx *)yinctx;
        break;
    case LYS_IN_YANG:
        ret = yang_parse_submodule(&yangctx, ctx, main_ctx, in, &submod);
        pctx = (struct lysp_ctx *)yangctx;
        break;
    default:
        LOGERR(ctx, LY_EINVAL, "Invalid schema input format.");
        ret = LY_EINVAL;
        break;
    }
    LY_CHECK_GOTO(ret, error);
    assert(submod);

    /* make sure that the newest revision is at position 0 */
    lysp_sort_revisions(submod->revs);

    /* decide the latest revision */
    latest_sp = (struct lysp_submodule *)ly_ctx_get_submodule2_latest(submod->mod, submod->name);
    if (latest_sp) {
        if (submod->revs) {
            if (!latest_sp->revs) {
                /* latest has no revision, so mod is anyway newer */
                submod->latest_revision = latest_sp->latest_revision;
                /* the latest_sp is zeroed later when the new module is being inserted into the context */
            } else if (strcmp(submod->revs[0].date, latest_sp->revs[0].date) > 0) {
                submod->latest_revision = latest_sp->latest_revision;
                /* the latest_sp is zeroed later when the new module is being inserted into the context */
            } else {
                latest_sp = NULL;
            }
        } else {
            latest_sp = NULL;
        }
    } else {
        submod->latest_revision = 1;
    }

    if (custom_check) {
        LY_CHECK_GOTO(ret = custom_check(ctx, NULL, submod, check_data), error);
    }

    if (latest_sp) {
        latest_sp->latest_revision = 0;
    }

    lys_parser_fill_filepath(ctx, in, &submod->filepath);

    /* resolve imports and includes */
    LY_CHECK_GOTO(ret = lysp_resolve_import_include(pctx, (struct lysp_module *)submod, new_mods), error);

    /* resolve extension instance plugin records */
    LY_CHECK_GOTO(ret = lysp_resolve_ext_instance_records(pctx), error);

    if (format == LYS_IN_YANG) {
        lysp_yang_ctx_free(yangctx);
    } else {
        lysp_yin_ctx_free(yinctx);
    }
    *submodule = submod;
    return LY_SUCCESS;

error:
    if (!submod || !submod->name) {
        LOGERR(ctx, ret, "Parsing submodule failed.");
    } else {
        LOGERR(ctx, ret, "Parsing submodule \"%s\" failed.", submod->name);
    }
    lysp_module_free(&fctx, (struct lysp_module *)submod);
    if (format == LYS_IN_YANG) {
        lysp_yang_ctx_free(yangctx);
    } else {
        lysp_yin_ctx_free(yinctx);
    }
    return ret;
}

/**
 * @brief Add ietf-netconf metadata to the parsed module. Operation, filter, and select are added.
 *
 * @param[in] pctx Parse context.
 * @param[in] mod Parsed module to add to.
 * @return LY_SUCCESS on success.
 * @return LY_ERR on error.
 */
static LY_ERR
lysp_add_internal_ietf_netconf(struct lysp_ctx *pctx, struct lysp_module *mod)
{
    struct lysp_ext_instance *extp;
    struct lysp_stmt *stmt;
    struct lysp_import *imp;

    /*
     * 1) edit-config's operation
     */
    LY_ARRAY_NEW_RET(mod->mod->ctx, mod->exts, extp, LY_EMEM);
    LY_CHECK_ERR_RET(!extp, LOGMEM(mod->mod->ctx), LY_EMEM);
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "md_:annotation", 0, &extp->name));
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "operation", 0, &extp->argument));
    extp->format = LY_VALUE_SCHEMA;
    extp->prefix_data = mod;
    extp->parent = mod;
    extp->parent_stmt = LY_STMT_MODULE;
    extp->flags = LYS_INTERNAL;

    extp->child = stmt = calloc(1, sizeof *extp->child);
    LY_CHECK_ERR_RET(!stmt, LOGMEM(mod->mod->ctx), LY_EMEM);
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "type", 0, &stmt->stmt));
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "enumeration", 0, &stmt->arg));
    stmt->format = LY_VALUE_SCHEMA;
    stmt->prefix_data = mod;
    stmt->kw = LY_STMT_TYPE;

    stmt->child = calloc(1, sizeof *stmt->child);
    stmt = stmt->child;
    LY_CHECK_ERR_RET(!stmt, LOGMEM(mod->mod->ctx), LY_EMEM);
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "enum", 0, &stmt->stmt));
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "merge", 0, &stmt->arg));
    stmt->format = LY_VALUE_SCHEMA;
    stmt->prefix_data = mod;
    stmt->kw = LY_STMT_ENUM;

    stmt->next = calloc(1, sizeof *stmt->child);
    stmt = stmt->next;
    LY_CHECK_ERR_RET(!stmt, LOGMEM(mod->mod->ctx), LY_EMEM);
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "enum", 0, &stmt->stmt));
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "replace", 0, &stmt->arg));
    stmt->format = LY_VALUE_SCHEMA;
    stmt->prefix_data = mod;
    stmt->kw = LY_STMT_ENUM;

    stmt->next = calloc(1, sizeof *stmt->child);
    stmt = stmt->next;
    LY_CHECK_ERR_RET(!stmt, LOGMEM(mod->mod->ctx), LY_EMEM);
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "enum", 0, &stmt->stmt));
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "create", 0, &stmt->arg));
    stmt->format = LY_VALUE_SCHEMA;
    stmt->prefix_data = mod;
    stmt->kw = LY_STMT_ENUM;

    stmt->next = calloc(1, sizeof *stmt->child);
    stmt = stmt->next;
    LY_CHECK_ERR_RET(!stmt, LOGMEM(mod->mod->ctx), LY_EMEM);
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "enum", 0, &stmt->stmt));
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "delete", 0, &stmt->arg));
    stmt->format = LY_VALUE_SCHEMA;
    stmt->prefix_data = mod;
    stmt->kw = LY_STMT_ENUM;

    stmt->next = calloc(1, sizeof *stmt->child);
    stmt = stmt->next;
    LY_CHECK_ERR_RET(!stmt, LOGMEM(mod->mod->ctx), LY_EMEM);
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "enum", 0, &stmt->stmt));
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "remove", 0, &stmt->arg));
    stmt->format = LY_VALUE_SCHEMA;
    stmt->prefix_data = mod;
    stmt->kw = LY_STMT_ENUM;

    /*
     * 2) filter's type
     */
    LY_ARRAY_NEW_RET(mod->mod->ctx, mod->exts, extp, LY_EMEM);
    LY_CHECK_ERR_RET(!extp, LOGMEM(mod->mod->ctx), LY_EMEM);
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "md_:annotation", 0, &extp->name));
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "type", 0, &extp->argument));
    extp->format = LY_VALUE_SCHEMA;
    extp->prefix_data = mod;
    extp->parent = mod;
    extp->parent_stmt = LY_STMT_MODULE;
    extp->flags = LYS_INTERNAL;

    extp->child = stmt = calloc(1, sizeof *extp->child);
    LY_CHECK_ERR_RET(!stmt, LOGMEM(mod->mod->ctx), LY_EMEM);
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "type", 0, &stmt->stmt));
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "enumeration", 0, &stmt->arg));
    stmt->format = LY_VALUE_SCHEMA;
    stmt->prefix_data = mod;
    stmt->kw = LY_STMT_TYPE;

    stmt->child = calloc(1, sizeof *stmt->child);
    stmt = stmt->child;
    LY_CHECK_ERR_RET(!stmt, LOGMEM(mod->mod->ctx), LY_EMEM);
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "enum", 0, &stmt->stmt));
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "subtree", 0, &stmt->arg));
    stmt->format = LY_VALUE_SCHEMA;
    stmt->prefix_data = mod;
    stmt->kw = LY_STMT_ENUM;

    stmt->next = calloc(1, sizeof *stmt->child);
    stmt = stmt->next;
    LY_CHECK_ERR_RET(!stmt, LOGMEM(mod->mod->ctx), LY_EMEM);
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "enum", 0, &stmt->stmt));
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "xpath", 0, &stmt->arg));
    stmt->format = LY_VALUE_SCHEMA;
    stmt->prefix_data = mod;
    stmt->kw = LY_STMT_ENUM;

    /* if-feature for enum allowed only for YANG 1.1 modules */
    if (mod->version >= LYS_VERSION_1_1) {
        stmt->child = calloc(1, sizeof *stmt->child);
        stmt = stmt->child;
        LY_CHECK_ERR_RET(!stmt, LOGMEM(mod->mod->ctx), LY_EMEM);
        LY_CHECK_RET(lydict_insert(mod->mod->ctx, "if-feature", 0, &stmt->stmt));
        LY_CHECK_RET(lydict_insert(mod->mod->ctx, "xpath", 0, &stmt->arg));
        stmt->format = LY_VALUE_SCHEMA;
        stmt->prefix_data = mod;
        stmt->kw = LY_STMT_IF_FEATURE;
    }

    /*
     * 3) filter's select
     */
    LY_ARRAY_NEW_RET(mod->mod->ctx, mod->exts, extp, LY_EMEM);
    LY_CHECK_ERR_RET(!extp, LOGMEM(mod->mod->ctx), LY_EMEM);
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "md_:annotation", 0, &extp->name));
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "select", 0, &extp->argument));
    extp->format = LY_VALUE_SCHEMA;
    extp->prefix_data = mod;
    extp->parent = mod;
    extp->parent_stmt = LY_STMT_MODULE;
    extp->flags = LYS_INTERNAL;

    extp->child = stmt = calloc(1, sizeof *extp->child);
    LY_CHECK_ERR_RET(!stmt, LOGMEM(mod->mod->ctx), LY_EMEM);
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "type", 0, &stmt->stmt));
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "yang_:xpath1.0", 0, &stmt->arg));
    stmt->format = LY_VALUE_SCHEMA;
    stmt->prefix_data = mod;
    stmt->kw = LY_STMT_TYPE;

    if (LY_ARRAY_COUNT(mod->exts) == 3) {
        /* first extension instances */
        LY_CHECK_RET(ly_set_add(&pctx->ext_inst, mod->exts, 1, NULL));
    }

    /* create new imports for the used prefixes */
    LY_ARRAY_NEW_RET(mod->mod->ctx, mod->imports, imp, LY_EMEM);
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "ietf-yang-metadata", 0, &imp->name));
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "md_", 0, &imp->prefix));
    imp->flags = LYS_INTERNAL;

    LY_ARRAY_NEW_RET(mod->mod->ctx, mod->imports, imp, LY_EMEM);
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "ietf-yang-types", 0, &imp->name));
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "yang_", 0, &imp->prefix));
    imp->flags = LYS_INTERNAL;

    return LY_SUCCESS;
}

/**
 * @brief Add ietf-netconf-with-defaults "default" metadata to the parsed module.
 *
 * @param[in] pctx Parse context.
 * @param[in] mod Parsed module to add to.
 * @return LY_SUCCESS on success.
 * @return LY_ERR on error.
 */
static LY_ERR
lysp_add_internal_ietf_netconf_with_defaults(struct lysp_ctx *pctx, struct lysp_module *mod)
{
    struct lysp_ext_instance *extp;
    struct lysp_stmt *stmt;
    struct lysp_import *imp;

    /* add new extension instance */
    LY_ARRAY_NEW_RET(mod->mod->ctx, mod->exts, extp, LY_EMEM);

    /* fill in the extension instance fields */
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "md_:annotation", 0, &extp->name));
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "default", 0, &extp->argument));
    extp->format = LY_VALUE_SCHEMA;
    extp->prefix_data = mod;
    extp->parent = mod;
    extp->parent_stmt = LY_STMT_MODULE;
    extp->flags = LYS_INTERNAL;

    extp->child = stmt = calloc(1, sizeof *extp->child);
    LY_CHECK_ERR_RET(!stmt, LOGMEM(mod->mod->ctx), LY_EMEM);
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "type", 0, &stmt->stmt));
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "boolean", 0, &stmt->arg));
    stmt->format = LY_VALUE_SCHEMA;
    stmt->prefix_data = mod;
    stmt->kw = LY_STMT_TYPE;

    if (LY_ARRAY_COUNT(mod->exts) == 1) {
        /* first extension instance */
        LY_CHECK_RET(ly_set_add(&pctx->ext_inst, mod->exts, 1, NULL));
    }

    /* create new import for the used prefix */
    LY_ARRAY_NEW_RET(mod->mod->ctx, mod->imports, imp, LY_EMEM);
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "ietf-yang-metadata", 0, &imp->name));
    LY_CHECK_RET(lydict_insert(mod->mod->ctx, "md_", 0, &imp->prefix));
    imp->flags = LYS_INTERNAL;

    return LY_SUCCESS;
}

LY_ERR
lys_parse_in(struct ly_ctx *ctx, struct ly_in *in, LYS_INFORMAT format,
        LY_ERR (*custom_check)(const struct ly_ctx *ctx, struct lysp_module *mod, struct lysp_submodule *submod, void *data),
        void *check_data, struct ly_set *new_mods, struct lys_module **module)
{
    struct lys_module *mod = NULL, *latest, *mod_dup = NULL;
    LY_ERR ret;
    struct lysp_yang_ctx *yangctx = NULL;
    struct lysp_yin_ctx *yinctx = NULL;
    struct lysp_ctx *pctx = NULL;
    struct lysf_ctx fctx = {.ctx = ctx};
    char *filename, *rev, *dot;
    size_t len;
    ly_bool module_created = 0;

    assert(ctx && in && new_mods);

    if (module) {
        *module = NULL;
    }

    mod = calloc(1, sizeof *mod);
    LY_CHECK_ERR_RET(!mod, LOGMEM(ctx), LY_EMEM);
    mod->ctx = ctx;

    /* parse */
    switch (format) {
    case LYS_IN_YIN:
        ret = yin_parse_module(&yinctx, in, mod);
        pctx = (struct lysp_ctx *)yinctx;
        break;
    case LYS_IN_YANG:
        ret = yang_parse_module(&yangctx, in, mod);
        pctx = (struct lysp_ctx *)yangctx;
        break;
    default:
        LOGERR(ctx, LY_EINVAL, "Invalid schema input format.");
        ret = LY_EINVAL;
        break;
    }
    LY_CHECK_GOTO(ret, cleanup);

    /* make sure that the newest revision is at position 0 */
    lysp_sort_revisions(mod->parsed->revs);
    if (mod->parsed->revs) {
        LY_CHECK_GOTO(ret = lydict_insert(ctx, mod->parsed->revs[0].date, 0, &mod->revision), cleanup);
    }

    /* decide the latest revision */
    latest = ly_ctx_get_module_latest(ctx, mod->name);
    if (latest) {
        if (mod->revision) {
            if (!latest->revision) {
                /* latest has no revision, so mod is anyway newer */
                mod->latest_revision = latest->latest_revision & (LYS_MOD_LATEST_REV | LYS_MOD_LATEST_SEARCHDIRS);
                /* the latest is zeroed later when the new module is being inserted into the context */
            } else if (strcmp(mod->revision, latest->revision) > 0) {
                mod->latest_revision = latest->latest_revision & (LYS_MOD_LATEST_REV | LYS_MOD_LATEST_SEARCHDIRS);
                /* the latest is zeroed later when the new module is being inserted into the context */
            } else {
                latest = NULL;
            }
        } else {
            latest = NULL;
        }
    } else {
        mod->latest_revision = LYS_MOD_LATEST_REV;
    }

    if (custom_check) {
        LY_CHECK_GOTO(ret = custom_check(ctx, mod->parsed, NULL, check_data), cleanup);
    }

    /* check whether it is not already in the context in the same revision */
    mod_dup = ly_ctx_get_module(ctx, mod->name, mod->revision);
    if (mod_dup) {
        /* nothing to do */
        LOGVRB("Module \"%s@%s\" is already present in the context.", mod_dup->name,
                mod_dup->revision ? mod_dup->revision : "<none>");
        goto cleanup;
    }

    /* check whether there is not a namespace collision */
    mod_dup = ly_ctx_get_module_latest_ns(ctx, mod->ns);
    if (mod_dup && (mod_dup->revision == mod->revision)) {
        LOGERR(ctx, LY_EINVAL, "Two different modules (\"%s\" and \"%s\") have the same namespace \"%s\".",
                mod_dup->name, mod->name, mod->ns);
        ret = LY_EINVAL;
        goto cleanup;
    }

    switch (in->type) {
    case LY_IN_FILEPATH:
        /* check that name and revision match filename */
        filename = strrchr(in->method.fpath.filepath, '/');
        if (!filename) {
            filename = in->method.fpath.filepath;
        } else {
            filename++;
        }
        rev = strchr(filename, '@');
        dot = strrchr(filename, '.');

        /* name */
        len = strlen(mod->name);
        if (strncmp(filename, mod->name, len) ||
                ((rev && (rev != &filename[len])) || (!rev && (dot != &filename[len])))) {
            LOGWRN(ctx, "File name \"%s\" does not match module name \"%s\".", filename, mod->name);
        }
        if (rev) {
            len = dot - ++rev;
            if (!mod->parsed->revs || (len != LY_REV_SIZE - 1) || strncmp(mod->parsed->revs[0].date, rev, len)) {
                LOGWRN(ctx, "File name \"%s\" does not match module revision \"%s\".", filename,
                        mod->parsed->revs ? mod->parsed->revs[0].date : "none");
            }
        }

        break;
    case LY_IN_FD:
    case LY_IN_FILE:
    case LY_IN_MEMORY:
        /* nothing special to do */
        break;
    case LY_IN_ERROR:
        LOGINT(ctx);
        ret = LY_EINT;
        goto cleanup;
    }
    lys_parser_fill_filepath(ctx, in, &mod->filepath);

    if (latest) {
        latest->latest_revision &= ~(LYS_MOD_LATEST_REV | LYS_MOD_LATEST_SEARCHDIRS);
    }

    /* add internal data in case specific modules were parsed */
    if (!strcmp(mod->name, "ietf-netconf")) {
        LY_CHECK_GOTO(ret = lysp_add_internal_ietf_netconf(pctx, mod->parsed), cleanup);
    } else if (!strcmp(mod->name, "ietf-netconf-with-defaults")) {
        LY_CHECK_GOTO(ret = lysp_add_internal_ietf_netconf_with_defaults(pctx, mod->parsed), cleanup);
    }

    /* add the module into newly created module set, will also be freed from there on any error */
    LY_CHECK_GOTO(ret = ly_set_add(new_mods, mod, 1, NULL), cleanup);
    module_created = 1;

    /* add into context */
    ret = ly_set_add(&ctx->list, mod, 1, NULL);
    LY_CHECK_GOTO(ret, cleanup);
    ctx->change_count++;

    /* resolve includes and all imports */
    LY_CHECK_GOTO(ret = lysp_resolve_import_include(pctx, mod->parsed, new_mods), cleanup);

    /* resolve extension instance plugin records */
    LY_CHECK_GOTO(ret = lysp_resolve_ext_instance_records(pctx), cleanup);

    /* check name collisions */
    LY_CHECK_GOTO(ret = lysp_check_dup_typedefs(pctx, mod->parsed), cleanup);
    LY_CHECK_GOTO(ret = lysp_check_dup_groupings(pctx, mod->parsed), cleanup);
    LY_CHECK_GOTO(ret = lysp_check_dup_features(pctx, mod->parsed), cleanup);
    LY_CHECK_GOTO(ret = lysp_check_dup_identities(pctx, mod->parsed), cleanup);

    /* compile features */
    LY_CHECK_GOTO(ret = lys_compile_feature_iffeatures(mod->parsed), cleanup);

    /* compile identities */
    LY_CHECK_GOTO(ret = lys_compile_identities(mod), cleanup);

cleanup:
    if (ret && (ret != LY_EEXIST)) {
        if (mod && mod->name) {
            /* there are cases when path is not available for parsing error, so this additional
             * message tries to add information about the module where the error occurred */
            struct ly_err_item *e = ly_err_last(ctx);

            if (e && (!e->path || !strncmp(e->path, "Line ", ly_strlen_const("Line ")))) {
                LOGERR(ctx, ret, "Parsing module \"%s\" failed.", mod->name);
            }
        }
    }
    if (!module_created) {
        fctx.mod = mod;
        lys_module_free(&fctx, mod, 0);
        lysf_ctx_erase(&fctx);

        mod = mod_dup;
    }

    if (format == LYS_IN_YANG) {
        lysp_yang_ctx_free(yangctx);
    } else {
        lysp_yin_ctx_free(yinctx);
    }

    if (!ret && module) {
        *module = mod;
    }
    return ret;
}

static LYS_INFORMAT
lys_parse_get_format(const struct ly_in *in, LYS_INFORMAT format)
{
    if (!format && (in->type == LY_IN_FILEPATH)) {
        /* unknown format - try to detect it from filename's suffix */
        const char *path = in->method.fpath.filepath;
        size_t len = strlen(path);

        /* ignore trailing whitespaces */
        for ( ; len > 0 && isspace(path[len - 1]); len--) {}

        if ((len >= LY_YANG_SUFFIX_LEN + 1) &&
                !strncmp(&path[len - LY_YANG_SUFFIX_LEN], LY_YANG_SUFFIX, LY_YANG_SUFFIX_LEN)) {
            format = LYS_IN_YANG;
        } else if ((len >= LY_YIN_SUFFIX_LEN + 1) &&
                !strncmp(&path[len - LY_YIN_SUFFIX_LEN], LY_YIN_SUFFIX, LY_YIN_SUFFIX_LEN)) {
            format = LYS_IN_YIN;
        } /* else still unknown */
    }

    return format;
}

LIBYANG_API_DEF LY_ERR
lys_parse(struct ly_ctx *ctx, struct ly_in *in, LYS_INFORMAT format, const char **features, struct lys_module **module)
{
    LY_ERR ret = LY_SUCCESS;
    struct lys_module *mod;

    if (module) {
        *module = NULL;
    }
    LY_CHECK_ARG_RET(NULL, ctx, in, LY_EINVAL);

    format = lys_parse_get_format(in, format);
    LY_CHECK_ARG_RET(ctx, format, LY_EINVAL);

    /* remember input position */
    in->func_start = in->current;

    /* parse */
    ret = lys_parse_in(ctx, in, format, NULL, NULL, &ctx->unres.creating, &mod);
    LY_CHECK_GOTO(ret, cleanup);

    /* implement */
    ret = _lys_set_implemented(mod, features, &ctx->unres);
    LY_CHECK_GOTO(ret, cleanup);

    if (!(ctx->flags & LY_CTX_EXPLICIT_COMPILE)) {
        /* create dep set for the module and mark all the modules that will be (re)compiled */
        LY_CHECK_GOTO(ret = lys_unres_dep_sets_create(ctx, &ctx->unres.dep_sets, mod), cleanup);

        /* (re)compile the whole dep set (other dep sets will have no modules marked for compilation) */
        LY_CHECK_GOTO(ret = lys_compile_depset_all(ctx, &ctx->unres), cleanup);

        /* unres resolved */
        lys_unres_glob_erase(&ctx->unres);
    }

cleanup:
    if (ret) {
        lys_unres_glob_revert(ctx, &ctx->unres);
        lys_unres_glob_erase(&ctx->unres);
    } else if (module) {
        *module = mod;
    }
    return ret;
}

LIBYANG_API_DEF LY_ERR
lys_parse_mem(struct ly_ctx *ctx, const char *data, LYS_INFORMAT format, struct lys_module **module)
{
    LY_ERR ret;
    struct ly_in *in = NULL;

    LY_CHECK_ARG_RET(ctx, data, format != LYS_IN_UNKNOWN, LY_EINVAL);

    LY_CHECK_ERR_RET(ret = ly_in_new_memory(data, &in), LOGERR(ctx, ret, "Unable to create input handler."), ret);

    ret = lys_parse(ctx, in, format, NULL, module);
    ly_in_free(in, 0);

    return ret;
}

LIBYANG_API_DEF LY_ERR
lys_parse_fd(struct ly_ctx *ctx, int fd, LYS_INFORMAT format, struct lys_module **module)
{
    LY_ERR ret;
    struct ly_in *in = NULL;

    LY_CHECK_ARG_RET(ctx, fd > -1, format != LYS_IN_UNKNOWN, LY_EINVAL);

    LY_CHECK_ERR_RET(ret = ly_in_new_fd(fd, &in), LOGERR(ctx, ret, "Unable to create input handler."), ret);

    ret = lys_parse(ctx, in, format, NULL, module);
    ly_in_free(in, 0);

    return ret;
}

LIBYANG_API_DEF LY_ERR
lys_parse_path(struct ly_ctx *ctx, const char *path, LYS_INFORMAT format, struct lys_module **module)
{
    LY_ERR ret;
    struct ly_in *in = NULL;

    LY_CHECK_ARG_RET(ctx, path, format != LYS_IN_UNKNOWN, LY_EINVAL);

    LY_CHECK_ERR_RET(ret = ly_in_new_filepath(path, 0, &in),
            LOGERR(ctx, ret, "Unable to create input handler for filepath %s.", path), ret);

    ret = lys_parse(ctx, in, format, NULL, module);
    ly_in_free(in, 0);

    return ret;
}

LIBYANG_API_DEF LY_ERR
lys_search_localfile(const char * const *searchpaths, ly_bool cwd, const char *name, const char *revision,
        char **localfile, LYS_INFORMAT *format)
{
    LY_ERR ret = LY_EMEM;
    size_t len, flen, match_len = 0, dir_len;
    ly_bool implicit_cwd = 0;
    char *wd, *wn = NULL;
    DIR *dir = NULL;
    struct dirent *file;
    char *match_name = NULL;
    LYS_INFORMAT format_aux, match_format = 0;
    struct ly_set *dirs;
    struct stat st;

    LY_CHECK_ARG_RET(NULL, localfile, LY_EINVAL);

    /* start to fill the dir fifo with the context's search path (if set)
     * and the current working directory */
    LY_CHECK_RET(ly_set_new(&dirs));

    len = strlen(name);
    if (cwd) {
        wd = get_current_dir_name();
        if (!wd) {
            LOGMEM(NULL);
            goto cleanup;
        } else {
            /* add implicit current working directory (./) to be searched,
             * this directory is not searched recursively */
            ret = ly_set_add(dirs, wd, 0, NULL);
            LY_CHECK_GOTO(ret, cleanup);
            implicit_cwd = 1;
        }
    }
    if (searchpaths) {
        for (uint64_t i = 0; searchpaths[i]; i++) {
            /* check for duplicities with the implicit current working directory */
            if (implicit_cwd && !strcmp(dirs->objs[0], searchpaths[i])) {
                implicit_cwd = 0;
                continue;
            }
            wd = strdup(searchpaths[i]);
            if (!wd) {
                LOGMEM(NULL);
                goto cleanup;
            } else {
                ret = ly_set_add(dirs, wd, 0, NULL);
                LY_CHECK_GOTO(ret, cleanup);
            }
        }
    }
    wd = NULL;

    /* start searching */
    while (dirs->count) {
        free(wd);
        free(wn); wn = NULL;

        dirs->count--;
        wd = (char *)dirs->objs[dirs->count];
        dirs->objs[dirs->count] = NULL;
        LOGVRB("Searching for \"%s\" in \"%s\".", name, wd);

        if (dir) {
            closedir(dir);
        }
        dir = opendir(wd);
        dir_len = strlen(wd);
        if (!dir) {
            LOGWRN(NULL, "Unable to open directory \"%s\" for searching (sub)modules (%s).", wd, strerror(errno));
        } else {
            while ((file = readdir(dir))) {
                if (!strcmp(".", file->d_name) || !strcmp("..", file->d_name)) {
                    /* skip . and .. */
                    continue;
                }
                free(wn);
                if (asprintf(&wn, "%s/%s", wd, file->d_name) == -1) {
                    LOGMEM(NULL);
                    goto cleanup;
                }
                if (stat(wn, &st) == -1) {
                    LOGWRN(NULL, "Unable to get information about \"%s\" file in \"%s\" when searching for (sub)modules (%s)",
                            file->d_name, wd, strerror(errno));
                    continue;
                }
                if (S_ISDIR(st.st_mode) && (dirs->count || !implicit_cwd)) {
                    /* we have another subdirectory in searchpath to explore,
                     * subdirectories are not taken into account in current working dir (dirs->set.g[0]) */
                    ret = ly_set_add(dirs, wn, 0, NULL);
                    LY_CHECK_GOTO(ret, cleanup);

                    /* continue with the next item in current directory */
                    wn = NULL;
                    continue;
                } else if (!S_ISREG(st.st_mode)) {
                    /* not a regular file (note that we see the target of symlinks instead of symlinks */
                    continue;
                }

                /* here we know that the item is a file which can contain a module */
                if (strncmp(name, file->d_name, len) ||
                        ((file->d_name[len] != '.') && (file->d_name[len] != '@'))) {
                    /* different filename than the module we search for */
                    continue;
                }

                /* get type according to filename suffix */
                flen = strlen(file->d_name);
                if ((flen >= LY_YANG_SUFFIX_LEN + 1) &&
                        !strcmp(&file->d_name[flen - LY_YANG_SUFFIX_LEN], LY_YANG_SUFFIX)) {
                    format_aux = LYS_IN_YANG;
                } else if ((flen >= LY_YIN_SUFFIX_LEN + 1) &&
                        !strcmp(&file->d_name[flen - LY_YIN_SUFFIX_LEN], LY_YIN_SUFFIX)) {
                    format_aux = LYS_IN_YIN;
                } else {
                    /* not supportde suffix/file format */
                    continue;
                }

                if (revision) {
                    /* we look for the specific revision, try to get it from the filename */
                    if (file->d_name[len] == '@') {
                        /* check revision from the filename */
                        if (strncmp(revision, &file->d_name[len + 1], strlen(revision))) {
                            /* another revision */
                            continue;
                        } else {
                            /* exact revision */
                            free(match_name);
                            match_name = wn;
                            wn = NULL;
                            match_len = dir_len + 1 + len;
                            match_format = format_aux;
                            goto success;
                        }
                    } else {
                        /* continue trying to find exact revision match, use this only if not found */
                        free(match_name);
                        match_name = wn;
                        wn = NULL;
                        match_len = dir_len + 1 + len;
                        match_format = format_aux;
                        continue;
                    }
                } else {
                    /* remember the revision and try to find the newest one */
                    if (match_name) {
                        if ((file->d_name[len] != '@') ||
                                lysp_check_date(NULL, &file->d_name[len + 1],
                                flen - ((format_aux == LYS_IN_YANG) ? LY_YANG_SUFFIX_LEN : LY_YIN_SUFFIX_LEN) - len - 1, NULL)) {
                            continue;
                        } else if ((match_name[match_len] == '@') &&
                                (strncmp(&match_name[match_len + 1], &file->d_name[len + 1], LY_REV_SIZE - 1) >= 0)) {
                            continue;
                        }
                        free(match_name);
                    }

                    match_name = wn;
                    wn = NULL;
                    match_len = dir_len + 1 + len;
                    match_format = format_aux;
                    continue;
                }
            }
        }
    }

success:
    (*localfile) = match_name;
    match_name = NULL;
    if (format) {
        (*format) = match_format;
    }
    ret = LY_SUCCESS;

cleanup:
    free(wn);
    free(wd);
    if (dir) {
        closedir(dir);
    }
    free(match_name);
    ly_set_free(dirs, free);

    return ret;
}
