1#ifndef SOURCEMETA_CORE_JSONSCHEMA_FRAME_H_
2#define SOURCEMETA_CORE_JSONSCHEMA_FRAME_H_
4#ifndef SOURCEMETA_CORE_JSONSCHEMA_EXPORT
5#include <sourcemeta/core/jsonschema_export.h>
9#include <sourcemeta/core/jsonschema_error.h>
10#include <sourcemeta/core/jsonschema_types.h>
13#include <sourcemeta/core/json.h>
14#include <sourcemeta/core/jsonpointer.h>
27namespace sourcemeta::core {
57class SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaFrame {
71 enum class Mode : std::uint8_t {
100 [[nodiscard]]
auto mode() const noexcept ->
Mode {
return this->mode_; }
120#pragma GCC diagnostic push
123#pragma GCC diagnostic ignored "-Wshadow"
138#pragma GCC diagnostic pop
144 std::optional<sourcemeta::core::WeakPointer>
parent;
164 using Paths = std::vector<sourcemeta::core::WeakPointer>;
169 const std::optional<sourcemeta::core::PointerPositionTracker> &tracker =
205 std::string_view default_dialect =
"", std::string_view default_id =
"",
208 std::string_view default_base =
"",
209 std::uint64_t max_locations = std::numeric_limits<std::uint64_t>::max());
215 -> std::optional<std::reference_wrapper<const Reference>>;
219 const std::string_view
uri)
const
220 -> std::optional<std::reference_wrapper<const Location>>;
235 [[nodiscard]] auto
root() const noexcept
236 -> const sourcemeta::core::
JSON::String &;
241 -> std::optional<std::reference_wrapper<const
Location>>;
246 -> const sourcemeta::core::
JSON &;
260 const sourcemeta::core::
WeakPointer &relative_schema_location =
262 -> sourcemeta::core::
JSON::String;
267 const sourcemeta::core::
WeakPointer &relative_schema_location) const
272 -> std::optional<std::reference_wrapper<const
Location>>;
277 -> std::optional<std::reference_wrapper<const
Location>>;
282 -> std::optional<std::reference_wrapper<const
Location>>;
287 std::reference_wrapper<const sourcemeta::core::
JSON::String>>;
292 const sourcemeta::core::
WeakPointer &relative_schema_location =
295 std::optional<std::reference_wrapper<const
Location>>>;
299 template <std::invocable<const
Location &> F>
301 for (
const auto &entry : this->locations_) {
304 callback(entry.second);
311 template <std::invocable<const Location &> F>
313 const F &callback)
const ->
void {
314 for (
const auto &entry : this->locations_) {
317 entry.second.pointer.size() > pointer.size() &&
318 entry.second.pointer.starts_with(pointer)) {
319 callback(entry.second);
325 template <std::predicate<const Location &> F>
327 for (
const auto &entry : this->locations_) {
330 predicate(entry.second)) {
340 template <std::predicate<const Location &> F>
343 const F &predicate)
const ->
bool {
344 for (
const auto &entry : this->locations_) {
347 entry.second.pointer.size() > pointer.size() &&
348 entry.second.pointer.starts_with(pointer) &&
349 predicate(entry.second)) {
358 template <std::invocable<std::
string_view, const Location &> F>
361 for (
const auto &entry : this->locations_) {
362 if (entry.first.first == type &&
364 callback(entry.first.second, entry.second);
370 template <std::predicate<std::
string_view, const Location &> F>
372 const F &predicate)
const ->
bool {
373 for (
const auto &entry : this->locations_) {
374 if (entry.first.first == type &&
376 predicate(entry.first.second, entry.second)) {
385 template <std::invocable<std::
string_view, const Location &> F>
387 for (
const auto &entry : this->locations_) {
389 callback(entry.first.second, entry.second);
396 std::invocable<SchemaReferenceType, std::string_view, const Location &> F>
398 for (
const auto &entry : this->locations_) {
399 callback(entry.first.first, entry.first.second, entry.second);
405 std::predicate<SchemaReferenceType, std::string_view, const Location &> F>
407 for (
const auto &entry : this->locations_) {
408 if (predicate(entry.first.first, entry.first.second, entry.second)) {
422 for (
const auto &entry : this->references_) {
423 callback(entry.first.first, entry.first.second, entry.second);
433 for (
const auto &entry : this->references_) {
434 if (predicate(entry.first.first, entry.first.second, entry.second)) {
448 const F &callback)
const ->
void {
449 for (
const auto &entry : this->references_) {
450 if (entry.first.second.starts_with(pointer)) {
451 callback(entry.first.first, entry.first.second, entry.second);
464 const F &predicate)
const ->
bool {
465 for (
const auto &entry : this->references_) {
466 if (entry.first.second.starts_with(pointer) &&
467 predicate(entry.first.first, entry.first.second, entry.second)) {
484 const F &callback)
const ->
void {
485 for (
const auto &entry : this->references_) {
486 const auto destination{this->
traverse(entry.second.destination)};
487 if (destination.has_value() &&
488 destination.value().get().pointer.starts_with(pointer)) {
489 callback(entry.first.first, entry.first.second, entry.second);
502 const F &predicate)
const ->
bool {
503 for (
const auto &entry : this->references_) {
504 const auto destination{this->
traverse(entry.second.destination)};
505 if (destination.has_value() &&
506 destination.value().get().pointer.starts_with(pointer) &&
507 predicate(entry.first.first, entry.first.second, entry.second)) {
516 template <std::invocable<std::
string_view> F>
518 for (
const auto &[key,
location] : this->locations_) {
520 callback(key.second);
528 std::invocable<const sourcemeta::core::WeakPointer &, const Reference &>
531 for (
const auto &[key, reference] : this->references_) {
532 if (!this->
traverse(reference.destination).has_value()) {
533 callback(key.second, reference);
572 std::map<std::pair<SchemaReferenceType, sourcemeta::core::WeakPointer>,
581 std::map<std::pair<SchemaReferenceType, sourcemeta::core::JSON::String>,
589#pragma warning(disable : 4251 4275)
596 std::deque<sourcemeta::core::Pointer> reference_pointers_;
597 Locations locations_;
598 References references_;
602 std::unique_ptr<Cache> cache_;
604#pragma warning(default : 4251 4275)
std::basic_string< Char, CharTraits, Allocator< Char > > String
The string type used by the JSON document.
Definition json_value.h:52
GenericToken< std::reference_wrapper< const std::string >, PropertyHashJSON< JSON::String > > Token
Definition jsonpointer_pointer.h:28
const WeakPointer EMPTY_WEAK_POINTER
Definition jsonpointer.h:54
GenericPointer< JSON::String, PropertyHashJSON< JSON::String > > Pointer
Definition jsonpointer.h:39
GenericPointer< std::reference_wrapper< const std::string >, PropertyHashJSON< JSON::String > > WeakPointer
Definition jsonpointer.h:44
std::vector< sourcemeta::core::WeakPointer > Paths
A list of paths to frame within a schema wrapper.
Definition jsonschema_frame.h:164
auto for_each_resource(const F &callback) const -> void
Iterate over every schema resource, along with its URI.
Definition jsonschema_frame.h:386
auto for_each_subschema_under(const sourcemeta::core::WeakPointer &pointer, const F &callback) const -> void
Definition jsonschema_frame.h:312
auto for_each_anchor(const SchemaReferenceType type, const F &callback) const -> void
Iterate over every anchor of the given kind, along with its URI.
Definition jsonschema_frame.h:359
auto vocabularies(const Location &location, const SchemaResolver &resolver) const -> const SchemaVocabularies &
auto for_each_reference(const F &callback) const -> void
Iterate over every reference, along with the pointer it originates from.
Definition jsonschema_frame.h:421
auto any_reference_from(const sourcemeta::core::WeakPointer &pointer, const F &predicate) const -> bool
Definition jsonschema_frame.h:463
auto standalone() const noexcept -> bool
Check whether the analysed schema has no external references.
auto metaschema(const SchemaResolver &resolver) const -> const sourcemeta::core::JSON &
auto for_each_location(const F &callback) const -> void
Iterate over every location, whatever kind it is.
Definition jsonschema_frame.h:397
auto any_anchor(const SchemaReferenceType type, const F &predicate) const -> bool
Check whether any anchor of the given kind satisfies the predicate.
Definition jsonschema_frame.h:371
auto reference_count() const noexcept -> std::size_t
The number of references in the frame.
auto any_reference_into(const sourcemeta::core::WeakPointer &pointer, const F &predicate) const -> bool
Definition jsonschema_frame.h:501
auto has_references_through(const sourcemeta::core::WeakPointer &pointer, const sourcemeta::core::WeakPointer::Token &tail) const -> bool
auto to_json(const SchemaResolver &resolver, const std::optional< sourcemeta::core::PointerPositionTracker > &tracker=std::nullopt) const -> sourcemeta::core::JSON
Export the frame as JSON.
IdentifierMode
Definition jsonschema_frame.h:84
@ Additional
Register the default identifier in addition to the schema's own.
Definition jsonschema_frame.h:86
auto for_each_reference_from(const sourcemeta::core::WeakPointer &pointer, const F &callback) const -> void
Iterate over every reference that originates at or below the given pointer.
Definition jsonschema_frame.h:447
auto has_dynamic_references() const noexcept -> bool
Check whether the analysed schema makes use of dynamic referencing at all.
auto dereference(const Location &location, const sourcemeta::core::WeakPointer &relative_schema_location=sourcemeta::core::EMPTY_WEAK_POINTER) const -> std::pair< SchemaReferenceType, std::optional< std::reference_wrapper< const Location > > >
Try to dereference a reference location into its destination location.
auto is_reachable(const Location &base, const Location &location, const SchemaWalker &walker, const SchemaResolver &resolver) const -> bool
Determines if a location could be evaluated during validation.
auto any_reference(const F &predicate) const -> bool
Check whether any reference satisfies the predicate.
Definition jsonschema_frame.h:432
SchemaFrame(const Mode mode, const sourcemeta::core::JSON &root, const SchemaWalker &walker, const SchemaResolver &resolver, std::string_view default_dialect="", std::string_view default_id="", IdentifierMode identifier_mode=IdentifierMode::Additional, const Paths &paths={sourcemeta::core::EMPTY_WEAK_POINTER}, std::string_view default_base="", std::uint64_t max_locations=std::numeric_limits< std::uint64_t >::max())
auto any_location(const F &predicate) const -> bool
Check whether any location satisfies the predicate.
Definition jsonschema_frame.h:406
Mode
Definition jsonschema_frame.h:71
auto mode() const noexcept -> Mode
Query the current mode that the schema frame was configured with.
Definition jsonschema_frame.h:100
auto for_each_subschema(const F &callback) const -> void
Definition jsonschema_frame.h:300
auto has_references_through(const sourcemeta::core::WeakPointer &pointer) const -> bool
Check if there are any references that go through a given location pointer.
auto any_subschema_under(const sourcemeta::core::WeakPointer &pointer, const F &predicate) const -> bool
Definition jsonschema_frame.h:342
auto for_each_unresolved_reference(const F &callback) const -> void
Definition jsonschema_frame.h:530
auto has_references_to(const sourcemeta::core::WeakPointer &pointer) const -> bool
Check if there are any references to a given location pointer.
auto root_location() const -> std::optional< std::reference_wrapper< const Location > >
auto any_subschema(const F &predicate) const -> bool
Check whether any schema resource or subschema satisfies the predicate.
Definition jsonschema_frame.h:326
auto uri(const Location &location, const sourcemeta::core::WeakPointer &relative_schema_location=sourcemeta::core::EMPTY_WEAK_POINTER) const -> sourcemeta::core::JSON::String
Get the URI associated with a location entry.
auto location(const SchemaReferenceType type, const std::string_view uri) const -> std::optional< std::reference_wrapper< const Location > >
Get a specific location entry by reference type and URI.
auto relative_instance_location(const Location &location) const -> sourcemeta::core::WeakPointer
Get the relative instance location pointer for a given location entry.
auto root() const noexcept -> const sourcemeta::core::JSON::String &
Get the root schema identifier (empty if none).
auto for_each_reference_into(const sourcemeta::core::WeakPointer &pointer, const F &callback) const -> void
Definition jsonschema_frame.h:483
auto location_count() const noexcept -> std::size_t
The number of locations in the frame.
auto for_each_resource_uri(const F &callback) const -> void
Iterate over all resource URIs in the frame.
Definition jsonschema_frame.h:517
auto traverse(const Location &location, const sourcemeta::core::WeakPointer &relative_schema_location) const -> const Location &
Get the location associated by traversing a pointer from another location.
LocationType
Definition jsonschema_frame.h:127
SchemaReferenceType
Definition jsonschema_types.h:45
std::function< SchemaResolverResult(std::string_view)> SchemaResolver
Definition jsonschema_types.h:41
std::function< const SchemaWalkerResult &( std::string_view, const SchemaVocabularies &)> SchemaWalker
Definition jsonschema_types.h:254
SchemaBaseDialect
Definition jsonschema_types.h:54
@ Subschema
A subschema that declares no identifier of its own.
Definition jsonschema_frame.h:135
@ Anchor
An anchor declared within a schema resource.
Definition jsonschema_frame.h:131
@ Resource
A schema resource, as introduced by an identifier.
Definition jsonschema_frame.h:129
@ Reference
The JSON Schema keyword is a reference.
Definition jsonschema_types.h:110