# frozen_string_literal: true
# # Generated by Puppet::Pops::Types::RubyGenerator from TypeSet Puppet::AST on -4712-01-01

module Puppet
module Pops
module Model
class PopsObject
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::PopsObject', {
    })
  end

  include Types::PuppetObject

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::PopsObject initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new
  end

  def self.create
    new
  end
  attr_reader :hash

  def initialize
    @hash = 2270595461303489901
  end
  def _pcore_init_hash
    {}
  end

  def _pcore_contents
  end

  def _pcore_all_contents(path)
  end

  def to_s
    Types::TypeFormatter.string(self)
  end

  def eql?(o)
    o.instance_of?(self.class)
  end
  alias == eql?
end

class Positioned < PopsObject
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::Positioned', {
      'parent' => PopsObject._pcore_type,
      'attributes' => {
        'locator' => {
          'type' => Parser::Locator::Locator19._pcore_type,
          'kind' => 'reference'
        },
        'offset' => Types::PIntegerType::DEFAULT,
        'length' => Types::PIntegerType::DEFAULT,
        'file' => {
          'type' => Types::PStringType::DEFAULT,
          'kind' => 'derived'
        },
        'line' => {
          'type' => Types::PIntegerType::DEFAULT,
          'kind' => 'derived'
        },
        'pos' => {
          'type' => Types::PIntegerType::DEFAULT,
          'kind' => 'derived'
        }
      },
      'equality' => []
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::Positioned initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'])
  end

  def self.create(locator, offset, length)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    new(locator, offset, length)
  end

  attr_reader :locator
  attr_reader :offset
  attr_reader :length

  def file
    @locator.file
  end

  def line
    @locator.line_for_offset(@offset)
  end

  def pos
    @locator.pos_on_line(@offset)
  end

  def initialize(locator, offset, length)
    super()
    @locator = locator
    @offset = offset
    @length = length
  end

  def _pcore_init_hash
    result = super
    result['locator'] = @locator
    result['offset'] = @offset
    result['length'] = @length
    result
  end
end

class Expression < Positioned
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::Expression', {
      'parent' => Positioned._pcore_type
    })
  end
end

class Nop < Expression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::Nop', {
      'parent' => Expression._pcore_type
    })
  end
end

class BinaryExpression < Expression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::BinaryExpression', {
      'parent' => Expression._pcore_type,
      'attributes' => {
        'left_expr' => Expression._pcore_type,
        'right_expr' => Expression._pcore_type
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::BinaryExpression initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['left_expr'],
      init_hash['right_expr'])
  end

  def self.create(locator, offset, length, left_expr, right_expr)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::BinaryExpression[left_expr]', attrs['left_expr'].type, left_expr)
    ta.assert_instance_of('Puppet::AST::BinaryExpression[right_expr]', attrs['right_expr'].type, right_expr)
    new(locator, offset, length, left_expr, right_expr)
  end

  attr_reader :left_expr
  attr_reader :right_expr

  def initialize(locator, offset, length, left_expr, right_expr)
    super(locator, offset, length)
    @hash = @hash ^ left_expr.hash ^ right_expr.hash
    @left_expr = left_expr
    @right_expr = right_expr
  end

  def _pcore_init_hash
    result = super
    result['left_expr'] = @left_expr
    result['right_expr'] = @right_expr
    result
  end

  def _pcore_contents
    yield(@left_expr) unless @left_expr.nil?
    yield(@right_expr) unless @right_expr.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @left_expr.nil?
      block.call(@left_expr, path)
      @left_expr._pcore_all_contents(path, &block)
    end
    unless @right_expr.nil?
      block.call(@right_expr, path)
      @right_expr._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @left_expr.eql?(o.left_expr) &&
    @right_expr.eql?(o.right_expr)
  end
  alias == eql?
end

class UnaryExpression < Expression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::UnaryExpression', {
      'parent' => Expression._pcore_type,
      'attributes' => {
        'expr' => Expression._pcore_type
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::UnaryExpression initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['expr'])
  end

  def self.create(locator, offset, length, expr)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::UnaryExpression[expr]', attrs['expr'].type, expr)
    new(locator, offset, length, expr)
  end

  attr_reader :expr

  def initialize(locator, offset, length, expr)
    super(locator, offset, length)
    @hash = @hash ^ expr.hash
    @expr = expr
  end

  def _pcore_init_hash
    result = super
    result['expr'] = @expr
    result
  end

  def _pcore_contents
    yield(@expr) unless @expr.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @expr.nil?
      block.call(@expr, path)
      @expr._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @expr.eql?(o.expr)
  end
  alias == eql?
end

class ParenthesizedExpression < UnaryExpression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::ParenthesizedExpression', {
      'parent' => UnaryExpression._pcore_type
    })
  end

  def _pcore_contents
    yield(@expr) unless @expr.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @expr.nil?
      block.call(@expr, path)
      @expr._pcore_all_contents(path, &block)
    end
    path.pop
  end
end

class NotExpression < UnaryExpression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::NotExpression', {
      'parent' => UnaryExpression._pcore_type
    })
  end

  def _pcore_contents
    yield(@expr) unless @expr.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @expr.nil?
      block.call(@expr, path)
      @expr._pcore_all_contents(path, &block)
    end
    path.pop
  end
end

class UnaryMinusExpression < UnaryExpression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::UnaryMinusExpression', {
      'parent' => UnaryExpression._pcore_type
    })
  end

  def _pcore_contents
    yield(@expr) unless @expr.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @expr.nil?
      block.call(@expr, path)
      @expr._pcore_all_contents(path, &block)
    end
    path.pop
  end
end

class UnfoldExpression < UnaryExpression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::UnfoldExpression', {
      'parent' => UnaryExpression._pcore_type
    })
  end

  def _pcore_contents
    yield(@expr) unless @expr.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @expr.nil?
      block.call(@expr, path)
      @expr._pcore_all_contents(path, &block)
    end
    path.pop
  end
end

class AssignmentExpression < BinaryExpression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::AssignmentExpression', {
      'parent' => BinaryExpression._pcore_type,
      'attributes' => {
        'operator' => Types::PEnumType.new(['+=', '-=', '='])
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::AssignmentExpression initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['left_expr'],
      init_hash['right_expr'],
      init_hash['operator'])
  end

  def self.create(locator, offset, length, left_expr, right_expr, operator)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::BinaryExpression[left_expr]', attrs['left_expr'].type, left_expr)
    ta.assert_instance_of('Puppet::AST::BinaryExpression[right_expr]', attrs['right_expr'].type, right_expr)
    ta.assert_instance_of('Puppet::AST::AssignmentExpression[operator]', attrs['operator'].type, operator)
    new(locator, offset, length, left_expr, right_expr, operator)
  end

  attr_reader :operator

  def initialize(locator, offset, length, left_expr, right_expr, operator)
    super(locator, offset, length, left_expr, right_expr)
    @hash = @hash ^ operator.hash
    @operator = operator
  end

  def _pcore_init_hash
    result = super
    result['operator'] = @operator
    result
  end

  def _pcore_contents
    yield(@left_expr) unless @left_expr.nil?
    yield(@right_expr) unless @right_expr.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @left_expr.nil?
      block.call(@left_expr, path)
      @left_expr._pcore_all_contents(path, &block)
    end
    unless @right_expr.nil?
      block.call(@right_expr, path)
      @right_expr._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @operator.eql?(o.operator)
  end
  alias == eql?
end

class ArithmeticExpression < BinaryExpression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::ArithmeticExpression', {
      'parent' => BinaryExpression._pcore_type,
      'attributes' => {
        'operator' => Types::PEnumType.new(['%', '*', '+', '-', '/', '<<', '>>'])
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::ArithmeticExpression initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['left_expr'],
      init_hash['right_expr'],
      init_hash['operator'])
  end

  def self.create(locator, offset, length, left_expr, right_expr, operator)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::BinaryExpression[left_expr]', attrs['left_expr'].type, left_expr)
    ta.assert_instance_of('Puppet::AST::BinaryExpression[right_expr]', attrs['right_expr'].type, right_expr)
    ta.assert_instance_of('Puppet::AST::ArithmeticExpression[operator]', attrs['operator'].type, operator)
    new(locator, offset, length, left_expr, right_expr, operator)
  end

  attr_reader :operator

  def initialize(locator, offset, length, left_expr, right_expr, operator)
    super(locator, offset, length, left_expr, right_expr)
    @hash = @hash ^ operator.hash
    @operator = operator
  end

  def _pcore_init_hash
    result = super
    result['operator'] = @operator
    result
  end

  def _pcore_contents
    yield(@left_expr) unless @left_expr.nil?
    yield(@right_expr) unless @right_expr.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @left_expr.nil?
      block.call(@left_expr, path)
      @left_expr._pcore_all_contents(path, &block)
    end
    unless @right_expr.nil?
      block.call(@right_expr, path)
      @right_expr._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @operator.eql?(o.operator)
  end
  alias == eql?
end

class RelationshipExpression < BinaryExpression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::RelationshipExpression', {
      'parent' => BinaryExpression._pcore_type,
      'attributes' => {
        'operator' => Types::PEnumType.new(['->', '<-', '<~', '~>'])
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::RelationshipExpression initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['left_expr'],
      init_hash['right_expr'],
      init_hash['operator'])
  end

  def self.create(locator, offset, length, left_expr, right_expr, operator)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::BinaryExpression[left_expr]', attrs['left_expr'].type, left_expr)
    ta.assert_instance_of('Puppet::AST::BinaryExpression[right_expr]', attrs['right_expr'].type, right_expr)
    ta.assert_instance_of('Puppet::AST::RelationshipExpression[operator]', attrs['operator'].type, operator)
    new(locator, offset, length, left_expr, right_expr, operator)
  end

  attr_reader :operator

  def initialize(locator, offset, length, left_expr, right_expr, operator)
    super(locator, offset, length, left_expr, right_expr)
    @hash = @hash ^ operator.hash
    @operator = operator
  end

  def _pcore_init_hash
    result = super
    result['operator'] = @operator
    result
  end

  def _pcore_contents
    yield(@left_expr) unless @left_expr.nil?
    yield(@right_expr) unless @right_expr.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @left_expr.nil?
      block.call(@left_expr, path)
      @left_expr._pcore_all_contents(path, &block)
    end
    unless @right_expr.nil?
      block.call(@right_expr, path)
      @right_expr._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @operator.eql?(o.operator)
  end
  alias == eql?
end

class AccessExpression < Expression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::AccessExpression', {
      'parent' => Expression._pcore_type,
      'attributes' => {
        'left_expr' => Expression._pcore_type,
        'keys' => {
          'type' => Types::PArrayType.new(Expression._pcore_type),
          'value' => []
        }
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::AccessExpression initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['left_expr'],
      init_hash.fetch('keys') { _pcore_type['keys'].value })
  end

  def self.create(locator, offset, length, left_expr, keys = _pcore_type['keys'].value)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::AccessExpression[left_expr]', attrs['left_expr'].type, left_expr)
    ta.assert_instance_of('Puppet::AST::AccessExpression[keys]', attrs['keys'].type, keys)
    new(locator, offset, length, left_expr, keys)
  end

  attr_reader :left_expr
  attr_reader :keys

  def initialize(locator, offset, length, left_expr, keys = _pcore_type['keys'].value)
    super(locator, offset, length)
    @hash = @hash ^ left_expr.hash ^ keys.hash
    @left_expr = left_expr
    @keys = keys
  end

  def _pcore_init_hash
    result = super
    result['left_expr'] = @left_expr
    result['keys'] = @keys unless _pcore_type['keys'].default_value?(@keys)
    result
  end

  def _pcore_contents
    yield(@left_expr) unless @left_expr.nil?
    @keys.each { |value| yield(value) }
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @left_expr.nil?
      block.call(@left_expr, path)
      @left_expr._pcore_all_contents(path, &block)
    end
    @keys.each do |value|
      block.call(value, path)
      value._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @left_expr.eql?(o.left_expr) &&
    @keys.eql?(o.keys)
  end
  alias == eql?
