Skip to content

Commit

Permalink
Expose location parents during framing
Browse files Browse the repository at this point in the history
Signed-off-by: Juan Cruz Viotti <[email protected]>
  • Loading branch information
jviotti committed Feb 10, 2025
1 parent d6470ad commit 057aa4c
Show file tree
Hide file tree
Showing 13 changed files with 1,353 additions and 1,255 deletions.
52 changes: 33 additions & 19 deletions src/core/jsonschema/frame.cc
Original file line number Diff line number Diff line change
Expand Up @@ -226,14 +226,16 @@ store(sourcemeta::core::SchemaFrame::Locations &frame,
const sourcemeta::core::Pointer &pointer_from_base,
const std::string &dialect, const std::string &base_dialect,
const std::vector<sourcemeta::core::PointerTemplate> &instance_locations,
const std::optional<sourcemeta::core::Pointer> &parent,
const bool ignore_if_present = false) -> void {
assert(std::set<sourcemeta::core::PointerTemplate>(
instance_locations.cbegin(), instance_locations.cend())
.size() == instance_locations.size());
const auto canonical{sourcemeta::core::URI{uri}.canonicalize().recompose()};
const auto inserted{frame
.insert({{type, canonical},
{entry_type,
{parent,
entry_type,
root_id,
base_id,
pointer_from_root,
Expand Down Expand Up @@ -284,6 +286,12 @@ static auto traverse_instance_locations(
}
}

struct CacheSubschema {
const sourcemeta::core::PointerTemplate instance_location;
const bool orphan;
const std::optional<sourcemeta::core::Pointer> parent;
};

auto internal_analyse(const sourcemeta::core::JSON &schema,
sourcemeta::core::SchemaFrame::Locations &frame,
sourcemeta::core::SchemaFrame::References &references,
Expand All @@ -294,8 +302,7 @@ auto internal_analyse(const sourcemeta::core::JSON &schema,
using namespace sourcemeta::core;

std::vector<InternalEntry> subschema_entries;
std::map<Pointer, std::pair<sourcemeta::core::PointerTemplate, bool>>
subschemas;
std::map<Pointer, CacheSubschema> subschemas;
std::map<sourcemeta::core::Pointer, std::vector<std::string>> base_uris;
std::map<sourcemeta::core::Pointer, std::vector<std::string>> base_dialects;

Expand Down Expand Up @@ -326,7 +333,7 @@ auto internal_analyse(const sourcemeta::core::JSON &schema,
SchemaFrame::LocationType::Resource, default_id.value(),
root_id.value(), root_id.value(), sourcemeta::core::empty_pointer,
sourcemeta::core::empty_pointer, root_dialect.value(),
root_base_dialect.value(), {{}});
root_base_dialect.value(), {{}}, std::nullopt);
base_uris.insert({sourcemeta::core::empty_pointer, {default_id.value()}});
}

Expand All @@ -346,9 +353,9 @@ auto internal_analyse(const sourcemeta::core::JSON &schema,

// Store information
subschema_entries.emplace_back(InternalEntry{entry, std::move(id)});
subschemas.emplace(entry.pointer,
std::pair<sourcemeta::core::PointerTemplate, bool>{
entry.instance_location, entry.orphan});
subschemas.emplace(
entry.pointer,
CacheSubschema{entry.instance_location, entry.orphan, entry.parent});
}

for (const auto &entry : subschema_entries) {
Expand Down Expand Up @@ -393,15 +400,15 @@ auto internal_analyse(const sourcemeta::core::JSON &schema,
new_id, entry.common.pointer,
sourcemeta::core::empty_pointer,
entry.common.dialect.value(),
entry.common.base_dialect.value(), {});
entry.common.base_dialect.value(), {}, entry.common.parent);
} else {
store(frame, SchemaReferenceType::Static,
SchemaFrame::LocationType::Resource, new_id, root_id,
new_id, entry.common.pointer,
sourcemeta::core::empty_pointer,
entry.common.dialect.value(),
entry.common.base_dialect.value(),
{entry.common.instance_location});
{entry.common.instance_location}, entry.common.parent);
}
}

Expand Down Expand Up @@ -457,7 +464,7 @@ auto internal_analyse(const sourcemeta::core::JSON &schema,
"", entry.common.pointer,
entry.common.pointer.resolve_from(bases.second),
entry.common.dialect.value(), entry.common.base_dialect.value(),
instance_locations);
instance_locations, entry.common.parent);
}

