data tree REFACTOR remove lys_value_validate

Its functionality was added into lyd_value_validate.
diff --git a/doc/transition.dox b/doc/transition.dox
index a466f78..5374691 100644
--- a/doc/transition.dox
+++ b/doc/transition.dox
@@ -180,7 +180,6 @@
  * -                            | ::lys_find_child()              | Helpers wrapper around ::lys_getnext().
  * -                            | ::lys_getnext_ext()             | Alternative to ::lys_getnext() allowing processing schema trees inside extension instances.
  * -                            | ::lys_nodetype2str()            | New functionality.
- * -                            | ::lys_value_validate()          | Supplement functionality to ::lyd_value_validate().
  * lys_is_key()                 | ::lysc_is_key()                 | Renamed to connect with the compiled schema tree.
  * -                            | ::lysc_is_userordered()         | Added functionality to simplify the examination of generic compiled schema nodes.
  * -                            | ::lysc_is_np_cont()             | ^
diff --git a/src/parser_json.c b/src/parser_json.c
index 6e6d752..bea4003 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -355,7 +355,7 @@
                         goto cleanup;
                     }
 
-                    ret = _lys_value_validate(NULL, snode, jsonctx->value, jsonctx->value_len, LY_PREF_JSON, NULL);
+                    ret = lys_value_validate(NULL, snode, jsonctx->value, jsonctx->value_len, LY_PREF_JSON, NULL);
                     LY_CHECK_GOTO(ret, cleanup);
 
                     /* key with a valid value, remove from the set */
@@ -468,7 +468,7 @@
                 break;
             }
 
