2
3
4
5
6
7
8
9#include <nlohmann/json-schema.hpp>
25#ifdef JSON_SCHEMA_BOOST_REGEX
26# include <boost/regex.hpp>
27# define REGEX_NAMESPACE boost
28#elif defined(JSON_SCHEMA_NO_REGEX)
32# define REGEX_NAMESPACE std
46 std::shared_ptr<::
schema> & ,
71 const std::vector<std::string> &key,
77 const std::string
id_;
89 e
.error(ptr
, instance
, "unresolved or freed schema-reference " +
id_);
101 e
.error(ptr
, instance
, "unresolved or freed schema-reference " +
id_);
108 std::shared_ptr<::
schema> &sch,
111 nlohmann::json &default_value)
const override
125 const std::string &
id()
const {
return id_; }
161 auto file =
files_.lower_bound(loc);
162 if (file !=
files_.end() && !(
files_.key_comp()(loc, file->first)))
165 return files_.insert(file, {loc, {}})->second;
187 throw std::invalid_argument(
"schema with " + uri
.to_string() +
" already inserted");
208 auto unresolved = file
.unresolved.find(fragment.to_string());
219 std::deque<std::string> ref_tokens;
221 while (!uri_pointer.empty()) {
222 ref_tokens.push_front(uri_pointer.back());
223 uri_pointer.pop_back();
228 for (
auto &rt : ref_tokens) {
230 json::json_pointer rt_ptr{
"/" + rt};
231 if (unk_kw->contains(rt_ptr) ==
false)
232 (*unk_kw)[rt] = json::object();
233 unk_kw = &(*unk_kw)[rt_ptr];
235 (*unk_kw)[key] = value;
239 if (value.type() == json::value_t::object)
240 for (
auto &subsch : value.items())
259 if (contains_pointer) {
287 bool new_schema_loaded =
false;
290 std::vector<std::string> locations;
292 locations.push_back(file.first);
294 for (
auto &loc : locations) {
302 new_schema_loaded =
true;
304 throw std::invalid_argument(
"external schema reference '" + loc +
"' needs loading, but no loader callback given");
309 if (!new_schema_loaded)
313 for (
const auto &file :
files_) {
318 std::string urefs =
"[";
320 decltype(n_urefs) counter = 0;
324 if (counter != n_urefs - 1u) {
333 throw std::invalid_argument(
"after all files have been parsed, '" +
334 (file.first ==
"" ?
"<root>" : file.first) +
335 "' has still the following undefined references: " + urefs);
341 const json &instance,
347 e
.error(ptr
, "", "no root schema has yet been set for validating an instance");
352 if (file_entry ==
files_.end()) {
357 auto &file = file_entry->second;
382 void error(
const json::json_pointer &ptr,
const json &instance,
const std::string &message)
override
405 e
.error(ptr
, instance
, "the subschema has succeeded, but it is required to not validate");
440 void error(
const json::json_pointer &ptr,
const json &instance,
const std::string &message)
override
464 for (std::size_t index = 0; index <
subschemata_.size(); ++index) {
473 esub
.propagate(error_summary
, "case#" + std::to_string(index) +
"] ");
481 e
.error(ptr
, instance
, "no subschema has succeeded, but one of them is required to validate. Type: " +
key +
", number of failed subschemas: " + std::to_string(
subschemata_.size())
);
487 static const std::string
key;
497 for (
auto &subschema : sch)
517 esub
.propagate(e
, "[combination: allOf / case#" + std::to_string(current_schema_index) +
"] ");
532 e
.error(ptr
, instance
, "more than one subschema has succeeded, but exactly one of them is required to validate");
546 std::set<std::string> &);
553 auto type =
type_[
static_cast<uint8_t>(instance.type())];
558 e
.error(ptr
, instance
, "unexpected instance type");
561 bool seen_in_enum =
false;
562 for (
auto &v :
enum_.second)
569 e
.error(ptr
, instance
, "instance not found in required enum");
573 const_.second != instance)
591 if (instance.is_null()) {
598 std::shared_ptr<::
schema> & ,
601 nlohmann::json &default_value)
const override
603 auto result = std::make_shared<
type_schema>(*
this);
612 :
schema(root
),
type_(
static_cast<uint8_t>(json::value_t::discarded) + 1)
615 static const std::vector<std::pair<std::string, json::value_t>> schema_types = {
616 {
"null", json::value_t::null},
617 {
"object", json::value_t::object},
618 {
"array", json::value_t::array},
619 {
"string", json::value_t::string},
620 {
"boolean", json::value_t::boolean},
621 {
"integer", json::value_t::number_integer},
622 {
"number", json::value_t::number_float},
625 std::set<std::string> known_keywords;
627 auto attr = sch.find(
"type");
628 if (attr == sch.end())
629 for (
auto &t : schema_types)
632 switch (attr.value().type()) {
634 case json::value_t::string: {
635 auto schema_type = attr.value().get<std::string>();
636 for (
auto &t : schema_types)
637 if (t.first == schema_type)
641 case json::value_t::array:
642 for (
auto &array_value : attr.value()) {
643 auto schema_type = array_value.get<std::string>();
644 for (
auto &t : schema_types)
645 if (t.first == schema_type)
657 attr = sch.find(
"default");
658 if (attr != sch.end()) {
663 for (
auto &key : known_keywords)
668 if (
type_[
static_cast<uint8_t>(json::value_t::number_float)] && !
type_[
static_cast<uint8_t>(json::value_t::number_integer)])
669 type_[
static_cast<uint8_t>(json::value_t::number_integer)] =
type_[
static_cast<uint8_t>(json::value_t::number_float)];
673 type_[
static_cast<uint8_t>(json::value_t::number_unsigned)] =
type_[
static_cast<uint8_t>(json::value_t::number_integer)];
676 if (
type_[
static_cast<uint8_t>(json::value_t::string)]) {
677 type_[
static_cast<uint8_t>(json::value_t::binary)] =
type_[
static_cast<uint8_t>(json::value_t::string)];
680 attr = sch.find(
"enum");
681 if (attr != sch.end()) {
682 enum_ = {
true, attr.value()};
686 attr = sch.find(
"const");
687 if (attr != sch.end()) {
688 const_ = {
true, attr.value()};
692 attr = sch.find(
"not");
693 if (attr != sch.end()) {
698 attr = sch.find(
"allOf");
699 if (attr != sch.end()) {
704 attr = sch.find(
"anyOf");
705 if (attr != sch.end()) {
710 attr = sch.find(
"oneOf");
711 if (attr != sch.end()) {
716 attr = sch.find(
"if");
717 if (attr != sch.end()) {
718 auto attr_then = sch.find(
"then");
719 auto attr_else = sch.find(
"else");
721 if (attr_then != sch.end() || attr_else != sch.end()) {
724 if (attr_then != sch.end()) {
726 sch.erase(attr_then);
729 if (attr_else != sch.end()) {
731 sch.erase(attr_else);
750 std::tuple<
bool, std::string, std::string>
content_{
false,
"",
""};
756 if ((c & 0xc0) != 0x80)
765 std::ostringstream s;
766 s <<
"instance is too short as per minLength:" <<
minLength_.second;
773 std::ostringstream s;
774 s <<
"instance is too long as per maxLength: " <<
maxLength_.second;
781 e
.error(ptr
, instance
, std::string(
"a content checker was not provided but a contentEncoding or contentMediaType for this string have been present: '") + std::get<1>(
content_) +
"' '" + std::get<2>(
content_) +
"'");
785 }
catch (
const std::exception &ex) {
786 e
.error(ptr
, instance
, std::string(
"content-checking failed: ") + ex.what()
);
789 }
else if (instance.type() == json::value_t::binary) {
790 e
.error(ptr
, instance
, "expected string, but get binary data");
793 if (instance.type() != json::value_t::string) {
805 e
.error(ptr
, instance
, std::string(
"a format checker was not provided but a format keyword for this string is present: ") +
format_.second
);
809 }
catch (
const std::exception &ex) {
810 e
.error(ptr
, instance
, std::string(
"format-checking failed: ") + ex.what()
);
820 auto attr = sch.find(
"maxLength");
821 if (attr != sch.end()) {
822 maxLength_ = {
true, attr.value().get<size_t>()};
826 attr = sch.find(
"minLength");
827 if (attr != sch.end()) {
828 minLength_ = {
true, attr.value().get<size_t>()};
832 attr = sch.find(
"contentEncoding");
833 if (attr != sch.end()) {
835 std::get<1>(
content_) = attr.value().get<std::string>();
851 attr = sch.find(
"contentMediaType");
852 if (attr != sch.end()) {
854 std::get<2>(
content_) = attr.value().get<std::string>();
860 throw std::invalid_argument{
"schema contains contentEncoding/contentMediaType but content checker was not set"};
864 attr = sch.find(
"pattern");
865 if (attr != sch.end()) {
873 attr = sch.find(
"format");
874 if (attr != sch.end()) {
876 throw std::invalid_argument{
"a format checker was not provided but a format keyword for this string is present: " +
format_.second};
878 format_ = {
true, attr.value().get<std::string>()};
898 double res = std::remainder(x,
multipleOf_.second);
899 double multiple = std::fabs(
static_cast<
double>(x) /
multipleOf_.second);
901 res = res / multiple;
903 double eps = std::nextafter(x, 0) -
static_cast<
double>(x);
905 return std::fabs(res) > std::fabs(eps);
912 std::ostringstream oss;
916 oss <<
"instance is not a multiple of " << json(
multipleOf_.second);
920 oss <<
"instance exceeds or equals maximum of " << json(
maximum_.second);
922 oss <<
"instance exceeds maximum of " << json(
maximum_.second);
927 oss <<
"instance is below or equals minimum of " << json(
minimum_.second);
929 oss <<
"instance is below minimum of " << json(
minimum_.second);
932 oss.seekp(0, std::ios::end);
933 auto size = oss.tellp();
935 oss.seekp(0, std::ios::beg);
944 auto attr = sch.find(
"maximum");
945 if (attr != sch.end()) {
946 maximum_ = {
true, attr.value().get<T>()};
947 kw.insert(
"maximum");
950 attr = sch.find(
"minimum");
951 if (attr != sch.end()) {
952 minimum_ = {
true, attr.value().get<T>()};
953 kw.insert(
"minimum");
956 attr = sch.find(
"exclusiveMaximum");
957 if (attr != sch.end()) {
959 maximum_ = {
true, attr.value().get<T>()};
960 kw.insert(
"exclusiveMaximum");
963 attr = sch.find(
"exclusiveMinimum");
964 if (attr != sch.end()) {
966 minimum_ = {
true, attr.value().get<T>()};
967 kw.insert(
"exclusiveMinimum");
970 attr = sch.find(
"multipleOf");
971 if (attr != sch.end()) {
972 multipleOf_ = {
true, attr.value().get<json::number_float_t>()};
973 kw.insert(
"multipleOf");
982 if (!instance.is_null())
983 e
.error(ptr
, instance
, "expected to be null");
1014 e
.error(ptr
, instance
, "instance invalid as per false-schema");
1030 if (instance.find(r) == instance.end())
1031 e
.error(ptr
, instance
, "required property '" + r +
"' not found in object as a dependency");
1058 e
.error(ptr
, instance
, "too many properties");
1061 e
.error(ptr
, instance
, "too few properties");
1064 if (instance.find(r) == instance.end())
1065 e
.error(ptr
, instance
, "required property '" + r +
"' not found in object");
1068 for (
auto &p : instance.items()) {
1072 bool a_prop_or_pattern_matched =
false;
1076 a_prop_or_pattern_matched =
true;
1077 schema_p->second->
validate(ptr / p.key()
, p.value()
, patch
, e
);
1084 a_prop_or_pattern_matched =
true;
1085 schema_pp.second->
validate(ptr / p.key()
, p.value()
, patch
, e
);
1093 if (additional_prop_err)
1094 e
.error(ptr
, instance
, "validation failed for additional property '" + p.key() +
"': " + additional_prop_err
.message_);
1100 const auto finding = instance.find(prop.first);
1101 if (instance.end() == finding) {
1103 if (!default_value.is_null()) {
1104 patch
.add((ptr / prop.first)
, default_value
);
1110 auto prop = instance.find(dep.first);
1111 if (prop != instance.end())
1122 auto attr = sch.find(
"maxProperties");
1123 if (attr != sch.end()) {
1128 attr = sch.find(
"minProperties");
1129 if (attr != sch.end()) {
1134 attr = sch.find(
"required");
1135 if (attr != sch.end()) {
1136 required_ = attr.value().get<std::vector<std::string>>();
1140 attr = sch.find(
"properties");
1141 if (attr != sch.end()) {
1142 for (
auto prop : attr.value().items())
1151 attr = sch.find(
"patternProperties");
1152 if (attr != sch.end()) {
1153 for (
auto prop : attr.value().items())
1162 attr = sch.find(
"additionalProperties");
1163 if (attr != sch.end()) {
1168 attr = sch.find(
"dependencies");
1169 if (attr != sch.end()) {
1170 for (
auto &dep : attr.value().items())
1171 switch (dep.value().type()) {
1172 case json::value_t::array:
1175 dep.value().get<std::vector<std::string>>(), root));
1186 attr = sch.find(
"propertyNames");
1187 if (attr != sch.end()) {
1192 attr = sch.find(
"default");
1193 if (attr != sch.end()) {
1215 e
.error(ptr
, instance
, "array has too many items");
1218 e
.error(ptr
, instance
, "array has too few items");
1221 for (
auto it = instance.cbegin(); it != instance.cend(); ++it) {
1222 auto v = std::find(it + 1, instance.end(), *it);
1223 if (v != instance.end())
1224 e
.error(ptr
, instance
, "items have to be unique for this array");
1230 for (
auto &i : instance) {
1235 auto item =
items_.cbegin();
1236 for (
auto &i : instance) {
1237 std::shared_ptr<
schema> item_validator;
1238 if (item ==
items_.cend())
1241 item_validator = *item;
1245 if (!item_validator)
1253 bool contained =
false;
1254 for (
auto &item : instance) {
1263 e
.error(ptr
, instance
, "array does not contain required element as per 'contains'");
1271 auto attr = sch.find(
"maxItems");
1272 if (attr != sch.end()) {
1273 maxItems_ = {
true, attr.value().get<size_t>()};
1277 attr = sch.find(
"minItems");
1278 if (attr != sch.end()) {
1279 minItems_ = {
true, attr.value().get<size_t>()};
1283 attr = sch.find(
"uniqueItems");
1284 if (attr != sch.end()) {
1289 attr = sch.find(
"items");
1290 if (attr != sch.end()) {
1292 if (attr.value().type() == json::value_t::array) {
1294 for (
auto &subsch : attr.value())
1297 auto attr_add = sch.find(
"additionalItems");
1298 if (attr_add != sch.end()) {
1300 sch.erase(attr_add);
1303 }
else if (attr.value().type() == json::value_t::object ||
1304 attr.value().type() == json::value_t::boolean)
1310 attr = sch.find(
"contains");
1311 if (attr != sch.end()) {
1322 std::set<std::string> &kw)
1325 case json::value_t::null:
1326 return std::make_shared<
null>(schema, root);
1328 case json::value_t::number_unsigned:
1329 case json::value_t::number_integer:
1330 return std::make_shared<
numeric<json::number_integer_t>>(schema, root, kw);
1331 case json::value_t::number_float:
1332 return std::make_shared<
numeric<json::number_float_t>>(schema, root, kw);
1333 case json::value_t::string:
1334 return std::make_shared<
string>(schema, root);
1335 case json::value_t::boolean:
1337 case json::value_t::object:
1338 return std::make_shared<
object>(schema, root, uris);
1339 case json::value_t::array:
1340 return std::make_shared<
array>(schema, root, uris);
1342 case json::value_t::discarded:
1345 case json::value_t::binary:
1357 const std::vector<std::string> &keys,
1361 for (
auto uri = uris.begin(); uri != uris.end();)
1362 if (uri->identifier() !=
"")
1363 uri = uris.erase(uri);
1368 for (
auto &key : keys)
1369 for (
auto &uri : uris)
1372 std::shared_ptr<::
schema> sch;
1375 if (schema.type() == json::value_t::boolean)
1376 sch = std::make_shared<
boolean>(schema, root);
1377 else if (schema.type() == json::value_t::object) {
1379 auto attr = schema.find(
"$id");
1381 if (attr != schema.end()) {
1382 if (std::find(uris.begin(),
1384 attr.value().get<std::string>()) == uris.end())
1385 uris.push_back(uris.back()
.derive(attr.value().get<std::string>()
));
1389 auto findDefinitions = [&](
const std::string &defs) ->
bool {
1390 attr = schema.find(defs);
1391 if (attr != schema.end()) {
1392 for (
auto &def : attr.value().items())
1399 if (!findDefinitions(
"$defs")) {
1400 findDefinitions(
"definitions");
1403 attr = schema.find(
"$ref");
1404 if (attr != schema.end()) {
1407 auto id = uris.back()
.derive(attr.value().get<std::string>()
);
1413 attr = schema.find(
"default");
1414 if (attr != schema.end()) {
1422 sch = std::make_shared<
type_schema>(schema, root, uris);
1425 schema.erase(
"$schema");
1426 schema.erase(
"title");
1427 schema.erase(
"description");
1429 throw std::invalid_argument(
"invalid JSON-type for a schema for " + uris[0]
.to_string() +
", expected: boolean or object");
1432 for (
auto &uri : uris) {
1435 if (schema.type() == json::value_t::object)
1436 for (
auto &u : schema.items())
1444 void error(
const json::json_pointer &ptr,
const json &instance,
const std::string &message)
override
1446 throw std::invalid_argument(std::string(
"At ") + ptr.to_string() +
" of " + instance.dump() +
" - " + message +
"\n");
1462 std::move(content)
)))
1513 json::json_pointer ptr;
std::shared_ptr< schema > items_schema_
std::shared_ptr< schema > contains_
std::pair< bool, size_t > maxItems_
std::pair< bool, size_t > minItems_
std::shared_ptr< schema > additionalItems_
std::vector< std::shared_ptr< schema > > items_
array(json &sch, root_schema *root, const std::vector< nlohmann::json_uri > &uris)
void validate(const json::json_pointer &ptr, const json &instance, json_patch &patch, error_handler &e) const override
boolean_type(json &, root_schema *root)
void validate(const json::json_pointer &, const json &, json_patch &, error_handler &) const override
void validate(const json::json_pointer &ptr, const json &instance, json_patch &, error_handler &e) const override
boolean(json &sch, root_schema *root)
void error(const json::json_pointer &ptr, const json &instance, const std::string &message) override
std::vector< error_entry > error_entry_list_
void error(const json::json_pointer &ptr, const json &instance, const std::string &message) override
void propagate(error_handler &e, const std::string &prefix) const
static bool is_validate_complete(const json &, const json::json_pointer &, error_handler &, const logical_combination_error_handler &, size_t, size_t)
std::vector< std::shared_ptr< schema > > subschemata_
bool is_validate_complete(const json &instance, const json::json_pointer &ptr, error_handler &e, const logical_combination_error_handler &, size_t count, size_t)
void validate(const json::json_pointer &ptr, const json &instance, json_patch &patch, error_handler &e) const final
bool is_validate_complete(const json &, const json::json_pointer &, error_handler &e, const logical_combination_error_handler &esub, size_t, size_t current_schema_index)
bool is_validate_complete(const json &, const json::json_pointer &, error_handler &, const logical_combination_error_handler &, size_t count, size_t)
static const std::string key
logical_combination(json &sch, root_schema *root, const std::vector< nlohmann::json_uri > &uris)
const json & default_value(const json::json_pointer &ptr, const json &instance, error_handler &e) const override
logical_not(json &sch, root_schema *root, const std::vector< nlohmann::json_uri > &uris)
std::shared_ptr< schema > subschema_
void validate(const json::json_pointer &ptr, const json &instance, json_patch &patch, error_handler &e) const final
void validate(const json::json_pointer &ptr, const json &instance, json_patch &, error_handler &e) const override
null(json &, root_schema *root)
numeric(const json &sch, root_schema *root, std::set< std::string > &kw)
std::pair< bool, T > minimum_
std::pair< bool, T > maximum_
bool violates_multiple_of(T x) const
std::pair< bool, json::number_float_t > multipleOf_
void validate(const json::json_pointer &ptr, const json &instance, json_patch &, error_handler &e) const override
std::map< std::string, std::shared_ptr< schema > > dependencies_
void validate(const json::json_pointer &ptr, const json &instance, json_patch &patch, error_handler &e) const override
object(json &sch, root_schema *root, const std::vector< nlohmann::json_uri > &uris)
std::pair< bool, size_t > minProperties_
std::vector< std::pair< std::regex, std::shared_ptr< schema > > > patternProperties_
std::shared_ptr< schema > additionalProperties_
std::pair< bool, size_t > maxProperties_
std::vector< std::string > required_
std::map< std::string, std::shared_ptr< schema > > properties_
std::shared_ptr< schema > propertyNames_
void validate(const json::json_pointer &ptr, const json &instance, json_patch &, error_handler &e) const override final
required(const std::vector< std::string > &r, root_schema *root)
const std::vector< std::string > required_
const std::string & id() const
std::shared_ptr< schema > target_strong_
const json & default_value(const json::json_pointer &ptr, const json &instance, error_handler &e) const override final
std::weak_ptr< schema > target_
virtual std::shared_ptr< schema > make_for_default_(std::shared_ptr<::schema > &sch, root_schema *root, std::vector< nlohmann::json_uri > &uris, nlohmann::json &default_value) const override
schema_ref(const std::string &id, root_schema *root)
void validate(const json::json_pointer &ptr, const json &instance, json_patch &patch, error_handler &e) const final
void set_target(const std::shared_ptr< schema > &target, bool strong=false)
virtual ~schema()=default
virtual void validate(const json::json_pointer &ptr, const json &instance, json_patch &patch, error_handler &e) const =0
virtual const json & default_value(const json::json_pointer &, const json &, error_handler &) const
void set_default_value(const json &v)
virtual std::shared_ptr< schema > make_for_default_(std::shared_ptr<::schema > &, root_schema *, std::vector< nlohmann::json_uri > &, nlohmann::json &) const
static std::shared_ptr< schema > make(json &schema, root_schema *root, const std::vector< std::string > &key, std::vector< nlohmann::json_uri > uris)
schema(root_schema *root)
void validate(const json::json_pointer &ptr, const json &instance, json_patch &, error_handler &e) const override
std::pair< bool, std::regex > pattern_
std::pair< bool, size_t > maxLength_
std::pair< bool, std::string > format_
string(json &sch, root_schema *root)
std::string patternString_
std::tuple< bool, std::string, std::string > content_
std::pair< bool, size_t > minLength_
std::size_t utf8_length(const std::string &s) const
void error(const json::json_pointer &ptr, const json &instance, const std::string &message) override
std::vector< std::shared_ptr< schema > > type_
std::shared_ptr< schema > then_
virtual std::shared_ptr< schema > make_for_default_(std::shared_ptr<::schema > &, root_schema *, std::vector< nlohmann::json_uri > &, nlohmann::json &default_value) const override
type_schema(json &sch, root_schema *root, const std::vector< nlohmann::json_uri > &uris)
std::pair< bool, json > enum_
std::pair< bool, json > const_
std::shared_ptr< schema > if_
std::shared_ptr< schema > else_
std::vector< std::shared_ptr< schema > > logic_
static std::shared_ptr< schema > make(json &schema, json::value_t type, root_schema *, const std::vector< nlohmann::json_uri > &, std::set< std::string > &)
void validate(const json::json_pointer &ptr, const json &instance, json_patch &patch, error_handler &e) const override final
json_patch & add(const json::json_pointer &, json value)
virtual void error(const json::json_pointer &, const json &, const std::string &)=0
void set_root_schema(const json &)
void set_root_schema(json &&)
json_validator(json_validator &&)
std::unique_ptr< root_schema > root_
json_validator & operator=(json_validator &&)
json_validator(json &&, schema_loader=nullptr, format_checker=nullptr, content_checker=nullptr)
json_validator(schema_loader=nullptr, format_checker=nullptr, content_checker=nullptr)
json_validator(const json &, schema_loader=nullptr, format_checker=nullptr, content_checker=nullptr)
json validate(const json &, error_handler &, const json_uri &initial_uri=json_uri("#")) const
json validate(const json &) const
void validate(const json::json_pointer &ptr, const json &instance, json_patch &patch, error_handler &e, const json_uri &initial) const
void insert_unknown_keyword(const json_uri &uri, const std::string &key, json &value)
schema_file & get_or_create_file(const std::string &loc)
format_checker & format_check()
void insert(const json_uri &uri, const std::shared_ptr< schema > &s)
root_schema(schema_loader &&loader, format_checker &&format, content_checker &&content)
content_checker & content_check()
std::map< std::string, schema_file > files_
std::shared_ptr< schema > get_or_create_ref(const json_uri &uri)
std::shared_ptr< schema > root_
void set_root_schema(json sch)
content_checker content_check_
format_checker format_check_
std::string fragment() const
std::string to_string() const
std::string location() const
const json::json_pointer & pointer() const
json_uri derive(const std::string &uri) const
json_uri append(const std::string &field) const
const std::string logical_combination< anyOf >::key
logical_combination_types
const std::string logical_combination< allOf >::key
const std::string logical_combination< oneOf >::key
std::function< void(const json_uri &, json &)> schema_loader
std::function< void(const std::string &, const std::string &)> format_checker
std::function< void(const std::string &, const std::string &, const json &)> content_checker
std::map< std::string, std::shared_ptr< schema_ref > > unresolved
std::map< std::string, std::shared_ptr< schema > > schemas