end

class ComparisonExpression < BinaryExpression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::ComparisonExpression', {
      'parent' => BinaryExpression._pcore_type,
      'attributes' => {
        'operator' => Types::PEnumType.new(['!=', '<', '<=', '==', '>', '>='])
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::ComparisonExpression initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['left_expr'],
      init_hash['right_expr'],
      init_hash['operator'])
  end

  def self.create(locator, offset, length, left_expr, right_expr, operator)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::BinaryExpression[left_expr]', attrs['left_expr'].type, left_expr)
    ta.assert_instance_of('Puppet::AST::BinaryExpression[right_expr]', attrs['right_expr'].type, right_expr)
    ta.assert_instance_of('Puppet::AST::ComparisonExpression[operator]', attrs['operator'].type, operator)
    new(locator, offset, length, left_expr, right_expr, operator)
  end

  attr_reader :operator

  def initialize(locator, offset, length, left_expr, right_expr, operator)
    super(locator, offset, length, left_expr, right_expr)
    @hash = @hash ^ operator.hash
    @operator = operator
  end

  def _pcore_init_hash
    result = super
    result['operator'] = @operator
    result
  end

  def _pcore_contents
    yield(@left_expr) unless @left_expr.nil?
    yield(@right_expr) unless @right_expr.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @left_expr.nil?
      block.call(@left_expr, path)
      @left_expr._pcore_all_contents(path, &block)
    end
    unless @right_expr.nil?
      block.call(@right_expr, path)
      @right_expr._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @operator.eql?(o.operator)
  end
  alias == eql?
end

class MatchExpression < BinaryExpression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::MatchExpression', {
      'parent' => BinaryExpression._pcore_type,
      'attributes' => {
        'operator' => Types::PEnumType.new(['!~', '=~'])
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::MatchExpression initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['left_expr'],
      init_hash['right_expr'],
      init_hash['operator'])
  end

  def self.create(locator, offset, length, left_expr, right_expr, operator)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::BinaryExpression[left_expr]', attrs['left_expr'].type, left_expr)
    ta.assert_instance_of('Puppet::AST::BinaryExpression[right_expr]', attrs['right_expr'].type, right_expr)
    ta.assert_instance_of('Puppet::AST::MatchExpression[operator]', attrs['operator'].type, operator)
    new(locator, offset, length, left_expr, right_expr, operator)
  end

  attr_reader :operator

  def initialize(locator, offset, length, left_expr, right_expr, operator)
    super(locator, offset, length, left_expr, right_expr)
    @hash = @hash ^ operator.hash
    @operator = operator
  end

  def _pcore_init_hash
    result = super
    result['operator'] = @operator
    result
  end

  def _pcore_contents
    yield(@left_expr) unless @left_expr.nil?
    yield(@right_expr) unless @right_expr.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @left_expr.nil?
      block.call(@left_expr, path)
      @left_expr._pcore_all_contents(path, &block)
    end
    unless @right_expr.nil?
      block.call(@right_expr, path)
      @right_expr._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @operator.eql?(o.operator)
  end
  alias == eql?
end

class InExpression < BinaryExpression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::InExpression', {
      'parent' => BinaryExpression._pcore_type
    })
  end

  def _pcore_contents
    yield(@left_expr) unless @left_expr.nil?
    yield(@right_expr) unless @right_expr.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @left_expr.nil?
      block.call(@left_expr, path)
      @left_expr._pcore_all_contents(path, &block)
    end
    unless @right_expr.nil?
      block.call(@right_expr, path)
      @right_expr._pcore_all_contents(path, &block)
    end
    path.pop
  end
end

class BooleanExpression < BinaryExpression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::BooleanExpression', {
      'parent' => BinaryExpression._pcore_type
    })
  end

  def _pcore_contents
    yield(@left_expr) unless @left_expr.nil?
    yield(@right_expr) unless @right_expr.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @left_expr.nil?
      block.call(@left_expr, path)
      @left_expr._pcore_all_contents(path, &block)
    end
    unless @right_expr.nil?
      block.call(@right_expr, path)
      @right_expr._pcore_all_contents(path, &block)
    end
    path.pop
  end
end

class AndExpression < BooleanExpression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::AndExpression', {
      'parent' => BooleanExpression._pcore_type
    })
  end

  def _pcore_contents
    yield(@left_expr) unless @left_expr.nil?
    yield(@right_expr) unless @right_expr.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @left_expr.nil?
      block.call(@left_expr, path)
      @left_expr._pcore_all_contents(path, &block)
    end
    unless @right_expr.nil?
      block.call(@right_expr, path)
      @right_expr._pcore_all_contents(path, &block)
    end
    path.pop
  end
end

class OrExpression < BooleanExpression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::OrExpression', {
      'parent' => BooleanExpression._pcore_type
    })
  end

  def _pcore_contents
    yield(@left_expr) unless @left_expr.nil?
    yield(@right_expr) unless @right_expr.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @left_expr.nil?
      block.call(@left_expr, path)
      @left_expr._pcore_all_contents(path, &block)
    end
    unless @right_expr.nil?
      block.call(@right_expr, path)
      @right_expr._pcore_all_contents(path, &block)
    end
    path.pop
  end
end

class LiteralList < Expression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::LiteralList', {
      'parent' => Expression._pcore_type,
      'attributes' => {
        'values' => {
          'type' => Types::PArrayType.new(Expression._pcore_type),
          'value' => []
        }
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::LiteralList initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash.fetch('values') { _pcore_type['values'].value })
  end

  def self.create(locator, offset, length, values = _pcore_type['values'].value)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::LiteralList[values]', attrs['values'].type, values)
    new(locator, offset, length, values)
  end

  attr_reader :values

  def initialize(locator, offset, length, values = _pcore_type['values'].value)
    super(locator, offset, length)
    @hash = @hash ^ values.hash
    @values = values
  end

  def _pcore_init_hash
    result = super
    result['values'] = @values unless _pcore_type['values'].default_value?(@values)
    result
  end

  def _pcore_contents
    @values.each { |value| yield(value) }
  end

  def _pcore_all_contents(path, &block)
    path << self
    @values.each do |value|
      block.call(value, path)
      value._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @values.eql?(o.values)
  end
  alias == eql?
end

class KeyedEntry < Positioned
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::KeyedEntry', {
      'parent' => Positioned._pcore_type,
      'attributes' => {
        'key' => Expression._pcore_type,
        'value' => Expression._pcore_type
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::KeyedEntry initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['key'],
      init_hash['value'])
  end

  def self.create(locator, offset, length, key, value)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::KeyedEntry[key]', attrs['key'].type, key)
    ta.assert_instance_of('Puppet::AST::KeyedEntry[value]', attrs['value'].type, value)
    new(locator, offset, length, key, value)
  end

  attr_reader :key
  attr_reader :value

  def initialize(locator, offset, length, key, value)
    super(locator, offset, length)
    @hash = @hash ^ key.hash ^ value.hash
    @key = key
    @value = value
  end

  def _pcore_init_hash
    result = super
    result['key'] = @key
    result['value'] = @value
    result
  end

  def _pcore_contents
    yield(@key) unless @key.nil?
    yield(@value) unless @value.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @key.nil?
      block.call(@key, path)
      @key._pcore_all_contents(path, &block)
    end
    unless @value.nil?
      block.call(@value, path)
      @value._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @key.eql?(o.key) &&
    @value.eql?(o.value)
  end
  alias == eql?
end

class LiteralHash < Expression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::LiteralHash', {
      'parent' => Expression._pcore_type,
      'attributes' => {
        'entries' => {
          'type' => Types::PArrayType.new(KeyedEntry._pcore_type),
          'value' => []
        }
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::LiteralHash initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash.fetch('entries') { _pcore_type['entries'].value })
  end

  def self.create(locator, offset, length, entries = _pcore_type['entries'].value)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::LiteralHash[entries]', attrs['entries'].type, entries)
    new(locator, offset, length, entries)
  end

  attr_reader :entries

  def initialize(locator, offset, length, entries = _pcore_type['entries'].value)
    super(locator, offset, length)
    @hash = @hash ^ entries.hash
    @entries = entries
  end

  def _pcore_init_hash
    result = super
    result['entries'] = @entries unless _pcore_type['entries'].default_value?(@entries)
    result
  end

  def _pcore_contents
    @entries.each { |value| yield(value) }
  end

  def _pcore_all_contents(path, &block)
    path << self
    @entries.each do |value|
      block.call(value, path)
      value._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @entries.eql?(o.entries)
  end
  alias == eql?
end

class BlockExpression < Expression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::BlockExpression', {
      'parent' => Expression._pcore_type,
      'attributes' => {
        'statements' => {
          'type' => Types::PArrayType.new(Expression._pcore_type),
          'value' => []
        }
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::BlockExpression initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash.fetch('statements') { _pcore_type['statements'].value })
  end

  def self.create(locator, offset, length, statements = _pcore_type['statements'].value)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::BlockExpression[statements]', attrs['statements'].type, statements)
    new(locator, offset, length, statements)
  end

  attr_reader :statements

  def initialize(locator, offset, length, statements = _pcore_type['statements'].value)
    super(locator, offset, length)
    @hash = @hash ^ statements.hash
    @statements = statements
  end

  def _pcore_init_hash
    result = super
    result['statements'] = @statements unless _pcore_type['statements'].default_value?(@statements)
    result
  end

  def _pcore_contents
    @statements.each { |value| yield(value) }
  end

  def _pcore_all_contents(path, &block)
    path << self
    @statements.each do |value|
      block.call(value, path)
      value._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @statements.eql?(o.statements)
  end
  alias == eql?
end

class ApplyBlockExpression < BlockExpression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::ApplyBlockExpression', {
      'parent' => BlockExpression._pcore_type,
    })
  end
end

class CaseOption < Expression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::CaseOption', {
      'parent' => Expression._pcore_type,
      'attributes' => {
        'values' => Types::PArrayType.new(Expression._pcore_type, Types::PCollectionType::NOT_EMPTY_SIZE),
        'then_expr' => {
          'type' => Types::POptionalType.new(Expression._pcore_type),
          'value' => nil
        }
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::CaseOption initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['values'],
      init_hash['then_expr'])
  end

  def self.create(locator, offset, length, values, then_expr = nil)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::CaseOption[values]', attrs['values'].type, values)
    ta.assert_instance_of('Puppet::AST::CaseOption[then_expr]', attrs['then_expr'].type, then_expr)
    new(locator, offset, length, values, then_expr)
  end

  attr_reader :values
  attr_reader :then_expr

  def initialize(locator, offset, length, values, then_expr = nil)
    super(locator, offset, length)
    @hash = @hash ^ values.hash ^ then_expr.hash
    @values = values
    @then_expr = then_expr
  end

  def _pcore_init_hash
    result = super
    result['values'] = @values
    result['then_expr'] = @then_expr unless @then_expr == nil
    result
  end

  def _pcore_contents
    @values.each { |value| yield(value) }
    yield(@then_expr) unless @then_expr.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    @values.each do |value|
      block.call(value, path)
      value._pcore_all_contents(path, &block)
    end
    unless @then_expr.nil?
      block.call(@then_expr, path)
      @then_expr._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @values.eql?(o.values) &&
    @then_expr.eql?(o.then_expr)
  end
  alias == eql?
