module T::Props::Private::DeserializerGenerator

def self.generate(props, defaults)

def self.generate(props, defaults)
  stored_props = props.reject {|_, rules| rules[:dont_store]}
  parts = stored_props.map do |prop, rules|
    # All of these strings should already be validated (directly or
    # indirectly) in `validate_prop_name`, so we don't bother with a nice
    # error message, but we double check here to prevent a refactoring
    # from introducing a security vulnerability.
    raise unless T::Props::Decorator::SAFE_NAME.match?(prop.to_s)
    hash_key = rules.fetch(:serialized_form)
    raise unless T::Props::Decorator::SAFE_NAME.match?(hash_key)
    ivar_name = rules.fetch(:accessor_key).to_s
    raise unless ivar_name.start_with?('@') && T::Props::Decorator::SAFE_NAME.match?(ivar_name[1..-1])
    transformation = SerdeTransform.generate(
      T::Utils::Nilable.get_underlying_type_object(rules.fetch(:type_object)),
      SerdeTransform::Mode::DESERIALIZE,
      'val'
    )
    transformed_val = if transformation
      # Rescuing exactly NoMethodError is intended as a temporary hack
      # to preserve the semantics from before codegen. More generally
      # we are inconsistent about typechecking on deser and need to decide
      # our strategy here.
      <<~RUBY
        begin
          #{transformation}
        rescue NoMethodError => e
          T::Configuration.soft_assert_handler(
            'Deserialization error (probably unexpected stored type)',
            storytime: {
              klass: self.class,
              prop: #{prop.inspect},
              value: val,
              error: e.message,
              notify: 'djudd'
            }
          )
          val
        end
      RUBY
    else
      'val'
    end
    nil_handler = generate_nil_handler(
      prop: prop,
      serialized_form: hash_key,
      default: defaults[prop],
      nilable_type: T::Props::Utils.optional_prop?(rules),
      raise_on_nil_write: !!rules[:raise_on_nil_write],
    )
    <<~RUBY
      val = hash[#{hash_key.inspect}]
      #{ivar_name} = if val.nil?
        found -= 1 unless hash.key?(#{hash_key.inspect})
        #{nil_handler}
      else
        #{transformed_val}
      end
    RUBY
  end
  <<~RUBY
    def __t_props_generated_deserialize(hash)
      found = #{stored_props.size}
      #{parts.join("\n\n")}
      found
    end
  RUBY
end

def self.generate_nil_handler(

def self.generate_nil_handler(

orator.raise_nil_deserialize_error(#{serialized_form.inspect})"
veDefault
lt.default
teger, Symbol, Float, TrueClass, FalseClass, NilClass
ct
ecorator.props_with_defaults.fetch(#{prop.inspect}).default"
rayDefault
shDefault
orator.props_with_defaults.fetch(#{prop.inspect}).default"
write
ssing_from_deserialize(#{prop.inspect})"