module Lutaml::Model::Serialize::Initialization

def add_custom_handling_methods_to_model(klass)

Parameters:
  • klass (Class) -- The model class
def add_custom_handling_methods_to_model(klass)
  Utils.add_method_if_not_defined(klass,
                                  :using_default_for) do |attribute_name|
    @using_default ||= {}
    @using_default[attribute_name] = true
  end
  Utils.add_method_if_not_defined(klass,
                                  :value_set_for) do |attribute_name|
    @using_default ||= {}
    @using_default[attribute_name] = false
  end
  Utils.add_method_if_not_defined(klass,
                                  :values_set_for) do |attribute_names|
    @using_default ||= {}
    attribute_names.each { |name| @using_default[name] = false }
  end
  Utils.add_method_if_not_defined(klass,
                                  :using_default?) do |attribute_name|
    @using_default ||= {}
    !!@using_default[attribute_name]
  end
  # Hook for format-specific model methods (e.g., XML adds ordered, mixed, element_order)
  add_format_specific_model_methods(klass)
end

def add_format_specific_model_methods(_klass)

Parameters:
  • _klass (Class) -- The model class
def add_format_specific_model_methods(_klass)
  # No-op by default
end

def allocate_for_deserialization(register = nil)

Returns:
  • (Object) - The allocated instance

Parameters:
  • register (Symbol, nil) -- The register context
def allocate_for_deserialization(register = nil)
  instance = allocate
  register_id = extract_register_id(register)
  instance.finalize_deserialization(register_id)
  instance
end

def attributes(register = nil)

Returns:
  • (Hash) - The attributes hash

Parameters:
  • register (Symbol, nil) -- The register context
def attributes(register = nil)
  ensure_imports!(register) if finalized?
  if @register_records&.any?
    @attributes.merge(@register_records[extract_register_id(register)][:attributes])
  else
    @attributes
  end
end

def cast(value)

Returns:
  • (Object) - The same value

Parameters:
  • value (Object) -- The value to cast
def cast(value)
  value
end

def choice(min: 1, max: 1, format: nil, &block)

Parameters:
  • block (Proc) -- The choice definition block
  • max (Integer) -- Maximum number of choices
  • min (Integer) -- Minimum number of choices
def choice(min: 1, max: 1, format: nil, &block)
  @choice_attributes << Choice.new(self, min, max,
                                   format: format).tap do |c|
    c.instance_eval(&block)
  end
end

def choice_attributes(register = nil)

Returns:
  • (Array) - The choice attributes array

Parameters:
  • register (Symbol, nil) -- The register context
def choice_attributes(register = nil)
  ensure_imports!(register) if finalized?
  if @register_records&.any?
    @choice_attributes + @register_records[extract_register_id(register)][:choice_attributes]
  else
    @choice_attributes
  end
end

def class_attributes

Returns:
  • (Hash) - The raw attributes hash
def class_attributes
  @attributes
end

def clear_cache(register_id = nil)

Parameters:
  • register_id (Symbol, nil) -- If provided, only clear cache for this specific context
def clear_cache(register_id = nil)
  # Clear centralized type cache in GlobalContext.resolver
  if defined?(Lutaml::Model::GlobalContext)
    GlobalContext.resolver.clear_cache(register_id)
  end
  # Clear per-Attribute type caches (stale entries from GC'd TypeContext objects)
  class_attributes.each_value(&:clear_type_cache)
  @register_records&.each_value do |record|
    record[:attributes]&.each_value(&:clear_type_cache)
  end
  # Clear centralized mapping and transformation caches
  # (Single Source of Truth - no longer uses instance variables)
  TransformationRegistry.instance.clear
  # Clear Transform cache (uses class identity as key)
  Transform.invalidate_for(self, register_id)
  # Clear import resolution guard flags so imports can be re-resolved
  instance_variables.each do |ivar|
    ivar_s = ivar.to_s
    remove_instance_variable(ivar) if ivar_s.start_with?("@_imports_resolved_") ||
      ivar_s == "@_register_methods_defined"
  end
end

def deep_duplicate_choice_attributes(source_class, register = nil)

Returns:
  • (Array) - The duplicated choice attributes

Parameters:
  • source_class (Class) -- The source class
def deep_duplicate_choice_attributes(source_class, register = nil)
  choice_attrs = Array(source_class.choice_attributes)
  choice_attrs.map do |choice_attr|
    choice_attr.deep_duplicate(self, register)
  end
end

def define_collection_register_methods(name)

Define getter/setter for a collection register-specific attribute.
def define_collection_register_methods(name)
  define_method(name) do |*args|
    if args.empty?
      current = instance_variable_get(:"@#{name}")
      current.equal?(LAZY_EMPTY_COLLECTION) ? [] : current
    else
      value = args.first
      current = instance_variable_get(:"@#{name}")
      current = [] if current.equal?(LAZY_EMPTY_COLLECTION)
      new_value = current.is_a?(Array) ? current + [value] : value
      instance_variable_set(:"@#{name}", new_value)
      record_mutation(name, value)
      value
    end
  end
  define_method(:"#{name}=") do |value|
    value_set_for(name)
    reg_attr = resolve_register_attr(name)
    value = reg_attr.cast_value(value, lutaml_register)
    current = instance_variable_get(:"@#{name}")
    if current.equal?(LAZY_EMPTY_COLLECTION) &&
        (value.nil? || Lutaml::Model::Utils.uninitialized?(value))
      # Sentinel stays — no allocation for empty collections
    else
      instance_variable_set(:"@#{name}", value)
    end
    record_mutation_collection(name, value)
  end