end

class CaseExpression < Expression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::CaseExpression', {
      'parent' => Expression._pcore_type,
      'attributes' => {
        'test' => Expression._pcore_type,
        'options' => {
          'type' => Types::PArrayType.new(CaseOption._pcore_type),
          'value' => []
        }
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::CaseExpression initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['test'],
      init_hash.fetch('options') { _pcore_type['options'].value })
  end

  def self.create(locator, offset, length, test, options = _pcore_type['options'].value)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::CaseExpression[test]', attrs['test'].type, test)
    ta.assert_instance_of('Puppet::AST::CaseExpression[options]', attrs['options'].type, options)
    new(locator, offset, length, test, options)
  end

  attr_reader :test
  attr_reader :options

  def initialize(locator, offset, length, test, options = _pcore_type['options'].value)
    super(locator, offset, length)
    @hash = @hash ^ test.hash ^ options.hash
    @test = test
    @options = options
  end

  def _pcore_init_hash
    result = super
    result['test'] = @test
    result['options'] = @options unless _pcore_type['options'].default_value?(@options)
    result
  end

  def _pcore_contents
    yield(@test) unless @test.nil?
    @options.each { |value| yield(value) }
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @test.nil?
      block.call(@test, path)
      @test._pcore_all_contents(path, &block)
    end
    @options.each do |value|
      block.call(value, path)
      value._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @test.eql?(o.test) &&
    @options.eql?(o.options)
  end
  alias == eql?
end

class QueryExpression < Expression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::QueryExpression', {
      'parent' => Expression._pcore_type,
      'attributes' => {
        'expr' => {
          'type' => Types::POptionalType.new(Expression._pcore_type),
          'value' => nil
        }
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::QueryExpression initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['expr'])
  end

  def self.create(locator, offset, length, expr = nil)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::QueryExpression[expr]', attrs['expr'].type, expr)
    new(locator, offset, length, expr)
  end

  attr_reader :expr

  def initialize(locator, offset, length, expr = nil)
    super(locator, offset, length)
    @hash = @hash ^ expr.hash
    @expr = expr
  end

  def _pcore_init_hash
    result = super
    result['expr'] = @expr unless @expr == nil
    result
  end

  def _pcore_contents
    yield(@expr) unless @expr.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @expr.nil?
      block.call(@expr, path)
      @expr._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @expr.eql?(o.expr)
  end
  alias == eql?
end

class ExportedQuery < QueryExpression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::ExportedQuery', {
      'parent' => QueryExpression._pcore_type
    })
  end

  def _pcore_contents
    yield(@expr) unless @expr.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @expr.nil?
      block.call(@expr, path)
      @expr._pcore_all_contents(path, &block)
    end
    path.pop
  end
end

class VirtualQuery < QueryExpression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::VirtualQuery', {
      'parent' => QueryExpression._pcore_type
    })
  end

  def _pcore_contents
    yield(@expr) unless @expr.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @expr.nil?
      block.call(@expr, path)
      @expr._pcore_all_contents(path, &block)
    end
    path.pop
  end
end

class AbstractAttributeOperation < Positioned
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::AbstractAttributeOperation', {
      'parent' => Positioned._pcore_type
    })
  end
end

class AttributeOperation < AbstractAttributeOperation
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::AttributeOperation', {
      'parent' => AbstractAttributeOperation._pcore_type,
      'attributes' => {
        'attribute_name' => Types::PStringType::DEFAULT,
        'operator' => Types::PEnumType.new(['+>', '=>']),
        'value_expr' => Expression._pcore_type
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::AttributeOperation initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['attribute_name'],
      init_hash['operator'],
      init_hash['value_expr'])
  end

  def self.create(locator, offset, length, attribute_name, operator, value_expr)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::AttributeOperation[attribute_name]', attrs['attribute_name'].type, attribute_name)
    ta.assert_instance_of('Puppet::AST::AttributeOperation[operator]', attrs['operator'].type, operator)
    ta.assert_instance_of('Puppet::AST::AttributeOperation[value_expr]', attrs['value_expr'].type, value_expr)
    new(locator, offset, length, attribute_name, operator, value_expr)
  end

  attr_reader :attribute_name
  attr_reader :operator
  attr_reader :value_expr

  def initialize(locator, offset, length, attribute_name, operator, value_expr)
    super(locator, offset, length)
    @hash = @hash ^ attribute_name.hash ^ operator.hash ^ value_expr.hash
    @attribute_name = attribute_name
    @operator = operator
    @value_expr = value_expr
  end

  def _pcore_init_hash
    result = super
    result['attribute_name'] = @attribute_name
    result['operator'] = @operator
    result['value_expr'] = @value_expr
    result
  end

  def _pcore_contents
    yield(@value_expr) unless @value_expr.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @value_expr.nil?
      block.call(@value_expr, path)
      @value_expr._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @attribute_name.eql?(o.attribute_name) &&
    @operator.eql?(o.operator) &&
    @value_expr.eql?(o.value_expr)
  end
  alias == eql?
end

class AttributesOperation < AbstractAttributeOperation
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::AttributesOperation', {
      'parent' => AbstractAttributeOperation._pcore_type,
      'attributes' => {
        'expr' => Expression._pcore_type
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::AttributesOperation initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['expr'])
  end

  def self.create(locator, offset, length, expr)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::AttributesOperation[expr]', attrs['expr'].type, expr)
    new(locator, offset, length, expr)
  end

  attr_reader :expr

  def initialize(locator, offset, length, expr)
    super(locator, offset, length)
    @hash = @hash ^ expr.hash
    @expr = expr
  end

  def _pcore_init_hash
    result = super
    result['expr'] = @expr
    result
  end

  def _pcore_contents
    yield(@expr) unless @expr.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @expr.nil?
      block.call(@expr, path)
      @expr._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @expr.eql?(o.expr)
  end
  alias == eql?
end

class CollectExpression < Expression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::CollectExpression', {
      'parent' => Expression._pcore_type,
      'attributes' => {
        'type_expr' => Expression._pcore_type,
        'query' => QueryExpression._pcore_type,
        'operations' => {
          'type' => Types::PArrayType.new(AbstractAttributeOperation._pcore_type),
          'value' => []
        }
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::CollectExpression initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['type_expr'],
      init_hash['query'],
      init_hash.fetch('operations') { _pcore_type['operations'].value })
  end

  def self.create(locator, offset, length, type_expr, query, operations = _pcore_type['operations'].value)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::CollectExpression[type_expr]', attrs['type_expr'].type, type_expr)
    ta.assert_instance_of('Puppet::AST::CollectExpression[query]', attrs['query'].type, query)
    ta.assert_instance_of('Puppet::AST::CollectExpression[operations]', attrs['operations'].type, operations)
    new(locator, offset, length, type_expr, query, operations)
  end

  attr_reader :type_expr
  attr_reader :query
  attr_reader :operations

  def initialize(locator, offset, length, type_expr, query, operations = _pcore_type['operations'].value)
    super(locator, offset, length)
    @hash = @hash ^ type_expr.hash ^ query.hash ^ operations.hash
    @type_expr = type_expr
    @query = query
    @operations = operations
  end

  def _pcore_init_hash
    result = super
    result['type_expr'] = @type_expr
    result['query'] = @query
    result['operations'] = @operations unless _pcore_type['operations'].default_value?(@operations)
    result
  end

  def _pcore_contents
    yield(@type_expr) unless @type_expr.nil?
    yield(@query) unless @query.nil?
    @operations.each { |value| yield(value) }
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @type_expr.nil?
      block.call(@type_expr, path)
      @type_expr._pcore_all_contents(path, &block)
    end
    unless @query.nil?
      block.call(@query, path)
      @query._pcore_all_contents(path, &block)
    end
    @operations.each do |value|
      block.call(value, path)
      value._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @type_expr.eql?(o.type_expr) &&
    @query.eql?(o.query) &&
    @operations.eql?(o.operations)
  end
  alias == eql?
end

class Parameter < Positioned
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::Parameter', {
      'parent' => Positioned._pcore_type,
      'attributes' => {
        'name' => Types::PStringType::DEFAULT,
        'value' => {
          'type' => Types::POptionalType.new(Expression._pcore_type),
          'value' => nil
        },
        'type_expr' => {
          'type' => Types::POptionalType.new(Expression._pcore_type),
          'value' => nil
        },
        'captures_rest' => {
          'type' => Types::POptionalType.new(Types::PBooleanType::DEFAULT),
          'value' => nil
        }
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::Parameter initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['name'],
      init_hash['value'],
      init_hash['type_expr'],
      init_hash['captures_rest'])
  end

  def self.create(locator, offset, length, name, value = nil, type_expr = nil, captures_rest = nil)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::Parameter[name]', attrs['name'].type, name)
    ta.assert_instance_of('Puppet::AST::Parameter[value]', attrs['value'].type, value)
    ta.assert_instance_of('Puppet::AST::Parameter[type_expr]', attrs['type_expr'].type, type_expr)
    ta.assert_instance_of('Puppet::AST::Parameter[captures_rest]', attrs['captures_rest'].type, captures_rest)
    new(locator, offset, length, name, value, type_expr, captures_rest)
  end

  attr_reader :name
  attr_reader :value
  attr_reader :type_expr
  attr_reader :captures_rest

  def initialize(locator, offset, length, name, value = nil, type_expr = nil, captures_rest = nil)
    super(locator, offset, length)
    @hash = @hash ^ name.hash ^ value.hash ^ type_expr.hash ^ captures_rest.hash
    @name = name
    @value = value
    @type_expr = type_expr
    @captures_rest = captures_rest
  end

  def _pcore_init_hash
    result = super
    result['name'] = @name
    result['value'] = @value unless @value == nil
    result['type_expr'] = @type_expr unless @type_expr == nil
    result['captures_rest'] = @captures_rest unless @captures_rest == nil
    result
  end

  def _pcore_contents
    yield(@value) unless @value.nil?
    yield(@type_expr) unless @type_expr.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @value.nil?
      block.call(@value, path)
      @value._pcore_all_contents(path, &block)
    end
    unless @type_expr.nil?
      block.call(@type_expr, path)
      @type_expr._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @name.eql?(o.name) &&
    @value.eql?(o.value) &&
    @type_expr.eql?(o.type_expr) &&
    @captures_rest.eql?(o.captures_rest)
  end
  alias == eql?
end

class Definition < Expression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::Definition', {
      'parent' => Expression._pcore_type
    })
  end
end

