Skip to content

Commit 091ec3a

Browse files
committed
Turn schema framing into a class
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
1 parent 6667b99 commit 091ec3a

20 files changed

+1474
-1774
lines changed

src/jsonschema/bundle.cc

Lines changed: 20 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -52,19 +52,14 @@ auto is_official_metaschema_reference(
5252
auto bundle_schema(sourcemeta::jsontoolkit::JSON &root,
5353
const std::string &container,
5454
const sourcemeta::jsontoolkit::JSON &subschema,
55-
sourcemeta::jsontoolkit::FrameLocations &frame,
56-
sourcemeta::jsontoolkit::FrameReferences &references,
55+
sourcemeta::jsontoolkit::Frame &frame,
5756
const sourcemeta::jsontoolkit::SchemaWalker &walker,
5857
const sourcemeta::jsontoolkit::SchemaResolver &resolver,
5958
const std::optional<std::string> &default_dialect) -> void {
60-
sourcemeta::jsontoolkit::frame(subschema, frame, references, walker, resolver,
61-
default_dialect);
59+
frame.analyse(subschema, walker, resolver, default_dialect);
6260

63-
for (const auto &[key, reference] : references) {
64-
if (frame.contains({sourcemeta::jsontoolkit::ReferenceType::Static,
65-
reference.destination}) ||
66-
frame.contains({sourcemeta::jsontoolkit::ReferenceType::Dynamic,
67-
reference.destination}) ||
61+
for (const auto &[key, reference] : frame.references()) {
62+
if (frame.traverse(reference.destination).has_value() ||
6863

6964
// We don't want to bundle official schemas, as we can expect
7065
// virtually all implementations to understand them out of the box
@@ -74,15 +69,11 @@ auto bundle_schema(sourcemeta::jsontoolkit::JSON &root,
7469

7570
// If we can't find the destination but there is a base and we can
7671
// find base, then we are facing an unresolved fragment
77-
if (reference.base.has_value()) {
78-
if (frame.contains({sourcemeta::jsontoolkit::ReferenceType::Static,
79-
reference.base.value()}) ||
80-
frame.contains({sourcemeta::jsontoolkit::ReferenceType::Dynamic,
81-
reference.base.value()})) {
82-
throw sourcemeta::jsontoolkit::SchemaReferenceError(
83-
reference.destination, key.second,
84-
"Could not resolve schema reference");
85-
}
72+
if (reference.base.has_value() &&
73+
frame.traverse(reference.base.value()).has_value()) {
74+
throw sourcemeta::jsontoolkit::SchemaReferenceError(
75+
reference.destination, key.second,
76+
"Could not resolve schema reference");
8677
}
8778

8879
root.assign_if_missing(container,
@@ -98,10 +89,7 @@ auto bundle_schema(sourcemeta::jsontoolkit::JSON &root,
9889
const auto identifier{reference.base.value()};
9990
const auto remote{resolver(identifier)};
10091
if (!remote.has_value()) {
101-
if (frame.contains(
102-
{sourcemeta::jsontoolkit::ReferenceType::Static, identifier}) ||
103-
frame.contains(
104-
{sourcemeta::jsontoolkit::ReferenceType::Dynamic, identifier})) {
92+
if (frame.traverse(identifier).has_value()) {
10593
throw sourcemeta::jsontoolkit::SchemaReferenceError(
10694
reference.destination, key.second,
10795
"Could not resolve schema reference");
@@ -134,7 +122,7 @@ auto bundle_schema(sourcemeta::jsontoolkit::JSON &root,
134122
}
135123

136124
embed_schema(root.at(container), identifier, copy);
137-
bundle_schema(root, container, copy, frame, references, walker, resolver,
125+
bundle_schema(root, container, copy, frame, walker, resolver,
138126
default_dialect);
139127
}
140128
}
@@ -145,10 +133,8 @@ auto remove_identifiers(sourcemeta::jsontoolkit::JSON &schema,
145133
const std::optional<std::string> &default_dialect)
146134
-> void {
147135
// (1) Re-frame before changing anything
148-
sourcemeta::jsontoolkit::FrameLocations frame;
149-
sourcemeta::jsontoolkit::FrameReferences references;
150-
sourcemeta::jsontoolkit::frame(schema, frame, references, walker, resolver,
151-
default_dialect);
136+
sourcemeta::jsontoolkit::Frame frame;
137+
frame.analyse(schema, walker, resolver, default_dialect);
152138

153139
// (2) Remove all identifiers and anchors
154140
for (const auto &entry : sourcemeta::jsontoolkit::SchemaIterator{
@@ -175,28 +161,20 @@ auto remove_identifiers(sourcemeta::jsontoolkit::JSON &schema,
175161
}
176162

177163
// (3) Fix-up reference based on pointers from the root
178-
for (const auto &[key, reference] : references) {
164+
for (const auto &[key, reference] : frame.references()) {
179165
// We don't want to bundle official schemas, as we can expect
180166
// virtually all implementations to understand them out of the box
181167
if (is_official_metaschema_reference(key.second, reference.destination)) {
182168
continue;
183169
}
184170

185-
assert(frame.contains({sourcemeta::jsontoolkit::ReferenceType::Static,
186-
reference.destination}) ||
187-
frame.contains({sourcemeta::jsontoolkit::ReferenceType::Dynamic,
188-
reference.destination}));
189-
const auto &entry{
190-
frame.contains({sourcemeta::jsontoolkit::ReferenceType::Static,
191-
reference.destination})
192-
? frame.at({sourcemeta::jsontoolkit::ReferenceType::Static,
193-
reference.destination})
194-
: frame.at({sourcemeta::jsontoolkit::ReferenceType::Dynamic,
195-
reference.destination})};
171+
const auto result{frame.traverse(reference.destination)};
172+
assert(result.has_value());
196173
sourcemeta::jsontoolkit::set(
197174
schema, key.second,
198175
sourcemeta::jsontoolkit::JSON{
199-
sourcemeta::jsontoolkit::to_uri(entry.pointer).recompose()});
176+
sourcemeta::jsontoolkit::to_uri(result.value().get().pointer)
177+
.recompose()});
200178
}
201179
}
202180

@@ -209,10 +187,9 @@ auto bundle(sourcemeta::jsontoolkit::JSON &schema, const SchemaWalker &walker,
209187
const std::optional<std::string> &default_dialect) -> void {
210188
const auto vocabularies{
211189
sourcemeta::jsontoolkit::vocabularies(schema, resolver, default_dialect)};
212-
sourcemeta::jsontoolkit::FrameLocations frame;
213-
sourcemeta::jsontoolkit::FrameReferences references;
190+
sourcemeta::jsontoolkit::Frame frame;
214191
bundle_schema(schema, definitions_keyword(vocabularies), schema, frame,
215-
references, walker, resolver, default_dialect);
192+
walker, resolver, default_dialect);
216193

217194
if (options == BundleOptions::WithoutIdentifiers) {
218195
remove_identifiers(schema, walker, resolver, default_dialect);

0 commit comments

Comments
 (0)