blob: c6f4b5e616a9e1580d4bf6e6548c6966c80368e0 [file] [log] [blame]
Radek Krejcid7e8a622018-10-29 15:54:55 +01001/**
Radek Krejci0935f412019-08-20 16:15:18 +02002 * @file plugins_exts.h
Radek Krejcid7e8a622018-10-29 15:54:55 +01003 * @author Radek Krejci <rkrejci@cesnet.cz>
4 * @brief libyang support for YANG extensions implementation.
5 *
Radek Krejci0935f412019-08-20 16:15:18 +02006 * Copyright (c) 2015 - 2019 CESNET, z.s.p.o.
Radek Krejcid7e8a622018-10-29 15:54:55 +01007 *
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
Radek Krejci0935f412019-08-20 16:15:18 +020015#ifndef LY_PLUGINS_EXTS_H_
16#define LY_PLUGINS_EXTS_H_
Radek Krejcid7e8a622018-10-29 15:54:55 +010017
Radek Krejci535ea9f2020-05-29 16:01:05 +020018#include "log.h"
Radek Krejci3e6632f2021-03-22 22:08:21 +010019#include "plugins.h"
Radek Krejci859a15a2021-03-05 20:56:59 +010020#include "tree_edit.h"
Radek Krejci0e59c312019-08-15 15:34:15 +020021#include "tree_schema.h"
Radek Krejci535ea9f2020-05-29 16:01:05 +020022
Radek Krejci5f9a3672021-03-05 21:35:22 +010023#include "plugins_exts_compile.h"
Radek Krejcif8d7f9a2021-03-10 14:32:36 +010024#include "plugins_exts_print.h"
Radek Krejci5f9a3672021-03-05 21:35:22 +010025
Radek Krejci535ea9f2020-05-29 16:01:05 +020026struct ly_ctx;
27struct lyd_node;
Radek Krejci77114102021-03-10 15:21:57 +010028struct lysc_ctx;
29struct lyspr_ctx;
Radek Krejci0e59c312019-08-15 15:34:15 +020030
Radek Krejcid7e8a622018-10-29 15:54:55 +010031#ifdef __cplusplus
32extern "C" {
33#endif
34
35/**
36 * @defgroup extensions YANG Extensions
37 *
38 * @{
39 */
40
41/**
Radek Krejci0935f412019-08-20 16:15:18 +020042 * @brief Extensions API version
43 */
Radek Krejcia6f61e72021-03-24 21:00:19 +010044#define LYPLG_EXT_API_VERSION 1
Radek Krejci0935f412019-08-20 16:15:18 +020045
46/**
Radek Krejcia6f61e72021-03-24 21:00:19 +010047 * @brief Macro to define plugin information in external plugins
48 *
49 * Use as follows:
50 * LYPLG_EXTENSIONS = {{<filled information of ::lyplg_ext_record>}, ..., {0}};
Radek Krejci0935f412019-08-20 16:15:18 +020051 */
Radek Krejcia6f61e72021-03-24 21:00:19 +010052#define LYPLG_EXTENSIONS \
53 uint32_t plugins_extensions_apiver__ = LYPLG_EXT_API_VERSION; \
54 const struct lyplg_ext_record plugins_extensions__[]
Radek Krejci0935f412019-08-20 16:15:18 +020055
56/**
Radek Krejci8678fa42020-08-18 16:07:28 +020057 * @brief Free the extension instance's data compiled with ::lys_compile_extension_instance().
Radek Krejci1b2eef82021-02-17 11:17:27 +010058 *
59 * @param[in] libyang context
60 * @param[in] substmts The sized array of extension instance's substatements. The whole array is freed except the storage
61 * places which are expected to be covered by the extension plugin.
Radek Krejci38d85362019-09-05 16:26:38 +020062 */
Radek Krejci0b013302021-03-29 15:22:32 +020063void lyplg_ext_instance_substatements_free(struct ly_ctx *ctx, struct lysc_ext_substmt *substmts);
Radek Krejci38d85362019-09-05 16:26:38 +020064
65/**
Radek Krejci0e59c312019-08-15 15:34:15 +020066 * @brief Callback to compile extension from the lysp_ext_instance to the lysc_ext_instance. The later structure is generally prepared
67 * and only the extension specific data are supposed to be added (if any).
68 *
Radek Krejciadcf63d2021-02-09 10:21:18 +010069 * The parsed generic statements can be processed by the callback on its own or the ::lys_compile_extension_instance
70 * function can be used to let the compilation to libyang following the standard rules for processing the YANG statements.
71 *
Radek Krejci0e59c312019-08-15 15:34:15 +020072 * @param[in] cctx Current compile context.
73 * @param[in] p_ext Parsed extension instance data.
74 * @param[in,out] c_ext Prepared compiled extension instance structure where an addition, extension-specific, data are supposed to be placed
75 * for later use (data validation or use of external tool).
76 * @return LY_SUCCESS in case of success.
77 * @return LY_EVALID in case of non-conforming parsed data.
Michal Vasko7b1ad1a2020-11-02 15:41:27 +010078 * @return LY_ENOT in case the extension instance is not supported and should be removed.
Radek Krejci0e59c312019-08-15 15:34:15 +020079 */
Radek Krejci0b013302021-03-29 15:22:32 +020080typedef LY_ERR (*lyplg_ext_compile_clb)(struct lysc_ctx *cctx, const struct lysp_ext_instance *p_ext, struct lysc_ext_instance *c_ext);
Radek Krejci0e59c312019-08-15 15:34:15 +020081
82/**
Radek Krejci0b013302021-03-29 15:22:32 +020083 * @brief Callback to free the extension specific data created by the ::lyplg_ext_compile_clb callback of the same extension plugin.
Radek Krejci0e59c312019-08-15 15:34:15 +020084 *
Radek Krejci38d85362019-09-05 16:26:38 +020085 * @param[in] ctx libyang context.
Radek Krejci0e59c312019-08-15 15:34:15 +020086 * @param[in,out] ext Compiled extension structure where the data to free are placed.
87 */
Radek Krejci0b013302021-03-29 15:22:32 +020088typedef void (*lyplg_ext_free_clb)(struct ly_ctx *ctx, struct lysc_ext_instance *ext);
Radek Krejci0e59c312019-08-15 15:34:15 +020089
90/**
91 * @brief Callback to decide if data instance is valid according to the schema.
92 *
Radek Krejci4f2e3e52021-03-30 14:20:28 +020093 * The callback is used only for the extension instances placed in the data nodes or type (the
94 * ::lysc_ext_instance.parent_stmt value must be ::LY_STMT_IS_DATA_NODE() values or ::LY_STMT_TYPE):
Radek Krejci0e59c312019-08-15 15:34:15 +020095 *
96 * @param[in] ext Extension instance to be checked.
Radek Krejci4f2e3e52021-03-30 14:20:28 +020097 * @param[in] node Data node connected with the extension instance.
Radek Krejci0e59c312019-08-15 15:34:15 +020098 *
99 * @return LY_SUCCESS on data validation success.
100 * @return LY_EVALID in case the validation fails.
101 */
Radek Krejci0b013302021-03-29 15:22:32 +0200102typedef LY_ERR (*lyplg_ext_data_validation_clb)(struct lysc_ext_instance *ext, struct lyd_node *node);
Radek Krejci0e59c312019-08-15 15:34:15 +0200103
104/**
Radek Krejciadcf63d2021-02-09 10:21:18 +0100105 * @brief Callback to print the compiled extension instance's private data in the INFO format.
106 *
107 * @param[in] ctx YANG printer context to provide output handler and other information for printing.
108 * @param[in] ext The compiled extension instance, mainly to access the extensions.
109 * @param[in, out] flag Flag to be shared with the caller regarding the opening brackets - 0 if the '{' not yet printed,
110 * 1 otherwise.
111 *
112 * @return LY_SUCCESS when everything was fine, other LY_ERR values in case of failure
113 */
Radek Krejci0b013302021-03-29 15:22:32 +0200114typedef LY_ERR (*lyplg_ext_schema_printer_clb)(struct lyspr_ctx *ctx, struct lysc_ext_instance *ext, ly_bool *flag);
Radek Krejciadcf63d2021-02-09 10:21:18 +0100115
116/**
Radek Krejci0e59c312019-08-15 15:34:15 +0200117 * @brief Extension plugin implementing various aspects of a YANG extension
118 */
Radek Krejcicc9e30f2021-03-29 12:45:08 +0200119struct lyplg_ext {
Radek Krejci0b013302021-03-29 15:22:32 +0200120 const char *id; /**< Plugin identification (mainly for distinguish incompatible versions of the plugins for external tools) */
121 lyplg_ext_compile_clb compile; /**< Callback to compile extension instance from the parsed data */
122 lyplg_ext_data_validation_clb validate; /**< Callback to decide if data instance is valid according to the schema. */
123 lyplg_ext_schema_printer_clb sprinter; /**< Callback to print the compiled content (info format) of the extension instance */
124 lyplg_ext_free_clb free; /**< Free the extension instance specific data created by ::lyplg_ext.compile callback */
Radek Krejci0e59c312019-08-15 15:34:15 +0200125};
126
Radek Krejci3e6632f2021-03-22 22:08:21 +0100127struct lyplg_ext_record {
128 /* plugin identification */
129 const char *module; /**< name of the module where the extension is defined */
130 const char *revision; /**< optional module revision - if not specified, the plugin applies to any revision,
131 which is not an optimal approach due to a possible future revisions of the module.
132 Instead, there should be defined multiple items in the plugins list, each with the
133 different revision, but all with the same pointer to the plugin functions. The
134 only valid use case for the NULL revision is the case the module has no revision. */
135 const char *name; /**< name of the extension */
136
137 /* runtime data */
138 struct lyplg_ext plugin; /**< data to utilize plugin implementation */
139};
140
Radek Krejci0935f412019-08-20 16:15:18 +0200141/**
142 * @brief Provide a log message from an extension plugin.
143 *
144 * @param[in] ext Compiled extension structure providing generic information about the extension/plugin causing the message.
145 * @param[in] level Log message level (error, warning, etc.)
146 * @param[in] err_no Error type code.
147 * @param[in] path Path relevant to the message.
148 * @param[in] format Format string to print.
149 */
Radek Krejci0b013302021-03-29 15:22:32 +0200150void lyplg_ext_log(const struct lysc_ext_instance *ext, LY_LOG_LEVEL level, LY_ERR err_no, const char *path,
151 const char *format, ...);
Radek Krejci0935f412019-08-20 16:15:18 +0200152
Radek Krejci0e59c312019-08-15 15:34:15 +0200153/** @} extensions */
Radek Krejcid7e8a622018-10-29 15:54:55 +0100154
155#ifdef __cplusplus
156}
157#endif
158
Radek Krejci0935f412019-08-20 16:15:18 +0200159#endif /* LY_PLUGINS_EXTS_H_ */