class NamedDefinition < Definition
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::NamedDefinition', {
      'parent' => Definition._pcore_type,
      'attributes' => {
        'name' => Types::PStringType::DEFAULT,
        'parameters' => {
          'type' => Types::PArrayType.new(Parameter._pcore_type),
          'value' => []
        },
        'body' => {
          'type' => Types::POptionalType.new(Expression._pcore_type),
          'value' => nil
        }
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::NamedDefinition initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['name'],
      init_hash.fetch('parameters') { _pcore_type['parameters'].value },
      init_hash['body'])
  end

  def self.create(locator, offset, length, name, parameters = _pcore_type['parameters'].value, body = nil)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::NamedDefinition[name]', attrs['name'].type, name)
    ta.assert_instance_of('Puppet::AST::NamedDefinition[parameters]', attrs['parameters'].type, parameters)
    ta.assert_instance_of('Puppet::AST::NamedDefinition[body]', attrs['body'].type, body)
    new(locator, offset, length, name, parameters, body)
  end

  attr_reader :name
  attr_reader :parameters
  attr_reader :body

  def initialize(locator, offset, length, name, parameters = _pcore_type['parameters'].value, body = nil)
    super(locator, offset, length)
    @hash = @hash ^ name.hash ^ parameters.hash ^ body.hash
    @name = name
    @parameters = parameters
    @body = body
  end

  def _pcore_init_hash
    result = super
    result['name'] = @name
    result['parameters'] = @parameters unless _pcore_type['parameters'].default_value?(@parameters)
    result['body'] = @body unless @body == nil
    result
  end

  def _pcore_contents
    @parameters.each { |value| yield(value) }
    yield(@body) unless @body.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    @parameters.each do |value|
      block.call(value, path)
      value._pcore_all_contents(path, &block)
    end
    unless @body.nil?
      block.call(@body, path)
      @body._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @name.eql?(o.name) &&
    @parameters.eql?(o.parameters) &&
    @body.eql?(o.body)
  end
  alias == eql?
end

class FunctionDefinition < NamedDefinition
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::FunctionDefinition', {
      'parent' => NamedDefinition._pcore_type,
      'attributes' => {
        'return_type' => {
          'type' => Types::POptionalType.new(Expression._pcore_type),
          'value' => nil
        }
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::FunctionDefinition initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['name'],
      init_hash.fetch('parameters') { _pcore_type['parameters'].value },
      init_hash['body'],
      init_hash['return_type'])
  end

  def self.create(locator, offset, length, name, parameters = _pcore_type['parameters'].value, body = nil, return_type = nil)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::NamedDefinition[name]', attrs['name'].type, name)
    ta.assert_instance_of('Puppet::AST::NamedDefinition[parameters]', attrs['parameters'].type, parameters)
    ta.assert_instance_of('Puppet::AST::NamedDefinition[body]', attrs['body'].type, body)
    ta.assert_instance_of('Puppet::AST::FunctionDefinition[return_type]', attrs['return_type'].type, return_type)
    new(locator, offset, length, name, parameters, body, return_type)
  end

  attr_reader :return_type

  def initialize(locator, offset, length, name, parameters = _pcore_type['parameters'].value, body = nil, return_type = nil)
    super(locator, offset, length, name, parameters, body)
    @hash = @hash ^ return_type.hash
    @return_type = return_type
  end

  def _pcore_init_hash
    result = super
    result['return_type'] = @return_type unless @return_type == nil
    result
  end

  def _pcore_contents
    @parameters.each { |value| yield(value) }
    yield(@body) unless @body.nil?
    yield(@return_type) unless @return_type.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    @parameters.each do |value|
      block.call(value, path)
      value._pcore_all_contents(path, &block)
    end
    unless @body.nil?
      block.call(@body, path)
      @body._pcore_all_contents(path, &block)
    end
    unless @return_type.nil?
      block.call(@return_type, path)
      @return_type._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @return_type.eql?(o.return_type)
  end
  alias == eql?
end

class ResourceTypeDefinition < NamedDefinition
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::ResourceTypeDefinition', {
      'parent' => NamedDefinition._pcore_type
    })
  end

  def _pcore_contents
    @parameters.each { |value| yield(value) }
    yield(@body) unless @body.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    @parameters.each do |value|
      block.call(value, path)
      value._pcore_all_contents(path, &block)
    end
    unless @body.nil?
      block.call(@body, path)
      @body._pcore_all_contents(path, &block)
    end
    path.pop
  end
end

class QRefDefinition < Definition
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::QRefDefinition', {
      'parent' => Definition._pcore_type,
      'attributes' => {
        'name' => Types::PStringType::DEFAULT
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::QRefDefinition initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['name'])
  end

  def self.create(locator, offset, length, name)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::QRefDefinition[name]', attrs['name'].type, name)
    new(locator, offset, length, name)
  end

  attr_reader :name

  def initialize(locator, offset, length, name)
    super(locator, offset, length)
    @hash = @hash ^ name.hash
    @name = name
  end

  def _pcore_init_hash
    result = super
    result['name'] = @name
    result
  end

  def eql?(o)
    super &&
    @name.eql?(o.name)
  end
  alias == eql?
end

class TypeAlias < QRefDefinition
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::TypeAlias', {
      'parent' => QRefDefinition._pcore_type,
      'attributes' => {
        'type_expr' => {
          'type' => Types::POptionalType.new(Expression._pcore_type),
          'value' => nil
        }
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::TypeAlias initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['name'],
      init_hash['type_expr'])
  end

  def self.create(locator, offset, length, name, type_expr = nil)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::QRefDefinition[name]', attrs['name'].type, name)
    ta.assert_instance_of('Puppet::AST::TypeAlias[type_expr]', attrs['type_expr'].type, type_expr)
    new(locator, offset, length, name, type_expr)
  end

  attr_reader :type_expr

  def initialize(locator, offset, length, name, type_expr = nil)
    super(locator, offset, length, name)
    @hash = @hash ^ type_expr.hash
    @type_expr = type_expr
  end

  def _pcore_init_hash
    result = super
    result['type_expr'] = @type_expr unless @type_expr == nil
    result
  end

  def _pcore_contents
    yield(@type_expr) unless @type_expr.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @type_expr.nil?
      block.call(@type_expr, path)
      @type_expr._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @type_expr.eql?(o.type_expr)
  end
  alias == eql?
end

class TypeMapping < Definition
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::TypeMapping', {
      'parent' => Definition._pcore_type,
      'attributes' => {
        'type_expr' => {
          'type' => Types::POptionalType.new(Expression._pcore_type),
          'value' => nil
        },
        'mapping_expr' => {
          'type' => Types::POptionalType.new(Expression._pcore_type),
          'value' => nil
        }
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::TypeMapping initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['type_expr'],
      init_hash['mapping_expr'])
  end

  def self.create(locator, offset, length, type_expr = nil, mapping_expr = nil)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::TypeMapping[type_expr]', attrs['type_expr'].type, type_expr)
    ta.assert_instance_of('Puppet::AST::TypeMapping[mapping_expr]', attrs['mapping_expr'].type, mapping_expr)
    new(locator, offset, length, type_expr, mapping_expr)
  end

  attr_reader :type_expr
  attr_reader :mapping_expr

  def initialize(locator, offset, length, type_expr = nil, mapping_expr = nil)
    super(locator, offset, length)
    @hash = @hash ^ type_expr.hash ^ mapping_expr.hash
    @type_expr = type_expr
    @mapping_expr = mapping_expr
  end

  def _pcore_init_hash
    result = super
    result['type_expr'] = @type_expr unless @type_expr == nil
    result['mapping_expr'] = @mapping_expr unless @mapping_expr == nil
    result
  end

  def _pcore_contents
    yield(@type_expr) unless @type_expr.nil?
    yield(@mapping_expr) unless @mapping_expr.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @type_expr.nil?
      block.call(@type_expr, path)
      @type_expr._pcore_all_contents(path, &block)
    end
    unless @mapping_expr.nil?
      block.call(@mapping_expr, path)
      @mapping_expr._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @type_expr.eql?(o.type_expr) &&
    @mapping_expr.eql?(o.mapping_expr)
  end
  alias == eql?
end

class TypeDefinition < QRefDefinition
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::TypeDefinition', {
      'parent' => QRefDefinition._pcore_type,
      'attributes' => {
        'parent' => {
          'type' => Types::POptionalType.new(Types::PStringType::DEFAULT),
          'value' => nil
        },
        'body' => {
          'type' => Types::POptionalType.new(Expression._pcore_type),
          'value' => nil
        }
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::TypeDefinition initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['name'],
      init_hash['parent'],
      init_hash['body'])
  end

  def self.create(locator, offset, length, name, parent = nil, body = nil)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::QRefDefinition[name]', attrs['name'].type, name)
    ta.assert_instance_of('Puppet::AST::TypeDefinition[parent]', attrs['parent'].type, parent)
    ta.assert_instance_of('Puppet::AST::TypeDefinition[body]', attrs['body'].type, body)
    new(locator, offset, length, name, parent, body)
  end

  attr_reader :parent
  attr_reader :body

  def initialize(locator, offset, length, name, parent = nil, body = nil)
    super(locator, offset, length, name)
    @hash = @hash ^ parent.hash ^ body.hash
    @parent = parent
    @body = body
  end

  def _pcore_init_hash
    result = super
    result['parent'] = @parent unless @parent == nil
    result['body'] = @body unless @body == nil
    result
  end

  def _pcore_contents
    yield(@body) unless @body.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @body.nil?
      block.call(@body, path)
      @body._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @parent.eql?(o.parent) &&
    @body.eql?(o.body)
  end
  alias == eql?
end

class NodeDefinition < Definition
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::NodeDefinition', {
      'parent' => Definition._pcore_type,
      'attributes' => {
        'parent' => {
          'type' => Types::POptionalType.new(Expression._pcore_type),
          'value' => nil
        },
        'host_matches' => Types::PArrayType.new(Expression._pcore_type, Types::PCollectionType::NOT_EMPTY_SIZE),
        'body' => {
          'type' => Types::POptionalType.new(Expression._pcore_type),
          'value' => nil
        }
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::NodeDefinition initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['host_matches'],
      init_hash['parent'],
      init_hash['body'])
  end

  def self.create(locator, offset, length, host_matches, parent = nil, body = nil)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::NodeDefinition[parent]', attrs['parent'].type, parent)
    ta.assert_instance_of('Puppet::AST::NodeDefinition[host_matches]', attrs['host_matches'].type, host_matches)
    ta.assert_instance_of('Puppet::AST::NodeDefinition[body]', attrs['body'].type, body)
    new(locator, offset, length, host_matches, parent, body)
  end

  attr_reader :parent
  attr_reader :host_matches
  attr_reader :body

  def initialize(locator, offset, length, host_matches, parent = nil, body = nil)
    super(locator, offset, length)
    @hash = @hash ^ parent.hash ^ host_matches.hash ^ body.hash
    @parent = parent
    @host_matches = host_matches
    @body = body
  end

  def _pcore_init_hash
    result = super
    result['parent'] = @parent unless @parent == nil
    result['host_matches'] = @host_matches
    result['body'] = @body unless @body == nil
    result
  end

  def _pcore_contents
    yield(@parent) unless @parent.nil?
    @host_matches.each { |value| yield(value) }
    yield(@body) unless @body.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @parent.nil?
      block.call(@parent, path)
      @parent._pcore_all_contents(path, &block)
    end
    @host_matches.each do |value|
      block.call(value, path)
      value._pcore_all_contents(path, &block)
    end
    unless @body.nil?
      block.call(@body, path)
      @body._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @parent.eql?(o.parent) &&
    @host_matches.eql?(o.host_matches) &&
    @body.eql?(o.body)
  end
  alias == eql?
end

