blob: 5734763d836d774330137db84faa9105dbe570e8 [file] [log] [blame]
Radek Krejcie534c132016-11-23 13:32:31 +01001/**
2 * @file extensions.h
3 * @author Radek Krejci <rkrejci@cesnet.cz>
4 * @brief libyang support for YANG extension implementations.
5 *
6 * Copyright (c) 2016 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#ifndef LY_EXTENSIONS_H_
16#define LY_EXTENSIONS_H_
17
18#include "tree_schema.h"
19
20#ifdef __cplusplus
21extern "C" {
22#endif
23
Radek Krejcie534c132016-11-23 13:32:31 +010024/**
Radek Krejci8d6b7422017-02-03 14:42:13 +010025 * @addtogroup extensions
26 * @{
27 */
28
29/**
Radek Krejcie534c132016-11-23 13:32:31 +010030 * @brief Callback to check that the extension can be instantiated inside the provided node
31 *
Radek Krejci43ce4b72017-01-04 11:02:38 +010032 * @param[in] parent The parent of the instantiated extension.
33 * @param[in] parent_type The type of the structure provided as \p parent.
34 * @param[in] substmt_type libyang does not store all the extension instances in the structures where they are
35 * instantiated in the module. In some cases (see #LYEXT_SUBSTMT) they are stored in parent
36 * structure and marked with flag to know in which substatement of the parent the extension
37 * was originally instantiated.
38 * @return 0 - yes
39 * 1 - no
40 * 2 - ignore / skip without an error
41 */
42typedef int (*lyext_check_position_clb)(const void *parent, LYEXT_PAR parent_type, LYEXT_SUBSTMT substmt_type);
43
44/**
45 * @brief Callback to check that the extension instance is correct - have
46 * the valid argument, all the mandatory substatements, etc.
47 *
Radek Krejci80056d52017-01-05 13:13:33 +010048 * @param[in] ext Extension instance to be checked.
Radek Krejci90db7552017-01-04 16:17:46 +010049 * @return 0 - ok
50 * 1 - error
Radek Krejcie534c132016-11-23 13:32:31 +010051 */
Radek Krejci43ce4b72017-01-04 11:02:38 +010052typedef int (*lyext_check_result_clb)(struct lys_ext_instance *ext);
Radek Krejcie534c132016-11-23 13:32:31 +010053
Radek Krejci80056d52017-01-05 13:13:33 +010054/**
55 * @brief Callback to decide whether the extension will be inherited into the provided schema node. The extension
56 * instance is always from some of the node's parents.
57 *
58 * @param[in] ext Extension instance to be inherited.
59 * @param[in] node Schema node where the node is supposed to be inherited.
60 * @return 0 - yes
61 * 1 - no (do not process the node's children)
62 * 2 - no, but continue with children
63 */
64typedef int (*lyext_check_inherit_clb)(struct lys_ext_instance *ext, struct lys_node *node);
65
Radek Krejci43ce4b72017-01-04 11:02:38 +010066struct lyext_plugin {
67 LYEXT_TYPE type; /**< type of the extension, according to it the structure will be casted */
Radek Krejci80056d52017-01-05 13:13:33 +010068 uint16_t flags; /**< [extension flags](@ref extflags) */
Radek Krejcie534c132016-11-23 13:32:31 +010069
Radek Krejci80056d52017-01-05 13:13:33 +010070 lyext_check_position_clb check_position; /**< callbcak for testing that the extension can be instantiated
Radek Krejci43ce4b72017-01-04 11:02:38 +010071 under the provided parent. Mandatory callback. */
Radek Krejci80056d52017-01-05 13:13:33 +010072 lyext_check_result_clb check_result; /**< callback for testing if the argument value of the extension instance
Radek Krejci43ce4b72017-01-04 11:02:38 +010073 is valid. Mandatory if the extension has the argument. */
Radek Krejci80056d52017-01-05 13:13:33 +010074 lyext_check_inherit_clb check_inherit; /**< callback to decide if the extension is supposed to be inherited into
75 the provided node */
Radek Krejcie534c132016-11-23 13:32:31 +010076};
77
Radek Krejci8d6b7422017-02-03 14:42:13 +010078struct lyext_plugin_complex {
79 LYEXT_TYPE type; /**< type of the extension, according to it the structure will be casted */
80 uint16_t flags; /**< [extension flags](@ref extflags) */
81
82 lyext_check_position_clb check_position; /**< callbcak for testing that the extension can be instantiated
83 under the provided parent. Mandatory callback. */
84 lyext_check_result_clb check_result; /**< callback for testing if the argument value of the extension instance
85 is valid. Mandatory if the extension has the argument. */
86 lyext_check_inherit_clb check_inherit; /**< callback to decide if the extension is supposed to be inherited into
87 the provided node */
88 struct lyext_substmt *substmt; /**< NULL-terminated array of allowed substatements and restrictions
89 to their instantiation inside the extension instance */
90 size_t instance_size; /**< size of the instance structure to allocate, the structure is
91 is provided as ::lys_ext_instance_complex, but the content array
92 is accessed according to the substmt specification provided by
93 plugin */
94};
95
Radek Krejci43ce4b72017-01-04 11:02:38 +010096struct lyext_plugin_list {
Radek Krejci3b88c6c2017-01-04 16:12:12 +010097 const char *module; /**< name of the module where the extension is defined */
98 const char *revision; /**< optional module revision - if not specified, the plugin applies to any revision,
99 which is not an optional approach due to a possible future revisions of the module.
100 Instead, there should be defined multiple items in the plugins list, each with the
101 different revision, but all with the same pointer to the plugin extension. The
102 only valid use case for the NULL revision is the case the module has no revision. */
Radek Krejci43ce4b72017-01-04 11:02:38 +0100103 const char *name; /**< name of the extension */
104 struct lyext_plugin *plugin; /**< plugin for the extension */
Radek Krejcie534c132016-11-23 13:32:31 +0100105};
106
Radek Krejci8d6b7422017-02-03 14:42:13 +0100107/**
108 * @}
109 */
Radek Krejci43ce4b72017-01-04 11:02:38 +0100110
Radek Krejcie534c132016-11-23 13:32:31 +0100111#ifdef __cplusplus
112}
113#endif
114
115#endif /* LY_EXTENSIONS_H_ */