Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DEPENDENCIES
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
vendorpull https://github.com/sourcemeta/vendorpull dea311b5bfb53b6926a4140267959ae334d3ecf4
core https://github.com/sourcemeta/core 89c1394849a488667f03ec5ee1844326570f486d
core https://github.com/sourcemeta/core 78c8548ce280f2bf88a1f21eb509046ac54f1532
jsonschema-test-suite https://github.com/json-schema-org/JSON-Schema-Test-Suite 4ba013d58e747ecaf48c8bb7cf248cb0d564afbc
42 changes: 27 additions & 15 deletions src/compiler/compile.cc
Original file line number Diff line number Diff line change
Expand Up @@ -103,20 +103,11 @@ namespace sourcemeta::blaze {
auto compile(const sourcemeta::core::JSON &schema,
const sourcemeta::core::SchemaWalker &walker,
const sourcemeta::core::SchemaResolver &resolver,
const Compiler &compiler, const Mode mode,
const Compiler &compiler,
const sourcemeta::core::SchemaFrame &frame, const Mode mode,
const std::optional<std::string> &default_dialect) -> Template {
assert(is_schema(schema));

// Make sure the input schema is bundled, otherwise we won't be able to
// resolve remote references here
const sourcemeta::core::JSON result{
sourcemeta::core::bundle(schema, walker, resolver, default_dialect)};

// Perform framing to resolve references later on
sourcemeta::core::SchemaFrame frame{
sourcemeta::core::SchemaFrame::Mode::References};
frame.analyse(result, walker, resolver, default_dialect);

const std::string base{sourcemeta::core::URI{
sourcemeta::core::identify(
schema, resolver,
Expand Down Expand Up @@ -144,7 +135,7 @@ auto compile(const sourcemeta::core::JSON &schema,

SchemaContext schema_context{
sourcemeta::core::empty_pointer,
result,
schema,
vocabularies(schema, resolver, root_frame_entry.dialect),
sourcemeta::core::URI{root_frame_entry.base}.canonicalize().recompose(),
{},
Expand Down Expand Up @@ -207,10 +198,10 @@ auto compile(const sourcemeta::core::JSON &schema,
}

auto unevaluated{
sourcemeta::core::unevaluated(result, frame, walker, resolver)};
sourcemeta::core::unevaluated(schema, frame, walker, resolver)};

const Context context{result,
std::move(frame),
const Context context{schema,
frame,
std::move(resources),
walker,
resolver,
Expand Down Expand Up @@ -275,6 +266,27 @@ auto compile(const sourcemeta::core::JSON &schema,
}
}

auto compile(const sourcemeta::core::JSON &schema,
const sourcemeta::core::SchemaWalker &walker,
const sourcemeta::core::SchemaResolver &resolver,
const Compiler &compiler, const Mode mode,
const std::optional<std::string> &default_dialect) -> Template {
assert(is_schema(schema));

// Make sure the input schema is bundled, otherwise we won't be able to
// resolve remote references here
const sourcemeta::core::JSON result{
sourcemeta::core::bundle(schema, walker, resolver, default_dialect)};

// Perform framing to resolve references later on
sourcemeta::core::SchemaFrame frame{
sourcemeta::core::SchemaFrame::Mode::References};
frame.analyse(result, walker, resolver, default_dialect);

return compile(result, walker, resolver, compiler, frame, mode,
default_dialect);
}

auto compile(const Context &context, const SchemaContext &schema_context,
const DynamicContext &dynamic_context,
const sourcemeta::core::Pointer &schema_suffix,
Expand Down
18 changes: 18 additions & 0 deletions src/compiler/include/sourcemeta/blaze/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,24 @@ compile(const sourcemeta::core::JSON &schema,
const std::optional<std::string> &default_dialect = std::nullopt)
-> Template;

/// @ingroup compiler
///
/// This function compiles an input JSON Schema into a template that can be
/// later evaluated, but given an existing schema frame. The schema frame must
/// contain reference information for the given schema and the input schema must
/// be bundled. If those pre-conditions are not met, you will hit undefined
/// behavior.
///
/// Don't use this function unless you know what you are doing.
auto SOURCEMETA_BLAZE_COMPILER_EXPORT
compile(const sourcemeta::core::JSON &schema,
const sourcemeta::core::SchemaWalker &walker,
const sourcemeta::core::SchemaResolver &resolver,
const Compiler &compiler, const sourcemeta::core::SchemaFrame &frame,
const Mode mode = Mode::FastValidation,
const std::optional<std::string> &default_dialect = std::nullopt)
-> Template;

/// @ingroup compiler
///
/// This function compiles a single subschema into a compiler template as
Expand Down
45 changes: 45 additions & 0 deletions test/evaluator/evaluator_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,51 @@ TEST(Evaluator, cross_2012_12_ref_2019_09_without_id) {
EXPECT_TRUE(evaluator.validate(compiled_schema, instance));
}

TEST(Evaluator, explicit_frame) {
const sourcemeta::core::JSON schema{sourcemeta::core::parse_json(R"JSON({
"$schema": "https://json-schema.org/draft/2020-12/schema",
"allOf": [ { "$ref": "https://json-schema.org/draft/2020-12/schema" } ]
})JSON")};

const sourcemeta::core::JSON result{
sourcemeta::core::bundle(schema, sourcemeta::core::schema_official_walker,
sourcemeta::core::schema_official_resolver)};
sourcemeta::core::SchemaFrame frame{
sourcemeta::core::SchemaFrame::Mode::References};
frame.analyse(result, sourcemeta::core::schema_official_walker,
sourcemeta::core::schema_official_resolver);

const auto compiled_schema{sourcemeta::blaze::compile(
result, sourcemeta::core::schema_official_walker,
sourcemeta::core::schema_official_resolver,
sourcemeta::blaze::default_schema_compiler, frame)};

sourcemeta::blaze::Evaluator evaluator;
const sourcemeta::core::JSON instance{true};
EXPECT_TRUE(evaluator.validate(compiled_schema, instance));
}

TEST(Evaluator, explicit_frame_locations_only) {
const sourcemeta::core::JSON schema{sourcemeta::core::parse_json(R"JSON({
"$schema": "https://json-schema.org/draft/2020-12/schema",
"allOf": [ { "$ref": "https://json-schema.org/draft/2020-12/schema" } ]
})JSON")};

const sourcemeta::core::JSON result{
sourcemeta::core::bundle(schema, sourcemeta::core::schema_official_walker,
sourcemeta::core::schema_official_resolver)};
sourcemeta::core::SchemaFrame frame{
sourcemeta::core::SchemaFrame::Mode::Locations};
frame.analyse(result, sourcemeta::core::schema_official_walker,
sourcemeta::core::schema_official_resolver);

EXPECT_THROW(sourcemeta::blaze::compile(
result, sourcemeta::core::schema_official_walker,
sourcemeta::core::schema_official_resolver,
sourcemeta::blaze::default_schema_compiler, frame),
sourcemeta::core::SchemaReferenceError);
}

TEST(Evaluator, is_annotation) {
EXPECT_TRUE(sourcemeta::blaze::is_annotation(
sourcemeta::blaze::InstructionIndex::AnnotationBasenameToParent));
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.