tests CHANGE extend tests of default values in schemas

Covers deviating the default values and their types. Also fixes several
bugs in schema compilation and built-in data type plugins.
diff --git a/src/plugins_types.c b/src/plugins_types.c
index 15386ad..cbcbc88 100644
--- a/src/plugins_types.c
+++ b/src/plugins_types.c
@@ -451,7 +451,7 @@
 
     switch (type->basetype) {
     case LY_TYPE_INT8:
-        LY_CHECK_RET(ly_type_parse_int("int16", (options & LY_TYPE_OPTS_SCHEMA) ? 0 : 10, INT64_C(-128), INT64_C(127), value, value_len, &i, err));
+        LY_CHECK_RET(ly_type_parse_int("int8", (options & LY_TYPE_OPTS_SCHEMA) ? 0 : 10, INT64_C(-128), INT64_C(127), value, value_len, &i, err));
         break;
     case LY_TYPE_INT16:
         LY_CHECK_RET(ly_type_parse_int("int16", (options & LY_TYPE_OPTS_SCHEMA) ? 0 : 10, INT64_C(-32768), INT64_C(32767), value, value_len, &i, err));
@@ -525,7 +525,7 @@
 
     switch (type->basetype) {
     case LY_TYPE_UINT8:
-        LY_CHECK_RET(ly_type_parse_uint("uint16", (options & LY_TYPE_OPTS_SCHEMA) ? 0 : 10, UINT64_C(255), value, value_len, &u, err));
+        LY_CHECK_RET(ly_type_parse_uint("uint8", (options & LY_TYPE_OPTS_SCHEMA) ? 0 : 10, UINT64_C(255), value, value_len, &u, err));
         break;
     case LY_TYPE_UINT16:
         LY_CHECK_RET(ly_type_parse_uint("uint16", (options & LY_TYPE_OPTS_SCHEMA) ? 0 : 10, UINT64_C(65535), value, value_len, &u, err));
@@ -1380,7 +1380,7 @@
         }
     }
 
