| Filename | /Users/ether/.perlbrew/libs/36.0@std/lib/perl5/JSON/Schema/Modern/Vocabulary/OpenAPI.pm | 
| Statements | Executed 2053 statements in 5.41ms | 
| Calls | P | F | Exclusive Time  | 
        Inclusive Time  | 
        Subroutine | 
|---|---|---|---|---|---|
| 2018 | 1 | 1 | 2.46ms | 2.46ms | JSON::Schema::Modern::Vocabulary::OpenAPI::keywords | 
| 1 | 1 | 1 | 47µs | 51µs | Module::Runtime::BEGIN@1.320 | 
| 1 | 1 | 1 | 45µs | 72µs | JSON::Schema::Modern::Vocabulary::OpenAPI::BEGIN@13 | 
| 1 | 1 | 1 | 33µs | 370µs | JSON::Schema::Modern::Vocabulary::OpenAPI::BEGIN@10 | 
| 1 | 1 | 1 | 16µs | 16µs | JSON::Schema::Modern::Vocabulary::OpenAPI::BEGIN@9 | 
| 1 | 1 | 1 | 14µs | 908µs | JSON::Schema::Modern::Vocabulary::OpenAPI::BEGIN@11 | 
| 1 | 1 | 1 | 10µs | 56µs | JSON::Schema::Modern::Vocabulary::OpenAPI::BEGIN@17 | 
| 1 | 1 | 1 | 9µs | 24µs | JSON::Schema::Modern::Vocabulary::OpenAPI::BEGIN@14 | 
| 1 | 1 | 1 | 9µs | 49µs | Module::Runtime::BEGIN@2.321 | 
| 1 | 1 | 1 | 8µs | 111µs | JSON::Schema::Modern::Vocabulary::OpenAPI::BEGIN@12 | 
| 1 | 1 | 1 | 8µs | 16µs | JSON::Schema::Modern::Vocabulary::OpenAPI::BEGIN@15 | 
| 1 | 1 | 1 | 8µs | 15µs | JSON::Schema::Modern::Vocabulary::OpenAPI::BEGIN@16 | 
| 1 | 1 | 1 | 6µs | 321µs | JSON::Schema::Modern::Vocabulary::OpenAPI::BEGIN@18 | 
| 5 | 1 | 1 | 5µs | 5µs | JSON::Schema::Modern::Vocabulary::OpenAPI::_traverse_keyword_externalDocs | 
| 0 | 0 | 0 | 0s | 0s | JSON::Schema::Modern::Vocabulary::OpenAPI::_eval_keyword_discriminator | 
| 0 | 0 | 0 | 0s | 0s | JSON::Schema::Modern::Vocabulary::OpenAPI::_eval_keyword_example | 
| 0 | 0 | 0 | 0s | 0s | JSON::Schema::Modern::Vocabulary::OpenAPI::_eval_keyword_externalDocs | 
| 0 | 0 | 0 | 0s | 0s | JSON::Schema::Modern::Vocabulary::OpenAPI::_eval_keyword_xml | 
| 0 | 0 | 0 | 0s | 0s | JSON::Schema::Modern::Vocabulary::OpenAPI::_traverse_keyword_discriminator | 
| 0 | 0 | 0 | 0s | 0s | JSON::Schema::Modern::Vocabulary::OpenAPI::_traverse_keyword_example | 
| 0 | 0 | 0 | 0s | 0s | JSON::Schema::Modern::Vocabulary::OpenAPI::_traverse_keyword_xml | 
| 1 | 1 | 1 | 0s | 0s | JSON::Schema::Modern::Vocabulary::OpenAPI::vocabulary | 
| Line | State ments  | 
      Time on line  | 
      Calls | Time in subs  | 
      Code | 
