Class: Senko::Compiler::RefResolver

Inherits:
Object
  • Object
show all
Defined in:
lib/senko/compiler/ref_resolver.rb

Constant Summary collapse

ROOT_SCOPE =
:__senko_root__
BUILTIN_METASCHEMA_URIS =
[
  'https://json-schema.org/draft/2020-12/schema',
  'https://json-schema.org/draft/2020-12/schema#',
  'https://json-schema.org/draft/2019-09/schema',
  'https://json-schema.org/draft/2019-09/schema#',
  'http://json-schema.org/draft-07/schema',
  'http://json-schema.org/draft-07/schema#',
  'http://json-schema.org/draft-06/schema',
  'http://json-schema.org/draft-06/schema#',
  'http://json-schema.org/draft-04/schema',
  'http://json-schema.org/draft-04/schema#'
].freeze

Instance Method Summary collapse

Constructor Details

#initialize(root_schema, schemas: {}, ref_resolver: nil) ⇒ RefResolver

Returns a new instance of RefResolver.



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/senko/compiler/ref_resolver.rb', line 24

def initialize(root_schema, schemas: {}, ref_resolver: nil)
  @root_schema = root_schema
  @schemas = {}
  schemas.each do |uri, schema|
    @schemas[uri.to_s] = registered_schema(uri.to_s, schema)
  end
  @ref_resolver = ref_resolver
  @resources = {}
  @locations = {}
  @schema_scopes = {}
  @resource_scopes = {}
  @anchors = {}
  @dynamic_anchors = {}
  @base_by_location = {}
  @scope_base = {}
  index_schema(@root_schema, '', root_base_uri, ROOT_SCOPE)
  index_registered_schemas
end

Instance Method Details

#base_uri_for(location, scope) ⇒ Object



79
80
81
# File 'lib/senko/compiler/ref_resolver.rb', line 79

def base_uri_for(location, scope)
  base_for(location, scope)
end

#dynamic_anchors_for(base_uri) ⇒ Object



83
84
85
86
87
# File 'lib/senko/compiler/ref_resolver.rb', line 83

def dynamic_anchors_for(base_uri)
  @dynamic_anchors.each_with_object({}) do |((base, anchor), resolved), result|
    result[anchor] = resolved if base == base_uri
  end
end

#resolve(uri, from: '', scope: ROOT_SCOPE) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/senko/compiler/ref_resolver.rb', line 43

def resolve(uri, from: '', scope: ROOT_SCOPE)
  uri = uri.to_s
  base_uri = base_for(from, scope)
  absolute = absolute_ref(uri, base_uri)
  if absolute.empty? || absolute == '#'
    return ResolvedRef.new(schema: @root_schema, keyword_location: '', base_uri: root_base_uri, scope: ROOT_SCOPE)
  end

  base, fragment = split_fragment(absolute)
  schema, target_scope = schema_for_base(base)
  unless fragment
    return ResolvedRef.new(
      schema: schema,
      keyword_location: location_for_schema(schema),
      base_uri: base,
      scope: target_scope
    )
  end

  resolve_fragment(schema, fragment, base, target_scope)
end

#resolve_dynamic(uri, from: '', scope: ROOT_SCOPE) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/senko/compiler/ref_resolver.rb', line 65

def resolve_dynamic(uri, from: '', scope: ROOT_SCOPE)
  uri = uri.to_s
  base_uri = base_for(from, scope)
  absolute = absolute_ref(uri, base_uri)
  base, fragment = split_fragment(absolute)
  anchor = URI::DEFAULT_PARSER.unescape(fragment.to_s)

  if !anchor.empty? && !anchor.start_with?('/') && @dynamic_anchors.key?([base, anchor])
    return @dynamic_anchors.fetch([base, anchor])
  end

  resolve(uri, from: from, scope: scope)
end