class HeredocExpression < Expression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::HeredocExpression', {
      'parent' => Expression._pcore_type,
      'attributes' => {
        'syntax' => {
          'type' => Types::POptionalType.new(Types::PStringType::DEFAULT),
          'value' => nil
        },
        'text_expr' => Expression._pcore_type
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::HeredocExpression initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['text_expr'],
      init_hash['syntax'])
  end

  def self.create(locator, offset, length, text_expr, syntax = nil)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::HeredocExpression[syntax]', attrs['syntax'].type, syntax)
    ta.assert_instance_of('Puppet::AST::HeredocExpression[text_expr]', attrs['text_expr'].type, text_expr)
    new(locator, offset, length, text_expr, syntax)
  end

  attr_reader :syntax
  attr_reader :text_expr

  def initialize(locator, offset, length, text_expr, syntax = nil)
    super(locator, offset, length)
    @hash = @hash ^ syntax.hash ^ text_expr.hash
    @syntax = syntax
    @text_expr = text_expr
  end

  def _pcore_init_hash
    result = super
    result['syntax'] = @syntax unless @syntax == nil
    result['text_expr'] = @text_expr
    result
  end

  def _pcore_contents
    yield(@text_expr) unless @text_expr.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @text_expr.nil?
      block.call(@text_expr, path)
      @text_expr._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @syntax.eql?(o.syntax) &&
    @text_expr.eql?(o.text_expr)
  end
  alias == eql?
end

class HostClassDefinition < NamedDefinition
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::HostClassDefinition', {
      'parent' => NamedDefinition._pcore_type,
      'attributes' => {
        'parent_class' => {
          'type' => Types::POptionalType.new(Types::PStringType::DEFAULT),
          'value' => nil
        }
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::HostClassDefinition initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['name'],
      init_hash.fetch('parameters') { _pcore_type['parameters'].value },
      init_hash['body'],
      init_hash['parent_class'])
  end

  def self.create(locator, offset, length, name, parameters = _pcore_type['parameters'].value, body = nil, parent_class = nil)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::NamedDefinition[name]', attrs['name'].type, name)
    ta.assert_instance_of('Puppet::AST::NamedDefinition[parameters]', attrs['parameters'].type, parameters)
    ta.assert_instance_of('Puppet::AST::NamedDefinition[body]', attrs['body'].type, body)
    ta.assert_instance_of('Puppet::AST::HostClassDefinition[parent_class]', attrs['parent_class'].type, parent_class)
    new(locator, offset, length, name, parameters, body, parent_class)
  end

  attr_reader :parent_class

  def initialize(locator, offset, length, name, parameters = _pcore_type['parameters'].value, body = nil, parent_class = nil)
    super(locator, offset, length, name, parameters, body)
    @hash = @hash ^ parent_class.hash
    @parent_class = parent_class
  end

  def _pcore_init_hash
    result = super
    result['parent_class'] = @parent_class unless @parent_class == nil
    result
  end

  def _pcore_contents
    @parameters.each { |value| yield(value) }
    yield(@body) unless @body.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    @parameters.each do |value|
      block.call(value, path)
      value._pcore_all_contents(path, &block)
    end
    unless @body.nil?
      block.call(@body, path)
      @body._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @parent_class.eql?(o.parent_class)
  end
  alias == eql?
end

class PlanDefinition < FunctionDefinition
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::PlanDefinition', {
      'parent' => FunctionDefinition._pcore_type
    })
  end

  def _pcore_contents
    @parameters.each { |value| yield(value) }
    yield(@body) unless @body.nil?
    yield(@return_type) unless @return_type.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    @parameters.each do |value|
      block.call(value, path)
      value._pcore_all_contents(path, &block)
    end
    unless @body.nil?
      block.call(@body, path)
      @body._pcore_all_contents(path, &block)
    end
    unless @return_type.nil?
      block.call(@return_type, path)
      @return_type._pcore_all_contents(path, &block)
    end
    path.pop
  end
end

class LambdaExpression < Expression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::LambdaExpression', {
      'parent' => Expression._pcore_type,
      'attributes' => {
        'parameters' => {
          'type' => Types::PArrayType.new(Parameter._pcore_type),
          'value' => []
        },
        'body' => {
          'type' => Types::POptionalType.new(Expression._pcore_type),
          'value' => nil
        },
        'return_type' => {
          'type' => Types::POptionalType.new(Expression._pcore_type),
          'value' => nil
        }
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::LambdaExpression initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash.fetch('parameters') { _pcore_type['parameters'].value },
      init_hash['body'],
      init_hash['return_type'])
  end

  def self.create(locator, offset, length, parameters = _pcore_type['parameters'].value, body = nil, return_type = nil)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::LambdaExpression[parameters]', attrs['parameters'].type, parameters)
    ta.assert_instance_of('Puppet::AST::LambdaExpression[body]', attrs['body'].type, body)
    ta.assert_instance_of('Puppet::AST::LambdaExpression[return_type]', attrs['return_type'].type, return_type)
    new(locator, offset, length, parameters, body, return_type)
  end

  attr_reader :parameters
  attr_reader :body
  attr_reader :return_type

  def initialize(locator, offset, length, parameters = _pcore_type['parameters'].value, body = nil, return_type = nil)
    super(locator, offset, length)
    @hash = @hash ^ parameters.hash ^ body.hash ^ return_type.hash
    @parameters = parameters
    @body = body
    @return_type = return_type
  end

  def _pcore_init_hash
    result = super
    result['parameters'] = @parameters unless _pcore_type['parameters'].default_value?(@parameters)
    result['body'] = @body unless @body == nil
    result['return_type'] = @return_type unless @return_type == nil
    result
  end

  def _pcore_contents
    @parameters.each { |value| yield(value) }
    yield(@body) unless @body.nil?
    yield(@return_type) unless @return_type.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    @parameters.each do |value|
      block.call(value, path)
      value._pcore_all_contents(path, &block)
    end
    unless @body.nil?
      block.call(@body, path)
      @body._pcore_all_contents(path, &block)
    end
    unless @return_type.nil?
      block.call(@return_type, path)
      @return_type._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @parameters.eql?(o.parameters) &&
    @body.eql?(o.body) &&
    @return_type.eql?(o.return_type)
  end
  alias == eql?
end

class ApplyExpression < Expression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::ApplyExpression', {
      'parent' => Expression._pcore_type,
      'attributes' => {
        'arguments' => {
          'type' => Types::PArrayType.new(Expression._pcore_type),
          'value' => []
        },
        'body' => {
          'type' => Types::POptionalType.new(Expression._pcore_type),
          'value' => nil
        }
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::ApplyExpression initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash.fetch('arguments') { _pcore_type['arguments'].value },
      init_hash['body'])
  end

  def self.create(locator, offset, length, arguments = _pcore_type['arguments'].value, body = nil)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::ApplyExpression[arguments]', attrs['arguments'].type, arguments)
    ta.assert_instance_of('Puppet::AST::ApplyExpression[body]', attrs['body'].type, body)
    new(locator, offset, length, arguments, body)
  end

  attr_reader :arguments
  attr_reader :body

  def initialize(locator, offset, length, arguments = _pcore_type['arguments'].value, body = nil)
    super(locator, offset, length)
    @hash = @hash ^ arguments.hash ^ body.hash
    @arguments = arguments
    @body = body
  end

  def _pcore_init_hash
    result = super
    result['arguments'] = @arguments unless _pcore_type['arguments'].default_value?(@arguments)
    result['body'] = @body unless @body == nil
    result
  end

  def _pcore_contents
    @arguments.each { |value| yield(value) }
    yield(@body) unless @body.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    @arguments.each do |value|
      block.call(value, path)
      value._pcore_all_contents(path, &block)
    end
    unless @body.nil?
      block.call(@body, path)
      @body._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @arguments.eql?(o.arguments) &&
    @body.eql?(o.body)
  end
  alias == eql?
end

class IfExpression < Expression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::IfExpression', {
      'parent' => Expression._pcore_type,
      'attributes' => {
        'test' => Expression._pcore_type,
        'then_expr' => {
          'type' => Types::POptionalType.new(Expression._pcore_type),
          'value' => nil
        },
        'else_expr' => {
          'type' => Types::POptionalType.new(Expression._pcore_type),
          'value' => nil
        }
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::IfExpression initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['test'],
      init_hash['then_expr'],
      init_hash['else_expr'])
  end

  def self.create(locator, offset, length, test, then_expr = nil, else_expr = nil)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::IfExpression[test]', attrs['test'].type, test)
    ta.assert_instance_of('Puppet::AST::IfExpression[then_expr]', attrs['then_expr'].type, then_expr)
    ta.assert_instance_of('Puppet::AST::IfExpression[else_expr]', attrs['else_expr'].type, else_expr)
    new(locator, offset, length, test, then_expr, else_expr)
  end

  attr_reader :test
  attr_reader :then_expr
  attr_reader :else_expr

  def initialize(locator, offset, length, test, then_expr = nil, else_expr = nil)
    super(locator, offset, length)
    @hash = @hash ^ test.hash ^ then_expr.hash ^ else_expr.hash
    @test = test
    @then_expr = then_expr
    @else_expr = else_expr
  end

  def _pcore_init_hash
    result = super
    result['test'] = @test
    result['then_expr'] = @then_expr unless @then_expr == nil
    result['else_expr'] = @else_expr unless @else_expr == nil
    result
  end

  def _pcore_contents
    yield(@test) unless @test.nil?
    yield(@then_expr) unless @then_expr.nil?
    yield(@else_expr) unless @else_expr.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @test.nil?
      block.call(@test, path)
      @test._pcore_all_contents(path, &block)
    end
    unless @then_expr.nil?
      block.call(@then_expr, path)
      @then_expr._pcore_all_contents(path, &block)
    end
    unless @else_expr.nil?
      block.call(@else_expr, path)
      @else_expr._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @test.eql?(o.test) &&
    @then_expr.eql?(o.then_expr) &&
    @else_expr.eql?(o.else_expr)
  end
  alias == eql?
end

class UnlessExpression < IfExpression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::UnlessExpression', {
      'parent' => IfExpression._pcore_type
    })
  end

  def _pcore_contents
    yield(@test) unless @test.nil?
    yield(@then_expr) unless @then_expr.nil?
    yield(@else_expr) unless @else_expr.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @test.nil?
      block.call(@test, path)
      @test._pcore_all_contents(path, &block)
    end
    unless @then_expr.nil?
      block.call(@then_expr, path)
      @then_expr._pcore_all_contents(path, &block)
    end
    unless @else_expr.nil?
      block.call(@else_expr, path)
      @else_expr._pcore_all_contents(path, &block)
    end
    path.pop
  end
end