|---|---|---|---|---|---|
| 1 | 2 | 38µs | 2 | 55µs | # spent 51µs (47+4) within Module::Runtime::BEGIN@1.320 which was called:
#    once (47µs+4µs) by Module::Runtime::require_module at line 1 # spent    51µs making 1 call to Module::Runtime::BEGIN@1.320
# spent     4µs making 1 call to strict::import  | 
| 2 | 2 | 88µs | 2 | 89µs | # spent 49µs (9+40) within Module::Runtime::BEGIN@2.321 which was called:
#    once (9µs+40µs) by Module::Runtime::require_module at line 2 # spent    49µs making 1 call to Module::Runtime::BEGIN@2.321
# spent    40µs making 1 call to warnings::import  | 
| 3 | package JSON::Schema::Modern::Vocabulary::OpenAPI; | ||||
| 4 | # vim: set ts=8 sts=2 sw=2 tw=100 et : | ||||
| 5 | # ABSTRACT: Implementation of the JSON Schema OpenAPI vocabulary | ||||
| 6 | |||||
| 7 | 1 | 0s | our $VERSION = '0.031'; | ||
| 8 | |||||
| 9 | 2 | 74µs | 1 | 16µs | # spent 16µs within JSON::Schema::Modern::Vocabulary::OpenAPI::BEGIN@9 which was called:
#    once (16µs+0s) by Module::Runtime::require_module at line 9 # spent    16µs making 1 call to JSON::Schema::Modern::Vocabulary::OpenAPI::BEGIN@9  | 
| 10 | 2 | 27µs | 2 | 707µs | # spent 370µs (33+337) within JSON::Schema::Modern::Vocabulary::OpenAPI::BEGIN@10 which was called:
#    once (33µs+337µs) by Module::Runtime::require_module at line 10 # spent   370µs making 1 call to JSON::Schema::Modern::Vocabulary::OpenAPI::BEGIN@10
# spent   337µs making 1 call to Moo::import  | 
| 11 | 3 | 79µs | 3 | 1.80ms | # spent 908µs (14+894) within JSON::Schema::Modern::Vocabulary::OpenAPI::BEGIN@11 which was called:
#    once (14µs+894µs) by Module::Runtime::require_module at line 11 # spent   908µs making 1 call to JSON::Schema::Modern::Vocabulary::OpenAPI::BEGIN@11
# spent   875µs making 1 call to strictures::import
# spent    19µs making 1 call to strictures::VERSION  | 
| 12 | 2 | 72µs | 2 | 214µs | # spent 111µs (8+103) within JSON::Schema::Modern::Vocabulary::OpenAPI::BEGIN@12 which was called:
#    once (8µs+103µs) by Module::Runtime::require_module at line 12 # spent   111µs making 1 call to JSON::Schema::Modern::Vocabulary::OpenAPI::BEGIN@12
# spent   103µs making 1 call to experimental::import  | 
| 13 | 2 | 26µs | 2 | 76µs | # spent 72µs (45+27) within JSON::Schema::Modern::Vocabulary::OpenAPI::BEGIN@13 which was called:
#    once (45µs+27µs) by Module::Runtime::require_module at line 13 # spent    72µs making 1 call to JSON::Schema::Modern::Vocabulary::OpenAPI::BEGIN@13
# spent     4µs making 1 call to if::import  | 
| 14 | 2 | 19µs | 2 | 25µs | # spent 24µs (9+15) within JSON::Schema::Modern::Vocabulary::OpenAPI::BEGIN@14 which was called:
#    once (9µs+15µs) by Module::Runtime::require_module at line 14 # spent    24µs making 1 call to JSON::Schema::Modern::Vocabulary::OpenAPI::BEGIN@14
# spent     1µs making 1 call to if::unimport  | 
| 15 | 2 | 58µs | 2 | 16µs | # spent 16µs (8+8) within JSON::Schema::Modern::Vocabulary::OpenAPI::BEGIN@15 which was called:
#    once (8µs+8µs) by Module::Runtime::require_module at line 15 # spent    16µs making 1 call to JSON::Schema::Modern::Vocabulary::OpenAPI::BEGIN@15
# spent     0s making 1 call to if::unimport  | 
| 16 | 2 | 19µs | 2 | 15µs | # spent 15µs (8+7) within JSON::Schema::Modern::Vocabulary::OpenAPI::BEGIN@16 which was called:
#    once (8µs+7µs) by Module::Runtime::require_module at line 16 # spent    15µs making 1 call to JSON::Schema::Modern::Vocabulary::OpenAPI::BEGIN@16
# spent     0s making 1 call to if::unimport  | 
| 17 | 3 | 60µs | 3 | 102µs | # spent 56µs (10+46) within JSON::Schema::Modern::Vocabulary::OpenAPI::BEGIN@17 which was called:
#    once (10µs+46µs) by Module::Runtime::require_module at line 17 # spent    56µs making 1 call to JSON::Schema::Modern::Vocabulary::OpenAPI::BEGIN@17
# spent    39µs making 1 call to Exporter::import
# spent     7µs making 1 call to UNIVERSAL::VERSION  | 
| 18 | 2 | 830µs | 2 | 636µs | # spent 321µs (6+315) within JSON::Schema::Modern::Vocabulary::OpenAPI::BEGIN@18 which was called:
#    once (6µs+315µs) by Module::Runtime::require_module at line 18 # spent   321µs making 1 call to JSON::Schema::Modern::Vocabulary::OpenAPI::BEGIN@18
# spent   315µs making 1 call to namespace::clean::import  | 
| 19 | |||||
| 20 | 1 | 2µs | 1 | 486µs | with 'JSON::Schema::Modern::Vocabulary'; # spent   486µs making 1 call to Moo::with  | 
| 21 | |||||
| 22 | # spent 0s within JSON::Schema::Modern::Vocabulary::OpenAPI::vocabulary which was called:
#    once (0s+0s) by JSON::Schema::Modern::add_vocabulary at line 679 of JSON/Schema/Modern.pm  | ||||
| 23 | 1 | 2µs | 'https://spec.openapis.org/oas/3.1/vocab/base' => 'draft2020-12', | ||
| 24 | } | ||||
| 25 | |||||
| 26 | # spent 2.46ms within JSON::Schema::Modern::Vocabulary::OpenAPI::keywords which was called 2018 times, avg 1µs/call:
# 2018 times (2.46ms+0s) by JSON::Schema::Modern::_traverse_subschema at line 447 of JSON/Schema/Modern.pm, avg 1µs/call  | ||||
| 27 | 2018 | 3.94ms | qw(discriminator example externalDocs xml); | ||
| 28 | } | ||||
| 29 | |||||
| 30 | sub _traverse_keyword_discriminator ($self, $schema, $state) { | ||||
| 31 | return if not assert_keyword_type($state, $schema, 'object'); | ||||
| 32 | |||||
| 33 | # "the discriminator field MUST be a required field" | ||||
| 34 | return E($state, 'missing required field propertyName') | ||||
| 35 | if not exists $schema->{discriminator}{propertyName}; | ||||
| 36 | return E({ %$state, _schema_path_suffix => 'propertyName' }, 'discriminator propertyName is not a string') | ||||
| 37 | if not is_type('string', $schema->{discriminator}{propertyName}); | ||||
| 38 | |||||
| 39 | my $valid = 1; | ||||
| 40 | if (exists $schema->{discriminator}{mapping}) { | ||||
| 41 | return if not assert_keyword_type({ %$state, _schema_path_suffix => 'mapping' }, $schema, 'object'); | ||||
| 42 | return E({ %$state, _schema_path_suffix => 'mapping' }, 'discriminator mapping is not an object ') | ||||
| 43 | if not is_type('object', $schema->{discriminator}{mapping}); | ||||
| 44 | foreach my $mapping_key (sort keys $schema->{discriminator}{mapping}->%*) { | ||||
| 45 | my $uri = $schema->{discriminator}{mapping}{$mapping_key}; | ||||
| 46 | $valid = E({ %$state, _schema_path_suffix => [ 'mapping', $mapping_key ] }, 'discriminator mapping value for "%s" is not a string', $mapping_key), next if not is_type('string', $uri); | ||||
| 47 | } | ||||
| 48 | } | ||||
| 49 | |||||
| 50 | $valid = E($state, 'missing sibling keyword: one of oneOf, anyOf, allOf') | ||||
| 51 | if not grep exists $schema->{$_}, qw(oneOf anyOf allOf); | ||||
| 52 | |||||
| 53 | return 1; | ||||
| 54 | } | ||||
| 55 | |||||
| 56 | sub _eval_keyword_discriminator ($self, $data, $schema, $state) { | ||||
| 57 | # Note: the spec is unclear of the expected behaviour when the data instance is not an object | ||||
| 58 | return 1 if not is_type('object', $data); | ||||
| 59 | |||||
| 60 | my $discriminator_key = $schema->{discriminator}{propertyName}; | ||||
| 61 | |||||
| 62 | # property with name <propertyName> MUST be present in the data payload | ||||
| 63 | return E($state, 'missing required discriminator field "%s"', $discriminator_key) | ||||
| 64 | if not exists $data->{$discriminator_key}; | ||||
| 65 | |||||
| 66 | my $discriminator_value = $data->{$discriminator_key}; | ||||
| 67 | |||||
| 68 | # if /components/$discriminator_value exists, that schema must validate | ||||
| 69 | my $uri = Mojo::URL->new->fragment(jsonp('', qw(components schemas), $discriminator_value)) | ||||
| 70 | ->to_abs($state->{initial_schema_uri}); | ||||
| 71 | if (my $component_schema_info = $state->{evaluator}->_fetch_from_uri($uri)) { | ||||
| 72 | $state = { %$state, _schema_path_suffix => 'propertyName' }; | ||||
| 73 | } | ||||
| 74 | elsif (exists $schema->{discriminator}{mapping} and exists $schema->{discriminator}{mapping}{$discriminator_value}) { | ||||
| 75 | # use 'mapping' to determine which schema to use. | ||||
| 76 | $uri = Mojo::URL->new($schema->{discriminator}{mapping}{$discriminator_value}); | ||||
| 77 | $state = { %$state, _schema_path_suffix => [ 'mapping', $discriminator_value ] }; | ||||
| 78 | } | ||||
| 79 | else { | ||||
| 80 | # If the discriminator value does not match an implicit or explicit mapping, no schema can be | ||||
| 81 | # determined and validation SHOULD fail. | ||||
| 82 | return E($state, 'invalid %s: "%s"', $discriminator_key, $discriminator_value); | ||||
| 83 | } | ||||
| 84 | |||||
| 85 | return E($state, 'subschema for %s: %s is invalid', $discriminator_key, $discriminator_value) | ||||
| 86 | if not $self->eval_subschema_at_uri($data, $schema, $state, $uri); | ||||
| 87 | return 1; | ||||
| 88 | } | ||||
| 89 | |||||
| 90 | sub _traverse_keyword_example { 1 } | ||||
| 91 | |||||
| 92 | sub _eval_keyword_example ($self, $data, $schema, $state) { | ||||
| 93 | annotate_self($state, $schema); | ||||
| 94 | } | ||||
| 95 | |||||
| 96 | # until we do something with these values, we do not bother checking the structure | ||||
| 97 | 5 | 16µs | # spent 5µs within JSON::Schema::Modern::Vocabulary::OpenAPI::_traverse_keyword_externalDocs which was called 5 times, avg 1µs/call:
# 5 times (5µs+0s) by JSON::Schema::Modern::_traverse_subschema at line 457 of JSON/Schema/Modern.pm, avg 1µs/call  | ||
| 98 | |||||
| 99 | sub _eval_keyword_externalDocs { goto \&_eval_keyword_example } | ||||
| 100 | |||||
| 101 | # until we do something with these values, we do not bother checking the structure | ||||
| 102 | sub _traverse_keyword_xml { 1 } | ||||
| 103 | |||||
| 104 | sub _eval_keyword_xml { goto \&_eval_keyword_example } | ||||
| 105 | |||||
| 106 | 1 | 8µs | 1; | ||
| 107 | |||||
| 108 | 1 | 50µs | 1 | 360µs | __END__ # spent   360µs making 1 call to B::Hooks::EndOfScope::XS::__ANON__[B/Hooks/EndOfScope/XS.pm:26]  |