1313
1414enum class AnchorType : std::uint8_t { Static, Dynamic, All };
1515
16+ // Static keyword strings for reference pointers
17+ static const std::string KEYWORD_SCHEMA{" $schema" };
18+ static const std::string KEYWORD_REF{" $ref" };
19+ static const std::string KEYWORD_RECURSIVE_REF{" $recursiveRef" };
20+ static const std::string KEYWORD_DYNAMIC_REF{" $dynamicRef" };
21+
1622namespace {
1723
1824auto find_anchors (const sourcemeta::core::JSON &schema,
@@ -400,8 +406,8 @@ auto SchemaFrame::to_json(
400406
401407 if (tracker.has_value ()) {
402408 entry.assign_assume_new (" position" ,
403- sourcemeta::core::to_json (
404- tracker. value (). get ( reference.first .second )));
409+ sourcemeta::core::to_json (tracker. value (). get (
410+ to_pointer ( reference.first .second ) )));
405411 } else {
406412 entry.assign_assume_new (" position" , sourcemeta::core::to_json (nullptr ));
407413 }
@@ -527,7 +533,6 @@ auto SchemaFrame::analyse(const JSON &root, const SchemaWalker &walker,
527533 for (const auto &entry_index : current_subschema_entries) {
528534 const auto &entry{subschema_entries[entry_index]};
529535 const auto &common_pointer_weak{entry.common .pointer };
530- const auto common_pointer{to_pointer (common_pointer_weak)};
531536 const auto &common_parent{entry.common .parent };
532537 if (entry.id .has_value ()) {
533538 assert (entry.common .base_dialect .has_value ());
@@ -618,8 +623,10 @@ auto SchemaFrame::analyse(const JSON &root, const SchemaWalker &walker,
618623
619624 metaschema.canonicalize ();
620625 assert (entry.common .subschema .get ().defines (" $schema" ));
626+ auto schema_pointer{common_pointer_weak};
627+ schema_pointer.push_back (std::cref (KEYWORD_SCHEMA));
621628 const auto [it, inserted] = this ->references_ .insert_or_assign (
622- {SchemaReferenceType::Static, common_pointer. concat ({ " $schema " } )},
629+ {SchemaReferenceType::Static, std::move (schema_pointer )},
623630 SchemaFrame::ReferencesEntry{.original = maybe_metaschema,
624631 .destination =
625632 metaschema.recompose (),
@@ -809,7 +816,6 @@ auto SchemaFrame::analyse(const JSON &root, const SchemaWalker &walker,
809816 // Resolve references after all framing was performed
810817 for (const auto &entry : subschema_entries) {
811818 const auto &common_pointer_weak{entry.common .pointer };
812- const auto common_pointer{to_pointer (common_pointer_weak)};
813819 if (entry.common .subschema .get ().is_object ()) {
814820 const auto nearest_bases{find_nearest_bases (
815821 base_uris, common_pointer_weak,
@@ -825,8 +831,10 @@ auto SchemaFrame::analyse(const JSON &root, const SchemaWalker &walker,
825831 }
826832
827833 ref.canonicalize ();
834+ auto ref_pointer{common_pointer_weak};
835+ ref_pointer.push_back (std::cref (KEYWORD_REF));
828836 const auto [it, inserted] = this ->references_ .insert_or_assign (
829- {SchemaReferenceType::Static, common_pointer. concat ({ " $ref " } )},
837+ {SchemaReferenceType::Static, std::move (ref_pointer )},
830838 SchemaFrame::ReferencesEntry{.original = original,
831839 .destination = ref.recompose (),
832840 .base = std::string_view{},
@@ -848,7 +856,8 @@ auto SchemaFrame::analyse(const JSON &root, const SchemaWalker &walker,
848856 // https://json-schema.org/draft/2019-09/draft-handrews-json-schema-02#rfc.section.8.2.4.2.1
849857 if (ref != " #" ) {
850858 throw sourcemeta::core::SchemaReferenceError (
851- entry.id .value_or (" " ), common_pointer.concat ({" $recursiveRef" }),
859+ entry.id .value_or (" " ),
860+ to_pointer (common_pointer_weak).concat ({" $recursiveRef" }),
852861 " Invalid recursive reference" );
853862 }
854863
@@ -860,8 +869,10 @@ auto SchemaFrame::analyse(const JSON &root, const SchemaWalker &walker,
860869 ? SchemaReferenceType::Static
861870 : SchemaReferenceType::Dynamic};
862871 const sourcemeta::core::URI anchor_uri{anchor_uri_string};
872+ auto recursive_ref_pointer{common_pointer_weak};
873+ recursive_ref_pointer.push_back (std::cref (KEYWORD_RECURSIVE_REF));
863874 const auto [it, inserted] = this ->references_ .insert_or_assign (
864- {reference_type, common_pointer. concat ({ " $recursiveRef " } )},
875+ {reference_type, std::move (recursive_ref_pointer )},
865876 SchemaFrame::ReferencesEntry{.original = ref,
866877 .destination = anchor_uri.recompose (),
867878 .base = std::string_view{},
@@ -896,10 +907,12 @@ auto SchemaFrame::analyse(const JSON &root, const SchemaWalker &walker,
896907 !has_fragment ||
897908 (has_fragment && maybe_static_frame != this ->locations_ .end () &&
898909 maybe_dynamic_frame == this ->locations_ .end ())};
910+ auto dynamic_ref_pointer{common_pointer_weak};
911+ dynamic_ref_pointer.push_back (std::cref (KEYWORD_DYNAMIC_REF));
899912 const auto [it, inserted] = this ->references_ .insert_or_assign (
900913 {behaves_as_static ? SchemaReferenceType::Static
901914 : SchemaReferenceType::Dynamic,
902- common_pointer. concat ({ " $dynamicRef " } )},
915+ std::move (dynamic_ref_pointer )},
903916 SchemaFrame::ReferencesEntry{.original = original,
904917 .destination = std::move (ref_string),
905918 .base = std::string_view{},
@@ -981,7 +994,7 @@ auto SchemaFrame::references() const noexcept -> const References & {
981994auto SchemaFrame::reference (const SchemaReferenceType type,
982995 const WeakPointer &pointer) const
983996 -> std::optional<std::reference_wrapper<const ReferencesEntry>> {
984- const auto result{this ->references_ .find ({type, to_pointer ( pointer) })};
997+ const auto result{this ->references_ .find ({type, pointer})};
985998 if (result != this ->references_ .cend ()) {
986999 return result->second ;
9871000 }
@@ -1086,7 +1099,7 @@ auto SchemaFrame::dereference(const Location &location,
10861099 -> std::pair<SchemaReferenceType,
10871100 std::optional<std::reference_wrapper<const Location>>> {
10881101 const auto effective_location{
1089- to_pointer ( location.pointer .concat (relative_schema_location) )};
1102+ location.pointer .concat (relative_schema_location)};
10901103 const auto maybe_reference_entry{this ->references_ .find (
10911104 {SchemaReferenceType::Static, effective_location})};
10921105 if (maybe_reference_entry == this ->references_ .cend ()) {
@@ -1118,7 +1131,7 @@ auto SchemaFrame::for_each_resource_uri(
11181131}
11191132
11201133auto SchemaFrame::for_each_unresolved_reference (
1121- const std::function<void (const Pointer &, const ReferencesEntry &)>
1134+ const std::function<void (const WeakPointer &, const ReferencesEntry &)>
11221135 &callback) const -> void {
11231136 for (const auto &[key, reference] : this ->references_ ) {
11241137 if (!this ->traverse (reference.destination ).has_value ()) {
0 commit comments