tree schema REFACTOR move ext definitions to plugins_exts header
diff --git a/CMakeLists.txt b/CMakeLists.txt
index faad765..6ba8468 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -170,6 +170,7 @@
src/plugins_exts.h
src/plugins_exts_compile.h
src/plugins_exts_print.h
+ src/plugins_exts/metadata.h
src/plugins_types.h
src/printer_data.h
src/printer_schema.h
diff --git a/src/diff.c b/src/diff.c
index b01acbc..80b939c 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -27,6 +27,7 @@
#include "context.h"
#include "log.h"
#include "plugins_exts.h"
+#include "plugins_exts/metadata.h"
#include "plugins_types.h"
#include "set.h"
#include "tree.h"
diff --git a/src/libyang.h b/src/libyang.h
index 49657f7..9b636af 100644
--- a/src/libyang.h
+++ b/src/libyang.h
@@ -1,9 +1,10 @@
/**
* @file libyang.h
* @author Radek Krejci <rkrejci@cesnet.cz>
+ * @author Michal Vasko <mvasko@cesnet.cz>
* @brief The main libyang public header.
*
- * Copyright (c) 2015 - 2018 CESNET, z.s.p.o.
+ * Copyright (c) 2015 - 2022 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.
@@ -37,6 +38,7 @@
/*
* The following headers are supposed to be included explicitly:
+ * - metadata.h
* - plugins_types.h
* - plugins_exts.h
*/
diff --git a/src/parser_common.c b/src/parser_common.c
index 79a0f44..4a0e421 100644
--- a/src/parser_common.c
+++ b/src/parser_common.c
@@ -45,6 +45,7 @@
#include "log.h"
#include "parser_data.h"
#include "path.h"
+#include "plugins_exts/metadata.h"
#include "set.h"
#include "tree.h"
#include "tree_data.h"
diff --git a/src/parser_lyb.c b/src/parser_lyb.c
index 0e6bf9c..cacda64 100644
--- a/src/parser_lyb.c
+++ b/src/parser_lyb.c
@@ -31,6 +31,7 @@
#include "parser_data.h"
#include "parser_internal.h"
#include "plugins_exts.h"
+#include "plugins_exts/metadata.h"
#include "set.h"
#include "tree.h"
#include "tree_data.h"
diff --git a/src/plugins_exts.h b/src/plugins_exts.h
index 2c264a7..33199ca 100644
--- a/src/plugins_exts.h
+++ b/src/plugins_exts.h
@@ -30,6 +30,7 @@
struct ly_in;
struct lyd_node;
struct lysc_ext_substmt;
+struct lysp_ctx;
struct lysp_ext_instance;
#ifdef __cplusplus
@@ -105,6 +106,254 @@
#define LYPLG_EXT_API_VERSION 6
/**
+ * @brief Generic test for operation statements.
+ *
+ * This macro matches a subset of schema nodes that maps to common ::lysc_node or ::lysp_node structures. To match all
+ * such nodes, use ::LY_STMT_IS_NODE()
+ *
+ * This macro matches action and RPC.
+ */
+#define LY_STMT_IS_OP(STMT) (((STMT) == LY_STMT_ACTION) || ((STMT) == LY_STMT_RPC))
+
+/**
+ * @brief Generic test for schema data nodes.
+ *
+ * This macro matches a subset of schema nodes that maps to common ::lysc_node or ::lysp_node structures. To match all
+ * such nodes, use ::LY_STMT_IS_NODE()
+ *
+ * This macro matches anydata, anyxml, case, choice, container, leaf, leaf-list, and list.
+ */
+#define LY_STMT_IS_DATA_NODE(STMT) (((STMT) == LY_STMT_ANYDATA) || ((STMT) == LY_STMT_ANYXML) || \
+ ((STMT) == LY_STMT_CASE) || ((STMT) == LY_STMT_CHOICE) || ((STMT) == LY_STMT_CONTAINER) || \
+ ((STMT) == LY_STMT_LEAF) || ((STMT) == LY_STMT_LEAF_LIST) || ((STMT) == LY_STMT_LIST))
+
+/**
+ * @brief Generic test for any schema node that maps to common ::lysc_node or ::lysp_node structures.
+ *
+ * Note that the list of statements that can appear in parsed or compiled schema trees differs (e.g. no uses in compiled tree).
+ *
+ * To check for some of the subsets of this test, try ::LY_STMT_IS_DATA_NODE() or ::LY_STMT_IS_OP().
+ *
+ * This macro matches action, anydata, anyxml, augment, case, choice, container, grouping, input, leaf, leaf-list, list,
+ * notification, output, RPC and uses.
+ */
+#define LY_STMT_IS_NODE(STMT) (((STMT) >= LY_STMT_NOTIFICATION) && ((STMT) <= LY_STMT_LIST))
+
+/**
+ * @brief List of YANG statements
+ */
+enum ly_stmt {
+ LY_STMT_NONE = 0,
+
+ LY_STMT_NOTIFICATION, /**< in ::lysc_ext_substmt.storage stored as a pointer to linked list of `struct lysc_node_notif *`.
+ The RPCs/Actions and Notifications are expected in a separated lists than the rest of
+ data definition nodes as it is done in generic structures of libyang. */
+ LY_STMT_INPUT,
+ LY_STMT_OUTPUT,
+ LY_STMT_ACTION, /**< in ::lysc_ext_substmt.storage stored as a pointer to linked list of `struct lysc_node_action *`.
+ The RPCs/Actions and Notifications are expected in a separated lists than the rest of
+ data definition nodes as it is done in generic structures of libyang. */
+ LY_STMT_RPC, /**< in ::lysc_ext_substmt.storage stored as a pointer to linked list of `struct lysc_node_action *`.
+ The RPCs/Actions and Notifications are expected in a separated lists than the rest of
+ data definition nodes as it is done in generic structures of libyang. */
+ LY_STMT_ANYDATA, /**< in ::lysc_ext_substmt.storage stored as a pointer to linked list of `struct lysc_node *`.
+ Note that due to ::lysc_node compatibility the anydata is expected to be actually
+ mixed in the linked list with other ::lysc_node based nodes. The RPCs/Actions and
+ Notifications are expected in a separated lists as it is done in generic structures
+ of libyang. */
+ LY_STMT_ANYXML, /**< in ::lysc_ext_substmt.storage stored as a pointer to linked list of `struct lysc_node *`.
+ Note that due to ::lysc_node compatibility the anyxml is expected to be actually
+ mixed in the linked list with other ::lysc_node based nodes. The RPCs/Actions and
+ Notifications are expected in a separated lists as it is done in generic structures
+ of libyang. */
+ LY_STMT_AUGMENT,
+ LY_STMT_CASE, /**< TODO is it possible to compile cases without the parent choice? */
+ LY_STMT_CHOICE, /**< in ::lysc_ext_substmt.storage stored as a pointer to linked list of `struct lysc_node *`.
+ Note that due to ::lysc_node compatibility the choice is expected to be actually
+ mixed in the linked list with other ::lysc_node based nodes. The RPCs/Actions and
+ Notifications are expected in a separated lists as it is done in generic structures
+ of libyang. */
+ LY_STMT_CONTAINER, /**< in ::lysc_ext_substmt.storage stored as a pointer to linked list of `struct lysc_node *`.
+ Note that due to ::lysc_node compatibility the container is expected to be actually
+ mixed in the linked list with other ::lysc_node based nodes. The RPCs/Actions and
+ Notifications are expected in a separated lists as it is done in generic structures
+ of libyang. */
+ LY_STMT_GROUPING,
+ LY_STMT_LEAF, /**< in ::lysc_ext_substmt.storage stored as a pointer to linked list of `struct lysc_node *`.
+ Note that due to ::lysc_node compatibility the leaf is expected to be actually
+ mixed in the linked list with other ::lysc_node based nodes. The RPCs/Actions and
+ Notifications are expected in a separated lists as it is done in generic structures
+ of libyang. */
+ LY_STMT_LEAF_LIST, /**< in ::lysc_ext_substmt.storage stored as a pointer to linked list of `struct lysc_node *`.
+ Note that due to ::lysc_node compatibility the leaf-list is expected to be actually
+ mixed in the linked list with other ::lysc_node based nodes. The RPCs/Actions and
+ Notifications are expected in a separated lists as it is done in generic structures
+ of libyang. */
+ LY_STMT_LIST, /**< in ::lysc_ext_substmt.storage stored as a pointer to linked list of `struct lysc_node *`.
+ Note that due to ::lysc_node compatibility the list is expected to be actually
+ mixed in the linked list with other ::lysc_node based nodes. The RPCs/Actions and
+ Notifications are expected in a separated lists as it is done in generic structures
+ of libyang. */
+ LY_STMT_USES,
+
+ LY_STMT_ARGUMENT,
+ LY_STMT_BASE,
+ LY_STMT_BELONGS_TO,
+ LY_STMT_BIT,
+ LY_STMT_CONFIG, /**< in ::lysc_ext_substmt.storage stored as a pointer to `uint16_t`, only cardinality < #LY_STMT_CARD_SOME is allowed */
+ LY_STMT_CONTACT,
+ LY_STMT_DEFAULT,
+ LY_STMT_DESCRIPTION, /**< in ::lysc_ext_substmt.storage stored as a pointer to `const char *` (cardinality < #LY_STMT_CARD_SOME)
+ or as a pointer to a [sized array](@ref sizedarrays) `const char **` */
+ LY_STMT_DEVIATE,
+ LY_STMT_DEVIATION,
+ LY_STMT_ENUM,
+ LY_STMT_ERROR_APP_TAG,
+ LY_STMT_ERROR_MESSAGE,
+ LY_STMT_EXTENSION,
+ LY_STMT_EXTENSION_INSTANCE,
+ LY_STMT_FEATURE,
+ LY_STMT_FRACTION_DIGITS,
+ LY_STMT_IDENTITY,
+ LY_STMT_IF_FEATURE, /**< if-feature statements are not compiled, they are evaluated and the parent statement is
+ preserved only in case the evaluation of all the if-feature statements is true.
+ Therefore there is no storage expected. */
+ LY_STMT_IMPORT,
+ LY_STMT_INCLUDE,
+ LY_STMT_KEY,
+ LY_STMT_LENGTH,
+ LY_STMT_MANDATORY, /**< in ::lysc_ext_substmt.storage stored as a pointer to `uint16_t`, only cardinality < #LY_STMT_CARD_SOME is allowed */
+ LY_STMT_MAX_ELEMENTS,
+ LY_STMT_MIN_ELEMENTS,
+ LY_STMT_MODIFIER,
+ LY_STMT_MODULE,
+ LY_STMT_MUST,
+ LY_STMT_NAMESPACE,
+ LY_STMT_ORDERED_BY,
+ LY_STMT_ORGANIZATION,
+ LY_STMT_PATH,
+ LY_STMT_PATTERN,
+ LY_STMT_POSITION,
+ LY_STMT_PREFIX,
+ LY_STMT_PRESENCE,
+ LY_STMT_RANGE,
+ LY_STMT_REFERENCE, /**< in ::lysc_ext_substmt.storage stored as a pointer to `const char *` (cardinality < #LY_STMT_CARD_SOME)
+ or as a pointer to a [sized array](@ref sizedarrays) `const char **` */
+ LY_STMT_REFINE,
+ LY_STMT_REQUIRE_INSTANCE,
+ LY_STMT_REVISION,
+ LY_STMT_REVISION_DATE,
+ LY_STMT_STATUS, /**< in ::lysc_ext_substmt.storage stored as a pointer to `uint16_t`, only cardinality < #LY_STMT_CARD_SOME is allowed */
+ LY_STMT_SUBMODULE,
+ LY_STMT_TYPE, /**< in ::lysc_ext_substmt.storage stored as a pointer to `struct lysc_type *` (cardinality < #LY_STMT_CARD_SOME)
+ or as a pointer to a [sized array](@ref sizedarrays) `struct lysc_type **` */
+ LY_STMT_TYPEDEF,
+ LY_STMT_UNIQUE,
+ LY_STMT_UNITS, /**< in ::lysc_ext_substmt.storage stored as a pointer to `const char *` (cardinality < #LY_STMT_CARD_SOME)
+ or as a pointer to a [sized array](@ref sizedarrays) `const char **` */
+ LY_STMT_VALUE,
+ LY_STMT_WHEN,
+ LY_STMT_YANG_VERSION,
+ LY_STMT_YIN_ELEMENT,
+
+ /* separated from the list of statements
+ * the following tokens are part of the syntax and parsers have to work
+ * with them, but they are not a standard YANG statements
+ */
+ LY_STMT_SYNTAX_SEMICOLON,
+ LY_STMT_SYNTAX_LEFT_BRACE,
+ LY_STMT_SYNTAX_RIGHT_BRACE,
+
+ /*
+ * YIN-specific tokens, still they are part of the syntax, but not the standard statements
+ */
+ LY_STMT_ARG_TEXT,
+ LY_STMT_ARG_VALUE
+};
+
+/**
+ * @brief Possible cardinalities of the YANG statements.
+ *
+ * Used in extensions plugins to define cardinalities of the extension instance substatements.
+ */
+enum ly_stmt_cardinality {
+ LY_STMT_CARD_OPT, /* 0..1 */
+ LY_STMT_CARD_MAND, /* 1 */
+ LY_STMT_CARD_SOME, /* 1..n */
+ LY_STMT_CARD_ANY /* 0..n */
+};
+
+/**
+ * @brief Helper structure for generic storage of the extension instances content.
+ */
+struct lysp_stmt {
+ const char *stmt; /**< identifier of the statement */
+ const char *arg; /**< statement's argument */
+ LY_VALUE_FORMAT format; /**< prefix format of the identifier/argument (::LY_VALUE_XML is YIN format) */
+ void *prefix_data; /**< Format-specific data for prefix resolution (see ly_resolve_prefix()) */
+
+ struct lysp_stmt *next; /**< link to the next statement */
+ struct lysp_stmt *child; /**< list of the statement's substatements (linked list) */
+ uint16_t flags; /**< statement flags, can be set to LYS_YIN_ATTR */
+ enum ly_stmt kw; /**< numeric respresentation of the stmt value */
+};
+
+/**
+ * @brief YANG extension instance
+ */
+struct lysp_ext_instance {
+ const char *name; /**< extension identifier, including possible prefix */
+ const char *argument; /**< optional value of the extension's argument */
+ LY_VALUE_FORMAT format; /**< prefix format of the extension name/argument (::LY_VALUE_XML is YIN format) */
+ struct lysp_node *parsed; /**< Simply parsed (unresolved) YANG schema tree serving as a cache.
+ Only ::lys_compile_extension_instance() can set this. */
+ void *prefix_data; /**< Format-specific data for prefix resolution
+ (see ly_resolve_prefix()) */
+
+ struct lysp_stmt *child; /**< list of the extension's substatements (linked list) */
+
+ void *parent; /**< pointer to the parent element holding the extension instance(s), use
+ ::lysp_ext_instance#parent_stmt to access the schema element */
+ enum ly_stmt parent_stmt; /**< value identifying placement of the extension instance */
+ LY_ARRAY_COUNT_TYPE parent_stmt_index; /**< in case the instance is in a substatement, this identifies
+ the index of that substatement in its [sized array](@ref sizedarrays) (if any) */
+ uint16_t flags; /**< LYS_INTERNAL value (@ref snodeflags) */
+ const struct lyplg_ext_record *record; /**< extension defintion plugin record, if any */
+};
+
+/**
+ * @brief Description of the extension instance substatements.
+ *
+ * Provided by extensions plugins to libyang to be able to correctly compile the content of extension instances.
+ * Note that order of the defined records matters - just follow the values of ::ly_stmt and order the records from lower to higher values.
+ */
+struct lysc_ext_substmt {
+ enum ly_stmt stmt; /**< allowed substatement */
+ enum ly_stmt_cardinality cardinality; /**< cardinality of the substatement */
+ void *storage; /**< pointer to the storage of the compiled statement according to the specific
+ lysc_ext_substmt::stmt and lysc_ext_substmt::cardinality */
+};
+
+/**
+ * @brief YANG extension instance
+ */
+struct lysc_ext_instance {
+ struct lysc_ext *def; /**< pointer to the extension definition */
+ const char *argument; /**< optional value of the extension's argument */
+ struct lys_module *module; /**< module where the extension instantiated is defined */
+ struct lysc_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
+ struct lysc_ext_substmt *substmts; /**< list of allowed substatements with the storage to access the present
+ substatements ([sized array](@ref sizedarrays)) */
+ void *data; /**< private plugins's data, not used by libyang */
+
+ void *parent; /**< pointer to the parent element holding the extension instance(s), use
+ ::lysc_ext_instance#parent_stmt to access the schema element */
+ enum ly_stmt parent_stmt; /**< value identifying placement of the extension instance in specific statement */
+ LY_ARRAY_COUNT_TYPE parent_stmt_index; /**< in case the instance is in a substatement, this identifies
+ the index of that substatement in its [sized array](@ref sizedarrays) (if any) */
+};
+
+/**
* @brief Macro to define plugin information in external plugins
*
* Use as follows:
@@ -114,14 +363,6 @@
uint32_t plugins_extensions_apiver__ = LYPLG_EXT_API_VERSION; \
const struct lyplg_ext_record plugins_extensions__[]
-/**
- * @brief Free the extension instance's data compiled with ::lys_compile_extension_instance().
- *
- * @param[in] ctx libyang context
- * @param[in] substmts The sized array of extension instance's substatements. The whole array is freed except the storage
- * places which are expected to be covered by the extension plugin.
- */
-LIBYANG_API_DECL void lyplg_ext_instance_substatements_free(struct ly_ctx *ctx, struct lysc_ext_substmt *substmts);
/**
* @brief Callback to compile extension from the lysp_ext_instance to the lysc_ext_instance. The later structure is generally prepared
@@ -247,6 +488,39 @@
};
/**
+ * @brief Stringify statement identifier.
+ *
+ * @param[in] stmt The statement identifier to stringify.
+ * @return Constant string representation of the given @p stmt.
+ */
+LIBYANG_API_DECL const char *ly_stmt2str(enum ly_stmt stmt);
+
+/**
+ * @brief Stringify statement cardinality.
+ *
+ * @param[in] card The cardinality to stringify.
+ * @return Constant string representation of the given @p card.
+ */
+LIBYANG_API_DECL const char *ly_cardinality2str(enum ly_stmt_cardinality card);
+
+/**
+ * @brief Convert nodetype to statement identifier
+ *
+ * @param[in] nodetype Nodetype to convert.
+ * @return Statement identifier representing the given @p nodetype.
+ */
+LIBYANG_API_DECL enum ly_stmt lys_nodetype2stmt(uint16_t nodetype);
+
+/**
+ * @brief Free the extension instance's data compiled with ::lys_compile_extension_instance().
+ *
+ * @param[in] ctx libyang context
+ * @param[in] substmts The sized array of extension instance's substatements. The whole array is freed except the storage
+ * places which are expected to be covered by the extension plugin.
+ */
+LIBYANG_API_DECL void lyplg_ext_instance_substatements_free(struct ly_ctx *ctx, struct lysc_ext_substmt *substmts);
+
+/**
* @brief Get specific run-time extension instance data from a callback set by ::ly_ctx_set_ext_data_clb().
*
* @param[in] ctx Context with the callback.
@@ -302,6 +576,25 @@
*/
LIBYANG_API_DECL LY_ERR lyplg_ext_schema_mount_create_context(const struct lysc_ext_instance *ext, struct ly_ctx **ctx);
+/**
+ * @brief Get pointer to the storage of the specified substatement in the given extension instance.
+ *
+ * The function simplifies access into the ::lysc_ext_instance.substmts sized array.
+ *
+ * @param[in] ext Compiled extension instance to process.
+ * @param[in] substmt Extension substatement to search for.
+ * @param[out] instance_p Pointer where the storage of the @p substmt will be provided. The specific type returned depends
+ * on the @p substmt and can be found in the documentation of each ::ly_stmt value. Also note that some of the substatements
+ * (::lysc_node based or flags) can share the storage with other substatements. In case the pointer is NULL, still the return
+ * code can be used to at least know if the substatement is allowed for the extension.
+ * @param[out] cardinality_p Pointer to provide allowed cardinality of the substatements in the extension. Note that in some
+ * cases, the type of the storage depends also on the cardinality of the substatement.
+ * @return LY_SUCCESS if the @p substmt found.
+ * @return LY_ENOT in case the @p ext is not able to store (does not allow) the specified @p substmt.
+ */
+LIBYANG_API_DECL LY_ERR lysc_ext_substmt(const struct lysc_ext_instance *ext, enum ly_stmt substmt,
+ void **instance_p, enum ly_stmt_cardinality *cardinality_p);
+
/** @} pluginsExtensions */
#ifdef __cplusplus
diff --git a/src/plugins_exts/metadata.h b/src/plugins_exts/metadata.h
index f9dbd12..6387e1f 100644
--- a/src/plugins_exts/metadata.h
+++ b/src/plugins_exts/metadata.h
@@ -1,9 +1,10 @@
/**
* @file metadata.h
* @author Radek Krejci <rkrejci@cesnet.cz>
+ * @author Michal Vasko <mvasko@cesnet.cz>
* @brief ietf-yang-metadata API
*
- * Copyright (c) 2019 CESNET, z.s.p.o.
+ * Copyright (c) 2019 - 2022 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.
@@ -15,6 +16,9 @@
#ifndef LY_PLUGINS_EXTS_METADATA_H_
#define LY_PLUGINS_EXTS_METADATA_H_
+#include "plugins_exts.h"
+#include "tree_data.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -26,6 +30,42 @@
#define ANNOTATION_SUBSTMT_DSC 4 /**< index for the LY_STMT_DSC substatement in annotation's ::lysc_ext_instance.substmts */
#define ANNOTATION_SUBSTMT_REF 5 /**< index for the LY_STMT_REF substatement in annotation's ::lysc_ext_instance.substmts */
+/**
+ * @brief Metadata structure.
+ *
+ * The structure provides information about metadata of a data element. Such attributes must map to
+ * annotations as specified in RFC 7952. The only exception is the filter type (in NETCONF get operations)
+ * and edit-config's operation attributes. In XML, they are represented as standard XML attributes. In JSON,
+ * they are represented as JSON elements starting with the '@' character (for more information, see the
+ * YANG metadata RFC.
+ *
+ */
+struct lyd_meta {
+ struct lyd_node *parent; /**< data node where the metadata is placed */
+ struct lyd_meta *next; /**< pointer to the next metadata of the same element */
+ struct lysc_ext_instance *annotation; /**< pointer to the annotation's definition */
+ const char *name; /**< metadata name */
+ struct lyd_value value; /**< metadata value representation */
+};
+
+/**
+ * @brief Get the (canonical) value of a metadata node.
+ *
+ * @param[in] meta Metadata node to use.
+ * @return Canonical value.
+ */
+static inline const char *
+lyd_get_meta_value(const struct lyd_meta *meta)
+{
+ if (meta) {
+ const struct lyd_value *value = &meta->value;
+
+ return value->_canonical ? value->_canonical : lyd_value_get_canonical(meta->annotation->module->ctx, value);
+ }
+
+ return NULL;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/src/printer_json.c b/src/printer_json.c
index 31886c9..3c7a6fd 100644
--- a/src/printer_json.c
+++ b/src/printer_json.c
@@ -22,6 +22,7 @@
#include "out.h"
#include "out_internal.h"
#include "parser_data.h"
+#include "plugins_exts/metadata.h"
#include "plugins_types.h"
#include "printer_data.h"
#include "printer_internal.h"
diff --git a/src/printer_lyb.c b/src/printer_lyb.c
index cf373f9..f1583ee 100644
--- a/src/printer_lyb.c
+++ b/src/printer_lyb.c
@@ -27,6 +27,7 @@
#include "log.h"
#include "out.h"
#include "out_internal.h"
+#include "plugins_exts/metadata.h"
#include "printer_data.h"
#include "printer_internal.h"
#include "set.h"
diff --git a/src/printer_xml.c b/src/printer_xml.c
index 267fb09..b4921c0 100644
--- a/src/printer_xml.c
+++ b/src/printer_xml.c
@@ -25,6 +25,7 @@
#include "out.h"
#include "out_internal.h"
#include "parser_data.h"
+#include "plugins_exts/metadata.h"
#include "plugins_types.h"
#include "printer_data.h"
#include "printer_internal.h"
diff --git a/src/schema_compile.h b/src/schema_compile.h
index 919a994..5d60c26 100644
--- a/src/schema_compile.h
+++ b/src/schema_compile.h
@@ -20,6 +20,7 @@
#include <stdint.h>
#include "log.h"
+#include "plugins_exts.h"
#include "set.h"
#include "tree.h"
#include "tree_schema.h"
diff --git a/src/tree_data.h b/src/tree_data.h
index 1414bcc..39a3344 100644
--- a/src/tree_data.h
+++ b/src/tree_data.h
@@ -710,24 +710,6 @@
};
/**
- * @brief Metadata structure.
- *
- * The structure provides information about metadata of a data element. Such attributes must map to
- * annotations as specified in RFC 7952. The only exception is the filter type (in NETCONF get operations)
- * and edit-config's operation attributes. In XML, they are represented as standard XML attributes. In JSON,
- * they are represented as JSON elements starting with the '@' character (for more information, see the
- * YANG metadata RFC.
- *
- */
-struct lyd_meta {
- struct lyd_node *parent; /**< data node where the metadata is placed */
- struct lyd_meta *next; /**< pointer to the next metadata of the same element */
- struct lysc_ext_instance *annotation; /**< pointer to the annotation's definition */
- const char *name; /**< metadata name */
- struct lyd_value value; /**< metadata value representation */
-};
-
-/**
* @brief Generic prefix and namespace mapping, meaning depends on the format.
*
* The union is used as a reference to the data's module and according to the format, it can be used as a key for
@@ -1170,24 +1152,6 @@
}
/**
- * @brief Get the (canonical) value of a metadata node.
- *
- * @param[in] meta Metadata node to use.
- * @return Canonical value.
- */
-static inline const char *
-lyd_get_meta_value(const struct lyd_meta *meta)
-{
- if (meta) {
- const struct lyd_value *value = &meta->value;
-
- return value->_canonical ? value->_canonical : lyd_value_get_canonical(meta->annotation->module->ctx, value);
- }
-
- return NULL;
-}
-
-/**
* @brief Get anydata string value.
*
* @param[in] any Anyxml/anydata node to read from.
diff --git a/src/tree_data_free.c b/src/tree_data_free.c
index 88c3b34..bf17a91 100644
--- a/src/tree_data_free.c
+++ b/src/tree_data_free.c
@@ -19,6 +19,7 @@
#include "dict.h"
#include "hash_table.h"
#include "log.h"
+#include "plugins_exts/metadata.h"
#include "plugins_types.h"
#include "tree.h"
#include "tree_data.h"
diff --git a/src/tree_schema.h b/src/tree_schema.h
index f23c6fb..8a6b2a3 100644
--- a/src/tree_schema.h
+++ b/src/tree_schema.h
@@ -260,208 +260,6 @@
/** @} schemanodetypes */
/**
- * @brief Generic test for operation statements.
- *
- * This macro matches a subset of schema nodes that maps to common ::lysc_node or ::lysp_node structures. To match all
- * such nodes, use ::LY_STMT_IS_NODE()
- *
- * This macro matches action and RPC.
- */
-#define LY_STMT_IS_OP(STMT) (((STMT) == LY_STMT_ACTION) || ((STMT) == LY_STMT_RPC))
-
-/**
- * @brief Generic test for schema data nodes.
- *
- * This macro matches a subset of schema nodes that maps to common ::lysc_node or ::lysp_node structures. To match all
- * such nodes, use ::LY_STMT_IS_NODE()
- *
- * This macro matches anydata, anyxml, case, choice, container, leaf, leaf-list, and list.
- */
-#define LY_STMT_IS_DATA_NODE(STMT) (((STMT) == LY_STMT_ANYDATA) || ((STMT) == LY_STMT_ANYXML) || \
- ((STMT) == LY_STMT_CASE) || ((STMT) == LY_STMT_CHOICE) || ((STMT) == LY_STMT_CONTAINER) || \
- ((STMT) == LY_STMT_LEAF) || ((STMT) == LY_STMT_LEAF_LIST) || ((STMT) == LY_STMT_LIST))
-
-/**
- * @brief Generic test for any schema node that maps to common ::lysc_node or ::lysp_node structures.
- *
- * Note that the list of statements that can appear in parsed or compiled schema trees differs (e.g. no uses in compiled tree).
- *
- * To check for some of the subsets of this test, try ::LY_STMT_IS_DATA_NODE() or ::LY_STMT_IS_OP().
- *
- * This macro matches action, anydata, anyxml, augment, case, choice, container, grouping, input, leaf, leaf-list, list,
- * notification, output, RPC and uses.
- */
-#define LY_STMT_IS_NODE(STMT) (((STMT) >= LY_STMT_NOTIFICATION) && ((STMT) <= LY_STMT_LIST))
-
-/**
- * @brief List of YANG statements
- */
-enum ly_stmt {
- LY_STMT_NONE = 0,
-
- LY_STMT_NOTIFICATION, /**< in ::lysc_ext_substmt.storage stored as a pointer to linked list of `struct lysc_node_notif *`.
- The RPCs/Actions and Notifications are expected in a separated lists than the rest of
- data definition nodes as it is done in generic structures of libyang. */
- LY_STMT_INPUT,
- LY_STMT_OUTPUT,
- LY_STMT_ACTION, /**< in ::lysc_ext_substmt.storage stored as a pointer to linked list of `struct lysc_node_action *`.
- The RPCs/Actions and Notifications are expected in a separated lists than the rest of
- data definition nodes as it is done in generic structures of libyang. */
- LY_STMT_RPC, /**< in ::lysc_ext_substmt.storage stored as a pointer to linked list of `struct lysc_node_action *`.
- The RPCs/Actions and Notifications are expected in a separated lists than the rest of
- data definition nodes as it is done in generic structures of libyang. */
- LY_STMT_ANYDATA, /**< in ::lysc_ext_substmt.storage stored as a pointer to linked list of `struct lysc_node *`.
- Note that due to ::lysc_node compatibility the anydata is expected to be actually
- mixed in the linked list with other ::lysc_node based nodes. The RPCs/Actions and
- Notifications are expected in a separated lists as it is done in generic structures
- of libyang. */
- LY_STMT_ANYXML, /**< in ::lysc_ext_substmt.storage stored as a pointer to linked list of `struct lysc_node *`.
- Note that due to ::lysc_node compatibility the anyxml is expected to be actually
- mixed in the linked list with other ::lysc_node based nodes. The RPCs/Actions and
- Notifications are expected in a separated lists as it is done in generic structures
- of libyang. */
- LY_STMT_AUGMENT,
- LY_STMT_CASE, /**< TODO is it possible to compile cases without the parent choice? */
- LY_STMT_CHOICE, /**< in ::lysc_ext_substmt.storage stored as a pointer to linked list of `struct lysc_node *`.
- Note that due to ::lysc_node compatibility the choice is expected to be actually
- mixed in the linked list with other ::lysc_node based nodes. The RPCs/Actions and
- Notifications are expected in a separated lists as it is done in generic structures
- of libyang. */
- LY_STMT_CONTAINER, /**< in ::lysc_ext_substmt.storage stored as a pointer to linked list of `struct lysc_node *`.
- Note that due to ::lysc_node compatibility the container is expected to be actually
- mixed in the linked list with other ::lysc_node based nodes. The RPCs/Actions and
- Notifications are expected in a separated lists as it is done in generic structures
- of libyang. */
- LY_STMT_GROUPING,
- LY_STMT_LEAF, /**< in ::lysc_ext_substmt.storage stored as a pointer to linked list of `struct lysc_node *`.
- Note that due to ::lysc_node compatibility the leaf is expected to be actually
- mixed in the linked list with other ::lysc_node based nodes. The RPCs/Actions and
- Notifications are expected in a separated lists as it is done in generic structures
- of libyang. */
- LY_STMT_LEAF_LIST, /**< in ::lysc_ext_substmt.storage stored as a pointer to linked list of `struct lysc_node *`.
- Note that due to ::lysc_node compatibility the leaf-list is expected to be actually
- mixed in the linked list with other ::lysc_node based nodes. The RPCs/Actions and
- Notifications are expected in a separated lists as it is done in generic structures
- of libyang. */
- LY_STMT_LIST, /**< in ::lysc_ext_substmt.storage stored as a pointer to linked list of `struct lysc_node *`.
- Note that due to ::lysc_node compatibility the list is expected to be actually
- mixed in the linked list with other ::lysc_node based nodes. The RPCs/Actions and
- Notifications are expected in a separated lists as it is done in generic structures
- of libyang. */
- LY_STMT_USES,
-
- LY_STMT_ARGUMENT,
- LY_STMT_BASE,
- LY_STMT_BELONGS_TO,
- LY_STMT_BIT,
- LY_STMT_CONFIG, /**< in ::lysc_ext_substmt.storage stored as a pointer to `uint16_t`, only cardinality < #LY_STMT_CARD_SOME is allowed */
- LY_STMT_CONTACT,
- LY_STMT_DEFAULT,
- LY_STMT_DESCRIPTION, /**< in ::lysc_ext_substmt.storage stored as a pointer to `const char *` (cardinality < #LY_STMT_CARD_SOME)
- or as a pointer to a [sized array](@ref sizedarrays) `const char **` */
- LY_STMT_DEVIATE,
- LY_STMT_DEVIATION,
- LY_STMT_ENUM,
- LY_STMT_ERROR_APP_TAG,
- LY_STMT_ERROR_MESSAGE,
- LY_STMT_EXTENSION,
- LY_STMT_EXTENSION_INSTANCE,
- LY_STMT_FEATURE,
- LY_STMT_FRACTION_DIGITS,
- LY_STMT_IDENTITY,
- LY_STMT_IF_FEATURE, /**< if-feature statements are not compiled, they are evaluated and the parent statement is
- preserved only in case the evaluation of all the if-feature statements is true.
- Therefore there is no storage expected. */
- LY_STMT_IMPORT,
- LY_STMT_INCLUDE,
- LY_STMT_KEY,
- LY_STMT_LENGTH,
- LY_STMT_MANDATORY, /**< in ::lysc_ext_substmt.storage stored as a pointer to `uint16_t`, only cardinality < #LY_STMT_CARD_SOME is allowed */
- LY_STMT_MAX_ELEMENTS,
- LY_STMT_MIN_ELEMENTS,
- LY_STMT_MODIFIER,
- LY_STMT_MODULE,
- LY_STMT_MUST,
- LY_STMT_NAMESPACE,
- LY_STMT_ORDERED_BY,
- LY_STMT_ORGANIZATION,
- LY_STMT_PATH,
- LY_STMT_PATTERN,
- LY_STMT_POSITION,
- LY_STMT_PREFIX,
- LY_STMT_PRESENCE,
- LY_STMT_RANGE,
- LY_STMT_REFERENCE, /**< in ::lysc_ext_substmt.storage stored as a pointer to `const char *` (cardinality < #LY_STMT_CARD_SOME)
- or as a pointer to a [sized array](@ref sizedarrays) `const char **` */
- LY_STMT_REFINE,
- LY_STMT_REQUIRE_INSTANCE,
- LY_STMT_REVISION,
- LY_STMT_REVISION_DATE,
- LY_STMT_STATUS, /**< in ::lysc_ext_substmt.storage stored as a pointer to `uint16_t`, only cardinality < #LY_STMT_CARD_SOME is allowed */
- LY_STMT_SUBMODULE,
- LY_STMT_TYPE, /**< in ::lysc_ext_substmt.storage stored as a pointer to `struct lysc_type *` (cardinality < #LY_STMT_CARD_SOME)
- or as a pointer to a [sized array](@ref sizedarrays) `struct lysc_type **` */
- LY_STMT_TYPEDEF,
- LY_STMT_UNIQUE,
- LY_STMT_UNITS, /**< in ::lysc_ext_substmt.storage stored as a pointer to `const char *` (cardinality < #LY_STMT_CARD_SOME)
- or as a pointer to a [sized array](@ref sizedarrays) `const char **` */
- LY_STMT_VALUE,
- LY_STMT_WHEN,
- LY_STMT_YANG_VERSION,
- LY_STMT_YIN_ELEMENT,
-
- /* separated from the list of statements
- * the following tokens are part of the syntax and parsers have to work
- * with them, but they are not a standard YANG statements
- */
- LY_STMT_SYNTAX_SEMICOLON,
- LY_STMT_SYNTAX_LEFT_BRACE,
- LY_STMT_SYNTAX_RIGHT_BRACE,
-
- /*
- * YIN-specific tokens, still they are part of the syntax, but not the standard statements
- */
- LY_STMT_ARG_TEXT,
- LY_STMT_ARG_VALUE
-};
-
-/**
- * @brief Stringify statement identifier.
- *
- * @param[in] stmt The statement identifier to stringify.
- * @return Constant string representation of the given @p stmt.
- */
-LIBYANG_API_DECL const char *ly_stmt2str(enum ly_stmt stmt);
-
-/**
- * @brief Possible cardinalities of the YANG statements.
- *
- * Used in extensions plugins to define cardinalities of the extension instance substatements.
- */
-enum ly_stmt_cardinality {
- LY_STMT_CARD_OPT, /* 0..1 */
- LY_STMT_CARD_MAND, /* 1 */
- LY_STMT_CARD_SOME, /* 1..n */
- LY_STMT_CARD_ANY /* 0..n */
-};
-
-/**
- * @brief Stringify statement cardinality.
- *
- * @param[in] card The cardinality to stringify.
- * @return Constant string representation of the given @p card.
- */
-LIBYANG_API_DECL const char *ly_cardinality2str(enum ly_stmt_cardinality card);
-
-/**
- * @brief Convert nodetype to statement identifier
- *
- * @param[in] nodetype Nodetype to convert.
- * @return Statement identifier representing the given @p nodetype.
- */
-LIBYANG_API_DECL enum ly_stmt lys_nodetype2stmt(uint16_t nodetype);
-
-/**
* @brief YANG import-stmt
*/
struct lysp_import {
@@ -510,46 +308,6 @@
};
/**
- * @brief Helper structure for generic storage of the extension instances content.
- */
-struct lysp_stmt {
- const char *stmt; /**< identifier of the statement */
- const char *arg; /**< statement's argument */
- LY_VALUE_FORMAT format; /**< prefix format of the identifier/argument (::LY_VALUE_XML is YIN format) */
- void *prefix_data; /**< Format-specific data for prefix resolution (see ly_resolve_prefix()) */
-
- struct lysp_stmt *next; /**< link to the next statement */
- struct lysp_stmt *child; /**< list of the statement's substatements (linked list) */
- uint16_t flags; /**< statement flags, can be set to LYS_YIN_ATTR */
- enum ly_stmt kw; /**< numeric respresentation of the stmt value */
-};
-
-#define LYS_YIN 0x1 /**< used to specify input format of extension instance */
-
-/**
- * @brief YANG extension instance
- */
-struct lysp_ext_instance {
- const char *name; /**< extension identifier, including possible prefix */
- const char *argument; /**< optional value of the extension's argument */
- LY_VALUE_FORMAT format; /**< prefix format of the extension name/argument (::LY_VALUE_XML is YIN format) */
- struct lysp_node *parsed; /**< Simply parsed (unresolved) YANG schema tree serving as a cache.
- Only ::lys_compile_extension_instance() can set this. */
- void *prefix_data; /**< Format-specific data for prefix resolution
- (see ly_resolve_prefix()) */
-
- struct lysp_stmt *child; /**< list of the extension's substatements (linked list) */
-
- void *parent; /**< pointer to the parent element holding the extension instance(s), use
- ::lysp_ext_instance#parent_stmt to access the schema element */
- enum ly_stmt parent_stmt; /**< value identifying placement of the extension instance */
- LY_ARRAY_COUNT_TYPE parent_stmt_index; /**< in case the instance is in a substatement, this identifies
- the index of that substatement in its [sized array](@ref sizedarrays) (if any) */
- uint16_t flags; /**< LYS_INTERNAL value (@ref snodeflags) */
- const struct lyplg_ext_record *record; /**< extension defintion plugin record, if any */
-};
-
-/**
* @brief YANG feature-stmt
*/
struct lysp_feature {
@@ -1434,38 +1192,6 @@
};
/**
- * @brief Description of the extension instance substatements.
- *
- * Provided by extensions plugins to libyang to be able to correctly compile the content of extension instances.
- * Note that order of the defined records matters - just follow the values of ::ly_stmt and order the records from lower to higher values.
- */
-struct lysc_ext_substmt {
- enum ly_stmt stmt; /**< allowed substatement */
- enum ly_stmt_cardinality cardinality; /**< cardinality of the substatement */
- void *storage; /**< pointer to the storage of the compiled statement according to the specific
- lysc_ext_substmt::stmt and lysc_ext_substmt::cardinality */
-};
-
-/**
- * @brief YANG extension instance
- */
-struct lysc_ext_instance {
- struct lysc_ext *def; /**< pointer to the extension definition */
- const char *argument; /**< optional value of the extension's argument */
- struct lys_module *module; /**< module where the extension instantiated is defined */
- struct lysc_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
- struct lysc_ext_substmt *substmts; /**< list of allowed substatements with the storage to access the present
- substatements ([sized array](@ref sizedarrays)) */
- void *data; /**< private plugins's data, not used by libyang */
-
- void *parent; /**< pointer to the parent element holding the extension instance(s), use
- ::lysc_ext_instance#parent_stmt to access the schema element */
- enum ly_stmt parent_stmt; /**< value identifying placement of the extension instance in specific statement */
- LY_ARRAY_COUNT_TYPE parent_stmt_index; /**< in case the instance is in a substatement, this identifies
- the index of that substatement in its [sized array](@ref sizedarrays) (if any) */
-};
-
-/**
* @brief YANG when-stmt
*/
struct lysc_when {
@@ -2239,25 +1965,6 @@
uint32_t *idx);
/**
- * @brief Get pointer to the storage of the specified substatement in the given extension instance.
- *
- * The function simplifies access into the ::lysc_ext_instance.substmts sized array.
- *
- * @param[in] ext Compiled extension instance to process.
- * @param[in] substmt Extension substatement to search for.
- * @param[out] instance_p Pointer where the storage of the @p substmt will be provided. The specific type returned depends
- * on the @p substmt and can be found in the documentation of each ::ly_stmt value. Also note that some of the substatements
- * (::lysc_node based or flags) can share the storage with other substatements. In case the pointer is NULL, still the return
- * code can be used to at least know if the substatement is allowed for the extension.
- * @param[out] cardinality_p Pointer to provide allowed cardinality of the substatements in the extension. Note that in some
- * cases, the type of the storage depends also on the cardinality of the substatement.
- * @return LY_SUCCESS if the @p substmt found.
- * @return LY_ENOT in case the @p ext is not able to store (does not allow) the specified @p substmt.
- */
-LIBYANG_API_DECL LY_ERR lysc_ext_substmt(const struct lysc_ext_instance *ext, enum ly_stmt substmt,
- void **instance_p, enum ly_stmt_cardinality *cardinality_p);
-
-/**
* @defgroup findxpathoptions Atomize XPath options
* Options to modify behavior of ::lys_find_xpath() and ::lys_find_xpath_atoms() searching for schema nodes in schema tree.
* @{
diff --git a/src/xpath.c b/src/xpath.c
index 49b87d6..1d5ad53 100644
--- a/src/xpath.c
+++ b/src/xpath.c
@@ -32,6 +32,7 @@
#include "out.h"
#include "parser_data.h"
#include "path.h"
+#include "plugins_exts/metadata.h"
#include "plugins_types.h"
#include "printer_data.h"
#include "schema_compile_node.h"
diff --git a/tests/utests/extensions/test_schema_mount.c b/tests/utests/extensions/test_schema_mount.c
index 6f33d01..b9b81c0 100644
--- a/tests/utests/extensions/test_schema_mount.c
+++ b/tests/utests/extensions/test_schema_mount.c
@@ -156,7 +156,7 @@
" }\n"
"}\n";
assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, schema, LYS_IN_YANG, &mod));
- lys_print_mem(&str, mod, LYS_YIN, 0);
+ lys_print_mem(&str, mod, LYS_OUT_YIN, 0);
assert_string_equal(str, schema);
free(str);
}
diff --git a/tests/utests/utests.h b/tests/utests/utests.h
index d40c5ab..b1af68d 100644
--- a/tests/utests/utests.h
+++ b/tests/utests/utests.h
@@ -2,9 +2,10 @@
* @file utests.h
* @author Radek Iša <isa@cesnet.cz>
* @author Radek Krejci <rkrejci@cesnet.cz>
+ * @author Michal Vasko <mvasko@cesnet.cz>
* @brief this file contains macros for simplification test writing
*
- * Copyright (c) 2021 CESNET, z.s.p.o.
+ * Copyright (c) 2021 - 2022 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.
@@ -29,6 +30,7 @@
#include <string.h>
#include "libyang.h"
+#include "plugins_exts/metadata.h"
#include "plugins_internal.h"
#include "plugins_types.h"
#include "tests_config.h"