Class: Lutaml::Model::Schema::XmlCompiler::SpecBuilder

Inherits:
Object
  • Object
show all
Defined in:
lib/lutaml/model/schema/xml_compiler/spec_builder.rb,
lib/lutaml/model/schema/xml_compiler/spec_builder/members.rb,
lib/lutaml/model/schema/xml_compiler/spec_builder/simple_types.rb,
lib/lutaml/model/schema/xml_compiler/spec_builder/complex_types.rb

Overview

Walks parsed XSD AST objects and emits Definitions::* specs. Holds the in-progress class hashes that ref resolution looks up by name. Stateful by design (refs and forward references demand it); kept out of XmlCompiler.rb so the orchestrator stays focused on parse/dispatch.

Defined Under Namespace

Classes: ComplexTypes, Members, SimpleTypes

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeSpecBuilder

Returns a new instance of SpecBuilder.



22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/lutaml/model/schema/xml_compiler/spec_builder.rb', line 22

def initialize
  @simple_types = MappingHash.new
  @complex_types = MappingHash.new
  @group_types = MappingHash.new
  @elements = MappingHash.new
  @attributes = MappingHash.new
  @attribute_groups = MappingHash.new
  @namespace_classes = MappingHash.new
  @simple_types_builder  = SimpleTypes.new(self)
  @members_builder       = Members.new(self)
  @complex_types_builder = ComplexTypes.new(self)
end

Instance Attribute Details

#attribute_groupsObject (readonly)

Returns the value of attribute attribute_groups.



17
18
19
# File 'lib/lutaml/model/schema/xml_compiler/spec_builder.rb', line 17

def attribute_groups
  @attribute_groups
end

#attributesObject (readonly)

Returns the value of attribute attributes.



17
18
19
# File 'lib/lutaml/model/schema/xml_compiler/spec_builder.rb', line 17

def attributes
  @attributes
end

#complex_typesObject (readonly)

Returns the value of attribute complex_types.



17
18
19
# File 'lib/lutaml/model/schema/xml_compiler/spec_builder.rb', line 17

def complex_types
  @complex_types
end

#elementsObject (readonly)

Returns the value of attribute elements.



17
18
19
# File 'lib/lutaml/model/schema/xml_compiler/spec_builder.rb', line 17

def elements
  @elements
end

#group_typesObject (readonly)

Returns the value of attribute group_types.



17
18
19
# File 'lib/lutaml/model/schema/xml_compiler/spec_builder.rb', line 17

def group_types
  @group_types
end

#members_builderObject (readonly)

Returns the value of attribute members_builder.



17
18
19
# File 'lib/lutaml/model/schema/xml_compiler/spec_builder.rb', line 17

def members_builder
  @members_builder
end

#namespace_class_nameObject (readonly)

Returns the value of attribute namespace_class_name.



17
18
19
# File 'lib/lutaml/model/schema/xml_compiler/spec_builder.rb', line 17

def namespace_class_name
  @namespace_class_name
end

#namespace_classesObject (readonly)

Returns the value of attribute namespace_classes.



17
18
19
# File 'lib/lutaml/model/schema/xml_compiler/spec_builder.rb', line 17

def namespace_classes
  @namespace_classes
end

#simple_typesObject (readonly)

Returns the value of attribute simple_types.



17
18
19
# File 'lib/lutaml/model/schema/xml_compiler/spec_builder.rb', line 17

def simple_types
  @simple_types
end

Instance Method Details

#add_supported_typesObject

Add the built-in XSD types (NonNegativeInteger, NormalizedString, etc.) as Definitions::RestrictedType entries.



115
116
117
118
119
120
121
122
# File 'lib/lutaml/model/schema/xml_compiler/spec_builder.rb', line 115

def add_supported_types
  SupportedDataTypes.each do |name, info|
    next if info[:skippable]

    str_name = name.to_s
    @simple_types[str_name] = @simple_types_builder.build_supported(str_name, info)
  end
end

#all_modelsObject

Every generated class spec keyed by name. Used by the orchestrator to build CompiledOutput entries without reaching into the builder's internal hashes.



127
128
129
# File 'lib/lutaml/model/schema/xml_compiler/spec_builder.rb', line 127

def all_models
  @simple_types.merge(@complex_types).merge(@group_types)
end

#build_complex_type(complex_type) ⇒ Object



145
# File 'lib/lutaml/model/schema/xml_compiler/spec_builder.rb', line 145

def build_complex_type(complex_type) = @complex_types_builder.build(complex_type)

#build_complex_types(schemas) ⇒ Object



85
86
87
# File 'lib/lutaml/model/schema/xml_compiler/spec_builder.rb', line 85