class CallExpression < Expression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::CallExpression', {
      'parent' => Expression._pcore_type,
      'attributes' => {
        'rval_required' => {
          'type' => Types::PBooleanType::DEFAULT,
          'value' => false
        },
        'functor_expr' => Expression._pcore_type,
        'arguments' => {
          'type' => Types::PArrayType.new(Expression._pcore_type),
          'value' => []
        },
        'lambda' => {
          'type' => Types::POptionalType.new(Expression._pcore_type),
          'value' => nil
        }
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::CallExpression initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['functor_expr'],
      init_hash.fetch('rval_required') { false },
      init_hash.fetch('arguments') { _pcore_type['arguments'].value },
      init_hash['lambda'])
  end

  def self.create(locator, offset, length, functor_expr, rval_required = false, arguments = _pcore_type['arguments'].value, lambda = nil)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::CallExpression[rval_required]', attrs['rval_required'].type, rval_required)
    ta.assert_instance_of('Puppet::AST::CallExpression[functor_expr]', attrs['functor_expr'].type, functor_expr)
    ta.assert_instance_of('Puppet::AST::CallExpression[arguments]', attrs['arguments'].type, arguments)
    ta.assert_instance_of('Puppet::AST::CallExpression[lambda]', attrs['lambda'].type, lambda)
    new(locator, offset, length, functor_expr, rval_required, arguments, lambda)
  end

  attr_reader :rval_required
  attr_reader :functor_expr
  attr_reader :arguments
  attr_reader :lambda

  def initialize(locator, offset, length, functor_expr, rval_required = false, arguments = _pcore_type['arguments'].value, lambda = nil)
    super(locator, offset, length)
    @hash = @hash ^ rval_required.hash ^ functor_expr.hash ^ arguments.hash ^ lambda.hash
    @rval_required = rval_required
    @functor_expr = functor_expr
    @arguments = arguments
    @lambda = lambda
  end

  def _pcore_init_hash
    result = super
    result['rval_required'] = @rval_required unless @rval_required == false
    result['functor_expr'] = @functor_expr
    result['arguments'] = @arguments unless _pcore_type['arguments'].default_value?(@arguments)
    result['lambda'] = @lambda unless @lambda == nil
    result
  end

  def _pcore_contents
    yield(@functor_expr) unless @functor_expr.nil?
    @arguments.each { |value| yield(value) }
    yield(@lambda) unless @lambda.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @functor_expr.nil?
      block.call(@functor_expr, path)
      @functor_expr._pcore_all_contents(path, &block)
    end
    @arguments.each do |value|
      block.call(value, path)
      value._pcore_all_contents(path, &block)
    end
    unless @lambda.nil?
      block.call(@lambda, path)
      @lambda._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @rval_required.eql?(o.rval_required) &&
    @functor_expr.eql?(o.functor_expr) &&
    @arguments.eql?(o.arguments) &&
    @lambda.eql?(o.lambda)
  end
  alias == eql?
end

class CallFunctionExpression < CallExpression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::CallFunctionExpression', {
      'parent' => CallExpression._pcore_type
    })
  end

  def _pcore_contents
    yield(@functor_expr) unless @functor_expr.nil?
    @arguments.each { |value| yield(value) }
    yield(@lambda) unless @lambda.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @functor_expr.nil?
      block.call(@functor_expr, path)
      @functor_expr._pcore_all_contents(path, &block)
    end
    @arguments.each do |value|
      block.call(value, path)
      value._pcore_all_contents(path, &block)
    end
    unless @lambda.nil?
      block.call(@lambda, path)
      @lambda._pcore_all_contents(path, &block)
    end
    path.pop
  end
end

class CallNamedFunctionExpression < CallExpression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::CallNamedFunctionExpression', {
      'parent' => CallExpression._pcore_type
    })
  end

  def _pcore_contents
    yield(@functor_expr) unless @functor_expr.nil?
    @arguments.each { |value| yield(value) }
    yield(@lambda) unless @lambda.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @functor_expr.nil?
      block.call(@functor_expr, path)
      @functor_expr._pcore_all_contents(path, &block)
    end
    @arguments.each do |value|
      block.call(value, path)
      value._pcore_all_contents(path, &block)
    end
    unless @lambda.nil?
      block.call(@lambda, path)
      @lambda._pcore_all_contents(path, &block)
    end
    path.pop
  end
end

class CallMethodExpression < CallExpression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::CallMethodExpression', {
      'parent' => CallExpression._pcore_type
    })
  end

  def _pcore_contents
    yield(@functor_expr) unless @functor_expr.nil?
    @arguments.each { |value| yield(value) }
    yield(@lambda) unless @lambda.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @functor_expr.nil?
      block.call(@functor_expr, path)
      @functor_expr._pcore_all_contents(path, &block)
    end
    @arguments.each do |value|
      block.call(value, path)
      value._pcore_all_contents(path, &block)
    end
    unless @lambda.nil?
      block.call(@lambda, path)
      @lambda._pcore_all_contents(path, &block)
    end
    path.pop
  end
end

class Literal < Expression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::Literal', {
      'parent' => Expression._pcore_type
    })
  end
end

class LiteralValue < Literal
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::LiteralValue', {
      'parent' => Literal._pcore_type
    })
  end
end

class LiteralRegularExpression < LiteralValue
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::LiteralRegularExpression', {
      'parent' => LiteralValue._pcore_type,
      'attributes' => {
        'value' => Types::PAnyType::DEFAULT,
        'pattern' => Types::PStringType::DEFAULT
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::LiteralRegularExpression initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['value'],
      init_hash['pattern'])
  end

  def self.create(locator, offset, length, value, pattern)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::LiteralRegularExpression[value]', attrs['value'].type, value)
    ta.assert_instance_of('Puppet::AST::LiteralRegularExpression[pattern]', attrs['pattern'].type, pattern)
    new(locator, offset, length, value, pattern)
  end

  attr_reader :value
  attr_reader :pattern

  def initialize(locator, offset, length, value, pattern)
    super(locator, offset, length)
    @hash = @hash ^ value.hash ^ pattern.hash
    @value = value
    @pattern = pattern
  end

  def _pcore_init_hash
    result = super
    result['value'] = @value
    result['pattern'] = @pattern
    result
  end

  def eql?(o)
    super &&
    @value.eql?(o.value) &&
    @pattern.eql?(o.pattern)
  end
  alias == eql?
end

class LiteralString < LiteralValue
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::LiteralString', {
      'parent' => LiteralValue._pcore_type,
      'attributes' => {
        'value' => Types::PStringType::DEFAULT
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::LiteralString initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['value'])
  end

  def self.create(locator, offset, length, value)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::LiteralString[value]', attrs['value'].type, value)
    new(locator, offset, length, value)
  end

  attr_reader :value

  def initialize(locator, offset, length, value)
    super(locator, offset, length)
    @hash = @hash ^ value.hash
    @value = value
  end

  def _pcore_init_hash
    result = super
    result['value'] = @value
    result
  end

  def eql?(o)
    super &&
    @value.eql?(o.value)
  end
  alias == eql?
end

class LiteralNumber < LiteralValue
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::LiteralNumber', {
      'parent' => LiteralValue._pcore_type
    })
  end
end

class LiteralInteger < LiteralNumber
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::LiteralInteger', {
      'parent' => LiteralNumber._pcore_type,
      'attributes' => {
        'radix' => {
          'type' => Types::PIntegerType::DEFAULT,
          'value' => 10
        },
        'value' => Types::PIntegerType::DEFAULT
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::LiteralInteger initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['value'],
      init_hash.fetch('radix') { 10 })
  end

  def self.create(locator, offset, length, value, radix = 10)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::LiteralInteger[radix]', attrs['radix'].type, radix)
    ta.assert_instance_of('Puppet::AST::LiteralInteger[value]', attrs['value'].type, value)
    new(locator, offset, length, value, radix)
  end

  attr_reader :radix
  attr_reader :value

  def initialize(locator, offset, length, value, radix = 10)
    super(locator, offset, length)
    @hash = @hash ^ radix.hash ^ value.hash
    @radix = radix
    @value = value
  end

  def _pcore_init_hash
    result = super
    result['radix'] = @radix unless @radix == 10
    result['value'] = @value
    result
  end

  def eql?(o)
    super &&
    @radix.eql?(o.radix) &&
    @value.eql?(o.value)
  end
  alias == eql?
end

class LiteralFloat < LiteralNumber
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::LiteralFloat', {
      'parent' => LiteralNumber._pcore_type,
      'attributes' => {
        'value' => Types::PFloatType::DEFAULT
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::LiteralFloat initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['value'])
  end

  def self.create(locator, offset, length, value)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::LiteralFloat[value]', attrs['value'].type, value)
    new(locator, offset, length, value)
  end

  attr_reader :value

  def initialize(locator, offset, length, value)
    super(locator, offset, length)
    @hash = @hash ^ value.hash
    @value = value
  end

  def _pcore_init_hash
    result = super
    result['value'] = @value
    result
  end

  def eql?(o)
    super &&
    @value.eql?(o.value)
  end
  alias == eql?
end

class LiteralUndef < Literal
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::LiteralUndef', {
      'parent' => Literal._pcore_type
    })
  end
end

class LiteralDefault < Literal
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::LiteralDefault', {
      'parent' => Literal._pcore_type
    })
  end
end

class LiteralBoolean < LiteralValue
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::LiteralBoolean', {
      'parent' => LiteralValue._pcore_type,
      'attributes' => {
        'value' => Types::PBooleanType::DEFAULT
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::LiteralBoolean initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['value'])
  end

  def self.create(locator, offset, length, value)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::LiteralBoolean[value]', attrs['value'].type, value)
    new(locator, offset, length, value)
  end

  attr_reader :value

  def initialize(locator, offset, length, value)
    super(locator, offset, length)
    @hash = @hash ^ value.hash
    @value = value
  end

  def _pcore_init_hash
    result = super
    result['value'] = @value
    result
  end

  def eql?(o)
    super &&
    @value.eql?(o.value)
  end
  alias == eql?
end

class TextExpression < UnaryExpression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::TextExpression', {
      'parent' => UnaryExpression._pcore_type
    })
  end

  def _pcore_contents
    yield(@expr) unless @expr.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @expr.nil?
      block.call(@expr, path)
      @expr._pcore_all_contents(path, &block)
    end
    path.pop
  end
end

class ConcatenatedString < Expression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::ConcatenatedString', {
      'parent' => Expression._pcore_type,
      'attributes' => {
        'segments' => {
          'type' => Types::PArrayType.new(Expression._pcore_type),
          'value' => []
        }
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::ConcatenatedString initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash.fetch('segments') { _pcore_type['segments'].value })
  end

  def self.create(locator, offset, length, segments = _pcore_type['segments'].value)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::ConcatenatedString[segments]', attrs['segments'].type, segments)
    new(locator, offset, length, segments)
  end

  attr_reader :segments

  def initialize(locator, offset, length, segments = _pcore_type['segments'].value)
    super(locator, offset, length)
    @hash = @hash ^ segments.hash
    @segments = segments
  end

  def _pcore_init_hash
    result = super
    result['segments'] = @segments unless _pcore_type['segments'].default_value?(@segments)
    result
  end

  def _pcore_contents
    @segments.each { |value| yield(value) }
  end

  def _pcore_all_contents(path, &block)
    path << self
    @segments.each do |value|
      block.call(value, path)
      value._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @segments.eql?(o.segments)
  end
  alias == eql?
end

class QualifiedName < LiteralValue
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::QualifiedName', {
      'parent' => LiteralValue._pcore_type,
      'attributes' => {
        'value' => Types::PStringType::DEFAULT
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::QualifiedName initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['value'])
  end

  def self.create(locator, offset, length, value)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::QualifiedName[value]', attrs['value'].type, value)
    new(locator, offset, length, value)
  end

  attr_reader :value

  def initialize(locator, offset, length, value)
    super(locator, offset, length)
    @hash = @hash ^ value.hash
    @value = value
  end

  def _pcore_init_hash
    result = super
    result['value'] = @value
    result
  end

  def eql?(o)
    super &&
    @value.eql?(o.value)
  end
  alias == eql?
end

class ReservedWord < LiteralValue
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::ReservedWord', {
      'parent' => LiteralValue._pcore_type,
      'attributes' => {
        'word' => Types::PStringType::DEFAULT,
        'future' => {
          'type' => Types::POptionalType.new(Types::PBooleanType::DEFAULT),
          'value' => nil
        }
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::ReservedWord initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['word'],
      init_hash['future'])
  end

  def self.create(locator, offset, length, word, future = nil)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::ReservedWord[word]', attrs['word'].type, word)
    ta.assert_instance_of('Puppet::AST::ReservedWord[future]', attrs['future'].type, future)
    new(locator, offset, length, word, future)
  end

  attr_reader :word
  attr_reader :future

  def initialize(locator, offset, length, word, future = nil)
    super(locator, offset, length)
    @hash = @hash ^ word.hash ^ future.hash
    @word = word
    @future = future
  end

  def _pcore_init_hash
    result = super
    result['word'] = @word
    result['future'] = @future unless @future == nil
    result
  end

  def eql?(o)
    super &&
    @word.eql?(o.word) &&
    @future.eql?(o.future)
  end
  alias == eql?
