blob: 3ffc7cf8269fa285acf73d7c6e57459ac1da8ec5 [file] [log] [blame]
Radek Krejci3e6632f2021-03-22 22:08:21 +01001/**
2 * @file plugins.h
3 * @author Radek Krejci <rkrejci@cesnet.cz>
4 * @brief Plugins manipulation.
5 *
6 * Copyright (c) 2021 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_PLUGINS_H_
16#define LY_PLUGINS_H_
17
18#include "log.h"
19
stewegf7aeeae2024-04-02 13:15:52 +020020struct lyplg_ext_record;
21struct lyplg_type_record;
22
Radek Krejci3e6632f2021-03-22 22:08:21 +010023#ifdef __cplusplus
24extern "C" {
25#endif
26
27/**
Radek Krejci75104122021-04-01 15:37:45 +020028 * @page howtoPlugins Plugins
29 *
30 * libyang supports two types of plugins to better support generic features of YANG that need some specific code for
31 * their specific instances in YANG modules. This is the case of YANG types, which are derived from YANG built-in types.
32 * The description of a derived type can specify some additional requirements or restriction that cannot be implemented
33 * generically and some special code is needed. The second case for libyang plugins are YANG extensions. For YANG extensions,
34 * most of the specification is hidden in their description (e.g. allowed substatements or place of the extension
35 * instantiation) and libyang is not able to process such a text in a generic way.
36 *
37 * In both cases, libyang provides API to get functionality implementing the specifics of each type or extension.
38 * Furthermore, there are several internal plugins, implementing built-in data types and selected derived types and YANG
39 * extensions. These internal plugins uses the same API and can be taken as examples for implementing user plugins. Internal
40 * plugins are always loaded with the first created [context](@ref howtoContext) and unloaded with destroying the last one.
41 * The external plugins are in the same phase loaded from the default directories specified at compile time via cmake
42 * variables `PLUGINS_DIR` (where the `extensions` and `types` subdirectories are added for each plugin type) or separately
43 * via `PLUGINS_DIR_EXTENSIONS` and `PLUGINS_DIR_TYPES` for each plugin type. The default directories can be replaced runtime
44 * using environment variables `LIBYANG_TYPES_PLUGINS_DIR` and `LIBYANG_EXTENSIONS_PLUGINS_DIR`.
45 *
46 * Order of the plugins determines their priority. libyang searches for the first match with the extension and type, so the
47 * firstly loaded plugin for the specific item is used. Since the internal plugins are loaded always before the external
48 * plugins, the internal plugins cannot be replaced.
49 *
50 * There is also a separate function ::lyplg_add() to add a plugin anytime later. Note, that such a plugin is being used
51 * after it is added with the lowest priority among other already loaded plugins. Also note that since all the plugins are
52 * unloaded with the destruction of the last context, creating a new context after that starts the standard plugins
53 * initiation and the manually added plugins are not loaded automatically.
54 *
55 * The following pages contain description of the API for creating user plugins.
56 *
57 * - @subpage howtoPluginsTypes
58 * - @subpage howtoPluginsExtensions
59 */
60
61/**
Radek Krejci3e6632f2021-03-22 22:08:21 +010062 * @defgroup plugins Plugins
63 * @{
64 *
65 */
66
67/**
68 * @brief Identifiers of the plugin type.
69 */
70enum LYPLG {
71 LYPLG_TYPE, /**< Specific type (typedef) */
72 LYPLG_EXTENSION /**< YANG extension */
73};
74
Radek Krejcibf940f92021-03-24 21:04:13 +010075/**
76 * @brief Manually load a plugin file.
77 *
78 * Note, that a plugin can be loaded only if there is at least one context. The loaded plugins are connected with the
79 * existence of a context. When all the contexts are destroyed, all the plugins are unloaded.
80 *
81 * @param[in] pathname Path to the plugin file. It can contain types or extensions plugins, both are accepted and correctly
82 * loaded.
83 *
84 * @return LY_SUCCESS if the file contains valid plugin compatible with the library version.
85 * @return LY_EDENIED in case there is no context and the plugin cannot be loaded.
86 * @return LY_EINVAL when pathname is NULL or the plugin contains invalid content for this libyang version.
87 * @return LY_ESYS when the plugin file cannot be loaded.
88 */
Jan Kundrátc53a7ec2021-12-09 16:01:19 +010089LIBYANG_API_DECL LY_ERR lyplg_add(const char *pathname);
Radek Krejcibf940f92021-03-24 21:04:13 +010090
stewegf7aeeae2024-04-02 13:15:52 +020091/**
92 * @brief Manually load extension plugins from memory
93 *
94 * Note, that a plugin can be loaded only if there is at least one context. The loaded plugins are connected with the
95 * existence of a context. When all the contexts are destroyed, all the plugins are unloaded.
96 *
97 * @param[in] ctx The context to which the plugin should be associated with. If NULL, the plugin is considered to be shared
98 * between all existing contexts.
99 * @param[in] version The version of plugin records.
100 * @param[in] recs An array of plugin records provided by the plugin implementation. The array must be terminated by a zeroed
101 * record.
102 *
103 * @return LY_SUCCESS if the plugins with compatible version were successfully loaded.
104 * @return LY_EDENIED in case there is no context and the plugin cannot be loaded.
105 * @return LY_EINVAL when recs is NULL or the plugin contains invalid content for this libyang version.
106 */
107LIBYANG_API_DECL LY_ERR lyplg_add_extension_plugin(struct ly_ctx *ctx, uint32_t version, const struct lyplg_ext_record *recs);
108
109/**
110 * @brief Manually load type plugins from memory
111 *
112 * Note, that a plugin can be loaded only if there is at least one context. The loaded plugins are connected with the
113 * existence of a context. When all the contexts are destroyed, all the plugins are unloaded.
114 *
115 * @param[in] ctx The context to which the plugin should be associated with. If NULL, the plugin is considered to be shared
116 * between all existing contexts.
117 * @param[in] version The version of plugin records.
118 * @param[in] recs An array of plugin records provided by the plugin implementation. The array must be terminated by a zeroed
119 * record.
120 *
121 * @return LY_SUCCESS if the plugins with compatible version were successfully loaded.
122 * @return LY_EDENIED in case there is no context and the plugin cannot be loaded.
123 * @return LY_EINVAL when recs is NULL or the plugin contains invalid content for this libyang version.
124 */
125LIBYANG_API_DECL LY_ERR lyplg_add_type_plugin(struct ly_ctx *ctx, uint32_t version, const struct lyplg_type_record *recs);
Radek Krejci3e6632f2021-03-22 22:08:21 +0100126/** @} plugins */
127
128#ifdef __cplusplus
129}
130#endif
131
132#endif /* LY_PLUGINS_H_ */