-            if (_lys_value_validate(NULL, snode, jsonctx->value, jsonctx->value_len, LY_PREF_JSON, NULL)) {
+            if (lys_value_validate(NULL, snode, jsonctx->value, jsonctx->value_len, LY_PREF_JSON, NULL)) {
                 ret = LY_ENOT;
             }
             break;
diff --git a/src/parser_xml.c b/src/parser_xml.c
index decbaf4..de48509 100644
--- a/src/parser_xml.c
+++ b/src/parser_xml.c
@@ -248,7 +248,7 @@
         assert(xmlctx->status == LYXML_ELEM_CONTENT);
         if (i < key_set.count) {
             /* validate the value */
-            r = _lys_value_validate(NULL, snode, xmlctx->value, xmlctx->value_len, LY_PREF_XML, &xmlctx->ns);
+            r = lys_value_validate(NULL, snode, xmlctx->value, xmlctx->value_len, LY_PREF_XML, &xmlctx->ns);
             if (!r) {
                 /* key with a valid value, remove from the set */
                 ly_set_rm_index(&key_set, i, NULL);
@@ -346,7 +346,7 @@
 
         if ((*snode)->nodetype & LYD_NODE_TERM) {
             /* value may not be valid in which case we parse it as an opaque node */
-            if (_lys_value_validate(NULL, *snode, xmlctx->value, xmlctx->value_len, LY_PREF_XML, &xmlctx->ns)) {
+            if (lys_value_validate(NULL, *snode, xmlctx->value, xmlctx->value_len, LY_PREF_XML, &xmlctx->ns)) {
                 *snode = NULL;
             }
         } else {
diff --git a/src/tree_data.c b/src/tree_data.c
index 1a8bf2b..3013c0a 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -113,7 +113,7 @@
 }
 
 LY_ERR
-_lys_value_validate(const struct ly_ctx *ctx, const struct lysc_node *node, const char *value, size_t value_len,
+lys_value_validate(const struct ly_ctx *ctx, const struct lysc_node *node, const char *value, size_t value_len,
         LY_PREFIX_FORMAT format, void *prefix_data)
 {
     LY_ERR rc = LY_SUCCESS;
@@ -152,14 +152,8 @@
 }
 
 API LY_ERR
-lys_value_validate(const struct ly_ctx *ctx, const struct lysc_node *node, const char *value, size_t value_len)
-{
-    return _lys_value_validate(ctx, node, value, value_len, LY_PREF_JSON, NULL);
-}
-
-API LY_ERR
-lyd_value_validate(const struct ly_ctx *ctx, const struct lyd_node_term *node, const char *value, size_t value_len,
-        const struct lyd_node *tree, const struct lysc_type **realtype)
+lyd_value_validate(const struct ly_ctx *ctx, const struct lysc_node *schema, const char *value, size_t value_len,
+        const struct lyd_node *ctx_node, const struct lysc_type **realtype, const char **canonical)
 {
     LY_ERR rc;
     struct ly_err_item *err = NULL;
@@ -167,44 +161,65 @@
     struct lyd_value val = {0};
     ly_bool stored = 0;
 
-    LY_CHECK_ARG_RET(ctx, node, value, LY_EINVAL);
+    LY_CHECK_ARG_RET(ctx, schema, value, LY_EINVAL);
 
-    type = ((struct lysc_node_leaf *)node->schema)->type;
+    type = ((struct lysc_node_leaf *)schema)->type;
+
     /* store */
-    rc = type->plugin->store(ctx ? ctx : LYD_CTX(node), type, value, value_len, 0, LY_PREF_JSON, NULL,
-            LYD_HINT_DATA, node->schema, &val, NULL, &err);
-    if (rc == LY_EINCOMPLETE) {
+    rc = type->plugin->store(ctx ? ctx : schema->module->ctx, type, value, value_len, 0, LY_PREF_JSON, NULL,
+            LYD_HINT_DATA, schema, &val, NULL, &err);
+    if (!rc || (rc == LY_EINCOMPLETE)) {
         stored = 1;
+    }
 
+    if (ctx_node && (rc == LY_EINCOMPLETE)) {
         /* resolve */
-        rc = type->plugin->validate(ctx ? ctx : LYD_CTX(node), type, &node->node, tree, &val, &err);
+        rc = type->plugin->validate(ctx ? ctx : schema->module->ctx, type, ctx_node, ctx_node, &val, &err);
     }
 
-    if (rc) {
-        if (err) {
-            if (ctx) {
-                LOG_LOCSET(NULL, &node->node, NULL, NULL);
-                LOGVAL(ctx, err->vecode, err->msg);
-                LOG_LOCBACK(0, 1, 0, 0);
+    if (rc && (rc != LY_EINCOMPLETE) && err) {
+        if (ctx) {
+            /* log error */
+            if (err->path) {
+                LOG_LOCSET(NULL, NULL, err->path, NULL);
+            } else if (ctx_node) {
+                LOG_LOCSET(NULL, ctx_node, NULL, NULL);
+            } else {
+                LOG_LOCSET(schema, NULL, NULL, NULL);
             }
-            ly_err_free(err);
+            LOGVAL(ctx, err->vecode, err->msg);
+            if (err->path) {
+                LOG_LOCBACK(0, 0, 1, 0);
+            } else if (ctx_node) {
+                LOG_LOCBACK(0, 1, 0, 0);
+            } else {
+                LOG_LOCBACK(1, 0, 0, 0);
+            }
         }
-        if (stored) {
-            type->plugin->free(ctx ? ctx : LYD_CTX(node), &val);
-        }
-        return rc;
+        ly_err_free(err);
     }
 
-    if (realtype) {
-        if (val.realtype->basetype == LY_TYPE_UNION) {
-            *realtype = val.subvalue->value.realtype;
-        } else {
-            *realtype = val.realtype;
+    if (!rc || (rc == LY_EINCOMPLETE)) {
+        if (realtype) {
+            /* return realtype */
+            if (val.realtype->basetype == LY_TYPE_UNION) {
+                *realtype = val.subvalue->value.realtype;
+            } else {
+                *realtype = val.realtype;
+            }
+        }
+
+        if (canonical) {
+            /* return canonical value */
+            lydict_insert(ctx ? ctx : schema->module->ctx, val.canonical, 0, canonical);
         }
     }
 
-    type->plugin->free(ctx ? ctx : LYD_CTX(node), &val);
-    return LY_SUCCESS;
+    if (stored) {
+        /* free value */
+        type->plugin->free(ctx ? ctx : schema->module->ctx, &val);
+    }
+    return rc;
 }
 
 API LY_ERR
@@ -1587,7 +1602,7 @@
 
         r = LY_SUCCESS;
         if (options & LYD_NEW_PATH_OPAQ) {
-            r = lys_value_validate(NULL, schema, value, strlen(value));
+            r = lys_value_validate(NULL, schema, value, strlen(value), LY_PREF_JSON, NULL);
         }
         if (!r) {
             /* store the new predicate */
@@ -1772,7 +1787,7 @@
 
             r = LY_SUCCESS;
             if (options & LYD_NEW_PATH_OPAQ) {
-                r = lys_value_validate(NULL, schema, value, strlen(value));
+                r = lys_value_validate(NULL, schema, value, strlen(value), LY_PREF_JSON, NULL);
             }
             if (!r) {
                 ret = lyd_create_term(schema, value, strlen(value), NULL, LY_PREF_JSON, NULL, LYD_HINT_DATA, NULL, &node);
diff --git a/src/tree_data.h b/src/tree_data.h
index 9414baf..c4c8795 100644
--- a/src/tree_data.h
+++ b/src/tree_data.h
@@ -1529,23 +1529,21 @@
  *
  * The given node is not modified in any way - it is just checked if the @p value can be set to the node.
  *
- * If there is no data node instance and you are fine with checking just the type's restrictions without the
- * data tree context (e.g. for the case of require-instance restriction), use ::lys_value_validate().
- *
  * @param[in] ctx libyang context for logging (function does not log errors when @p ctx is NULL)
- * @param[in] node Data node for the @p value.
+ * @param[in] schema Schema node of the @p value.
  * @param[in] value String value to be checked, it is expected to be in JSON format.
  * @param[in] value_len Length of the given @p value (mandatory).
- * @param[in] tree Data tree (e.g. when validating RPC/Notification) where the required data instance (leafref target,
- *            instance-identifier) can be placed. NULL in case the data tree is not yet complete,
- *            then LY_EINCOMPLETE can be returned.
- * @param[out] realtype Optional real type of the value.
+ * @param[in] ctx_node Optional data tree context node for the value (leafref target, instance-identifier).
+ * If not set and is required for the validation to complete, ::LY_EINCOMPLETE is be returned.
+ * @param[out] realtype Optional real type of @p value.
+ * @param[out] canonical Optional canonical value of @p value (in the dictionary).
  * @return LY_SUCCESS on success
- * @return LY_EINCOMPLETE in case the @p trees is not provided and it was needed to finish the validation (e.g. due to require-instance).
+ * @return LY_EINCOMPLETE in case the @p ctx_node is not provided and it was needed to finish the validation
+ * (e.g. due to require-instance).
  * @return LY_ERR value if an error occurred.
  */
-LY_ERR lyd_value_validate(const struct ly_ctx *ctx, const struct lyd_node_term *node, const char *value, size_t value_len,
-        const struct lyd_node *tree, const struct lysc_type **realtype);
+LY_ERR lyd_value_validate(const struct ly_ctx *ctx, const struct lysc_node *schema, const char *value, size_t value_len,
+        const struct lyd_node *ctx_node, const struct lysc_type **realtype, const char **canonical);
 
 /**
  * @brief Compare the node's value with the given string value. The string value is first validated according to
diff --git a/src/tree_data_internal.h b/src/tree_data_internal.h
index e0f0149..b7d2e2e 100644
--- a/src/tree_data_internal.h
+++ b/src/tree_data_internal.h
@@ -331,8 +331,23 @@
 LY_ERR lyd_value_validate_incomplete(const struct ly_ctx *ctx, const struct lysc_type *type, struct lyd_value *val,
         const struct lyd_node *ctx_node, const struct lyd_node *tree);
 
-/* generic function lys_value_validate */
-LY_ERR _lys_value_validate(const struct ly_ctx *ctx, const struct lysc_node *node, const char *value, size_t value_len,
+/**
+ * @brief Check type restrictions applicable to the particular leaf/leaf-list with the given string @p value coming
+ * from a schema.
+ *
+ * This function check just the type's restriction, if you want to check also the data tree context (e.g. in case of
+ * require-instance restriction), use ::lyd_value_validate().
+ *
+ * @param[in] ctx libyang context for logging (function does not log errors when @p ctx is NULL)
+ * @param[in] node Schema node for the @p value.
+ * @param[in] value String value to be checked, expected to be in JSON format.
+ * @param[in] value_len Length of the given @p value (mandatory).
+ * @param[in] format Value prefix format.
+ * @param[in] prefix_data Format-specific data for resolving any prefixes (see ::ly_resolve_prefix).
+ * @return LY_SUCCESS on success
+ * @return LY_ERR value if an error occurred.
+ */
+LY_ERR lys_value_validate(const struct ly_ctx *ctx, const struct lysc_node *node, const char *value, size_t value_len,
         LY_PREFIX_FORMAT format, void *prefix_data);
 
 /**
diff --git a/src/tree_schema.h b/src/tree_schema.h
index c6f6bcd..70913cf 100644
--- a/src/tree_schema.h
+++ b/src/tree_schema.h
@@ -101,7 +101,6 @@
  * - ::lys_getnext()
  * - ::lys_nodetype2str()
  * - ::lys_set_implemented()
- * - ::lys_value_validate()
  *
  * - ::lysc_has_when()
  *
@@ -2432,21 +2431,6 @@
 LY_ERR lys_set_implemented(struct lys_module *mod, const char **features);
 
 /**
- * @brief Check type restrictions applicable to the particular leaf/leaf-list with the given string @p value.
- *
- * This function check just the type's restriction, if you want to check also the data tree context (e.g. in case of
- * require-instance restriction), use ::lyd_value_validate().
- *
- * @param[in] ctx libyang context for logging (function does not log errors when @p ctx is NULL)
- * @param[in] node Schema node for the @p value.
- * @param[in] value String value to be checked, expected to be in JSON format.
- * @param[in] value_len Length of the given @p value (mandatory).
- * @return LY_SUCCESS on success
- * @return LY_ERR value if an error occurred.
- */
-LY_ERR lys_value_validate(const struct ly_ctx *ctx, const struct lysc_node *node, const char *value, size_t value_len);
-
-/**
  * @brief Stringify schema nodetype.
  *
  * @param[in] nodetype Nodetype to stringify.
diff --git a/tests/utests/data/test_types.c b/tests/utests/data/test_types.c
index 607be2a..3b5d784 100644
--- a/tests/utests/data/test_types.c
+++ b/tests/utests/data/test_types.c
@@ -814,18 +814,18 @@
     CHECK_PARSE_LYD(data, tree);
     /* key-predicate */
     data = "/types:list2[id='a'][value='b']/id";
-    assert_int_equal(LY_ENOTFOUND, lyd_value_validate(UTEST_LYCTX, (const struct lyd_node_term *)tree->prev, data, strlen(data),
-            tree, NULL));
+    assert_int_equal(LY_ENOTFOUND, lyd_value_validate(UTEST_LYCTX, tree->prev->schema, data, strlen(data), tree->prev,
+            NULL, NULL));
     CHECK_LOG_CTX("Invalid instance-identifier \"/types:list2[id='a'][value='b']/id\" value - required instance not found.", "Data location /types:inst.");
     /* leaf-list-predicate */
     data = "/types:leaflisttarget[.='c']";
-    assert_int_equal(LY_ENOTFOUND, lyd_value_validate(UTEST_LYCTX, (const struct lyd_node_term *)tree->prev, data, strlen(data),
-            tree, NULL));
+    assert_int_equal(LY_ENOTFOUND, lyd_value_validate(UTEST_LYCTX, tree->prev->schema, data, strlen(data), tree->prev,
+            NULL, NULL));
     CHECK_LOG_CTX("Invalid instance-identifier \"/types:leaflisttarget[.='c']\" value - required instance not found.", "Data location /types:inst.");
     /* position predicate */
     data = "/types:list_keyless[4]";
-    assert_int_equal(LY_ENOTFOUND, lyd_value_validate(UTEST_LYCTX, (const struct lyd_node_term *)tree->prev, data, strlen(data),
-            tree, NULL));
+    assert_int_equal(LY_ENOTFOUND, lyd_value_validate(UTEST_LYCTX, tree->prev->schema, data, strlen(data), tree->prev,
+            NULL, NULL));
     CHECK_LOG_CTX("Invalid instance-identifier \"/types:list_keyless[4]\" value - required instance not found.", "Data location /types:inst.");
 
     lyd_free_all(tree);
diff --git a/tools/re/main.c b/tools/re/main.c
index 8583e73..701b0a1 100644
--- a/tools/re/main.c
+++ b/tools/re/main.c
@@ -269,7 +269,7 @@
     }
 
     /* check the value */
-    match = lys_value_validate(ctx, mod->compiled->data, str, strlen(str));
+    match = lyd_value_validate(ctx, mod->compiled->data, str, strlen(str), NULL, NULL, NULL);
 
     if (verbose) {
         for (i = 0; i < patterns_count; i++) {