if (type == AnchorType::Dynamic || type == AnchorType::All) {
Expand All @@ -466,7 +473,7 @@ auto internal_analyse(const sourcemeta::core::JSON &schema,
"", entry.common.pointer,
entry.common.pointer.resolve_from(bases.second),
entry.common.dialect.value(), entry.common.base_dialect.value(),
instance_locations);
instance_locations, entry.common.parent);

// Register a dynamic anchor as a static anchor if possible too
if (entry.common.vocabularies.contains(
Expand All @@ -476,7 +483,8 @@ auto internal_analyse(const sourcemeta::core::JSON &schema,
root_id, "", entry.common.pointer,
entry.common.pointer.resolve_from(bases.second),
entry.common.dialect.value(),
entry.common.base_dialect.value(), instance_locations, true);
entry.common.base_dialect.value(), instance_locations,
entry.common.parent, true);
}
}
} else {
Expand Down Expand Up @@ -505,7 +513,8 @@ auto internal_analyse(const sourcemeta::core::JSON &schema,
base_string, entry.common.pointer,
entry.common.pointer.resolve_from(bases.second),
entry.common.dialect.value(),
entry.common.base_dialect.value(), instance_locations);
entry.common.base_dialect.value(), instance_locations,
entry.common.parent);
}

if (type == AnchorType::Dynamic || type == AnchorType::All) {
Expand All @@ -514,7 +523,8 @@ auto internal_analyse(const sourcemeta::core::JSON &schema,
base_string, entry.common.pointer,
entry.common.pointer.resolve_from(bases.second),
entry.common.dialect.value(),
entry.common.base_dialect.value(), instance_locations);
entry.common.base_dialect.value(), instance_locations,
entry.common.parent);

// Register a dynamic anchor as a static anchor if possible too
if (entry.common.vocabularies.contains(
Expand All @@ -525,7 +535,7 @@ auto internal_analyse(const sourcemeta::core::JSON &schema,
entry.common.pointer.resolve_from(bases.second),
entry.common.dialect.value(),
entry.common.base_dialect.value(), instance_locations,
true);
entry.common.parent, true);
}
}

Expand Down Expand Up @@ -573,26 +583,30 @@ auto internal_analyse(const sourcemeta::core::JSON &schema,
const auto subschema{subschemas.find(pointer)};
if (subschema != subschemas.cend()) {
// Handle orphan schemas
if (subschema->second.second) {
if (subschema->second.orphan) {
store(frame, SchemaReferenceType::Static,
SchemaFrame::LocationType::Subschema, result, root_id,
current_base, pointer,
pointer.resolve_from(nearest_bases.second),
dialects.first.front(), current_base_dialect, {});
dialects.first.front(), current_base_dialect, {},
subschema->second.parent);
} else {
store(frame, SchemaReferenceType::Static,
SchemaFrame::LocationType::Subschema, result, root_id,
current_base, pointer,
pointer.resolve_from(nearest_bases.second),
dialects.first.front(), current_base_dialect,
{subschema->second.first});
{subschema->second.instance_location},
subschema->second.parent);
}
} else {
store(frame, SchemaReferenceType::Static,
SchemaFrame::LocationType::Pointer, result, root_id,
current_base, pointer,
pointer.resolve_from(nearest_bases.second),
dialects.first.front(), current_base_dialect, {});
dialects.first.front(), current_base_dialect, {},
// TODO: Get real parent
std::nullopt);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ class SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaFrame {

/// A single frame in a JSON Schema reference frame
struct LocationsEntry {
std::optional<Pointer> parent;
LocationType type;
std::optional<std::string> root;
std::string base;
Expand Down
Loading

0 comments on commit 057aa4c

Please sign in to comment.