end

def define_scalar_register_methods(name)

Define getter/setter for a scalar register-specific attribute.
def define_scalar_register_methods(name)
  define_method(name) do |*args|
    if args.empty?
      instance_variable_get(:"@#{name}")
    else
      public_send(:"#{name}=", args.first)
      args.first
    end
  end
  define_method(:"#{name}=") do |value|
    value_set_for(name)
    reg_attr = resolve_register_attr(name)
    value = reg_attr.cast_value(value, lutaml_register)
    instance_variable_set(:"@#{name}", value)
    record_mutation(name, value)
  end
end

def ensure_format_mapping_imports!(_register = nil)

Parameters:
  • _register (Symbol, nil) -- The register context
def ensure_format_mapping_imports!(_register = nil)
  # No-op by default; XML overrides via prepend
end

def ensure_imports!(register = nil)

Parameters:
  • register (Symbol, nil) -- The register context
def ensure_imports!(register = nil)
  ensure_model_imports!(register)
  ensure_choice_imports!(register)
  ensure_restrict_attributes!(register)
  # Hook for format-specific mapping import resolution.
  # XML overrides this to call mappings[:xml]&.ensure_mappings_imported!(register)
  ensure_format_mapping_imports!(register)
end

def ensure_register_methods_defined(register_id)

Parameters:
  • register_id (Symbol) -- The register ID
def ensure_register_methods_defined(register_id)
  return if register_id == :default
  @_register_methods_defined ||= {}
  return if @_register_methods_defined[register_id]
  reg_record = register_records[register_id]
  return unless reg_record
  default_attrs = class_attributes || {}
  reg_record_attrs = reg_record[:attributes] || {}
  reg_record_attrs.each do |name, attr|
    next if default_attrs.key?(name)
    next if method_defined?(name, false)
    if attr.collection?
      define_collection_register_methods(name)
    else
      define_scalar_register_methods(name)
    end
  end
  @_register_methods_defined[register_id] = true
end

def extract_register_id(register)

Returns:
  • (Symbol) - The normalized register ID

Parameters:
  • register (Symbol, String, nil) -- The register identifier
def extract_register_id(register)
  register&.to_sym || lutaml_default_register || Lutaml::Model::Config.default_register
end

def included(base)

Parameters:
  • base (Class) -- The including class
def included(base)
  base.extend(ClassMethods)
  base.initialize_attrs(self)
end

def inherited(subclass)

Parameters:
  • subclass (Class) -- The inheriting class
def inherited(subclass)
  super
  subclass.initialize_attrs(self)
end

def initialize_attrs(source_class)

Parameters:
  • source_class (Class) -- The source class to copy from
def initialize_attrs(source_class)
  @mappings = Utils.deep_dup(source_class.mappings) || {}
  @attributes = Utils.deep_dup(source_class.class_attributes) || {}
  @choice_attributes = deep_duplicate_choice_attributes(source_class)
  @register_records = Utils.deep_dup(
    source_class.register_records,
  ) || ::Hash.new do |hash, key|
         hash[key] = { attributes: {}, choice_attributes: [] }
       end
  model(self)
end

def lutaml_default_register

Returns:
  • (Symbol, nil) - The default register ID or nil to use Config.default_register
def lutaml_default_register
  nil
end

def model(klass = nil)

Returns:
  • (Class) - The model class

Parameters:
  • klass (Class, nil) -- The model class to set
def model(klass = nil)
  if klass
    @model = klass
    add_custom_handling_methods_to_model(klass)
  else
    @model
  end
end

def namespace(_ns_class = nil)

Returns:
  • (Class, nil) - the namespace class

Parameters:
  • _ns_class (Class, nil) -- Namespace class (handled by format modules)
def namespace(_ns_class = nil)
  @namespace_class
end

def namespace_prefix

Returns:
  • (String, nil) - the namespace prefix
def namespace_prefix
  nil
end

def namespace_uri

Returns:
  • (String, nil) - the namespace URI
def namespace_uri
  nil
end

def reference_resolvable?

opt out for classes that never participate in cross-referencing.
backward compatibility. Use `skip_reference_registration` to
global Store for reference resolution. Defaults to true for
Whether instances of this class should be registered in the
def reference_resolvable?
  return true unless instance_variable_defined?(:@skip_reference_registration)
  !@skip_reference_registration
end

def register(name)

Returns:
  • (Symbol, nil) - The register name as a symbol

Parameters:
  • name (Symbol, String, nil) -- The register name
def register(name)
  name&.to_sym
end

def register_record(register_id = nil)

Returns:
  • (Hash, nil) - The register record hash or nil

Parameters:
  • register_id (Symbol, nil) -- The register context
def register_record(register_id = nil)
  register_records[extract_register_id(register_id)]
end

def set_register_context(register_id)

Returns:
  • (void) -

Parameters:
  • register_id (Symbol) -- The register ID
def set_register_context(register_id)
  return if instance_variable_defined?(:@register)
  @register = register_id
end

def skip_reference_registration

resolved by reference (no xml_id or similar attributes).
memory and registration overhead for classes that are never
Instances will not be tracked in the global Store, saving
Opt out of Store registration for this class.
def skip_reference_registration
  @skip_reference_registration = true
end