@@ -102,8 +102,8 @@ lyd_val_getnext_ht_free(struct ly_ht *getnext_ht)
102102}
103103
104104LY_ERR
105- lyd_val_getnext_get (const struct lysc_node * sparent , const struct lys_module * mod , ly_bool output ,
106- struct ly_ht * getnext_ht , const struct lysc_node * * * choices , const struct lysc_node * * * snodes )
105+ lyd_val_getnext_get (const struct lysc_node * sparent , const struct lys_module * mod , const struct lysc_ext_instance * ext ,
106+ ly_bool output , struct ly_ht * getnext_ht , const struct lysc_node * * * choices , const struct lysc_node * * * snodes )
107107{
108108 LY_ERR rc = LY_SUCCESS ;
109109 struct lyd_val_getnext val = {0 }, * getnext = NULL ;
@@ -118,7 +118,8 @@ lyd_val_getnext_get(const struct lysc_node *sparent, const struct lys_module *mo
118118
119119 /* traverse all the children using getnext and store them */
120120 getnext_opts = LYS_GETNEXT_WITHCHOICE | (output ? LYS_GETNEXT_OUTPUT : 0 );
121- while ((snode = lys_getnext (snode , sparent , mod ? mod -> compiled : NULL , getnext_opts ))) {
121+ while (ext ? (snode = lys_getnext_ext (snode , sparent , ext , getnext_opts )) :
122+ (snode = lys_getnext (snode , sparent , mod ? mod -> compiled : NULL , getnext_opts ))) {
122123 if (snode -> nodetype == LYS_CHOICE ) {
123124 /* store a choice node */
124125 val .choices = ly_realloc (val .choices , (choice_count + 2 ) * sizeof * val .choices );
@@ -893,6 +894,7 @@ lyd_validate_autodel_case_dflt(struct lyd_node **first, struct lyd_node **node,
893894 * @param[in,out] first First sibling.
894895 * @param[in] sparent Schema parent of the siblings, NULL for top-level siblings.
895896 * @param[in] mod Module of the siblings, NULL for nested siblings.
897+ * @param[in] ext Extension instance to use, if relevant.
896898 * @param[in] val_opts Validation options.
897899 * @param[in] int_opts Internal parser options.
898900 * @param[in,out] getnext_ht Getnext HT to use, new @p sparent is added to it.
@@ -901,14 +903,15 @@ lyd_validate_autodel_case_dflt(struct lyd_node **first, struct lyd_node **node,
901903 */
902904static LY_ERR
903905lyd_validate_choice_r (struct lyd_node * * first , const struct lysc_node * sparent , const struct lys_module * mod ,
904- uint32_t val_opts , uint32_t int_opts , struct ly_ht * getnext_ht , struct lyd_node * * diff )
906+ const struct lysc_ext_instance * ext , uint32_t val_opts , uint32_t int_opts , struct ly_ht * getnext_ht ,
907+ struct lyd_node * * diff )
905908{
906909 LY_ERR r , rc = LY_SUCCESS ;
907910 const struct lysc_node * * choices , * * snodes ;
908911 uint32_t i ;
909912
910913 /* get cached getnext schema nodes */
911- rc = lyd_val_getnext_get (sparent , mod , int_opts & LYD_INTOPT_REPLY , getnext_ht , & choices , & snodes );
914+ rc = lyd_val_getnext_get (sparent , mod , ext , int_opts & LYD_INTOPT_REPLY , getnext_ht , & choices , & snodes );
912915 LY_CHECK_GOTO (rc , cleanup );
913916 if (!choices ) {
914917 goto cleanup ;
@@ -920,7 +923,7 @@ lyd_validate_choice_r(struct lyd_node **first, const struct lysc_node *sparent,
920923 LY_VAL_ERR_GOTO (r , rc = r , val_opts , cleanup );
921924
922925 /* check for nested choice */
923- r = lyd_validate_choice_r (first , choices [i ], mod , val_opts , int_opts , getnext_ht , diff );
926+ r = lyd_validate_choice_r (first , choices [i ], mod , ext , val_opts , int_opts , getnext_ht , diff );
924927 LY_VAL_ERR_GOTO (r , rc = r , val_opts , cleanup );
925928 }
926929
@@ -930,7 +933,8 @@ lyd_validate_choice_r(struct lyd_node **first, const struct lysc_node *sparent,
930933
931934LY_ERR
932935lyd_validate_new (struct lyd_node * * first , const struct lysc_node * sparent , const struct lys_module * mod ,
933- uint32_t val_opts , uint32_t int_opts , struct ly_ht * getnext_ht , struct lyd_node * * diff )
936+ const struct lysc_ext_instance * ext , uint32_t val_opts , uint32_t int_opts , struct ly_ht * getnext_ht ,
937+ struct lyd_node * * diff )
934938{
935939 LY_ERR r , rc = LY_SUCCESS ;
936940 struct lyd_node * node ;
@@ -939,7 +943,7 @@ lyd_validate_new(struct lyd_node **first, const struct lysc_node *sparent, const
939943 assert (first && (sparent || mod ));
940944
941945 /* validate choices */
942- r = lyd_validate_choice_r (first , sparent , mod , val_opts , int_opts , getnext_ht , diff );
946+ r = lyd_validate_choice_r (first , sparent , mod , ext , val_opts , int_opts , getnext_ht , diff );
943947 LY_VAL_ERR_GOTO (r , rc = r , val_opts , cleanup );
944948
945949 node = * first ;
@@ -1487,15 +1491,16 @@ lyd_validate_unique(const struct lyd_node *first, const struct lysc_node *snode,
14871491 * @param[in] parent Data parent.
14881492 * @param[in] sparent Schema parent of the nodes to check.
14891493 * @param[in] mod Module of the nodes to check.
1494+ * @param[in] ext Extension instance to use, if relevant.
14901495 * @param[in] val_opts Validation options, see @ref datavalidationoptions.
14911496 * @param[in] int_opts Internal parser options.
14921497 * @param[in,out] getnext_ht Getnext HT to use, new @p sparent is added to it.
14931498 * @return LY_ERR value.
14941499 */
14951500static LY_ERR
14961501lyd_validate_siblings_schema_r (const struct lyd_node * first , const struct lyd_node * parent ,
1497- const struct lysc_node * sparent , const struct lys_module * mod , uint32_t val_opts , uint32_t int_opts ,
1498- struct ly_ht * getnext_ht )
1502+ const struct lysc_node * sparent , const struct lys_module * mod , const struct lysc_ext_instance * ext ,
1503+ uint32_t val_opts , uint32_t int_opts , struct ly_ht * getnext_ht )
14991504{
15001505 LY_ERR r , rc = LY_SUCCESS ;
15011506 const struct lysc_node * snode , * scase , * * choices , * * snodes ;
@@ -1504,7 +1509,7 @@ lyd_validate_siblings_schema_r(const struct lyd_node *first, const struct lyd_no
15041509 uint32_t i ;
15051510
15061511 /* get cached getnext schema nodes */
1507- rc = lyd_val_getnext_get (sparent , mod , int_opts & LYD_INTOPT_REPLY , getnext_ht , & choices , & snodes );
1512+ rc = lyd_val_getnext_get (sparent , mod , ext , int_opts & LYD_INTOPT_REPLY , getnext_ht , & choices , & snodes );
15081513 LY_CHECK_GOTO (rc , cleanup );
15091514
15101515 for (i = 0 ; choices && choices [i ]; ++ i ) {
@@ -1525,7 +1530,7 @@ lyd_validate_siblings_schema_r(const struct lyd_node *first, const struct lyd_no
15251530 LY_LIST_FOR (lysc_node_child (snode ), scase ) {
15261531 if (lys_getnext_data (NULL , first , NULL , scase , NULL )) {
15271532 /* validate only this case */
1528- r = lyd_validate_siblings_schema_r (first , parent , scase , mod , val_opts , int_opts , getnext_ht );
1533+ r = lyd_validate_siblings_schema_r (first , parent , scase , mod , ext , val_opts , int_opts , getnext_ht );
15291534 LY_VAL_ERR_GOTO (r , rc = r , val_opts , cleanup );
15301535 break ;
15311536 }
@@ -1691,6 +1696,7 @@ lyd_validate_must(const struct lyd_node *node, uint32_t val_opts, uint32_t int_o
16911696 * @param[in] parent Data parent.
16921697 * @param[in] sparent Schema parent of the siblings, NULL for top-level siblings.
16931698 * @param[in] mod Module of the siblings, NULL for nested siblings.
1699+ * @param[in] ext Extension instance to use, if relevant.
16941700 * @param[in] val_opts Validation options (@ref datavalidationoptions).
16951701 * @param[in] int_opts Internal parser options.
16961702 * @param[in] must_xp_opts Additional XPath options to use for evaluating "must".
@@ -1699,8 +1705,8 @@ lyd_validate_must(const struct lyd_node *node, uint32_t val_opts, uint32_t int_o
16991705 */
17001706static LY_ERR
17011707lyd_validate_final_r (struct lyd_node * first , const struct lyd_node * parent , const struct lysc_node * sparent ,
1702- const struct lys_module * mod , uint32_t val_opts , uint32_t int_opts , uint32_t must_xp_opts ,
1703- struct ly_ht * getnext_ht )
1708+ const struct lys_module * mod , const struct lysc_ext_instance * ext , uint32_t val_opts , uint32_t int_opts ,
1709+ uint32_t must_xp_opts , struct ly_ht * getnext_ht )
17041710{
17051711 LY_ERR r , rc = LY_SUCCESS ;
17061712 const char * innode ;
@@ -1762,7 +1768,7 @@ lyd_validate_final_r(struct lyd_node *first, const struct lyd_node *parent, cons
17621768 }
17631769
17641770 /* validate schema-based restrictions */
1765- r = lyd_validate_siblings_schema_r (first , parent , sparent , mod , val_opts , int_opts , getnext_ht );
1771+ r = lyd_validate_siblings_schema_r (first , parent , sparent , mod , ext , val_opts , int_opts , getnext_ht );
17661772 LY_VAL_ERR_GOTO (r , rc = r , val_opts , cleanup );
17671773
17681774 LY_LIST_FOR (first , node ) {
@@ -1772,7 +1778,8 @@ lyd_validate_final_r(struct lyd_node *first, const struct lyd_node *parent, cons
17721778 }
17731779
17741780 /* validate all children recursively */
1775- r = lyd_validate_final_r (lyd_child (node ), node , node -> schema , NULL , val_opts , int_opts , must_xp_opts , getnext_ht );
1781+ r = lyd_validate_final_r (lyd_child (node ), node , node -> schema , NULL , NULL , val_opts , int_opts , must_xp_opts ,
1782+ getnext_ht );
17761783 LY_VAL_ERR_GOTO (r , rc = r , val_opts , cleanup );
17771784
17781785 /* set default for containers */
@@ -1909,7 +1916,7 @@ lyd_validate_subtree(struct lyd_node *root, struct ly_set *node_when, struct ly_
19091916 LY_CHECK_ERR_GOTO (r , rc = r , cleanup );
19101917 } else if (node -> schema -> nodetype & LYD_NODE_INNER ) {
19111918 /* new node validation, autodelete */
1912- r = lyd_validate_new (lyd_node_child_p (node ), node -> schema , NULL , val_opts , int_opts , getnext_ht , diff );
1919+ r = lyd_validate_new (lyd_node_child_p (node ), node -> schema , NULL , NULL , val_opts , int_opts , getnext_ht , diff );
19131920 LY_VAL_ERR_GOTO (r , rc = r , val_opts , cleanup );
19141921
19151922 /* add nested defaults */
@@ -1988,8 +1995,8 @@ lyd_validate(struct lyd_node **tree, const struct lys_module *module, const stru
19881995 LY_CHECK_ERR_GOTO (r , rc = r , cleanup );
19891996
19901997 /* validate new top-level nodes of this module, autodelete */
1991- r = lyd_validate_new (first2 , * first2 ? lysc_data_parent ((* first2 )-> schema ) : NULL , mod , val_opts , 0 , getnext_ht ,
1992- diff );
1998+ r = lyd_validate_new (first2 , * first2 ? lysc_data_parent ((* first2 )-> schema ) : NULL , mod , NULL , val_opts , 0 ,
1999+ getnext_ht , diff );
19932000 LY_VAL_ERR_GOTO (r , rc = r , val_opts , cleanup );
19942001
19952002 /* add all top-level defaults for this module, if going to validate subtree, do not add into unres sets
@@ -2040,7 +2047,7 @@ lyd_validate(struct lyd_node **tree, const struct lys_module *module, const stru
20402047
20412048 if (!(val_opts & LYD_VALIDATE_NOT_FINAL )) {
20422049 /* perform final validation that assumes the data tree is final */
2043- r = lyd_validate_final_r (* first2 , NULL , NULL , mod , val_opts , 0 , 0 , getnext_ht );
2050+ r = lyd_validate_final_r (* first2 , NULL , NULL , mod , NULL , val_opts , 0 , 0 , getnext_ht );
20442051 LY_VAL_ERR_GOTO (r , rc = r , val_opts , cleanup );
20452052 }
20462053
@@ -2059,6 +2066,62 @@ lyd_validate(struct lyd_node **tree, const struct lys_module *module, const stru
20592066 return rc ;
20602067}
20612068
2069+ LY_ERR
2070+ lyd_validate_ext (struct lyd_node * * tree , const struct lysc_ext_instance * ext , uint32_t val_opts ,
2071+ ly_bool validate_subtree , struct ly_set * node_when_p , struct ly_set * node_types_p , struct ly_set * meta_types_p ,
2072+ struct ly_set * ext_node_p , struct ly_set * ext_val_p , struct lyd_node * * diff )
2073+ {
2074+ LY_ERR r , rc = LY_SUCCESS ;
2075+ struct lyd_node * iter ;
2076+ struct ly_set node_types = {0 }, meta_types = {0 }, node_when = {0 }, ext_node = {0 }, ext_val = {0 };
2077+ struct ly_ht * getnext_ht = NULL ;
2078+
2079+ assert (tree );
2080+ assert ((node_when_p && node_types_p && meta_types_p && ext_node_p && ext_val_p ) ||
2081+ (!node_when_p && !node_types_p && !meta_types_p && !ext_node_p && !ext_val_p ));
2082+
2083+ if (!node_when_p ) {
2084+ node_when_p = & node_when ;
2085+ node_types_p = & node_types ;
2086+ meta_types_p = & meta_types ;
2087+ ext_node_p = & ext_node ;
2088+ ext_val_p = & ext_val ;
2089+ }
2090+
2091+ /* create the getnext hash table for these data */
2092+ r = lyd_val_getnext_ht_new (& getnext_ht );
2093+ LY_CHECK_ERR_GOTO (r , rc = r , cleanup );
2094+
2095+ if (validate_subtree ) {
2096+ /* process nested nodes */
2097+ LY_LIST_FOR (* tree , iter ) {
2098+ r = lyd_validate_subtree (iter , node_when_p , node_types_p , meta_types_p , ext_node_p , ext_val_p ,
2099+ val_opts , 0 , getnext_ht , diff );
2100+ LY_VAL_ERR_GOTO (r , rc = r , val_opts , cleanup );
2101+ }
2102+ }
2103+
2104+ /* finish incompletely validated terminal values/attributes and when conditions */
2105+ r = lyd_validate_unres (tree , NULL , LYD_TYPE_DATA_YANG , node_when_p , 0 , node_types_p , meta_types_p ,
2106+ ext_node_p , ext_val_p , val_opts , diff );
2107+ LY_VAL_ERR_GOTO (r , rc = r , val_opts , cleanup );
2108+
2109+ if (!(val_opts & LYD_VALIDATE_NOT_FINAL )) {
2110+ /* perform final validation that assumes the data tree is final */
2111+ r = lyd_validate_final_r (* tree , NULL , NULL , NULL , ext , val_opts , 0 , 0 , getnext_ht );
2112+ LY_VAL_ERR_GOTO (r , rc = r , val_opts , cleanup );
2113+ }
2114+
2115+ cleanup :
2116+ ly_set_erase (& node_when , NULL );
2117+ ly_set_erase (& node_types , NULL );
2118+ ly_set_erase (& meta_types , NULL );
2119+ ly_set_erase (& ext_node , free );
2120+ ly_set_erase (& ext_val , free );
2121+ lyd_val_getnext_ht_free (getnext_ht );
2122+ return rc ;
2123+ }
2124+
20622125LIBYANG_API_DEF LY_ERR
20632126lyd_validate_all (struct lyd_node * * tree , const struct ly_ctx * ctx , uint32_t val_opts , struct lyd_node * * diff )
20642127{
@@ -2107,7 +2170,7 @@ lyd_validate_module_final(struct lyd_node *tree, const struct lys_module *module
21072170 LY_CHECK_ERR_GOTO (r , rc = r , cleanup );
21082171
21092172 /* perform final validation that assumes the data tree is final */
2110- r = lyd_validate_final_r (first , NULL , NULL , mod , val_opts , 0 , 0 , getnext_ht );
2173+ r = lyd_validate_final_r (first , NULL , NULL , mod , NULL , val_opts , 0 , 0 , getnext_ht );
21112174 LY_VAL_ERR_GOTO (r , rc = r , val_opts , cleanup );
21122175
21132176cleanup :
@@ -2272,7 +2335,8 @@ _lyd_validate_op(struct lyd_node *op_tree, struct lyd_node *op_node, const struc
22722335 LY_CHECK_GOTO (rc = lyd_validate_must (op_node , 0 , int_opts , LYXP_IGNORE_WHEN ), cleanup );
22732336
22742337 /* final validation of all the descendants */
2275- rc = lyd_validate_final_r (lyd_child (op_node ), op_node , op_node -> schema , NULL , 0 , int_opts , LYXP_IGNORE_WHEN , getnext_ht );
2338+ rc = lyd_validate_final_r (lyd_child (op_node ), op_node , op_node -> schema , NULL , NULL , 0 , int_opts , LYXP_IGNORE_WHEN ,
2339+ getnext_ht );
22762340 LY_CHECK_GOTO (rc , cleanup );
22772341
22782342cleanup :
0 commit comments