Skip to content

Commit

Permalink
[WIP] Extend SchemaIteratorEntry to report parent schemas
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 34121cd commit 69b76de
Show file tree
Hide file tree
Showing 12 changed files with 490 additions and 393 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ using SchemaWalker = std::function<SchemaWalkerResult(
/// @ingroup jsonschema
/// An entry of a schema iterator.
struct SchemaIteratorEntry {
std::optional<Pointer> parent;
Pointer pointer;
std::optional<std::string> dialect;
std::map<std::string, bool> vocabularies;
Expand Down
112 changes: 65 additions & 47 deletions src/core/jsonschema/walker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
namespace {
enum class SchemaWalkerType_t : std::uint8_t { Deep, Flat };

auto walk(const sourcemeta::core::Pointer &pointer,
auto walk(const std::optional<sourcemeta::core::Pointer> &parent,
const sourcemeta::core::Pointer &pointer,
const sourcemeta::core::PointerTemplate &instance_location,
const sourcemeta::core::PointerTemplate &relative_instance_location,
std::vector<sourcemeta::core::SchemaIteratorEntry> &subschemas,
Expand Down Expand Up @@ -35,14 +36,10 @@ auto walk(const sourcemeta::core::Pointer &pointer,
resolver, base_dialect.value(), new_dialect)};

if (type == SchemaWalkerType_t::Deep || level > 0) {
sourcemeta::core::SchemaIteratorEntry entry{pointer,
new_dialect,
vocabularies,
base_dialect,
subschema,
instance_location,
relative_instance_location,
orphan};
sourcemeta::core::SchemaIteratorEntry entry{
parent, pointer, new_dialect, vocabularies,
base_dialect, subschema, instance_location, relative_instance_location,
orphan};
subschemas.push_back(std::move(entry));
}

Expand All @@ -61,7 +58,8 @@ auto walk(const sourcemeta::core::Pointer &pointer,
auto new_instance_location{instance_location};
new_instance_location.emplace_back(
sourcemeta::core::PointerTemplate::Wildcard::Property);
walk(new_pointer, new_instance_location,
// TODO: Set parent
walk(std::nullopt, new_pointer, new_instance_location,
{sourcemeta::core::PointerTemplate::Wildcard::Property},
subschemas, pair.second, walker, resolver, new_dialect, type,
level + 1, orphan);
Expand All @@ -74,7 +72,8 @@ auto walk(const sourcemeta::core::Pointer &pointer,
auto new_instance_location{instance_location};
new_instance_location.emplace_back(
sourcemeta::core::PointerTemplate::Wildcard::Key);
walk(new_pointer, new_instance_location,
// TODO: Set parent
walk(std::nullopt, new_pointer, new_instance_location,
{sourcemeta::core::PointerTemplate::Wildcard::Key}, subschemas,
pair.second, walker, resolver, new_dialect, type, level + 1,
orphan);
Expand All @@ -87,7 +86,8 @@ auto walk(const sourcemeta::core::Pointer &pointer,
auto new_instance_location{instance_location};
new_instance_location.emplace_back(
sourcemeta::core::PointerTemplate::Wildcard::Item);
walk(new_pointer, new_instance_location,
// TODO: Set parent
walk(std::nullopt, new_pointer, new_instance_location,
{sourcemeta::core::PointerTemplate::Wildcard::Item}, subschemas,
pair.second, walker, resolver, new_dialect, type, level + 1,
orphan);
Expand All @@ -98,17 +98,21 @@ auto walk(const sourcemeta::core::Pointer &pointer,
new_pointer.emplace_back(pair.first);
auto new_instance_location{instance_location};
new_instance_location.pop_back();
walk(new_pointer, new_instance_location, {}, subschemas, pair.second,
walker, resolver, new_dialect, type, level + 1, orphan);
// TODO: Set parent
walk(std::nullopt, new_pointer, new_instance_location, {}, subschemas,
pair.second, walker, resolver, new_dialect, type, level + 1,
orphan);
} break;

case sourcemeta::core::SchemaKeywordType::ApplicatorValueInPlaceOther:
[[fallthrough]];
case sourcemeta::core::SchemaKeywordType::ApplicatorValueInPlace: {
sourcemeta::core::Pointer new_pointer{pointer};
new_pointer.emplace_back(pair.first);
walk(new_pointer, instance_location, {}, subschemas, pair.second,
walker, resolver, new_dialect, type, level + 1, orphan);
// TODO: Set parent
walk(std::nullopt, new_pointer, instance_location, {}, subschemas,
pair.second, walker, resolver, new_dialect, type, level + 1,
orphan);
} break;

case sourcemeta::core::SchemaKeywordType::ApplicatorElementsTraverseItem:
Expand All @@ -119,9 +123,10 @@ auto walk(const sourcemeta::core::Pointer &pointer,
new_pointer.emplace_back(index);
auto new_instance_location{instance_location};
new_instance_location.emplace_back(new_pointer.back());
walk(new_pointer, new_instance_location, {new_pointer.back()},
subschemas, pair.second.at(index), walker, resolver,
new_dialect, type, level + 1, orphan);
// TODO: Set parent
walk(std::nullopt, new_pointer, new_instance_location,
{new_pointer.back()}, subschemas, pair.second.at(index),
walker, resolver, new_dialect, type, level + 1, orphan);
}
}

Expand All @@ -135,7 +140,8 @@ auto walk(const sourcemeta::core::Pointer &pointer,
sourcemeta::core::Pointer new_pointer{pointer};
new_pointer.emplace_back(pair.first);
new_pointer.emplace_back(index);
walk(new_pointer, instance_location, {}, subschemas,
// TODO: Set parent
walk(std::nullopt, new_pointer, instance_location, {}, subschemas,
pair.second.at(index), walker, resolver, new_dialect, type,
level + 1, orphan);
}
Expand All @@ -152,9 +158,10 @@ auto walk(const sourcemeta::core::Pointer &pointer,
new_pointer.emplace_back(subpair.first);
auto new_instance_location{instance_location};
new_instance_location.emplace_back(new_pointer.back());
walk(new_pointer, new_instance_location, {new_pointer.back()},
subschemas, subpair.second, walker, resolver, new_dialect,
type, level + 1, orphan);
// TODO: Set parent
walk(std::nullopt, new_pointer, new_instance_location,
{new_pointer.back()}, subschemas, subpair.second, walker,
resolver, new_dialect, type, level + 1, orphan);
}
}

Expand All @@ -169,9 +176,10 @@ auto walk(const sourcemeta::core::Pointer &pointer,
new_pointer.emplace_back(subpair.first);
auto new_instance_location{instance_location};
new_instance_location.emplace_back(subpair.first);
walk(new_pointer, new_instance_location, {subpair.first},
subschemas, subpair.second, walker, resolver, new_dialect,
type, level + 1, orphan);
// TODO: Set parent
walk(std::nullopt, new_pointer, new_instance_location,
{subpair.first}, subschemas, subpair.second, walker, resolver,
new_dialect, type, level + 1, orphan);
}
}

Expand All @@ -183,8 +191,10 @@ auto walk(const sourcemeta::core::Pointer &pointer,
sourcemeta::core::Pointer new_pointer{pointer};
new_pointer.emplace_back(pair.first);
new_pointer.emplace_back(subpair.first);
walk(new_pointer, instance_location, {}, subschemas, subpair.second,
walker, resolver, new_dialect, type, level + 1, orphan);
// TODO: Set parent
walk(std::nullopt, new_pointer, instance_location, {}, subschemas,
subpair.second, walker, resolver, new_dialect, type, level + 1,
orphan);
}
}

Expand All @@ -196,8 +206,10 @@ auto walk(const sourcemeta::core::Pointer &pointer,
sourcemeta::core::Pointer new_pointer{pointer};
new_pointer.emplace_back(pair.first);
new_pointer.emplace_back(subpair.first);
walk(new_pointer, instance_location, {}, subschemas, subpair.second,
walker, resolver, new_dialect, type, level + 1, true);
// TODO: Set parent
walk(std::nullopt, new_pointer, instance_location, {}, subschemas,
subpair.second, walker, resolver, new_dialect, type, level + 1,
true);
}
}

Expand All @@ -212,17 +224,19 @@ auto walk(const sourcemeta::core::Pointer &pointer,
new_pointer.emplace_back(index);
auto new_instance_location{instance_location};
new_instance_location.emplace_back(new_pointer.back());
walk(new_pointer, new_instance_location, {new_pointer.back()},
subschemas, pair.second.at(index), walker, resolver,
new_dialect, type, level + 1, orphan);
// TODO: Set parent
walk(std::nullopt, new_pointer, new_instance_location,
{new_pointer.back()}, subschemas, pair.second.at(index),
walker, resolver, new_dialect, type, level + 1, orphan);
}
} else {
sourcemeta::core::Pointer new_pointer{pointer};
new_pointer.emplace_back(pair.first);
auto new_instance_location{instance_location};
new_instance_location.emplace_back(
sourcemeta::core::PointerTemplate::Wildcard::Item);
walk(new_pointer, new_instance_location,
// TODO: Set parent
walk(std::nullopt, new_pointer, new_instance_location,
{sourcemeta::core::PointerTemplate::Wildcard::Item}, subschemas,
pair.second, walker, resolver, new_dialect, type, level + 1,
orphan);
Expand All @@ -237,15 +251,18 @@ auto walk(const sourcemeta::core::Pointer &pointer,
sourcemeta::core::Pointer new_pointer{pointer};
new_pointer.emplace_back(pair.first);
new_pointer.emplace_back(index);
walk(new_pointer, instance_location, {}, subschemas,
// TODO: Set parent
walk(std::nullopt, new_pointer, instance_location, {}, subschemas,
pair.second.at(index), walker, resolver, new_dialect, type,
level + 1, orphan);
}
} else {
sourcemeta::core::Pointer new_pointer{pointer};
new_pointer.emplace_back(pair.first);
walk(new_pointer, instance_location, {}, subschemas, pair.second,
walker, resolver, new_dialect, type, level + 1, orphan);
// TODO: Set parent
walk(std::nullopt, new_pointer, instance_location, {}, subschemas,
pair.second, walker, resolver, new_dialect, type, level + 1,
orphan);
}

break;
Expand Down Expand Up @@ -284,13 +301,13 @@ sourcemeta::core::SchemaIterator::SchemaIterator(
// the current schema is a subschema, but cannot walk any further.
if (!dialect.has_value()) {
sourcemeta::core::SchemaIteratorEntry entry{
pointer, std::nullopt, {}, std::nullopt, schema,
instance_location, instance_location, false};
std::nullopt, pointer, std::nullopt, {}, std::nullopt,
schema, instance_location, instance_location, false};
this->subschemas.push_back(std::move(entry));
} else {
walk(pointer, instance_location, instance_location, this->subschemas,
schema, walker, resolver, dialect.value(), SchemaWalkerType_t::Deep, 0,
false);
walk(std::nullopt, pointer, instance_location, instance_location,
this->subschemas, schema, walker, resolver, dialect.value(),
SchemaWalkerType_t::Deep, 0, false);
}
}

Expand All @@ -304,9 +321,9 @@ sourcemeta::core::SchemaIteratorFlat::SchemaIteratorFlat(
if (dialect.has_value()) {
sourcemeta::core::Pointer pointer;
sourcemeta::core::PointerTemplate instance_location;
walk(pointer, instance_location, instance_location, this->subschemas,
schema, walker, resolver, dialect.value(), SchemaWalkerType_t::Flat, 0,
false);
walk(std::nullopt, pointer, instance_location, instance_location,
this->subschemas, schema, walker, resolver, dialect.value(),
SchemaWalkerType_t::Flat, 0, false);
}
}

Expand All @@ -333,8 +350,9 @@ sourcemeta::core::SchemaKeywordIterator::SchemaKeywordIterator(

for (const auto &entry : schema.as_object()) {
sourcemeta::core::SchemaIteratorEntry subschema_entry{
{entry.first}, dialect, vocabularies, base_dialect,
entry.second, {}, {}, false};
std::nullopt, {entry.first}, dialect, vocabularies,
base_dialect, entry.second, {}, {},
false};
this->entries.push_back(std::move(subschema_entry));
}

Expand Down
Loading

0 comments on commit 69b76de

Please sign in to comment.