Skip to content

Commit 06bc76d

Browse files
committed
plugins types UPDATE separate validate clb into 2 clbs
Support validate_value and validate_tree callbacks. Only the validate_tree callback is called on the final data tree making validation more efficient.
1 parent 43a12a6 commit 06bc76d

31 files changed

+217
-131
lines changed

src/parser_data.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,8 +218,9 @@ struct ly_in;
218218
(such as NP containers) are still added. Validation will fail if a
219219
default node is required for it to pass. */
220220
#define LYD_VALIDATE_NOT_FINAL 0x0020 /**< Skip final validation tasks that require for all the data nodes to
221-
either exist or not, based on the YANG constraints. Once the data
222-
satisfy this requirement, the final validation should be performed. */
221+
either exist or not, based on the YANG constraints (including skipping
222+
type plugin validate_tree callbacks). Once the data satisfy this
223+
requirement, the final validation should be performed. */
223224

224225
#define LYD_VALIDATE_OPTS_MASK 0x0000FFFF /**< Mask for all the LYD_VALIDATE_* options. */
225226

src/plugins_types.h

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -543,19 +543,38 @@ LIBYANG_API_DECL typedef void (*lyplg_type_lyb_size_clb)(const struct lysc_type
543543
* @param[out] err Optionally provided error information in case of failure. If not provided to the caller, a generic
544544
* error message is prepared instead. The error structure can be created by ::ly_err_new().
545545
* @return LY_SUCCESS on success,
546-
* @return LY_EINCOMPLETE in case the ::lyplg_type_validate_clb should be called to finish value validation in data,
546+
* @return LY_EINCOMPLETE in case the ::lyplg_type_validate_tree_clb is defined and should be called to finish value
547+
* validation in data,
547548
* @return LY_ERR value on error, @p storage must not have any pointers to dynamic memory.
548549
*/
549550
LIBYANG_API_DECL typedef LY_ERR (*lyplg_type_store_clb)(const struct ly_ctx *ctx, const struct lysc_type *type,
550551
const void *value, uint32_t value_size_bits, uint32_t options, LY_VALUE_FORMAT format, void *prefix_data, uint32_t hints,
551552
const struct lysc_node *ctx_node, const struct lysc_ext_instance *top_ext, struct lyd_value *storage,
552553
struct lys_glob_unres *unres, struct ly_err_item **err);
553554

555+
/**
556+
* @brief Callback to validate the stored value local semantic constraints of the type.
557+
*
558+
* This callback should perform any required validation of the value after it is stored. If the stored value is always
559+
* valid disregarding the accessible data tree, this callback should not be defined (but ::lyplg_type_validate_tree()
560+
* may be).
561+
*
562+
* @param[in] ctx libyang context.
563+
* @param[in] type Original type of the value (not necessarily the stored one) being validated.
564+
* @param[in,out] storage Storage of the value successfully filled by ::lyplg_type_store_clb. May be modified.
565+
* @param[out] err Optionally provided error information in case of failure. If not provided to the caller, a generic
566+
* error message is prepared instead. The error structure can be created by ::ly_err_new().
567+
* @return LY_SUCCESS on success,
568+
* @return LY_ERR value on error.
569+
*/
570+
LIBYANG_API_DECL typedef LY_ERR (*lyplg_type_validate_value_clb)(const struct ly_ctx *ctx, const struct lysc_type *type,
571+
struct lyd_value *storage, struct ly_err_item **err);
572+
554573
/**
555574
* @brief Callback to validate the stored value in the accessible data tree.
556575
*
557-
* This callback is optional and may not be defined for types that do not require the accessible data tree for
558-
* validation (::lyplg_type_store_clb fully stores and validates the value).
576+
* This callback should perform any final validation that depends on the other data nodes in the accessible tree. If
577+
* the other nodes do not affect the validity of this value, this callback should not be defined.
559578
*
560579
* @param[in] ctx libyang context.
561580
* @param[in] type Original type of the value (not necessarily the stored one) being validated.
@@ -568,7 +587,7 @@ LIBYANG_API_DECL typedef LY_ERR (*lyplg_type_store_clb)(const struct ly_ctx *ctx
568587
* @return LY_SUCCESS on success,
569588
* @return LY_ERR value on error.
570589
*/
571-
LIBYANG_API_DECL typedef LY_ERR (*lyplg_type_validate_clb)(const struct ly_ctx *ctx, const struct lysc_type *type,
590+
LIBYANG_API_DECL typedef LY_ERR (*lyplg_type_validate_tree_clb)(const struct ly_ctx *ctx, const struct lysc_type *type,
572591
const struct lyd_node *ctx_node, const struct lyd_node *tree, const struct lysc_ext_instance *top_ext,
573592
struct lyd_value *storage, struct ly_err_item **err);
574593

@@ -660,7 +679,8 @@ struct lyplg_type {
660679
const char *id; /**< Plugin name id, can be used for distinguishing incompatible versions. */
661680
lyplg_type_lyb_size_clb lyb_size; /**< Size of the value in [LYB format](@ref howtoDataLYB) in bits. */
662681
lyplg_type_store_clb store; /**< Storing and canonization callback for the value. */
663-
lyplg_type_validate_clb validate; /**< Optional validation callback that can use the accessible data tree. */
682+
lyplg_type_validate_value_clb validate_value; /**< Optional value validation callback. */
683+
lyplg_type_validate_tree_clb validate_tree; /**< Optional data tree value validation callback. */
664684
lyplg_type_compare_clb compare; /**< Comparison callback for comparing 2 values of the same type. */
665685
lyplg_type_sort_clb sort; /**< Comparison callback for sorting values. */
666686
lyplg_type_print_clb print; /**< Printer callback for getting value representation in any format. */
@@ -747,6 +767,12 @@ LIBYANG_API_DECL LY_ERR lyplg_type_store_string(const struct ly_ctx *ctx, const
747767
const struct lysc_node *ctx_node, const struct lysc_ext_instance *top_ext, struct lyd_value *storage,
748768
struct lys_glob_unres *unres, struct ly_err_item **err);
749769

770+
/**
771+
* @brief Implementation of ::lyplg_type_validate_value_clb for the string type.
772+
*/
773+
LIBYANG_API_DECL LY_ERR lyplg_type_validate_value_string(const struct ly_ctx *ctx, const struct lysc_type *type,
774+
struct lyd_value *storage, struct ly_err_item **err);
775+
750776
/**
751777
* @brief Implementation of ::lyplg_type_print_clb for the ietf-yang-types xpath1.0 type.
752778
*/

src/plugins_types/binary.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,7 @@
4444
static const char b64_etable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
4545

4646
static void lyplg_type_free_binary(const struct ly_ctx *ctx, struct lyd_value *value);
47-
static LY_ERR lyplg_type_validate_binary(const struct ly_ctx *ctx, const struct lysc_type *type,
48-
const struct lyd_node *ctx_node, const struct lyd_node *tree, const struct lysc_ext_instance *top_ext,
47+
static LY_ERR lyplg_type_validate_value_binary(const struct ly_ctx *ctx, const struct lysc_type *type,
4948
struct lyd_value *storage, struct ly_err_item **err);
5049

5150
/**
@@ -332,7 +331,7 @@ lyplg_type_store_binary(const struct ly_ctx *ctx, const struct lysc_type *type,
332331

333332
if (!(options & LYPLG_TYPE_STORE_ONLY)) {
334333
/* validate value */
335-
ret = lyplg_type_validate_binary(ctx, type, NULL, NULL, NULL, storage, err);
334+
ret = lyplg_type_validate_value_binary(ctx, type, storage, err);
336335
LY_CHECK_GOTO(ret, cleanup);
337336
}
338337

@@ -348,11 +347,10 @@ lyplg_type_store_binary(const struct ly_ctx *ctx, const struct lysc_type *type,
348347
}
349348

350349
/**
351-
* @brief Implementation of ::lyplg_type_validate_clb for the binary type.
350+
* @brief Implementation of ::lyplg_type_validate_value_clb for the binary type.
352351
*/
353352
static LY_ERR
354-
lyplg_type_validate_binary(const struct ly_ctx *ctx, const struct lysc_type *type, const struct lyd_node *UNUSED(ctx_node),
355-
const struct lyd_node *UNUSED(tree), const struct lysc_ext_instance *UNUSED(top_ext), struct lyd_value *storage,
353+
lyplg_type_validate_value_binary(const struct ly_ctx *ctx, const struct lysc_type *type, struct lyd_value *storage,
356354
struct ly_err_item **err)
357355
{
358356
struct lysc_type_bin *type_bin = (struct lysc_type_bin *)type;
@@ -511,7 +509,8 @@ const struct lyplg_type_record plugins_binary[] = {
511509
.plugin.id = "ly2 binary",
512510
.plugin.lyb_size = lyplg_type_lyb_size_variable_bytes,
513511
.plugin.store = lyplg_type_store_binary,
514-
.plugin.validate = lyplg_type_validate_binary,
512+
.plugin.validate_value = lyplg_type_validate_value_binary,
513+
.plugin.validate_tree = NULL,
515514
.plugin.compare = lyplg_type_compare_binary,
516515
.plugin.sort = lyplg_type_sort_binary,
517516
.plugin.print = lyplg_type_print_binary,

src/plugins_types/bits.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,8 @@ const struct lyplg_type_record plugins_bits[] = {
504504
.plugin.id = "ly2 bits",
505505
.plugin.lyb_size = lyplg_type_lyb_size_bits,
506506
.plugin.store = lyplg_type_store_bits,
507-
.plugin.validate = NULL,
507+
.plugin.validate_value = NULL,
508+
.plugin.validate_tree = NULL,
508509
.plugin.compare = lyplg_type_compare_bits,
509510
.plugin.sort = lyplg_type_sort_bits,
510511
.plugin.print = lyplg_type_print_bits,

src/plugins_types/boolean.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,8 @@ const struct lyplg_type_record plugins_boolean[] = {
169169
.plugin.id = "ly2 boolean",
170170
.plugin.lyb_size = lyplg_type_lyb_size_boolean,
171171
.plugin.store = lyplg_type_store_boolean,
172-
.plugin.validate = NULL,
172+
.plugin.validate_value = NULL,
173+
.plugin.validate_tree = NULL,
173174
.plugin.compare = lyplg_type_compare_boolean,
174175
.plugin.sort = lyplg_type_sort_boolean,
175176
.plugin.print = lyplg_type_print_boolean,

src/plugins_types/date_and_time.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,8 @@ const struct lyplg_type_record plugins_date_and_time[] = {
396396
.plugin.id = "ly2 date-and-time",
397397
.plugin.lyb_size = lyplg_type_lyb_size_variable_bytes,
398398
.plugin.store = lyplg_type_store_date_and_time,
399-
.plugin.validate = NULL,
399+
.plugin.validate_value = NULL,
400+
.plugin.validate_tree = NULL,
400401
.plugin.compare = lyplg_type_compare_date_and_time,
401402
.plugin.sort = lyplg_type_sort_date_and_time,
402403
.plugin.print = lyplg_type_print_date_and_time,

src/plugins_types/decimal64.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@
3434
* | 64 | yes | `int64_t *` | little-endian value represented without floating point |
3535
*/
3636

37-
static LY_ERR lyplg_type_validate_decimal64(const struct ly_ctx *ctx, const struct lysc_type *type, const struct lyd_node *ctx_node, const struct lyd_node *tree, const struct lysc_ext_instance *top_ext, struct lyd_value *storage, struct ly_err_item **err);
37+
static LY_ERR lyplg_type_validate_value_decimal64(const struct ly_ctx *ctx, const struct lysc_type *type,
38+
struct lyd_value *storage, struct ly_err_item **err);
3839

3940
/**
4041
* @brief Convert decimal64 number to canonical string.
@@ -151,7 +152,7 @@ lyplg_type_store_decimal64(const struct ly_ctx *ctx, const struct lysc_type *typ
151152

152153
if (!(options & LYPLG_TYPE_STORE_ONLY)) {
153154
/* validate value */
154-
ret = lyplg_type_validate_decimal64(ctx, type, NULL, NULL, NULL, storage, err);
155+
ret = lyplg_type_validate_value_decimal64(ctx, type, storage, err);
155156
LY_CHECK_GOTO(ret, cleanup);
156157
}
157158

@@ -167,12 +168,11 @@ lyplg_type_store_decimal64(const struct ly_ctx *ctx, const struct lysc_type *typ
167168
}
168169

169170
/**
170-
* @brief Implementation of ::lyplg_type_validate_clb for the built-in decimal64 type.
171+
* @brief Implementation of ::lyplg_type_validate_value_clb for the built-in decimal64 type.
171172
*/
172173
static LY_ERR
173-
lyplg_type_validate_decimal64(const struct ly_ctx *UNUSED(ctx), const struct lysc_type *type,
174-
const struct lyd_node *UNUSED(ctx_node), const struct lyd_node *UNUSED(tree),
175-
const struct lysc_ext_instance *UNUSED(top_ext), struct lyd_value *storage, struct ly_err_item **err)
174+
lyplg_type_validate_value_decimal64(const struct ly_ctx *UNUSED(ctx), const struct lysc_type *type,
175+
struct lyd_value *storage, struct ly_err_item **err)
176176
{
177177
LY_ERR ret;
178178
struct lysc_type_dec *type_dec = (struct lysc_type_dec *)type;
@@ -271,7 +271,8 @@ const struct lyplg_type_record plugins_decimal64[] = {
271271
.plugin.id = "ly2 decimal64",
272272
.plugin.lyb_size = lyplg_type_lyb_size_decimal64,
273273
.plugin.store = lyplg_type_store_decimal64,
274-
.plugin.validate = lyplg_type_validate_decimal64,
274+
.plugin.validate_value = lyplg_type_validate_value_decimal64,
275+
.plugin.validate_tree = NULL,
275276
.plugin.compare = lyplg_type_compare_decimal64,
276277
.plugin.sort = lyplg_type_sort_decimal64,
277278
.plugin.print = lyplg_type_print_decimal64,

src/plugins_types/empty.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,8 @@ const struct lyplg_type_record plugins_empty[] = {
103103
.plugin.id = "ly2 empty",
104104
.plugin.lyb_size = lyplg_type_lyb_size_empty,
105105
.plugin.store = lyplg_type_store_empty,
106-
.plugin.validate = NULL,
106+
.plugin.validate_value = NULL,
107+
.plugin.validate_tree = NULL,
107108
.plugin.compare = lyplg_type_compare_simple,
108109
.plugin.sort = lyplg_type_sort_simple,
109110
.plugin.print = lyplg_type_print_simple,

src/plugins_types/enumeration.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,8 @@ const struct lyplg_type_record plugins_enumeration[] = {
229229
.plugin.id = "ly2 enumeration",
230230
.plugin.lyb_size = lyplg_type_lyb_size_enum,
231231
.plugin.store = lyplg_type_store_enum,
232-
.plugin.validate = NULL,
232+
.plugin.validate_value = NULL,
233+
.plugin.validate_tree = NULL,
233234
.plugin.compare = lyplg_type_compare_simple,
234235
.plugin.sort = lyplg_type_sort_enum,
235236
.plugin.print = lyplg_type_print_enum,

src/plugins_types/hex_string.c

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ lyplg_type_store_hex_string(const struct ly_ctx *ctx, const struct lysc_type *ty
4444
struct lyd_value *storage, struct lys_glob_unres *UNUSED(unres), struct ly_err_item **err)
4545
{
4646
LY_ERR ret = LY_SUCCESS;
47-
struct lysc_type_str *type_str = (struct lysc_type_str *)type;
4847
uint32_t value_size, i;
4948

5049
/* init storage */
@@ -87,16 +86,8 @@ lyplg_type_store_hex_string(const struct ly_ctx *ctx, const struct lysc_type *ty
8786
}
8887

8988
if (!(options & LYPLG_TYPE_STORE_ONLY)) {
90-
/* validate length restriction of the string */
91-
if (type_str->length) {
92-
/* value_size is in bytes, but we need number of characters here */
93-
ret = lyplg_type_validate_range(LY_TYPE_STRING, type_str->length, ly_utf8len(value, value_size), value,
94-
value_size, err);
95-
LY_CHECK_GOTO(ret, cleanup);
96-
}
97-
98-
/* validate pattern restrictions */
99-
ret = lyplg_type_validate_patterns(ctx, type_str->patterns, value, value_size, err);
89+
/* validate value */
90+
ret = lyplg_type_validate_value_string(ctx, type, storage, err);
10091
LY_CHECK_GOTO(ret, cleanup);
10192
}
10293

@@ -127,7 +118,8 @@ const struct lyplg_type_record plugins_hex_string[] = {
127118
.plugin.id = "ly2 hex-string",
128119
.plugin.lyb_size = lyplg_type_lyb_size_variable_bytes,
129120
.plugin.store = lyplg_type_store_hex_string,
130-
.plugin.validate = NULL,
121+
.plugin.validate_value = lyplg_type_validate_value_string,
122+
.plugin.validate_tree = NULL,
131123
.plugin.compare = lyplg_type_compare_simple,
132124
.plugin.sort = lyplg_type_sort_simple,
133125
.plugin.print = lyplg_type_print_simple,
@@ -142,7 +134,8 @@ const struct lyplg_type_record plugins_hex_string[] = {
142134
.plugin.id = "ly2 hex-string",
143135
.plugin.lyb_size = lyplg_type_lyb_size_variable_bytes,
144136
.plugin.store = lyplg_type_store_hex_string,
145-
.plugin.validate = NULL,
137+
.plugin.validate_value = lyplg_type_validate_value_string,
138+
.plugin.validate_tree = NULL,
146139
.plugin.compare = lyplg_type_compare_simple,
147140
.plugin.sort = lyplg_type_sort_simple,
148141
.plugin.print = lyplg_type_print_simple,
@@ -157,7 +150,8 @@ const struct lyplg_type_record plugins_hex_string[] = {
157150
.plugin.id = "ly2 hex-string",
158151
.plugin.lyb_size = lyplg_type_lyb_size_variable_bytes,
159152
.plugin.store = lyplg_type_store_hex_string,
160-
.plugin.validate = NULL,
153+
.plugin.validate_value = lyplg_type_validate_value_string,
154+
.plugin.validate_tree = NULL,
161155
.plugin.compare = lyplg_type_compare_simple,
162156
.plugin.sort = lyplg_type_sort_simple,
163157
.plugin.print = lyplg_type_print_simple,
@@ -172,7 +166,8 @@ const struct lyplg_type_record plugins_hex_string[] = {
172166
.plugin.id = "ly2 hex-string",
173167
.plugin.lyb_size = lyplg_type_lyb_size_variable_bytes,
174168
.plugin.store = lyplg_type_store_hex_string,
175-
.plugin.validate = NULL,
169+
.plugin.validate_value = lyplg_type_validate_value_string,
170+
.plugin.validate_tree = NULL,
176171
.plugin.compare = lyplg_type_compare_simple,
177172
.plugin.sort = lyplg_type_sort_simple,
178173
.plugin.print = lyplg_type_print_simple,

0 commit comments

Comments
 (0)