1 /** 2 * @file resolve.h 3 * @author Michal Vasko <mvasko@cesnet.cz> 4 * @brief libyang resolve header 5 * 6 * Copyright (c) 2015 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 _RESOLVE_H 16 #define _RESOLVE_H 17 18 #include "libyang.h" 19 #include "extensions.h" 20 21 /** 22 * @brief Type of an unresolved item (in either SCHEMA or DATA) 23 */ 24 enum UNRES_ITEM { 25 /* SCHEMA */ 26 UNRES_USES = 0x00000001, /* unresolved uses grouping (refines and augments in it are resolved as well) */ 27 UNRES_IFFEAT = 0x00000002, /* unresolved if-feature */ 28 UNRES_TYPE_DER = 0x00000004, /* unresolved derived type defined in leaf/leaflist */ 29 UNRES_TYPE_DER_TPDF = 0x00000008, /* unresolved derived type defined as typedef */ 30 UNRES_TYPE_DER_EXT = 0x00000010, 31 UNRES_TYPE_LEAFREF = 0x00000020, /* check leafref value */ 32 UNRES_AUGMENT = 0x00000040, /* unresolved augment targets */ 33 UNRES_CHOICE_DFLT = 0x00000080, /* check choice default case */ 34 UNRES_IDENT = 0x00000100, /* unresolved derived identities */ 35 UNRES_TYPE_IDENTREF = 0x00000200, /* check identityref value */ 36 UNRES_FEATURE = 0x00000400, /* feature for circular check, it must be postponed when all if-features are resolved */ 37 UNRES_TYPEDEF_DFLT = 0x00000800, /* validate default type value (from typedef) */ 38 UNRES_TYPE_DFLT = 0x00001000, /* validate default type value (from lys_node) */ 39 UNRES_LIST_KEYS = 0x00002000, /* list keys */ 40 UNRES_LIST_UNIQ = 0x00004000, /* list uniques */ 41 UNRES_MOD_IMPLEMENT = 0x00008000, /* unimplemented module */ 42 UNRES_EXT = 0x00010000, /* extension instances */ 43 UNRES_XPATH = 0x00020000, /* unchecked XPath expression */ 44 UNRES_EXT_FINALIZE = 0x00040000, /* extension is already resolved, but needs to be finalized via plugin callbacks */ 45 46 /* DATA */ 47 UNRES_LEAFREF = 0x00080000, /* unresolved leafref reference */ 48 UNRES_INSTID = 0x00100000, /* unresolved instance-identifier reference */ 49 UNRES_WHEN = 0x00200000, /* unresolved when condition */ 50 UNRES_MUST = 0x00400000, /* unresolved must condition */ 51 UNRES_MUST_INOUT = 0x00800000, /* unresolved must condition in parent input or output */ 52 UNRES_UNION = 0x01000000, /* union with leafref which must be checked because the type can change without changing the 53 value itself, but removing the target node */ 54 UNRES_UNIQ_LEAVES = 0x02000000, /* list with a unique statement(s) whose leaves need to be checked */ 55 56 /* generic */ 57 UNRES_RESOLVED = 0x04000000, /* a resolved item */ 58 UNRES_DELETE = 0x08000000, /* prepared for auto-delete */ 59 }; 60 61 /** 62 * @brief auxiliaty structure to hold all necessary information for UNRES_EXT 63 */ 64 struct unres_ext { 65 union { 66 struct lyxml_elem *yin; /**< YIN content of the extension instance */ 67 struct yang_ext_substmt *yang; /**< YANG content of strings */ 68 } data; 69 LYS_INFORMAT datatype; /**< type of the data in data union */ 70 71 /* data for lys_ext_instance structure */ 72 void *parent; 73 struct lys_module *mod; 74 LYEXT_PAR parent_type; 75 LYEXT_SUBSTMT substmt; 76 uint8_t substmt_index; 77 uint8_t ext_index; 78 }; 79 80 /** 81 * @brief auxiliary structure to hold all necessary information for UNRES_LIST_UNIQ 82 */ 83 struct unres_list_uniq { 84 struct lys_node *list; 85 const char *expr; 86 uint8_t *trg_type; 87 }; 88 89 /** 90 * @brief Unresolved items in DATA 91 */ 92 struct unres_data { 93 struct lyd_node **node; 94 enum UNRES_ITEM *type; 95 uint32_t count; 96 97 int store_diff; 98 struct lyd_difflist *diff; 99 unsigned int diff_size; 100 unsigned int diff_idx; 101 }; 102 103 /** 104 * @brief Unresolved items in a SCHEMA 105 */ 106 struct unres_schema { 107 void **item; /* array of pointers, each is determined by the type (one of lys_* structures) */ 108 enum UNRES_ITEM *type; /* array of unres types */ 109 void **str_snode; /* array of pointers, each is determined by the type (a string, a lys_node *, or NULL) */ 110 struct lys_module **module; /* array of pointers to the item's module */ 111 uint32_t count; /* count of unres items */ 112 }; 113 114 struct len_ran_intv { 115 /* 0 - unsigned, 1 - signed, 2 - floating point */ 116 uint8_t kind; 117 union { 118 struct { 119 uint64_t min; 120 uint64_t max; 121 } uval; 122 123 struct { 124 int64_t min; 125 int64_t max; 126 } sval; 127 128 struct { 129 int64_t min; 130 int64_t max; 131 } fval; 132 } value; 133 134 struct lys_type *type; /* just to be able to get to optional error-message and/or error-app-tag */ 135 struct len_ran_intv *next; 136 }; 137 138 /** 139 * @brief Convert a string with a decimal64 value into our representation. 140 * Syntax is expected to be correct. Does not log. 141 * 142 * @param[in,out] str_num Pointer to the beginning of the decimal64 number, returns the first unparsed character. 143 * @param[in] dig Fraction-digits of the resulting number. 144 * @param[out] num Decimal64 base value, fraction-digits equal \p dig. 145 * @return 0 on success, non-zero on error. 146 */ 147 int parse_range_dec64(const char **str_num, uint8_t dig, int64_t *num); 148 149 unsigned int parse_identifier(const char *id); 150 151 int parse_schema_nodeid(const char *id, const char **mod_name, int *mod_name_len, const char **name, int *nam_len, 152 int *is_relative, int *has_predicate, int *all_desc, int extended); 153 154 int parse_schema_json_predicate(const char *id, const char **mod_name, int *mod_name_len, const char **name, 155 int *nam_len, const char **value, int *val_len, int *has_predicate); 156 157 /** 158 * @param[in] expr compiled if-feature expression 159 * @return 1 if enabled, 0 if disabled 160 */ 161 int resolve_iffeature(struct lys_iffeature *expr); 162 void resolve_iffeature_getsizes(struct lys_iffeature *iffeat, unsigned int *expr_size, unsigned int *feat_size); 163 int resolve_iffeature_compile(struct lys_iffeature *iffeat_expr, const char *value, struct lys_node *node, 164 int infeature, struct unres_schema *unres); 165 uint8_t iff_getop(uint8_t *list, int pos); 166 167 int inherit_config_flag(struct lys_node *node, int flags, int clear); 168 169 void resolve_identity_backlink_update(struct lys_ident *der, struct lys_ident *base); 170 171 struct lyd_node *resolve_data_descendant_schema_nodeid(const char *nodeid, struct lyd_node *start); 172 173 int resolve_schema_nodeid(const char *nodeid, const struct lys_node *start, const struct lys_module *cur_module, 174 struct ly_set **ret, int extended, int no_node_error); 175 176 int resolve_descendant_schema_nodeid(const char *nodeid, const struct lys_node *start, int ret_nodetype, 177 int no_innerlist, const struct lys_node **ret); 178 179 int resolve_choice_default_schema_nodeid(const char *nodeid, const struct lys_node *start, const struct lys_node **ret); 180 181 int resolve_absolute_schema_nodeid(const char *nodeid, const struct lys_module *module, int ret_nodetype, 182 const struct lys_node **ret); 183 184 const struct lys_node *resolve_json_nodeid(const char *nodeid, const struct ly_ctx *ctx, const struct lys_node *start, int output); 185 186 struct lyd_node *resolve_partial_json_data_nodeid(const char *nodeid, const char *llist_value, struct lyd_node *start, 187 int options, int *parsed); 188 189 int resolve_len_ran_interval(struct ly_ctx *ctx, const char *str_restr, struct lys_type *type, struct len_ran_intv **ret); 190 191 int resolve_superior_type(const char *name, const char *prefix, const struct lys_module *module, 192 const struct lys_node *parent, struct lys_tpdf **ret); 193 194 int resolve_unique(struct lys_node *parent, const char *uniq_str_path, uint8_t *trg_type); 195 196 void resolve_when_ctx_snode(const struct lys_node *schema, struct lys_node **ctx_snode, 197 enum lyxp_node_type *ctx_snode_type); 198 199 /* get know if resolve_when() is applicable to the node (there is when condition connected with this node) 200 * 201 * @param[in] mode 0 - search for when in parent until there is another possible data node 202 * 2 - search for when until reached the stop node, if NULL, search in all parents 203 */ 204 int resolve_applies_when(const struct lys_node *schema, int mode, const struct lys_node *stop); 205 206 /* return: 0x0 - no applicable must, 207 * 0x1 - node's schema has must, 208 * 0x2 - node's parent is inout with must, 209 * 0x3 - 0x2 & 0x1 combined */ 210 int resolve_applies_must(const struct lyd_node *node); 211 212 struct lys_ident *resolve_identref(struct lys_type *type, const char *ident_name, struct lyd_node *node, 213 struct lys_module *mod, int dflt); 214 215 int resolve_unres_schema(struct lys_module *mod, struct unres_schema *unres); 216 217 int resolve_when(struct lyd_node *node, int ignore_fail, struct lys_when **failed_when); 218 219 int unres_schema_add_str(struct lys_module *mod, struct unres_schema *unres, void *item, enum UNRES_ITEM type, 220 const char *str); 221 222 int unres_schema_add_node(struct lys_module *mod, struct unres_schema *unres, void *item, enum UNRES_ITEM type, 223 struct lys_node *node); 224 225 int unres_schema_dup(struct lys_module *mod, struct unres_schema *unres, void *item, enum UNRES_ITEM type, 226 void *new_item); 227 228 /* start_on_backwards - unres is searched from the end to beginning, so the search will start 229 * on start_on_backwards index in unres (unless -1) and skip indices 230 * larger than start_on_backards 231 */ 232 int unres_schema_find(struct unres_schema *unres, int start_on_backwards, void *item, enum UNRES_ITEM type); 233 234 void unres_schema_free(struct lys_module *module, struct unres_schema **unres, int all); 235 236 /** 237 * @brief Resolve instance-identifier in JSON data format. Logs directly. 238 * 239 * @param[in] data Data node where the path is used 240 * @param[in] path Instance-identifier node value. 241 * @param[in,out] ret Resolved instance or NULL. 242 * 243 * @return 0 on success (even if unresolved and \p ret is NULL), -1 on error. 244 */ 245 int resolve_instid(struct lyd_node *data, const char *path, int req_inst, struct lyd_node **ret); 246 247 int resolve_leafref(struct lyd_node_leaf_list *leaf, const char *path, int req_inst, struct lyd_node **ret); 248 249 int resolve_union(struct lyd_node_leaf_list *leaf, struct lys_type *type, int store, int ignore_fail, 250 struct lys_type **resolved_type); 251 252 int resolve_unres_data_item(struct lyd_node *dnode, enum UNRES_ITEM type, int ignore_fail, int multi_error, 253 struct lys_when **failed_when); 254 255 int unres_data_addonly(struct unres_data *unres, struct lyd_node *node, enum UNRES_ITEM type); 256 int unres_data_add(struct unres_data *unres, struct lyd_node *node, enum UNRES_ITEM type); 257 void unres_data_del(struct unres_data *unres, uint32_t i); 258 259 int resolve_unres_data(struct ly_ctx *ctx, struct unres_data *unres, struct lyd_node **root, int options); 260 int schema_nodeid_siblingcheck(const struct lys_node *sibling, const struct lys_module *cur_module, 261 const char *mod_name, int mod_name_len, const char *name, int nam_len); 262 263 #endif /* _RESOLVE_H */ 264