16
16
17
17
static auto parse_regex (const std::string &pattern,
18
18
const sourcemeta::core::URI &base,
19
- const sourcemeta::core::Pointer &schema_location)
19
+ const sourcemeta::core::Pointer &schema_location,
20
+ const bool simplify_regexes)
20
21
-> sourcemeta::core::Regex<sourcemeta::core::JSON::String> {
21
- const auto result{sourcemeta::core::to_regex (pattern)};
22
+ const auto result{sourcemeta::core::to_regex (pattern, simplify_regexes )};
22
23
if (!result.has_value ()) {
23
24
std::ostringstream message;
24
25
message << " Invalid regular expression: " << pattern;
@@ -252,7 +253,8 @@ auto compiler_draft4_core_ref(const Context &context,
252
253
.pointer )) ||
253
254
schema_context.references .contains (reference.destination )};
254
255
255
- if (!is_recursive && direct_children_references <= 5 ) {
256
+ if (!is_recursive &&
257
+ direct_children_references <= options.expand_ref_threshold ) {
256
258
if (context.mode == Mode::FastValidation &&
257
259
// Expanding references inline when dynamic scoping is required
258
260
// may not work, as we might omit the instruction that introduces
@@ -610,8 +612,9 @@ auto compiler_draft4_validation_required(const Context &context,
610
612
if (context.mode == Mode::FastValidation &&
611
613
properties_set.size () == 3 &&
612
614
std::all_of (properties_set.begin (), properties_set.end (),
613
- [&hasher](const auto &property) {
614
- return hasher.is_perfect (property.second );
615
+ [&hasher, &options](const auto &property) {
616
+ return options.perfect_hash &&
617
+ hasher.is_perfect (property.second );
615
618
})) {
616
619
std::vector<std::pair<ValueString, ValueStringSet::hash_type>> hashes;
617
620
for (const auto &property : properties_set) {
@@ -1018,7 +1021,7 @@ auto compiler_draft4_applicator_properties_with_options(
1018
1021
perfect_hashes;
1019
1022
for (const auto &entry : required) {
1020
1023
assert (required.contains (entry.first , entry.second ));
1021
- if (hasher.is_perfect (entry.second )) {
1024
+ if (options. perfect_hash && hasher.is_perfect (entry.second )) {
1022
1025
perfect_hashes.emplace_back (entry.first , entry.second );
1023
1026
}
1024
1027
}
@@ -1249,14 +1252,18 @@ auto compiler_draft4_applicator_patternproperties_with_options(
1249
1252
make (sourcemeta::blaze::InstructionIndex::LoopPropertiesRegexClosed,
1250
1253
context, schema_context, dynamic_context,
1251
1254
ValueRegex{parse_regex (pattern, schema_context.base ,
1252
- schema_context.relative_pointer ),
1255
+ schema_context.relative_pointer ,
1256
+ options.simplify_regexes ),
1253
1257
pattern},
1254
1258
std::move (substeps)));
1255
1259
1256
1260
// If the `patternProperties` subschema for the given pattern does
1257
1261
// nothing, then we can avoid generating an entire loop for it
1258
1262
} else if (!substeps.empty ()) {
1259
- const auto maybe_prefix{pattern_as_prefix (pattern)};
1263
+ std::optional<std::basic_string<char >> maybe_prefix{std::nullopt};
1264
+ if (options.simplify_regexes ) {
1265
+ maybe_prefix = pattern_as_prefix (pattern);
1266
+ }
1260
1267
if (maybe_prefix.has_value ()) {
1261
1268
children.push_back (
1262
1269
make (sourcemeta::blaze::InstructionIndex::LoopPropertiesStartsWith,
@@ -1267,7 +1274,8 @@ auto compiler_draft4_applicator_patternproperties_with_options(
1267
1274
make (sourcemeta::blaze::InstructionIndex::LoopPropertiesRegex,
1268
1275
context, schema_context, dynamic_context,
1269
1276
ValueRegex{parse_regex (pattern, schema_context.base ,
1270
- schema_context.relative_pointer ),
1277
+ schema_context.relative_pointer ,
1278
+ options.simplify_regexes ),
1271
1279
pattern},
1272
1280
std::move (substeps)));
1273
1281
}
@@ -1323,14 +1331,18 @@ auto compiler_draft4_applicator_additionalproperties_with_options(
1323
1331
schema_context.schema .at (" patternProperties" ).is_object ()) {
1324
1332
for (const auto &entry :
1325
1333
schema_context.schema .at (" patternProperties" ).as_object ()) {
1326
- const auto maybe_prefix{pattern_as_prefix (entry.first )};
1334
+ std::optional<std::basic_string<char >> maybe_prefix{std::nullopt};
1335
+ if (options.simplify_regexes ) {
1336
+ maybe_prefix = pattern_as_prefix (entry.first );
1337
+ }
1327
1338
if (maybe_prefix.has_value ()) {
1328
1339
filter_prefixes.push_back (maybe_prefix.value ());
1329
1340
} else {
1330
1341
filter_regexes.push_back (
1331
1342
{parse_regex (entry.first , schema_context.base ,
1332
1343
schema_context.relative_pointer .initial ().concat (
1333
- {" patternProperties" })),
1344
+ {" patternProperties" }),
1345
+ options.simplify_regexes ),
1334
1346
entry.first });
1335
1347
}
1336
1348
}
@@ -1450,7 +1462,7 @@ auto compiler_draft4_applicator_additionalproperties(
1450
1462
1451
1463
auto compiler_draft4_validation_pattern (const Context &context,
1452
1464
const SchemaContext &schema_context,
1453
- const CompileOptions &,
1465
+ const CompileOptions &options ,
1454
1466
const DynamicContext &dynamic_context,
1455
1467
const Instructions &) -> Instructions {
1456
1468
assert (schema_context.schema .at (dynamic_context.keyword ).is_string ());
@@ -1466,13 +1478,14 @@ auto compiler_draft4_validation_pattern(const Context &context,
1466
1478
return {make (sourcemeta::blaze::InstructionIndex::AssertionRegex, context,
1467
1479
schema_context, dynamic_context,
1468
1480
ValueRegex{parse_regex (regex_string, schema_context.base ,
1469
- schema_context.relative_pointer ),
1481
+ schema_context.relative_pointer ,
1482
+ options.simplify_regexes ),
1470
1483
regex_string})};
1471
1484
}
1472
1485
1473
1486
auto compiler_draft4_validation_format (const Context &context,
1474
1487
const SchemaContext &schema_context,
1475
- const CompileOptions &,
1488
+ const CompileOptions &options ,
1476
1489
const DynamicContext &dynamic_context,
1477
1490
const Instructions &) -> Instructions {
1478
1491
if (!schema_context.schema .at (dynamic_context.keyword ).is_string ()) {
@@ -1507,7 +1520,8 @@ auto compiler_draft4_validation_format(const Context &context,
1507
1520
make (sourcemeta::blaze::InstructionIndex::AssertionRegex, context, \
1508
1521
schema_context, dynamic_context, \
1509
1522
ValueRegex{parse_regex (regular_expression, schema_context.base , \
1510
- schema_context.relative_pointer ), \
1523
+ schema_context.relative_pointer , \
1524
+ options.simplify_regexes ), \
1511
1525
(regular_expression)})}; \
1512
1526
}
1513
1527
@@ -1916,7 +1930,7 @@ auto compiler_draft4_applicator_dependencies(
1916
1930
1917
1931
auto compiler_draft4_validation_enum (const Context &context,
1918
1932
const SchemaContext &schema_context,
1919
- const CompileOptions &,
1933
+ const CompileOptions &options ,
1920
1934
const DynamicContext &dynamic_context,
1921
1935
const Instructions &) -> Instructions {
1922
1936
assert (schema_context.schema .at (dynamic_context.keyword ).is_array ());
@@ -1932,32 +1946,32 @@ auto compiler_draft4_validation_enum(const Context &context,
1932
1946
std::vector<std::pair<sourcemeta::blaze::ValueString,
1933
1947
sourcemeta::blaze::ValueStringSet::hash_type>>
1934
1948
perfect_string_hashes;
1935
- ValueSet options ;
1949
+ ValueSet enums ;
1936
1950
sourcemeta::core::PropertyHashJSON<ValueString> hasher;
1937
1951
for (const auto &option :
1938
1952
schema_context.schema .at (dynamic_context.keyword ).as_array ()) {
1939
1953
if (option.is_string ()) {
1940
1954
const auto hash{hasher (option.to_string ())};
1941
- if (hasher.is_perfect (hash)) {
1955
+ if (options. perfect_hash && hasher.is_perfect (hash)) {
1942
1956
perfect_string_hashes.emplace_back (option.to_string (), hash);
1943
1957
}
1944
1958
}
1945
1959
1946
- options .insert (option);
1960
+ enums .insert (option);
1947
1961
}
1948
1962
1949
1963
// Only apply this optimisation on fast validation, as it
1950
1964
// can affect error messages
1951
1965
if (context.mode == Mode::FastValidation &&
1952
- perfect_string_hashes.size () == options .size ()) {
1966
+ perfect_string_hashes.size () == enums .size ()) {
1953
1967
return {
1954
1968
make (sourcemeta::blaze::InstructionIndex::AssertionEqualsAnyStringHash,
1955
1969
context, schema_context, dynamic_context,
1956
1970
to_string_hashes (perfect_string_hashes))};
1957
1971
}
1958
1972
1959
1973
return {make (sourcemeta::blaze::InstructionIndex::AssertionEqualsAny, context,
1960
- schema_context, dynamic_context, std::move (options ))};
1974
+ schema_context, dynamic_context, std::move (enums ))};
1961
1975
}
1962
1976
1963
1977
auto compiler_draft4_validation_uniqueitems (
0 commit comments