|
@@ -31,28 +31,12 @@ public:
|
|
|
ReferenceManager(DocumentCache<A> & external, A const & root, schema::Version version,
|
|
ReferenceManager(DocumentCache<A> & external, A const & root, schema::Version version,
|
|
|
Keywords const & keywords)
|
|
Keywords const & keywords)
|
|
|
: external_(external), roots_{{{}, root}} {
|
|
: external_(external), roots_{{{}, root}} {
|
|
|
- prime_impl(root, {}, version, keywords);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- bool has_dynamic_anchor(detail::RootReference const & root) const {
|
|
|
|
|
- for (auto [it, end] = dynamic_anchors_.equal_range(root.uri()); it != end; ++it) {
|
|
|
|
|
- if (it->second == root.anchor()) {
|
|
|
|
|
- return true;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- std::optional<A> root(detail::RootReference const & root) const {
|
|
|
|
|
- if (auto it = roots_.find(root); it != roots_.end()) {
|
|
|
|
|
- return it->second;
|
|
|
|
|
- }
|
|
|
|
|
- return std::nullopt;
|
|
|
|
|
|
|
+ prime(root, {}, version, keywords);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
std::optional<A> load(detail::Reference const & ref, detail::ParserContext<A> const & context) {
|
|
std::optional<A> load(detail::Reference const & ref, detail::ParserContext<A> const & context) {
|
|
|
- if (std::optional<A> in_cache = root(ref.root())) {
|
|
|
|
|
- return ref.pointer().walk(*in_cache);
|
|
|
|
|
|
|
+ if (auto it = roots_.find(ref.root()); it != roots_.end()) {
|
|
|
|
|
+ return ref.pointer().walk(it->second);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
std::optional<A> external = external_.try_load(ref.uri());
|
|
std::optional<A> external = external_.try_load(ref.uri());
|
|
@@ -61,11 +45,12 @@ public:
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// TODO(samjaffe): Change Versions if needed...
|
|
// TODO(samjaffe): Change Versions if needed...
|
|
|
- prime(*external, ref.uri(), context.version, context.factory.keywords(context.version));
|
|
|
|
|
|
|
+ references_.emplace(ref.uri());
|
|
|
|
|
+ prime(*external, ref, context.version, context.factory.keywords(context.version));
|
|
|
|
|
|
|
|
// May have a sub-id that we map to
|
|
// May have a sub-id that we map to
|
|
|
- if (std::optional<A> in_cache = root(ref.root())) {
|
|
|
|
|
- return ref.pointer().walk(*in_cache);
|
|
|
|
|
|
|
+ if (auto it = roots_.find(ref.root()); it != roots_.end()) {
|
|
|
|
|
+ return ref.pointer().walk(it->second);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Will get called if the external schema does not declare a root document id?
|
|
// Will get called if the external schema does not declare a root document id?
|
|
@@ -110,15 +95,9 @@ public:
|
|
|
return rval;
|
|
return rval;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- void prime(Adapter auto const & json, URI const & where, schema::Version version,
|
|
|
|
|
- Keywords const & keywords) {
|
|
|
|
|
- references_.emplace(where);
|
|
|
|
|
- prime_impl(json, detail::Reference(where), version, keywords);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
private:
|
|
private:
|
|
|
- void prime_impl(Adapter auto const & json, detail::Reference where, schema::Version version,
|
|
|
|
|
- Keywords const & keywords) {
|
|
|
|
|
|
|
+ void prime(Adapter auto const & json, detail::Reference where, schema::Version version,
|
|
|
|
|
+ Keywords const & keywords) {
|
|
|
if (json.type() != adapter::Type::Object) {
|
|
if (json.type() != adapter::Type::Object) {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
@@ -134,16 +113,16 @@ private:
|
|
|
if (vit->second.contains(schema::Wraps::Array) && value.type() == adapter::Type::Array) {
|
|
if (vit->second.contains(schema::Wraps::Array) && value.type() == adapter::Type::Array) {
|
|
|
size_t index = 0;
|
|
size_t index = 0;
|
|
|
for (auto const & elem : value.as_array()) {
|
|
for (auto const & elem : value.as_array()) {
|
|
|
- prime_impl(elem, where / key / index, version, keywords);
|
|
|
|
|
|
|
+ prime(elem, where / key / index, version, keywords);
|
|
|
++index;
|
|
++index;
|
|
|
}
|
|
}
|
|
|
} else if (vit->second.contains(schema::Wraps::Object) &&
|
|
} else if (vit->second.contains(schema::Wraps::Object) &&
|
|
|
value.type() == adapter::Type::Object) {
|
|
value.type() == adapter::Type::Object) {
|
|
|
for (auto const & [prop, elem] : value.as_object()) {
|
|
for (auto const & [prop, elem] : value.as_object()) {
|
|
|
- prime_impl(elem, where / key / prop, version, keywords);
|
|
|
|
|
|
|
+ prime(elem, where / key / prop, version, keywords);
|
|
|
}
|
|
}
|
|
|
} else if (vit->second.contains(schema::Wraps::Schema)) {
|
|
} else if (vit->second.contains(schema::Wraps::Schema)) {
|
|
|
- prime_impl(value, where / key, version, keywords);
|
|
|
|
|
|
|
+ prime(value, where / key, version, keywords);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|