def build_complex_types(schemas)
  each_schema_item(schemas) { |item, schema| dispatch_complex(item, schema) }
end

#build_simple_type(simple_type) ⇒ Object

Public surface used by the Members sub-builder to register nested anonymous types it encounters during attribute / element resolution.



144
# File 'lib/lutaml/model/schema/xml_compiler/spec_builder.rb', line 144

def build_simple_type(simple_type) = @simple_types_builder.build(simple_type)

#collect_lookups(schemas) ⇒ Object



81
82
83
# File 'lib/lutaml/model/schema/xml_compiler/spec_builder.rb', line 81

def collect_lookups(schemas)
  each_schema_item(schemas) { |item, schema| dispatch_lookup(item, schema) }
end

#collect_namespaces(schemas, options) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/lutaml/model/schema/xml_compiler/spec_builder.rb', line 46

def collect_namespaces(schemas, options)
  requested_uri = options[:namespace]
  uris = []
  uris << requested_uri if requested_uri
  schemas.each do |schema|
    uris << schema.target_namespace if schema.target_namespace
  end
  uris.uniq.each do |uri|
    next if uri.nil? || uri.empty?

    prefix = options[:prefix] if requested_uri == uri
    ns = Definitions::Namespace.new(
      class_name: NamespaceNaming.class_name_for(uri),
      uri: uri,
      prefix_default: prefix || NamespaceNaming.prefix_for(uri),
    )
    @namespace_classes[ns.class_name] = ns
  end
  # Resolve the namespace_class_name once. When the caller
  # passed :namespace, every generated complex type gets this
  # name. Mirrors XmlCompiler::ComplexType#setup_options on main.
  @namespace_class_name =
    requested_uri && @namespace_classes.values.find { |ns| ns.uri == requested_uri }&.class_name
end

#dispatch_complex(item, _schema) ⇒ Object



104
105
106
107
108
109
110
111
# File 'lib/lutaml/model/schema/xml_compiler/spec_builder.rb', line 104

def dispatch_complex(item, _schema)
  case item
  when Lutaml::Xml::Schema::Xsd::ComplexType
    @complex_types[item.name] = @complex_types_builder.build(item)
  when Lutaml::Xml::Schema::Xsd::Group
    @group_types[item.name] = @complex_types_builder.build_group(item)
  end
end

#dispatch_lookup(item, schema) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/lutaml/model/schema/xml_compiler/spec_builder.rb', line 89

def dispatch_lookup(item, schema)
  case item
  when Lutaml::Xml::Schema::Xsd::SimpleType
    @simple_types[item.name] = build_simple_type(item)
  when Lutaml::Xml::Schema::Xsd::Element
    @elements[item.name] = @members_builder.build_top_level_attribute(item, kind: :element)
  when Lutaml::Xml::Schema::Xsd::Attribute
    return if xml_defined_attribute?(schema, item.name)

    @attributes[item.name] = @members_builder.build_top_level_attribute(item, kind: :attribute)
  when Lutaml::Xml::Schema::Xsd::AttributeGroup
    @attribute_groups[item.name] = @complex_types_builder.build_attribute_group(item)
  end
end

#finalize_required_files!Object

Stamp required_files on every walked complex / group model. The skippable predicate is supplied by SupportedDataTypes — the orchestrator never has to thread the type table through.



134
135
136
137
138
139
# File 'lib/lutaml/model/schema/xml_compiler/spec_builder.rb', line 134

def finalize_required_files!
  (@complex_types.each_value.to_a + @group_types.each_value.to_a).each do |model|
    model.required_files = Renderers::RequiredFilesCalculator
      .for_xml(model, skippable_type: SupportedDataTypes.method(:skippable?))
  end
end

#populate_default_attributesObject



35
36
37
38
39
40
41
42
43
44
# File 'lib/lutaml/model/schema/xml_compiler/spec_builder.rb', line 35

def populate_default_attributes
  XmlCompiler::XML_DEFINED_ATTRIBUTES.each do |name, w3c_class|
    @attributes[name] = Definitions::Attribute.new(
      name: Utils.snake_case(name),
      type: Definitions::TypeRef.new(kind: :w3c, value: w3c_class),
      xml_name: name,
      kind: :attribute,
    )
  end
end

#walk_schemas(schemas) ⇒ Object



71
72
73
74
75
76
77
78
79
# File 'lib/lutaml/model/schema/xml_compiler/spec_builder.rb', line 71

def walk_schemas(schemas)
  return if schemas.empty?

  # Two-pass walk: register top-level Elements / Attributes /
  # AttributeGroups / SimpleTypes first so forward references
  # from ComplexTypes / Groups resolve in pass 2.
  collect_lookups(schemas)
  build_complex_types(schemas)
end