Class: Schemurai::Internal::SchemaGraph
- Inherits:
-
Object
- Object
- Schemurai::Internal::SchemaGraph
- Defined in:
- lib/schemurai/schema_graph.rb
Defined Under Namespace
Classes: Resource
Instance Attribute Summary collapse
-
#nodes ⇒ Object
readonly
Returns the value of attribute nodes.
-
#resources ⇒ Object
readonly
Returns the value of attribute resources.
-
#uri_registry ⇒ Object
readonly
Returns the value of attribute uri_registry.
Instance Method Summary collapse
- #compile(schema, base_uri: nil, dialect: @default_dialect) ⇒ Object
- #dynamic_anchor(resource, name) ⇒ Object
- #dynamic_scope? ⇒ Boolean
-
#initialize(schemas: {}, dialect: Dialect.resolve) ⇒ SchemaGraph
constructor
A new instance of SchemaGraph.
- #make_shareable ⇒ Object
- #meta_schema_root(schema) ⇒ Object
- #node_at(uri) ⇒ Object
- #resolve(node, reference) ⇒ Object
Constructor Details
#initialize(schemas: {}, dialect: Dialect.resolve) ⇒ SchemaGraph
Returns a new instance of SchemaGraph.
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/schemurai/schema_graph.rb', line 84 def initialize(schemas: {}, dialect: Dialect.resolve) SchemaDomain.validate_registry!(schemas) @external_schemas = schemas.dup @indexed_external_schemas = nil @compiled_roots = {}.compare_by_identity @meta_schema_roots = {} @resources = {} @uri_registry = {} @nodes = [] @nodes_by_document_location = nil @resolved_refs = nil @dynamic_anchors = {} # External schemas are indexed lazily, so their references are not yet # available to compile_node. Track conservatively from the caller. # Once required, dynamic scope tracking must remain enabled because all # evaluators sharing this graph may reach the dynamic reference. @dynamic_scope = !schemas.empty? @default_dialect = dialect end |
Instance Attribute Details
#nodes ⇒ Object (readonly)
Returns the value of attribute nodes.
82 83 84 |
# File 'lib/schemurai/schema_graph.rb', line 82 def nodes @nodes end |
#resources ⇒ Object (readonly)
Returns the value of attribute resources.
82 83 84 |
# File 'lib/schemurai/schema_graph.rb', line 82 def resources @resources end |
#uri_registry ⇒ Object (readonly)
Returns the value of attribute uri_registry.
82 83 84 |
# File 'lib/schemurai/schema_graph.rb', line 82 def uri_registry @uri_registry end |
Instance Method Details
#compile(schema, base_uri: nil, dialect: @default_dialect) ⇒ Object
104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/schemurai/schema_graph.rb', line 104 def compile(schema, base_uri: nil, dialect: @default_dialect) SchemaDomain.validate!(schema) roots = (@compiled_roots[schema] ||= {}) base_uri = base_uri.to_s cache_key = [base_uri, dialect] root = roots[cache_key] return root if root roots[cache_key] = compile_atomically do |changes| root_dialect = dialect_for(schema, dialect, changes) compile_document(schema, base_uri, root_dialect, changes) end end |
#dynamic_anchor(resource, name) ⇒ Object
143 144 145 |
# File 'lib/schemurai/schema_graph.rb', line 143 def dynamic_anchor(resource, name) @dynamic_anchors.dig(resource, name) end |
#dynamic_scope? ⇒ Boolean
147 148 149 |
# File 'lib/schemurai/schema_graph.rb', line 147 def dynamic_scope? @dynamic_scope end |
#make_shareable ⇒ Object
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/schemurai/schema_graph.rb', line 151 def make_shareable return self if Ractor.shareable?(self) @external_schemas.each_key do |uri| index_external(strip_fragment(uri.to_s), @default_dialect) end index = 0 while index < nodes.length node = nodes[index] schema = node.schema if schema.is_a?(Hash) ["$ref", "$recursiveRef", "$dynamicRef"].each do |keyword| resolve(node, schema[keyword]) if schema.key?(keyword) end end index += 1 end @resolved_refs ||= {} Ractor.make_shareable(self) end |
#meta_schema_root(schema) ⇒ Object
118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/schemurai/schema_graph.rb', line 118 def (schema) SchemaDomain.validate!(schema) uri = if schema.is_a?(Hash) && schema.key?("$schema") schema["$schema"].to_s else @default_dialect.uri end root = (@meta_schema_roots[uri] ||= compile({"$ref" => uri})) resolve(root, uri) root end |
#node_at(uri) ⇒ Object
253 254 255 |
# File 'lib/schemurai/schema_graph.rb', line 253 def node_at(uri) uri_registry[uri.to_s] end |
#resolve(node, reference) ⇒ Object
130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/schemurai/schema_graph.rb', line 130 def resolve(node, reference) if (resolved = @resolved_refs&.[](node))&.key?(reference) return resolved[reference] end if Ractor.shareable?(self) raise ResolutionError, "reference #{reference.inspect} was not resolved before sharing" end target = resolve_uncached(node, reference) ((@resolved_refs ||= {})[node] ||= {})[reference] = target end |