end

class QualifiedReference < LiteralValue
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::QualifiedReference', {
      'parent' => LiteralValue._pcore_type,
      'attributes' => {
        'cased_value' => Types::PStringType::DEFAULT,
        'value' => {
          'type' => Types::PStringType::DEFAULT,
          'kind' => 'derived'
        }
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::QualifiedReference initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['cased_value'])
  end

  def self.create(locator, offset, length, cased_value)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::QualifiedReference[cased_value]', attrs['cased_value'].type, cased_value)
    new(locator, offset, length, cased_value)
  end

  attr_reader :cased_value

  def value
    @cased_value.downcase
  end

  def initialize(locator, offset, length, cased_value)
    super(locator, offset, length)
    @hash = @hash ^ cased_value.hash
    @cased_value = cased_value
  end

  def _pcore_init_hash
    result = super
    result['cased_value'] = @cased_value
    result
  end

  def eql?(o)
    super &&
    @cased_value.eql?(o.cased_value)
  end
  alias == eql?
end

class VariableExpression < UnaryExpression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::VariableExpression', {
      'parent' => UnaryExpression._pcore_type
    })
  end

  def _pcore_contents
    yield(@expr) unless @expr.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @expr.nil?
      block.call(@expr, path)
      @expr._pcore_all_contents(path, &block)
    end
    path.pop
  end
end

class EppExpression < Expression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::EppExpression', {
      'parent' => Expression._pcore_type,
      'attributes' => {
        'parameters_specified' => {
          'type' => Types::POptionalType.new(Types::PBooleanType::DEFAULT),
          'value' => nil
        },
        'body' => {
          'type' => Types::POptionalType.new(Expression._pcore_type),
          'value' => nil
        }
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::EppExpression initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['parameters_specified'],
      init_hash['body'])
  end

  def self.create(locator, offset, length, parameters_specified = nil, body = nil)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::EppExpression[parameters_specified]', attrs['parameters_specified'].type, parameters_specified)
    ta.assert_instance_of('Puppet::AST::EppExpression[body]', attrs['body'].type, body)
    new(locator, offset, length, parameters_specified, body)
  end

  attr_reader :parameters_specified
  attr_reader :body

  def initialize(locator, offset, length, parameters_specified = nil, body = nil)
    super(locator, offset, length)
    @hash = @hash ^ parameters_specified.hash ^ body.hash
    @parameters_specified = parameters_specified
    @body = body
  end

  def _pcore_init_hash
    result = super
    result['parameters_specified'] = @parameters_specified unless @parameters_specified == nil
    result['body'] = @body unless @body == nil
    result
  end

  def _pcore_contents
    yield(@body) unless @body.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @body.nil?
      block.call(@body, path)
      @body._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @parameters_specified.eql?(o.parameters_specified) &&
    @body.eql?(o.body)
  end
  alias == eql?
end

class RenderStringExpression < LiteralString
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::RenderStringExpression', {
      'parent' => LiteralString._pcore_type
    })
  end
end

class RenderExpression < UnaryExpression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::RenderExpression', {
      'parent' => UnaryExpression._pcore_type
    })
  end

  def _pcore_contents
    yield(@expr) unless @expr.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @expr.nil?
      block.call(@expr, path)
      @expr._pcore_all_contents(path, &block)
    end
    path.pop
  end
end

class ResourceBody < Positioned
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::ResourceBody', {
      'parent' => Positioned._pcore_type,
      'attributes' => {
        'title' => {
          'type' => Types::POptionalType.new(Expression._pcore_type),
          'value' => nil
        },
        'operations' => {
          'type' => Types::PArrayType.new(AbstractAttributeOperation._pcore_type),
          'value' => []
        }
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::ResourceBody initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['title'],
      init_hash.fetch('operations') { _pcore_type['operations'].value })
  end

  def self.create(locator, offset, length, title = nil, operations = _pcore_type['operations'].value)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::ResourceBody[title]', attrs['title'].type, title)
    ta.assert_instance_of('Puppet::AST::ResourceBody[operations]', attrs['operations'].type, operations)
    new(locator, offset, length, title, operations)
  end

  attr_reader :title
  attr_reader :operations

  def initialize(locator, offset, length, title = nil, operations = _pcore_type['operations'].value)
    super(locator, offset, length)
    @hash = @hash ^ title.hash ^ operations.hash
    @title = title
    @operations = operations
  end

  def _pcore_init_hash
    result = super
    result['title'] = @title unless @title == nil
    result['operations'] = @operations unless _pcore_type['operations'].default_value?(@operations)
    result
  end

  def _pcore_contents
    yield(@title) unless @title.nil?
    @operations.each { |value| yield(value) }
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @title.nil?
      block.call(@title, path)
      @title._pcore_all_contents(path, &block)
    end
    @operations.each do |value|
      block.call(value, path)
      value._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @title.eql?(o.title) &&
    @operations.eql?(o.operations)
  end
  alias == eql?
end

class AbstractResource < Expression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::AbstractResource', {
      'parent' => Expression._pcore_type,
      'attributes' => {
        'form' => {
          'type' => Types::PEnumType.new(['exported', 'regular', 'virtual']),
          'value' => 'regular'
        },
        'virtual' => {
          'type' => Types::PBooleanType::DEFAULT,
          'kind' => 'derived'
        },
        'exported' => {
          'type' => Types::PBooleanType::DEFAULT,
          'kind' => 'derived'
        }
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::AbstractResource initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash.fetch('form') { "regular" })
  end

  def self.create(locator, offset, length, form = "regular")
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::AbstractResource[form]', attrs['form'].type, form)
    new(locator, offset, length, form)
  end

  attr_reader :form

  def virtual
    @form == 'virtual' || @form == 'exported'
  end

  def exported
    @form == 'exported'
  end

  def initialize(locator, offset, length, form = "regular")
    super(locator, offset, length)
    @hash = @hash ^ form.hash
    @form = form
  end

  def _pcore_init_hash
    result = super
    result['form'] = @form unless @form == "regular"
    result
  end

  def eql?(o)
    super &&
    @form.eql?(o.form)
  end
  alias == eql?
end

class ResourceExpression < AbstractResource
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::ResourceExpression', {
      'parent' => AbstractResource._pcore_type,
      'attributes' => {
        'type_name' => Expression._pcore_type,
        'bodies' => {
          'type' => Types::PArrayType.new(ResourceBody._pcore_type),
          'value' => []
        }
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::ResourceExpression initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['type_name'],
      init_hash.fetch('form') { "regular" },
      init_hash.fetch('bodies') { _pcore_type['bodies'].value })
  end

  def self.create(locator, offset, length, type_name, form = "regular", bodies = _pcore_type['bodies'].value)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::AbstractResource[form]', attrs['form'].type, form)
    ta.assert_instance_of('Puppet::AST::ResourceExpression[type_name]', attrs['type_name'].type, type_name)
    ta.assert_instance_of('Puppet::AST::ResourceExpression[bodies]', attrs['bodies'].type, bodies)
    new(locator, offset, length, type_name, form, bodies)
  end

  attr_reader :type_name
  attr_reader :bodies

  def initialize(locator, offset, length, type_name, form = "regular", bodies = _pcore_type['bodies'].value)
    super(locator, offset, length, form)
    @hash = @hash ^ type_name.hash ^ bodies.hash
    @type_name = type_name
    @bodies = bodies
  end

  def _pcore_init_hash
    result = super
    result['type_name'] = @type_name
    result['bodies'] = @bodies unless _pcore_type['bodies'].default_value?(@bodies)
    result
  end

  def _pcore_contents
    yield(@type_name) unless @type_name.nil?
    @bodies.each { |value| yield(value) }
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @type_name.nil?
      block.call(@type_name, path)
      @type_name._pcore_all_contents(path, &block)
    end
    @bodies.each do |value|
      block.call(value, path)
      value._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @type_name.eql?(o.type_name) &&
    @bodies.eql?(o.bodies)
  end
  alias == eql?
end

class ResourceDefaultsExpression < AbstractResource
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::ResourceDefaultsExpression', {
      'parent' => AbstractResource._pcore_type,
      'attributes' => {
        'type_ref' => {
          'type' => Types::POptionalType.new(Expression._pcore_type),
          'value' => nil
        },
        'operations' => {
          'type' => Types::PArrayType.new(AbstractAttributeOperation._pcore_type),
          'value' => []
        }
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::ResourceDefaultsExpression initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash.fetch('form') { "regular" },
      init_hash['type_ref'],
      init_hash.fetch('operations') { _pcore_type['operations'].value })
  end

  def self.create(locator, offset, length, form = "regular", type_ref = nil, operations = _pcore_type['operations'].value)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::AbstractResource[form]', attrs['form'].type, form)
    ta.assert_instance_of('Puppet::AST::ResourceDefaultsExpression[type_ref]', attrs['type_ref'].type, type_ref)
    ta.assert_instance_of('Puppet::AST::ResourceDefaultsExpression[operations]', attrs['operations'].type, operations)
    new(locator, offset, length, form, type_ref, operations)
  end

  attr_reader :type_ref
  attr_reader :operations

  def initialize(locator, offset, length, form = "regular", type_ref = nil, operations = _pcore_type['operations'].value)
    super(locator, offset, length, form)
    @hash = @hash ^ type_ref.hash ^ operations.hash
    @type_ref = type_ref
    @operations = operations
  end

  def _pcore_init_hash
    result = super
    result['type_ref'] = @type_ref unless @type_ref == nil
    result['operations'] = @operations unless _pcore_type['operations'].default_value?(@operations)
    result
  end

  def _pcore_contents
    yield(@type_ref) unless @type_ref.nil?
    @operations.each { |value| yield(value) }
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @type_ref.nil?
      block.call(@type_ref, path)
      @type_ref._pcore_all_contents(path, &block)
    end
    @operations.each do |value|
      block.call(value, path)
      value._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @type_ref.eql?(o.type_ref) &&
    @operations.eql?(o.operations)
  end
  alias == eql?
end

class ResourceOverrideExpression < AbstractResource
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::ResourceOverrideExpression', {
      'parent' => AbstractResource._pcore_type,
      'attributes' => {
        'resources' => Expression._pcore_type,
        'operations' => {
          'type' => Types::PArrayType.new(AbstractAttributeOperation._pcore_type),
          'value' => []
        }
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::ResourceOverrideExpression initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['resources'],
      init_hash.fetch('form') { "regular" },
      init_hash.fetch('operations') { _pcore_type['operations'].value })
  end

  def self.create(locator, offset, length, resources, form = "regular", operations = _pcore_type['operations'].value)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::AbstractResource[form]', attrs['form'].type, form)
    ta.assert_instance_of('Puppet::AST::ResourceOverrideExpression[resources]', attrs['resources'].type, resources)
    ta.assert_instance_of('Puppet::AST::ResourceOverrideExpression[operations]', attrs['operations'].type, operations)
    new(locator, offset, length, resources, form, operations)
  end

  attr_reader :resources
  attr_reader :operations

  def initialize(locator, offset, length, resources, form = "regular", operations = _pcore_type['operations'].value)
    super(locator, offset, length, form)
    @hash = @hash ^ resources.hash ^ operations.hash
    @resources = resources
    @operations = operations
  end

  def _pcore_init_hash
    result = super
    result['resources'] = @resources
    result['operations'] = @operations unless _pcore_type['operations'].default_value?(@operations)
    result
  end

  def _pcore_contents
    yield(@resources) unless @resources.nil?
    @operations.each { |value| yield(value) }
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @resources.nil?
      block.call(@resources, path)
      @resources._pcore_all_contents(path, &block)
    end
    @operations.each do |value|
      block.call(value, path)
      value._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @resources.eql?(o.resources) &&
    @operations.eql?(o.operations)
  end
  alias == eql?