-    if ((options & LY_TYPE_OPTS_INCOMPLETE_DATA) || !require_instance) {
+    if ((options & LY_TYPE_OPTS_INCOMPLETE_DATA) || (options & LY_TYPE_OPTS_SCHEMA) || !require_instance) {
         /* a) in schema tree */
         *node_s = lys_child(*node_s, mod, id, id_len, 0, 0);
         if (!(*node_s)) {
@@ -1468,7 +1468,7 @@
     ret = type->plugin->store(ctx, type, val, val_len, options, ly_type_stored_prefixes_clb, prefixes, format, key, NULL,
                               pred->value, NULL, &err);
     if (ret == LY_EINCOMPLETE) {
-        /* actually expected success without complete data */
+        /* actually expected without complete data */
         ret = LY_SUCCESS;
     } else if (ret) {
         if (err) {
@@ -1547,9 +1547,20 @@
     /* init */
     *err = NULL;
 
-    if ((options & LY_TYPE_OPTS_SECOND_CALL) && (options & LY_TYPE_OPTS_STORE)) {
-        /* the second run, the first one ended with LY_EINCOMPLETE, but we have prepared the target structure */
+    if ((options & LY_TYPE_OPTS_SCHEMA) && (options & LY_TYPE_OPTS_INCOMPLETE_DATA)) {
+        if (options & LY_TYPE_OPTS_STORE) {
+            if (options & LY_TYPE_OPTS_DYNAMIC) {
+                ly_type_store_canonized(ctx, options, lydict_insert_zc(ctx, (char*)value), storage, NULL);
+                value = NULL;
+            } else {
+                ly_type_store_canonized(ctx, options, lydict_insert(ctx, value_len ? value : "", value_len), storage, NULL);
+            }
+        }
+        goto cleanup;
+    }
 
+    if (!(options & LY_TYPE_OPTS_SCHEMA) && (options & LY_TYPE_OPTS_SECOND_CALL) && (options & LY_TYPE_OPTS_STORE)) {
+        /* the second run in data tree, the first one ended with LY_EINCOMPLETE, but we have prepared the target structure */
         if (!lyd_target(storage->target, trees)) {
             /* in error message we print the JSON format of the instance-identifier - in case of XML, it is not possible
              * to get the exactly same string as original, JSON is less demanding and still well readable/understandable. */
@@ -1566,7 +1577,9 @@
         }
         return LY_SUCCESS;
     } else {
-        /* first run without prepared target, we will need all the prefixes used in the instance-identifier value */
+        /* a) first run without prepared target, we will need all the prefixes used in the instance-identifier value
+         * b) second run in schema tree - original value was stored as a canonical value and received now as value
+         */
         prefixes = ly_type_get_prefixes(ctx, value, value_len, resolve_prefix, parser);
     }
 
@@ -1842,9 +1855,15 @@
 
     if (options & LY_TYPE_OPTS_STORE) {
         storage->target = target;
+
+        if ((options & LY_TYPE_OPTS_SCHEMA) && (options & LY_TYPE_OPTS_SECOND_CALL)) {
+            /* remove the dummy canonized value from the first call */
+            lydict_remove(ctx, storage->canonized);
+        }
         storage->canonized = NULL;
     }
 
+cleanup:
     /* cleanup */
     LY_ARRAY_FOR(prefixes, u) {
         lydict_remove(ctx, prefixes[u].prefix);
@@ -1856,7 +1875,7 @@
         free((char*)value);
     }
 
-    if ((options & LY_TYPE_OPTS_INCOMPLETE_DATA) && type_inst->require_instance) {
+    if ((options & LY_TYPE_OPTS_INCOMPLETE_DATA) && ((options & LY_TYPE_OPTS_SCHEMA) || type_inst->require_instance)) {
         return LY_EINCOMPLETE;
     } else {
         return LY_SUCCESS;
@@ -1938,6 +1957,12 @@
     unsigned int u, v;
     char *result = NULL;
 
+    if (!value->target && value->canonized) {
+        /* value was not fully processed, but we have the original value so return it's copy */
+        *dynamic = 1;
+        return strdup(value->canonized);
+    }
+
     if (format == LYD_XML) {
         /* everything is prefixed */
         LY_ARRAY_FOR(value->target, u) {
@@ -2117,7 +2142,7 @@
         return ret;
     }
 
-    if (type_lr->require_instance) {
+    if (!(options & LY_TYPE_OPTS_SCHEMA) && type_lr->require_instance) {
         if (options & LY_TYPE_OPTS_INCOMPLETE_DATA) {
             return LY_EINCOMPLETE;
         }
diff --git a/src/plugins_types.h b/src/plugins_types.h
index 5023b1b..5ee152e 100644
--- a/src/plugins_types.h
+++ b/src/plugins_types.h
@@ -59,8 +59,11 @@
                                             In any case, the caller of the callback does not free the provided string value after calling
                                             the type's callbacks with this option */
 #define LY_TYPE_OPTS_STORE        0x04 /**< Flag announcing calling of ly_type_store_clb() */
-#define LY_TYPE_OPTS_SCHEMA       0x08 /**< Flag for the value used in schema instead of the data tree */
-#define LY_TYPE_OPTS_INCOMPLETE_DATA 0x10 /**< Flag for the case the data trees are not yet complete. In this case the plagin should do what it
+#define LY_TYPE_OPTS_SCHEMA       0x08 /**< Flag for the value used in schema instead of the data tree. With this flag also the meaning of
+                                            LY_TYPE_OPTS_INCOMPLETE_DATA changes and means that the schema tree is not complete (data tree
+                                            is not taken into account at all). */
+#define LY_TYPE_OPTS_INCOMPLETE_DATA 0x10 /**< Flag for the case the data trees (schema trees in case it is used in combination with
+                                            LY_TYPE_OPTS_SCHEMA) are not yet complete. In this case the plugin should do what it
                                             can (e.g. store the canonical/auxiliary value if it is requested) and in the case of need to use
                                             data trees (checking require-instance), it returns LY_EINCOMPLETE.
                                             Caller is supposed to call such validation callback again later with complete data trees. */
@@ -98,7 +101,7 @@
  * @param[in] parser Parser's data for @p resolve_prefix
  * @param[in] format Input format of the data.
  * @param[in] context_node The @p value's node for the case that the require-instance restriction is supposed to be resolved. This argument is of
- *            lys_node (in case LY_TYPE_OPTS_INCOMPLETE_DATA set in @p options) or lyd_node structure.
+ *            lys_node (in case LY_TYPE_OPTS_INCOMPLETE_DATA or LY_TYPE_OPTS_SCHEMA set in @p options) or lyd_node structure.
  * @param[in] trees ([Sized array](@ref sizedarrays)) of external data trees (e.g. when validating RPC/Notification) where the required data
  *            instance can be placed.
  *
diff --git a/src/tree_schema.c b/src/tree_schema.c
index 24e38b3..61ca70e 100644
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -216,8 +216,10 @@
     return NULL;
 }
 
+
+
 API char *
-lysc_path(struct lysc_node *node, LY_PATH_TYPE pathtype)
+lysc_path(struct lysc_node *node, LY_PATH_TYPE pathtype, char *buffer, size_t buflen)
 {
     struct lysc_node *iter;
     char *path = NULL;
@@ -226,7 +228,7 @@
     switch (pathtype) {
     case LY_PATH_LOG:
         for (iter = node; iter && len >= 0; iter = iter->parent) {
-            char *s = path;
+            char *s = buffer ? strdup(buffer) : path;
             char *id;
 
             switch (iter->nodetype) {
@@ -246,13 +248,26 @@
 
             if (!iter->parent || iter->parent->module != iter->module) {
                 /* print prefix */
-                len = asprintf(&path, "/%s:%s%s", iter->module->name, id, s ? s : "");
+                if (buffer) {
+                    len = snprintf(buffer, buflen, "/%s:%s%s", iter->module->name, id, s ? s : "");
+                } else {
+                    len = asprintf(&path, "/%s:%s%s", iter->module->name, id, s ? s : "");
+                }
             } else {
                 /* prefix is the same as in parent */
-                len = asprintf(&path, "/%s%s", id, s ? s : "");
+                if (buffer) {
+                    len = snprintf(buffer, buflen, "/%s%s", id, s ? s : "");
+                } else {
+                    len = asprintf(&path, "/%s%s", id, s ? s : "");
+                }
             }
             free(s);
             free(id);
+
+            if (buffer && buflen <= (size_t)len) {
+                /* not enough space in buffer */
+                break;
+            }
         }
 
         if (len < 0) {
@@ -265,7 +280,11 @@
         break;
     }
 
-    return path;
+    if (buffer) {
+        return buffer;
+    } else {
+        return path;
+    }
 }
 
 API int
diff --git a/src/tree_schema.h b/src/tree_schema.h
index d785d37..e8b3f75 100644
--- a/src/tree_schema.h
+++ b/src/tree_schema.h
@@ -464,7 +464,7 @@
  *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  *      11 LYS_SET_UNITS    | | |x|x| | | | | | | | | | | |
  *                          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *      11 LYS_SET_CONFIG   |x|x|x|x|x|x|x| | |x|x| | | | |
+ *      12 LYS_SET_CONFIG   |x|x|x|x|x|x|x| | |x|x| | | | |
  *     ---------------------+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  *
  */
@@ -1455,10 +1455,13 @@
  *
  * @param[in] node Schema path of this node will be generated.
  * @param[in] pathtype Format of the path to generate.
+ * @param[in,out] buffer Prepared buffer of the @p buflen length to store the generated path.
+ *                If NULL, memory for the complete path is allocated.
+ * @param[in] buflen Size of the provided @p buffer.
  * @return NULL in case of memory allocation error, path of the node otherwise.
- * Returned string is dynamically allocated and caller is responsible to free it.
+ * In case the @p buffer is NULL, the returned string is dynamically allocated and caller is responsible to free it.
  */
-char *lysc_path(struct lysc_node *node, LY_PATH_TYPE pathtype);
+char *lysc_path(struct lysc_node *node, LY_PATH_TYPE pathtype, char *buffer, size_t buflen);
 
 /**
  * @brief Available YANG schema tree structures representing YANG module.
diff --git a/src/tree_schema_compile.c b/src/tree_schema_compile.c
index 38b367b..49f544b 100644
--- a/src/tree_schema_compile.c
+++ b/src/tree_schema_compile.c
@@ -2408,16 +2408,14 @@
     int parent_times = 0, has_predicate;
     unsigned int iter, u;
     LY_ERR ret = LY_SUCCESS;
-    char *logpath;
 
     assert(ctx);
     assert(startnode);
     assert(leafref);
 
-    logpath = lysc_path(startnode, LY_PATH_LOG);
-    strncpy(ctx->path, logpath, LYSC_CTX_BUFSIZE - 1);
-    ctx->path_len = strlen(logpath);
-    free(logpath);
+    ctx->path[0] = '\0';
+    lysc_path(startnode, LY_PATH_LOG, ctx->path, LYSC_CTX_BUFSIZE);
+    ctx->path_len = strlen(ctx->path);
 
     iter = 0;
     id = leafref->path;
@@ -3154,6 +3152,18 @@
                    "Invalid type's default value \"%s\" which does not fit the type (%s).", dflt, err->msg);
             ly_err_free(err);
         }
+        if (ret == LY_EINCOMPLETE) {
+            /* postpone default compilation when the tree is complete */
+            struct lysc_incomplete_dflt *r;
+            r = malloc(sizeof *r);
+            r->context_node = NULL;
+            r->dflt = (*type)->dflt;
+            r->dflt_mod = (*type)->dflt_mod;
+            ly_set_add(&ctx->dflts, r, LY_SET_OPT_USEASLIST);
+
+            /* but in general result is so far ok */
+            ret = LY_SUCCESS;
+        }
         LY_CHECK_GOTO(ret, cleanup);
     }
 
@@ -3525,7 +3535,7 @@
         leaf->dflt->realtype = leaf->type;
         ret = leaf->type->plugin->store(ctx->ctx, leaf->type, leaf_p->dflt, strlen(leaf_p->dflt),
                                         LY_TYPE_OPTS_INCOMPLETE_DATA | LY_TYPE_OPTS_SCHEMA | LY_TYPE_OPTS_STORE,
-                                        lys_resolve_prefix, (void*)leaf->dflt_mod, LYD_XML, NULL, NULL, leaf->dflt, NULL, &err);
+                                        lys_resolve_prefix, (void*)leaf->dflt_mod, LYD_XML, node, NULL, leaf->dflt, NULL, &err);
         leaf->dflt->realtype->refcount++;
         if (err) {
             ly_err_print(err);
@@ -3534,7 +3544,15 @@
             ly_err_free(err);
         }
         if (ret == LY_EINCOMPLETE) {
-            /* expected for some types with incomplete data */
+            /* postpone default compilation when the tree is complete */
+            struct lysc_incomplete_dflt *r;
+            r = malloc(sizeof *r);
+            r->context_node = node;
+            r->dflt = leaf->dflt;
+            r->dflt_mod = leaf->dflt_mod;
+            ly_set_add(&ctx->dflts, r, LY_SET_OPT_USEASLIST);
+
+            /* but in general result is so far ok */
             ret = LY_SUCCESS;
         }
         LY_CHECK_GOTO(ret, done);
@@ -3584,7 +3602,7 @@
             llist->dflts[u]->realtype = llist->type;
             ret = llist->type->plugin->store(ctx->ctx, llist->type, llist_p->dflts[u], strlen(llist_p->dflts[u]),
                                              LY_TYPE_OPTS_INCOMPLETE_DATA | LY_TYPE_OPTS_SCHEMA | LY_TYPE_OPTS_STORE,
-                                             lys_resolve_prefix, (void*)llist->dflts_mods[u], LYD_XML, NULL, NULL, llist->dflts[u], NULL, &err);
+                                             lys_resolve_prefix, (void*)llist->dflts_mods[u], LYD_XML, node, NULL, llist->dflts[u], NULL, &err);
             llist->dflts[u]->realtype->refcount++;
             if (err) {
                 ly_err_print(err);
@@ -3592,6 +3610,18 @@
                        "Invalid leaf-lists's default value \"%s\" which does not fit the type (%s).", llist_p->dflts[u], err->msg);
                 ly_err_free(err);
             }
+            if (ret == LY_EINCOMPLETE) {
+                /* postpone default compilation when the tree is complete */
+                struct lysc_incomplete_dflt *r;
+                r = malloc(sizeof *r);
+                r->context_node = node;
+                r->dflt = llist->dflts[u];
+                r->dflt_mod = llist->dflts_mods[u];
+                ly_set_add(&ctx->dflts, r, LY_SET_OPT_USEASLIST);
+
+                /* but in general result is so far ok */
+                ret = LY_SUCCESS;
+            }
             LY_CHECK_GOTO(ret, done);
         }
         llist->flags |= LYS_SET_DFLT;
@@ -4774,7 +4804,7 @@
                 leaf->dflt_mod = ctx->mod_def;
                 rc = leaf->type->plugin->store(ctx->ctx, leaf->type, rfn->dflts[0], strlen(rfn->dflts[0]),
                                                 LY_TYPE_OPTS_INCOMPLETE_DATA | LY_TYPE_OPTS_SCHEMA | LY_TYPE_OPTS_STORE,
-                                                lys_resolve_prefix, (void*)leaf->dflt_mod, LYD_XML, NULL, NULL, leaf->dflt, NULL, &err);
+                                                lys_resolve_prefix, (void*)leaf->dflt_mod, LYD_XML, node, NULL, leaf->dflt, NULL, &err);
                 leaf->dflt->realtype->refcount++;
                 if (err) {
                     ly_err_print(err);
@@ -4782,6 +4812,18 @@
                            "Invalid refine of default - value \"%s\" does not fit the type (%s).", rfn->dflts[0], err->msg);
                     ly_err_free(err);
                 }
+                if (rc == LY_EINCOMPLETE) {
+                    /* postpone default compilation when the tree is complete */
+                    struct lysc_incomplete_dflt *r;
+                    r = malloc(sizeof *r);
+                    r->context_node = node;
+                    r->dflt = leaf->dflt;
+                    r->dflt_mod = leaf->dflt_mod;
+                    ly_set_add(&ctx->dflts, r, LY_SET_OPT_USEASLIST);
+
+                    /* but in general result is so far ok */
+                    rc = LY_SUCCESS;
+                }
                 LY_CHECK_GOTO(rc, cleanup);
                 leaf->flags |= LYS_SET_DFLT;
             } else if (node->nodetype == LYS_LEAFLIST) {
@@ -4814,9 +4856,9 @@
                     LY_ARRAY_INCREMENT(llist->dflts);
                     llist->dflts[u] = calloc(1, sizeof *llist->dflts[u]);
                     llist->dflts[u]->realtype = llist->type;
-                    ret = llist->type->plugin->store(ctx->ctx, llist->type, rfn->dflts[u], strlen(rfn->dflts[u]),
+                    rc = llist->type->plugin->store(ctx->ctx, llist->type, rfn->dflts[u], strlen(rfn->dflts[u]),
                                                      LY_TYPE_OPTS_INCOMPLETE_DATA | LY_TYPE_OPTS_SCHEMA | LY_TYPE_OPTS_STORE,
-                                                     lys_resolve_prefix, (void*)llist->dflts_mods[u], LYD_XML, NULL, NULL, llist->dflts[u], NULL, &err);
+                                                     lys_resolve_prefix, (void*)llist->dflts_mods[u], LYD_XML, node, NULL, llist->dflts[u], NULL, &err);
                     llist->dflts[u]->realtype->refcount++;
                     if (err) {
                         ly_err_print(err);
@@ -4824,7 +4866,19 @@
                                "Invalid refine of default in leaf-lists -  value \"%s\" does not fit the type (%s).", rfn->dflts[u], err->msg);
                         ly_err_free(err);
                     }
-                    LY_CHECK_GOTO(ret, cleanup);
+                    if (rc == LY_EINCOMPLETE) {
+                        /* postpone default compilation when the tree is complete */
+                        struct lysc_incomplete_dflt *r;
+                        r = malloc(sizeof *r);
+                        r->context_node = node;
+                        r->dflt = llist->dflts[u];
+                        r->dflt_mod = llist->dflts_mods[u];
+                        ly_set_add(&ctx->dflts, r, LY_SET_OPT_USEASLIST);
+
+                        /* but in general result is so far ok */
+                        rc = LY_SUCCESS;
+                    }
+                    LY_CHECK_GOTO(rc, cleanup);
                 }
                 llist->flags |= LYS_SET_DFLT;
             } else if (node->nodetype == LYS_CHOICE) {
@@ -5757,8 +5811,8 @@
                             llist->dflts[x] = calloc(1, sizeof *llist->dflts[x]);
                             llist->dflts[x]->realtype = llist->type;
                             rc = llist->type->plugin->store(ctx->ctx, llist->type, d_add->dflts[x - y], strlen(d_add->dflts[x - y]),
-                                                             LY_TYPE_OPTS_INCOMPLETE_DATA | LY_TYPE_OPTS_SCHEMA | LY_TYPE_OPTS_STORE,
-                                                             lys_resolve_prefix, (void*)llist->dflts_mods[x], LYD_XML, NULL, NULL, llist->dflts[x], NULL, &err);
+                                                            LY_TYPE_OPTS_SCHEMA | LY_TYPE_OPTS_STORE, lys_resolve_prefix,
+                                                            (void*)llist->dflts_mods[x], LYD_XML, devs[u]->target, NULL, llist->dflts[x], NULL, &err);
                             llist->dflts[x]->realtype->refcount++;
                             if (err) {
                                 ly_err_print(err);
@@ -6224,9 +6278,8 @@
             /* parse added/changed default value after possible change of the type */
             leaf->dflt_mod = ctx->mod_def;
             leaf->dflt->realtype = leaf->type;
-            rc = leaf->type->plugin->store(ctx->ctx, leaf->type, dflt, strlen(dflt),
-                                            LY_TYPE_OPTS_INCOMPLETE_DATA | LY_TYPE_OPTS_SCHEMA | LY_TYPE_OPTS_STORE,
-                                            lys_resolve_prefix, (void*)leaf->dflt_mod, LYD_XML, NULL, NULL, leaf->dflt, NULL, &err);
+            rc = leaf->type->plugin->store(ctx->ctx, leaf->type, dflt, strlen(dflt), LY_TYPE_OPTS_SCHEMA | LY_TYPE_OPTS_STORE,
+                                           lys_resolve_prefix, (void*)leaf->dflt_mod, LYD_XML, devs[u]->target, NULL, leaf->dflt, NULL, &err);
             leaf->dflt->realtype->refcount++;
             if (err) {
                 ly_err_print(err);
@@ -6243,9 +6296,8 @@
                 leaf->dflt->realtype->plugin->free(ctx->ctx, leaf->dflt);
                 lysc_type_free(ctx->ctx, leaf->dflt->realtype);
                 leaf->dflt->realtype = leaf->type;
-                rc = leaf->type->plugin->store(ctx->ctx, leaf->type, dflt, strlen(dflt),
-                                               LY_TYPE_OPTS_INCOMPLETE_DATA | LY_TYPE_OPTS_SCHEMA | LY_TYPE_OPTS_STORE,
-                                               lys_resolve_prefix, (void*)leaf->dflt_mod, LYD_XML, NULL, NULL, leaf->dflt, NULL, &err);
+                rc = leaf->type->plugin->store(ctx->ctx, leaf->type, dflt, strlen(dflt), LY_TYPE_OPTS_SCHEMA | LY_TYPE_OPTS_STORE,
+                                               lys_resolve_prefix, (void*)leaf->dflt_mod, LYD_XML, devs[u]->target, NULL, leaf->dflt, NULL, &err);
                 leaf->dflt->realtype->refcount++;
                 if (err) {
                     ly_err_print(err);
@@ -6264,9 +6316,9 @@
                     llist->dflts[x]->realtype->plugin->free(ctx->ctx, llist->dflts[x]);
                     lysc_type_free(ctx->ctx, llist->dflts[x]->realtype);
                     llist->dflts[x]->realtype = llist->type;
-                    rc = llist->type->plugin->store(ctx->ctx, llist->type, dflt, strlen(dflt),
-                                                    LY_TYPE_OPTS_INCOMPLETE_DATA | LY_TYPE_OPTS_SCHEMA | LY_TYPE_OPTS_STORE,
-                                                    lys_resolve_prefix, (void*)llist->dflts_mods[x], LYD_XML, NULL, NULL, llist->dflts[x], NULL, &err);
+                    rc = llist->type->plugin->store(ctx->ctx, llist->type, dflt, strlen(dflt), LY_TYPE_OPTS_SCHEMA | LY_TYPE_OPTS_STORE,
+                                                    lys_resolve_prefix, (void*)llist->dflts_mods[x], LYD_XML, devs[u]->target, NULL,
+                                                    llist->dflts[x], NULL, &err);
                     llist->dflts[x]->realtype->refcount++;
                     if (err) {
                         ly_err_print(err);
@@ -6451,6 +6503,24 @@
         LY_CHECK_GOTO(ret, error);
     }
 
+    /* finish incomplete default values compilation */
+    for (u = 0; u < ctx.dflts.count; ++u) {
+        struct ly_err_item *err = NULL;
+        struct lysc_incomplete_dflt *r = ctx.dflts.objs[u];
+        ret = r->dflt->realtype->plugin->store(ctx.ctx, r->dflt->realtype, r->dflt->canonized, strlen(r->dflt->canonized),
+                                               LY_TYPE_OPTS_SCHEMA | LY_TYPE_OPTS_STORE | LY_TYPE_OPTS_SECOND_CALL, lys_resolve_prefix,
+                                               (void*)r->dflt_mod, LYD_XML, r->context_node, NULL, r->dflt, NULL, &err);
+        if (err) {
+            ly_err_print(err);
+            ctx.path[0] = '\0';
+            lysc_path(r->context_node, LY_PATH_LOG, ctx.path, LYSC_CTX_BUFSIZE);
+            LOGVAL(ctx.ctx, LY_VLOG_STR, ctx.path, LYVE_SEMANTICS,
+                   "Invalid default - value does not fit the type (%s).", err->msg);
+            ly_err_free(err);
+        }
+        LY_CHECK_GOTO(ret, error);
+    }
+
     /* deviations */
     ret = lys_compile_deviations(&ctx, sp);
     LY_CHECK_GOTO(ret, error);
@@ -6520,6 +6590,7 @@
         }
     }
 
+    ly_set_erase(&ctx.dflts, free);
     ly_set_erase(&ctx.unres, NULL);
     ly_set_erase(&ctx.groupings, NULL);
     ly_set_erase(&ctx.tpdf_chain, NULL);
@@ -6545,6 +6616,7 @@
 
 error:
     lys_feature_precompile_revert(&ctx, mod);
+    ly_set_erase(&ctx.dflts, free);
     ly_set_erase(&ctx.unres, NULL);
     ly_set_erase(&ctx.groupings, NULL);
     ly_set_erase(&ctx.tpdf_chain, NULL);
diff --git a/src/tree_schema_internal.h b/src/tree_schema_internal.h
index e928a76..9069361 100644
--- a/src/tree_schema_internal.h
+++ b/src/tree_schema_internal.h
@@ -60,6 +60,12 @@
     uint8_t mod_version; /**< module's version */
 };
 
+struct lysc_incomplete_dflt {
+    struct lyd_value *dflt;
+    struct lys_module *dflt_mod;
+    struct lysc_node *context_node;
+};
+
 /**
  * @brief internal context for compilation
  */
@@ -72,6 +78,7 @@
                                      the target module (mod) */
     struct ly_set groupings;    /**< stack for groupings circular check */
     struct ly_set unres;        /**< to validate leafref's target and xpath of when/must */
+    struct ly_set dflts;        /**< set of incomplete default values */
     struct ly_set tpdf_chain;
     uint16_t path_len;
     int options;                /**< various @ref scflags. */