end

class SelectorEntry < Positioned
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::SelectorEntry', {
      'parent' => Positioned._pcore_type,
      'attributes' => {
        'matching_expr' => Expression._pcore_type,
        'value_expr' => Expression._pcore_type
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::SelectorEntry initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['matching_expr'],
      init_hash['value_expr'])
  end

  def self.create(locator, offset, length, matching_expr, value_expr)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::SelectorEntry[matching_expr]', attrs['matching_expr'].type, matching_expr)
    ta.assert_instance_of('Puppet::AST::SelectorEntry[value_expr]', attrs['value_expr'].type, value_expr)
    new(locator, offset, length, matching_expr, value_expr)
  end

  attr_reader :matching_expr
  attr_reader :value_expr

  def initialize(locator, offset, length, matching_expr, value_expr)
    super(locator, offset, length)
    @hash = @hash ^ matching_expr.hash ^ value_expr.hash
    @matching_expr = matching_expr
    @value_expr = value_expr
  end

  def _pcore_init_hash
    result = super
    result['matching_expr'] = @matching_expr
    result['value_expr'] = @value_expr
    result
  end

  def _pcore_contents
    yield(@matching_expr) unless @matching_expr.nil?
    yield(@value_expr) unless @value_expr.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @matching_expr.nil?
      block.call(@matching_expr, path)
      @matching_expr._pcore_all_contents(path, &block)
    end
    unless @value_expr.nil?
      block.call(@value_expr, path)
      @value_expr._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @matching_expr.eql?(o.matching_expr) &&
    @value_expr.eql?(o.value_expr)
  end
  alias == eql?
end

class SelectorExpression < Expression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::SelectorExpression', {
      'parent' => Expression._pcore_type,
      'attributes' => {
        'left_expr' => Expression._pcore_type,
        'selectors' => {
          'type' => Types::PArrayType.new(SelectorEntry._pcore_type),
          'value' => []
        }
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::SelectorExpression initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['offset'],
      init_hash['length'],
      init_hash['left_expr'],
      init_hash.fetch('selectors') { _pcore_type['selectors'].value })
  end

  def self.create(locator, offset, length, left_expr, selectors = _pcore_type['selectors'].value)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Positioned[locator]', attrs['locator'].type, locator)
    ta.assert_instance_of('Puppet::AST::Positioned[offset]', attrs['offset'].type, offset)
    ta.assert_instance_of('Puppet::AST::Positioned[length]', attrs['length'].type, length)
    ta.assert_instance_of('Puppet::AST::SelectorExpression[left_expr]', attrs['left_expr'].type, left_expr)
    ta.assert_instance_of('Puppet::AST::SelectorExpression[selectors]', attrs['selectors'].type, selectors)
    new(locator, offset, length, left_expr, selectors)
  end

  attr_reader :left_expr
  attr_reader :selectors

  def initialize(locator, offset, length, left_expr, selectors = _pcore_type['selectors'].value)
    super(locator, offset, length)
    @hash = @hash ^ left_expr.hash ^ selectors.hash
    @left_expr = left_expr
    @selectors = selectors
  end

  def _pcore_init_hash
    result = super
    result['left_expr'] = @left_expr
    result['selectors'] = @selectors unless _pcore_type['selectors'].default_value?(@selectors)
    result
  end

  def _pcore_contents
    yield(@left_expr) unless @left_expr.nil?
    @selectors.each { |value| yield(value) }
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @left_expr.nil?
      block.call(@left_expr, path)
      @left_expr._pcore_all_contents(path, &block)
    end
    @selectors.each do |value|
      block.call(value, path)
      value._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @left_expr.eql?(o.left_expr) &&
    @selectors.eql?(o.selectors)
  end
  alias == eql?
end

class NamedAccessExpression < BinaryExpression
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::NamedAccessExpression', {
      'parent' => BinaryExpression._pcore_type
    })
  end

  def _pcore_contents
    yield(@left_expr) unless @left_expr.nil?
    yield(@right_expr) unless @right_expr.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @left_expr.nil?
      block.call(@left_expr, path)
      @left_expr._pcore_all_contents(path, &block)
    end
    unless @right_expr.nil?
      block.call(@right_expr, path)
      @right_expr._pcore_all_contents(path, &block)
    end
    path.pop
  end
end

class Program < PopsObject
  def self._pcore_type
    @_pcore_type ||= Types::PObjectType.new('Puppet::AST::Program', {
      'parent' => PopsObject._pcore_type,
      'attributes' => {
        'body' => {
          'type' => Types::POptionalType.new(Expression._pcore_type),
          'value' => nil
        },
        'definitions' => {
          'type' => Types::PArrayType.new(Definition._pcore_type),
          'kind' => 'reference',
          'value' => []
        },
        'source_text' => {
          'type' => Types::PStringType::DEFAULT,
          'kind' => 'derived'
        },
        'source_ref' => {
          'type' => Types::PStringType::DEFAULT,
          'kind' => 'derived'
        },
        'line_offsets' => {
          'type' => Types::PArrayType.new(Types::PIntegerType::DEFAULT),
          'kind' => 'derived'
        },
        'locator' => Parser::Locator::Locator19._pcore_type
      }
    })
  end

  def self.from_hash(init_hash)
    from_asserted_hash(Types::TypeAsserter.assert_instance_of('Puppet::AST::Program initializer', _pcore_type.init_hash_type, init_hash))
  end

  def self.from_asserted_hash(init_hash)
    new(
      init_hash['locator'],
      init_hash['body'],
      init_hash.fetch('definitions') { _pcore_type['definitions'].value })
  end

  def self.create(locator, body = nil, definitions = _pcore_type['definitions'].value)
    ta = Types::TypeAsserter
    attrs = _pcore_type.attributes(true)
    ta.assert_instance_of('Puppet::AST::Program[body]', attrs['body'].type, body)
    ta.assert_instance_of('Puppet::AST::Program[definitions]', attrs['definitions'].type, definitions)
    ta.assert_instance_of('Puppet::AST::Program[locator]', attrs['locator'].type, locator)
    new(locator, body, definitions)
  end

  attr_reader :body
  attr_reader :definitions
  attr_reader :locator

  def current
    self
  end

  def source_text
    @locator.string
  end

  def source_ref
    @locator.file
  end

  def line_offsets
    @locator.line_index
  end

  def initialize(locator, body = nil, definitions = _pcore_type['definitions'].value)
    super()
    @hash = @hash ^ body.hash ^ definitions.hash ^ locator.hash
    @body = body
    @definitions = definitions
    @locator = locator
  end

  def _pcore_init_hash
    result = super
    result['body'] = @body unless @body == nil
    result['definitions'] = @definitions unless _pcore_type['definitions'].default_value?(@definitions)
    result['locator'] = @locator
    result
  end

  def _pcore_contents
    yield(@body) unless @body.nil?
    yield(@locator) unless @locator.nil?
  end

  def _pcore_all_contents(path, &block)
    path << self
    unless @body.nil?
      block.call(@body, path)
      @body._pcore_all_contents(path, &block)
    end
    unless @locator.nil?
      block.call(@locator, path)
      @locator._pcore_all_contents(path, &block)
    end
    path.pop
  end

  def eql?(o)
    super &&
    @body.eql?(o.body) &&
    @definitions.eql?(o.definitions) &&
    @locator.eql?(o.locator)
  end
  alias == eql?
end

end

module Model
@@pcore_ast_initialized = false
def self.register_pcore_types
  return if @@pcore_ast_initialized
  @@pcore_ast_initialized = true
  all_types = [
  Parser::Locator::Locator19,
  Model::PopsObject,
  Model::Positioned,
  Model::Expression,
  Model::Nop,
  Model::BinaryExpression,
  Model::UnaryExpression,
  Model::ParenthesizedExpression,
  Model::NotExpression,
  Model::UnaryMinusExpression,
  Model::UnfoldExpression,
  Model::AssignmentExpression,
  Model::ArithmeticExpression,
  Model::RelationshipExpression,
  Model::AccessExpression,
  Model::ComparisonExpression,
  Model::MatchExpression,
  Model::InExpression,
  Model::BooleanExpression,
  Model::AndExpression,
  Model::OrExpression,
  Model::LiteralList,
  Model::KeyedEntry,
  Model::LiteralHash,
  Model::BlockExpression,
  Model::ApplyBlockExpression,
  Model::CaseOption,
  Model::CaseExpression,
  Model::QueryExpression,
  Model::ExportedQuery,
  Model::VirtualQuery,
  Model::AbstractAttributeOperation,
  Model::AttributeOperation,
  Model::AttributesOperation,
  Model::CollectExpression,
  Model::Parameter,
  Model::Definition,
  Model::NamedDefinition,
  Model::FunctionDefinition,
  Model::ResourceTypeDefinition,
  Model::QRefDefinition,
  Model::TypeAlias,
  Model::TypeMapping,
  Model::TypeDefinition,
  Model::NodeDefinition,
  Model::HeredocExpression,
  Model::HostClassDefinition,
  Model::PlanDefinition,
  Model::LambdaExpression,
  Model::ApplyExpression,
  Model::IfExpression,
  Model::UnlessExpression,
  Model::CallExpression,
  Model::CallFunctionExpression,
  Model::CallNamedFunctionExpression,
  Model::CallMethodExpression,
  Model::Literal,
  Model::LiteralValue,
  Model::LiteralRegularExpression,
  Model::LiteralString,
  Model::LiteralNumber,
  Model::LiteralInteger,
  Model::LiteralFloat,
  Model::LiteralUndef,
  Model::LiteralDefault,
  Model::LiteralBoolean,
  Model::TextExpression,
  Model::ConcatenatedString,
  Model::QualifiedName,
  Model::ReservedWord,
  Model::QualifiedReference,
  Model::VariableExpression,
  Model::EppExpression,
  Model::RenderStringExpression,
  Model::RenderExpression,
  Model::ResourceBody,
  Model::AbstractResource,
  Model::ResourceExpression,
  Model::ResourceDefaultsExpression,
  Model::ResourceOverrideExpression,
  Model::SelectorEntry,
  Model::SelectorExpression,
  Model::NamedAccessExpression,
  Model::Program]

  # Create and register a TypeSet that corresponds to all types in the AST model
  types_map = {}
  all_types.each do |type|
    types_map[type._pcore_type.simple_name] = type._pcore_type
  end
  type_set = Types::PTypeSetType.new({
    'name' => 'Puppet::AST',
    'pcore_version' => '1.0.0',
    'types' => types_map
  })
  loc = Puppet::Util.path_to_uri("#{__FILE__}")
  Loaders.static_loader.set_entry(Loader::TypedName.new(:type, 'puppet::ast', Pcore::RUNTIME_NAME_AUTHORITY), type_set, URI("#{loc}?line=1"))
  Loaders.register_static_implementations(all_types)
end
end

end
end
