/*
 * Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
 * Copyright (c) 2011, 2012 Open Networking Foundation
 * Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler.
 * Copyright 2018, Red Hat, Inc.
 */
// Automatically generated by LOXI from template module.go
// Do not modify

package of13

import (
	"bytes"
	"encoding/binary"
	"fmt"

	"github.com/donNewtonAlpha/goloxi"
)

type Instruction struct {
	Type uint16
	Len  uint16
}

type IInstruction interface {
	goloxi.Serializable
	GetType() uint16
	GetLen() uint16
}

func (self *Instruction) GetType() uint16 {
	return self.Type
}

func (self *Instruction) SetType(v uint16) {
	self.Type = v
}

func (self *Instruction) GetLen() uint16 {
	return self.Len
}

func (self *Instruction) SetLen(v uint16) {
	self.Len = v
}

func (self *Instruction) Serialize(encoder *goloxi.Encoder) error {

	encoder.PutUint16(uint16(self.Type))
	encoder.PutUint16(uint16(self.Len))

	return nil
}

func DecodeInstruction(decoder *goloxi.Decoder) (IInstruction, error) {
	_instruction := &Instruction{}
	if decoder.Length() < 4 {
		return nil, fmt.Errorf("Instruction packet too short: %d < 4", decoder.Length())
	}
	_instruction.Type = uint16(decoder.ReadUint16())
	_instruction.Len = uint16(decoder.ReadUint16())
	oldDecoder := decoder
	defer func() { decoder = oldDecoder }()
	decoder = decoder.SliceDecoder(int(_instruction.Len), 2+2)

	switch _instruction.Type {
	case 1:
		return DecodeInstructionGotoTable(_instruction, decoder)
	case 2:
		return DecodeInstructionWriteMetadata(_instruction, decoder)
	case 3:
		return DecodeInstructionWriteActions(_instruction, decoder)
	case 4:
		return DecodeInstructionApplyActions(_instruction, decoder)
	case 5:
		return DecodeInstructionClearActions(_instruction, decoder)
	case 6:
		return DecodeInstructionMeter(_instruction, decoder)
	case 65535:
		return DecodeInstructionExperimenter(_instruction, decoder)
	default:
		return nil, fmt.Errorf("Invalid type '%d' for 'Instruction'", _instruction.Type)
	}
}

func NewInstruction(_type uint16) *Instruction {
	obj := &Instruction{}
	obj.Type = _type
	return obj
}

type InstructionApplyActions struct {
	*Instruction
	Actions []goloxi.IAction
}

type IInstructionApplyActions interface {
	IInstruction
	GetActions() []goloxi.IAction
}

func (self *InstructionApplyActions) GetActions() []goloxi.IAction {
	return self.Actions
}

func (self *InstructionApplyActions) SetActions(v []goloxi.IAction) {
	self.Actions = v
}

func (self *InstructionApplyActions) Serialize(encoder *goloxi.Encoder) error {
	if err := self.Instruction.Serialize(encoder); err != nil {
		return err
	}

	encoder.Write(bytes.Repeat([]byte{0}, 4))
	for _, obj := range self.Actions {
		if err := obj.Serialize(encoder); err != nil {
			return err
		}
	}

	binary.BigEndian.PutUint16(encoder.Bytes()[2:4], uint16(len(encoder.Bytes())))

	return nil
}

func DecodeInstructionApplyActions(parent *Instruction, decoder *goloxi.Decoder) (*InstructionApplyActions, error) {
	_instructionapplyactions := &InstructionApplyActions{Instruction: parent}
	if decoder.Length() < 4 {
		return nil, fmt.Errorf("InstructionApplyActions packet too short: %d < 4", decoder.Length())
	}
	decoder.Skip(4)

	for decoder.Length() >= 8 {
		item, err := DecodeAction(decoder)
		if err != nil {
			return nil, err
		}
		if item != nil {
			_instructionapplyactions.Actions = append(_instructionapplyactions.Actions, item)
		}
	}
	return _instructionapplyactions, nil
}

func NewInstructionApplyActions() *InstructionApplyActions {
	obj := &InstructionApplyActions{
		Instruction: NewInstruction(4),
	}
	return obj
}

type InstructionExperimenter struct {
	*Instruction
	Experimenter uint32
}

type IInstructionExperimenter interface {
	IInstruction
	GetExperimenter() uint32
}

func (self *InstructionExperimenter) GetExperimenter() uint32 {
	return self.Experimenter
}

func (self *InstructionExperimenter) SetExperimenter(v uint32) {
	self.Experimenter = v
}

func (self *InstructionExperimenter) Serialize(encoder *goloxi.Encoder) error {
	if err := self.Instruction.Serialize(encoder); err != nil {
		return err
	}

	encoder.PutUint32(uint32(self.Experimenter))

	return nil
}

func DecodeInstructionExperimenter(parent *Instruction, decoder *goloxi.Decoder) (IInstructionExperimenter, error) {
	_instructionexperimenter := &InstructionExperimenter{Instruction: parent}
	if decoder.Length() < 4 {
		return nil, fmt.Errorf("InstructionExperimenter packet too short: %d < 4", decoder.Length())
	}
	_instructionexperimenter.Experimenter = uint32(decoder.ReadUint32())

	switch _instructionexperimenter.Experimenter {
	case 6035143:
		return DecodeInstructionBsn(_instructionexperimenter, decoder)
	default:
		return nil, fmt.Errorf("Invalid type '%d' for 'InstructionExperimenter'", _instructionexperimenter.Experimenter)
	}
}

func NewInstructionExperimenter(_experimenter uint32) *InstructionExperimenter {
	obj := &InstructionExperimenter{
		Instruction: NewInstruction(65535),
	}
	obj.Experimenter = _experimenter
	return obj
}

type InstructionBsn struct {
	*InstructionExperimenter
	Subtype uint32
}

type IInstructionBsn interface {
	IInstructionExperimenter
	GetSubtype() uint32
}

func (self *InstructionBsn) GetSubtype() uint32 {
	return self.Subtype
}

func (self *InstructionBsn) SetSubtype(v uint32) {
	self.Subtype = v
}

func (self *InstructionBsn) Serialize(encoder *goloxi.Encoder) error {
	if err := self.InstructionExperimenter.Serialize(encoder); err != nil {
		return err
	}

	encoder.PutUint32(uint32(self.Subtype))

	return nil
}

func DecodeInstructionBsn(parent *InstructionExperimenter, decoder *goloxi.Decoder) (IInstructionBsn, error) {
	_instructionbsn := &InstructionBsn{InstructionExperimenter: parent}
	if decoder.Length() < 4 {
		return nil, fmt.Errorf("InstructionBsn packet too short: %d < 4", decoder.Length())
	}
	_instructionbsn.Subtype = uint32(decoder.ReadUint32())

	switch _instructionbsn.Subtype {
	case 0:
		return DecodeInstructionBsnDisableSrcMacCheck(_instructionbsn, decoder)
	case 1:
		return DecodeInstructionBsnArpOffload(_instructionbsn, decoder)
	case 2:
		return DecodeInstructionBsnDhcpOffload(_instructionbsn, decoder)
	case 3:
		return DecodeInstructionBsnDisableSplitHorizonCheck(_instructionbsn, decoder)
	case 4:
		return DecodeInstructionBsnPermit(_instructionbsn, decoder)
	case 5:
		return DecodeInstructionBsnDeny(_instructionbsn, decoder)
	case 6:
		return DecodeInstructionBsnPacketOfDeath(_instructionbsn, decoder)
	case 7:
		return DecodeInstructionBsnPrioritizePdus(_instructionbsn, decoder)
	case 8:
		return DecodeInstructionBsnRequireVlanXlate(_instructionbsn, decoder)
	case 9:
		return DecodeInstructionBsnDisableVlanCounters(_instructionbsn, decoder)
	case 10:
		return DecodeInstructionBsnSpanDestination(_instructionbsn, decoder)
	case 11:
		return DecodeInstructionBsnAutoNegotiation(_instructionbsn, decoder)
	case 12:
		return DecodeInstructionBsnInternalPriority(_instructionbsn, decoder)
	case 13:
		return DecodeInstructionBsnDisableL3(_instructionbsn, decoder)
	case 14:
		return DecodeInstructionBsnNdpOffload(_instructionbsn, decoder)
	case 15:
		return DecodeInstructionBsnHashSelect(_instructionbsn, decoder)
	case 16:
		return DecodeInstructionBsnDirectedBroadcast(_instructionbsn, decoder)
	default:
		return nil, fmt.Errorf("Invalid type '%d' for 'InstructionBsn'", _instructionbsn.Subtype)
	}
}

func NewInstructionBsn(_subtype uint32) *InstructionBsn {
	obj := &InstructionBsn{
		InstructionExperimenter: NewInstructionExperimenter(6035143),
	}
	obj.Subtype = _subtype
	return obj
}

type InstructionBsnArpOffload struct {
	*InstructionBsn
}

type IInstructionBsnArpOffload interface {
	IInstructionBsn
}

func (self *InstructionBsnArpOffload) Serialize(encoder *goloxi.Encoder) error {
	if err := self.InstructionBsn.Serialize(encoder); err != nil {
		return err
	}

	encoder.Write(bytes.Repeat([]byte{0}, 4))

	binary.BigEndian.PutUint16(encoder.Bytes()[2:4], uint16(len(encoder.Bytes())))

	return nil
}

func DecodeInstructionBsnArpOffload(parent *InstructionBsn, decoder *goloxi.Decoder) (*InstructionBsnArpOffload, error) {
	_instructionbsnarpoffload := &InstructionBsnArpOffload{InstructionBsn: parent}
	if decoder.Length() < 4 {
		return nil, fmt.Errorf("InstructionBsnArpOffload packet too short: %d < 4", decoder.Length())
	}
	decoder.Skip(4)
	return _instructionbsnarpoffload, nil
}

func NewInstructionBsnArpOffload() *InstructionBsnArpOffload {
	obj := &InstructionBsnArpOffload{
		InstructionBsn: NewInstructionBsn(1),
	}
	return obj
}

type InstructionBsnAutoNegotiation struct {
	*InstructionBsn
}

type IInstructionBsnAutoNegotiation interface {
	IInstructionBsn
}

func (self *InstructionBsnAutoNegotiation) Serialize(encoder *goloxi.Encoder) error {
	if err := self.InstructionBsn.Serialize(encoder); err != nil {
		return err
	}

	encoder.Write(bytes.Repeat([]byte{0}, 4))

	binary.BigEndian.PutUint16(encoder.Bytes()[2:4], uint16(len(encoder.Bytes())))

	return nil
}

func DecodeInstructionBsnAutoNegotiation(parent *InstructionBsn, decoder *goloxi.Decoder) (*InstructionBsnAutoNegotiation, error) {
	_instructionbsnautonegotiation := &InstructionBsnAutoNegotiation{InstructionBsn: parent}
	if decoder.Length() < 4 {
		return nil, fmt.Errorf("InstructionBsnAutoNegotiation packet too short: %d < 4", decoder.Length())
	}
	decoder.Skip(4)
	return _instructionbsnautonegotiation, nil
}

func NewInstructionBsnAutoNegotiation() *InstructionBsnAutoNegotiation {
	obj := &InstructionBsnAutoNegotiation{
		InstructionBsn: NewInstructionBsn(11),
	}
	return obj
}

type InstructionBsnDeny struct {
	*InstructionBsn
}

type IInstructionBsnDeny interface {
	IInstructionBsn
}

func (self *InstructionBsnDeny) Serialize(encoder *goloxi.Encoder) error {
	if err := self.InstructionBsn.Serialize(encoder); err != nil {
		return err
	}

	encoder.Write(bytes.Repeat([]byte{0}, 4))

	binary.BigEndian.PutUint16(encoder.Bytes()[2:4], uint16(len(encoder.Bytes())))

	return nil
}

func DecodeInstructionBsnDeny(parent *InstructionBsn, decoder *goloxi.Decoder) (*InstructionBsnDeny, error) {
	_instructionbsndeny := &InstructionBsnDeny{InstructionBsn: parent}
	if decoder.Length() < 4 {
		return nil, fmt.Errorf("InstructionBsnDeny packet too short: %d < 4", decoder.Length())
	}
	decoder.Skip(4)
	return _instructionbsndeny, nil
}

func NewInstructionBsnDeny() *InstructionBsnDeny {
	obj := &InstructionBsnDeny{
		InstructionBsn: NewInstructionBsn(5),
	}
	return obj
}

type InstructionBsnDhcpOffload struct {
	*InstructionBsn
}

type IInstructionBsnDhcpOffload interface {
	IInstructionBsn
}

func (self *InstructionBsnDhcpOffload) Serialize(encoder *goloxi.Encoder) error {
	if err := self.InstructionBsn.Serialize(encoder); err != nil {
		return err
	}

	encoder.Write(bytes.Repeat([]byte{0}, 4))

	binary.BigEndian.PutUint16(encoder.Bytes()[2:4], uint16(len(encoder.Bytes())))

	return nil
}

func DecodeInstructionBsnDhcpOffload(parent *InstructionBsn, decoder *goloxi.Decoder) (*InstructionBsnDhcpOffload, error) {
	_instructionbsndhcpoffload := &InstructionBsnDhcpOffload{InstructionBsn: parent}
	if decoder.Length() < 4 {
		return nil, fmt.Errorf("InstructionBsnDhcpOffload packet too short: %d < 4", decoder.Length())
	}
	decoder.Skip(4)
	return _instructionbsndhcpoffload, nil
}

func NewInstructionBsnDhcpOffload() *InstructionBsnDhcpOffload {
	obj := &InstructionBsnDhcpOffload{
		InstructionBsn: NewInstructionBsn(2),
	}
	return obj
}

type InstructionBsnDirectedBroadcast struct {
	*InstructionBsn
}

type IInstructionBsnDirectedBroadcast interface {
	IInstructionBsn
}

func (self *InstructionBsnDirectedBroadcast) Serialize(encoder *goloxi.Encoder) error {
	if err := self.InstructionBsn.Serialize(encoder); err != nil {
		return err
	}

	encoder.Write(bytes.Repeat([]byte{0}, 4))

	binary.BigEndian.PutUint16(encoder.Bytes()[2:4], uint16(len(encoder.Bytes())))

	return nil
}

func DecodeInstructionBsnDirectedBroadcast(parent *InstructionBsn, decoder *goloxi.Decoder) (*InstructionBsnDirectedBroadcast, error) {
	_instructionbsndirectedbroadcast := &InstructionBsnDirectedBroadcast{InstructionBsn: parent}
	if decoder.Length() < 4 {
		return nil, fmt.Errorf("InstructionBsnDirectedBroadcast packet too short: %d < 4", decoder.Length())
	}
	decoder.Skip(4)
	return _instructionbsndirectedbroadcast, nil
}

func NewInstructionBsnDirectedBroadcast() *InstructionBsnDirectedBroadcast {
	obj := &InstructionBsnDirectedBroadcast{
		InstructionBsn: NewInstructionBsn(16),
	}
	return obj
}

type InstructionBsnDisableL3 struct {
	*InstructionBsn
}

type IInstructionBsnDisableL3 interface {
	IInstructionBsn
}

func (self *InstructionBsnDisableL3) Serialize(encoder *goloxi.Encoder) error {
	if err := self.InstructionBsn.Serialize(encoder); err != nil {
		return err
	}

	encoder.Write(bytes.Repeat([]byte{0}, 4))

	binary.BigEndian.PutUint16(encoder.Bytes()[2:4], uint16(len(encoder.Bytes())))

	return nil
}

func DecodeInstructionBsnDisableL3(parent *InstructionBsn, decoder *goloxi.Decoder) (*InstructionBsnDisableL3, error) {
	_instructionbsndisablel3 := &InstructionBsnDisableL3{InstructionBsn: parent}
	if decoder.Length() < 4 {
		return nil, fmt.Errorf("InstructionBsnDisableL3 packet too short: %d < 4", decoder.Length())
	}
	decoder.Skip(4)
	return _instructionbsndisablel3, nil
}

func NewInstructionBsnDisableL3() *InstructionBsnDisableL3 {
	obj := &InstructionBsnDisableL3{
		InstructionBsn: NewInstructionBsn(13),
	}
	return obj
}

type InstructionBsnDisableSplitHorizonCheck struct {
	*InstructionBsn
}

type IInstructionBsnDisableSplitHorizonCheck interface {
	IInstructionBsn
}

func (self *InstructionBsnDisableSplitHorizonCheck) Serialize(encoder *goloxi.Encoder) error {
	if err := self.InstructionBsn.Serialize(encoder); err != nil {
		return err
	}

	encoder.Write(bytes.Repeat([]byte{0}, 4))

	binary.BigEndian.PutUint16(encoder.Bytes()[2:4], uint16(len(encoder.Bytes())))

	return nil
}

func DecodeInstructionBsnDisableSplitHorizonCheck(parent *InstructionBsn, decoder *goloxi.Decoder) (*InstructionBsnDisableSplitHorizonCheck, error) {
	_instructionbsndisablesplithorizoncheck := &InstructionBsnDisableSplitHorizonCheck{InstructionBsn: parent}
	if decoder.Length() < 4 {
		return nil, fmt.Errorf("InstructionBsnDisableSplitHorizonCheck packet too short: %d < 4", decoder.Length())
	}
	decoder.Skip(4)
	return _instructionbsndisablesplithorizoncheck, nil
}

func NewInstructionBsnDisableSplitHorizonCheck() *InstructionBsnDisableSplitHorizonCheck {
	obj := &InstructionBsnDisableSplitHorizonCheck{
		InstructionBsn: NewInstructionBsn(3),
	}
	return obj
}

type InstructionBsnDisableSrcMacCheck struct {
	*InstructionBsn
}

type IInstructionBsnDisableSrcMacCheck interface {
	IInstructionBsn
}

func (self *InstructionBsnDisableSrcMacCheck) Serialize(encoder *goloxi.Encoder) error {
	if err := self.InstructionBsn.Serialize(encoder); err != nil {
		return err
	}

	encoder.Write(bytes.Repeat([]byte{0}, 4))

	binary.BigEndian.PutUint16(encoder.Bytes()[2:4], uint16(len(encoder.Bytes())))

	return nil
}

func DecodeInstructionBsnDisableSrcMacCheck(parent *InstructionBsn, decoder *goloxi.Decoder) (*InstructionBsnDisableSrcMacCheck, error) {
	_instructionbsndisablesrcmaccheck := &InstructionBsnDisableSrcMacCheck{InstructionBsn: parent}
	if decoder.Length() < 4 {
		return nil, fmt.Errorf("InstructionBsnDisableSrcMacCheck packet too short: %d < 4", decoder.Length())
	}
	decoder.Skip(4)
	return _instructionbsndisablesrcmaccheck, nil
}

func NewInstructionBsnDisableSrcMacCheck() *InstructionBsnDisableSrcMacCheck {
	obj := &InstructionBsnDisableSrcMacCheck{
		InstructionBsn: NewInstructionBsn(0),
	}
	return obj
}

type InstructionBsnDisableVlanCounters struct {
	*InstructionBsn
}

type IInstructionBsnDisableVlanCounters interface {
	IInstructionBsn
}

func (self *InstructionBsnDisableVlanCounters) Serialize(encoder *goloxi.Encoder) error {
	if err := self.InstructionBsn.Serialize(encoder); err != nil {
		return err
	}

	encoder.Write(bytes.Repeat([]byte{0}, 4))

	binary.BigEndian.PutUint16(encoder.Bytes()[2:4], uint16(len(encoder.Bytes())))

	return nil
}

func DecodeInstructionBsnDisableVlanCounters(parent *InstructionBsn, decoder *goloxi.Decoder) (*InstructionBsnDisableVlanCounters, error) {
	_instructionbsndisablevlancounters := &InstructionBsnDisableVlanCounters{InstructionBsn: parent}
	if decoder.Length() < 4 {
		return nil, fmt.Errorf("InstructionBsnDisableVlanCounters packet too short: %d < 4", decoder.Length())
	}
	decoder.Skip(4)
	return _instructionbsndisablevlancounters, nil
}

func NewInstructionBsnDisableVlanCounters() *InstructionBsnDisableVlanCounters {
	obj := &InstructionBsnDisableVlanCounters{
		InstructionBsn: NewInstructionBsn(9),
	}
	return obj
}

type InstructionBsnHashSelect struct {
	*InstructionBsn
	Flags BsnHashSelectFlags
}

type IInstructionBsnHashSelect interface {
	IInstructionBsn
	GetFlags() BsnHashSelectFlags
}

func (self *InstructionBsnHashSelect) GetFlags() BsnHashSelectFlags {
	return self.Flags
}

func (self *InstructionBsnHashSelect) SetFlags(v BsnHashSelectFlags) {
	self.Flags = v
}

func (self *InstructionBsnHashSelect) Serialize(encoder *goloxi.Encoder) error {
	if err := self.InstructionBsn.Serialize(encoder); err != nil {
		return err
	}

	encoder.PutUint32(uint32(self.Flags))

	binary.BigEndian.PutUint16(encoder.Bytes()[2:4], uint16(len(encoder.Bytes())))

	return nil
}

func DecodeInstructionBsnHashSelect(parent *InstructionBsn, decoder *goloxi.Decoder) (*InstructionBsnHashSelect, error) {
	_instructionbsnhashselect := &InstructionBsnHashSelect{InstructionBsn: parent}
	if decoder.Length() < 4 {
		return nil, fmt.Errorf("InstructionBsnHashSelect packet too short: %d < 4", decoder.Length())
	}
	_instructionbsnhashselect.Flags = BsnHashSelectFlags(decoder.ReadUint32())
	return _instructionbsnhashselect, nil
}

func NewInstructionBsnHashSelect() *InstructionBsnHashSelect {
	obj := &InstructionBsnHashSelect{
		InstructionBsn: NewInstructionBsn(15),
	}
	return obj
}

type InstructionBsnInternalPriority struct {
	*InstructionBsn
	Value uint32
}

type IInstructionBsnInternalPriority interface {
	IInstructionBsn
	GetValue() uint32
}

func (self *InstructionBsnInternalPriority) GetValue() uint32 {
	return self.Value
}

func (self *InstructionBsnInternalPriority) SetValue(v uint32) {
	self.Value = v
}

func (self *InstructionBsnInternalPriority) Serialize(encoder *goloxi.Encoder) error {
	if err := self.InstructionBsn.Serialize(encoder); err != nil {
		return err
	}

	encoder.PutUint32(uint32(self.Value))

	binary.BigEndian.PutUint16(encoder.Bytes()[2:4], uint16(len(encoder.Bytes())))

	return nil
}

func DecodeInstructionBsnInternalPriority(parent *InstructionBsn, decoder *goloxi.Decoder) (*InstructionBsnInternalPriority, error) {
	_instructionbsninternalpriority := &InstructionBsnInternalPriority{InstructionBsn: parent}
	if decoder.Length() < 4 {
		return nil, fmt.Errorf("InstructionBsnInternalPriority packet too short: %d < 4", decoder.Length())
	}
	_instructionbsninternalpriority.Value = uint32(decoder.ReadUint32())
	return _instructionbsninternalpriority, nil
}

func NewInstructionBsnInternalPriority() *InstructionBsnInternalPriority {
	obj := &InstructionBsnInternalPriority{
		InstructionBsn: NewInstructionBsn(12),
	}
	return obj
}

type InstructionBsnNdpOffload struct {
	*InstructionBsn
}

type IInstructionBsnNdpOffload interface {
	IInstructionBsn
}

func (self *InstructionBsnNdpOffload) Serialize(encoder *goloxi.Encoder) error {
	if err := self.InstructionBsn.Serialize(encoder); err != nil {
		return err
	}

	encoder.Write(bytes.Repeat([]byte{0}, 4))

	binary.BigEndian.PutUint16(encoder.Bytes()[2:4], uint16(len(encoder.Bytes())))

	return nil
}

func DecodeInstructionBsnNdpOffload(parent *InstructionBsn, decoder *goloxi.Decoder) (*InstructionBsnNdpOffload, error) {
	_instructionbsnndpoffload := &InstructionBsnNdpOffload{InstructionBsn: parent}
	if decoder.Length() < 4 {
		return nil, fmt.Errorf("InstructionBsnNdpOffload packet too short: %d < 4", decoder.Length())
	}
	decoder.Skip(4)
	return _instructionbsnndpoffload, nil
}

func NewInstructionBsnNdpOffload() *InstructionBsnNdpOffload {
	obj := &InstructionBsnNdpOffload{
		InstructionBsn: NewInstructionBsn(14),
	}
	return obj
}

type InstructionBsnPacketOfDeath struct {
	*InstructionBsn
}

type IInstructionBsnPacketOfDeath interface {
	IInstructionBsn
}

func (self *InstructionBsnPacketOfDeath) Serialize(encoder *goloxi.Encoder) error {
	if err := self.InstructionBsn.Serialize(encoder); err != nil {
		return err
	}

	encoder.Write(bytes.Repeat([]byte{0}, 4))

	binary.BigEndian.PutUint16(encoder.Bytes()[2:4], uint16(len(encoder.Bytes())))

	return nil
}

func DecodeInstructionBsnPacketOfDeath(parent *InstructionBsn, decoder *goloxi.Decoder) (*InstructionBsnPacketOfDeath, error) {
	_instructionbsnpacketofdeath := &InstructionBsnPacketOfDeath{InstructionBsn: parent}
	if decoder.Length() < 4 {
		return nil, fmt.Errorf("InstructionBsnPacketOfDeath packet too short: %d < 4", decoder.Length())
	}
	decoder.Skip(4)
	return _instructionbsnpacketofdeath, nil
}

func NewInstructionBsnPacketOfDeath() *InstructionBsnPacketOfDeath {
	obj := &InstructionBsnPacketOfDeath{
		InstructionBsn: NewInstructionBsn(6),
	}
	return obj
}

type InstructionBsnPermit struct {
	*InstructionBsn
}

type IInstructionBsnPermit interface {
	IInstructionBsn
}

func (self *InstructionBsnPermit) Serialize(encoder *goloxi.Encoder) error {
	if err := self.InstructionBsn.Serialize(encoder); err != nil {
		return err
	}

	encoder.Write(bytes.Repeat([]byte{0}, 4))

	binary.BigEndian.PutUint16(encoder.Bytes()[2:4], uint16(len(encoder.Bytes())))

	return nil
}

func DecodeInstructionBsnPermit(parent *InstructionBsn, decoder *goloxi.Decoder) (*InstructionBsnPermit, error) {
	_instructionbsnpermit := &InstructionBsnPermit{InstructionBsn: parent}
	if decoder.Length() < 4 {
		return nil, fmt.Errorf("InstructionBsnPermit packet too short: %d < 4", decoder.Length())
	}
	decoder.Skip(4)
	return _instructionbsnpermit, nil
}

func NewInstructionBsnPermit() *InstructionBsnPermit {
	obj := &InstructionBsnPermit{
		InstructionBsn: NewInstructionBsn(4),
	}
	return obj
}

type InstructionBsnPrioritizePdus struct {
	*InstructionBsn
}

type IInstructionBsnPrioritizePdus interface {
	IInstructionBsn
}

func (self *InstructionBsnPrioritizePdus) Serialize(encoder *goloxi.Encoder) error {
	if err := self.InstructionBsn.Serialize(encoder); err != nil {
		return err
	}

	encoder.Write(bytes.Repeat([]byte{0}, 4))

	binary.BigEndian.PutUint16(encoder.Bytes()[2:4], uint16(len(encoder.Bytes())))

	return nil
}

func DecodeInstructionBsnPrioritizePdus(parent *InstructionBsn, decoder *goloxi.Decoder) (*InstructionBsnPrioritizePdus, error) {
	_instructionbsnprioritizepdus := &InstructionBsnPrioritizePdus{InstructionBsn: parent}
	if decoder.Length() < 4 {
		return nil, fmt.Errorf("InstructionBsnPrioritizePdus packet too short: %d < 4", decoder.Length())
	}
	decoder.Skip(4)
	return _instructionbsnprioritizepdus, nil
}

func NewInstructionBsnPrioritizePdus() *InstructionBsnPrioritizePdus {
	obj := &InstructionBsnPrioritizePdus{
		InstructionBsn: NewInstructionBsn(7),
	}
	return obj
}

type InstructionBsnRequireVlanXlate struct {
	*InstructionBsn
}

type IInstructionBsnRequireVlanXlate interface {
	IInstructionBsn
}

func (self *InstructionBsnRequireVlanXlate) Serialize(encoder *goloxi.Encoder) error {
	if err := self.InstructionBsn.Serialize(encoder); err != nil {
		return err
	}

	encoder.Write(bytes.Repeat([]byte{0}, 4))

	binary.BigEndian.PutUint16(encoder.Bytes()[2:4], uint16(len(encoder.Bytes())))

	return nil
}

func DecodeInstructionBsnRequireVlanXlate(parent *InstructionBsn, decoder *goloxi.Decoder) (*InstructionBsnRequireVlanXlate, error) {
	_instructionbsnrequirevlanxlate := &InstructionBsnRequireVlanXlate{InstructionBsn: parent}
	if decoder.Length() < 4 {
		return nil, fmt.Errorf("InstructionBsnRequireVlanXlate packet too short: %d < 4", decoder.Length())
	}
	decoder.Skip(4)
	return _instructionbsnrequirevlanxlate, nil
}

func NewInstructionBsnRequireVlanXlate() *InstructionBsnRequireVlanXlate {
	obj := &InstructionBsnRequireVlanXlate{
		InstructionBsn: NewInstructionBsn(8),
	}
	return obj
}

type InstructionBsnSpanDestination struct {
	*InstructionBsn
}

type IInstructionBsnSpanDestination interface {
	IInstructionBsn
}

func (self *InstructionBsnSpanDestination) Serialize(encoder *goloxi.Encoder) error {
	if err := self.InstructionBsn.Serialize(encoder); err != nil {
		return err
	}

	encoder.Write(bytes.Repeat([]byte{0}, 4))

	binary.BigEndian.PutUint16(encoder.Bytes()[2:4], uint16(len(encoder.Bytes())))

	return nil
}

func DecodeInstructionBsnSpanDestination(parent *InstructionBsn, decoder *goloxi.Decoder) (*InstructionBsnSpanDestination, error) {
	_instructionbsnspandestination := &InstructionBsnSpanDestination{InstructionBsn: parent}
	if decoder.Length() < 4 {
		return nil, fmt.Errorf("InstructionBsnSpanDestination packet too short: %d < 4", decoder.Length())
	}
	decoder.Skip(4)
	return _instructionbsnspandestination, nil
}

func NewInstructionBsnSpanDestination() *InstructionBsnSpanDestination {
	obj := &InstructionBsnSpanDestination{
		InstructionBsn: NewInstructionBsn(10),
	}
	return obj
}

type InstructionClearActions struct {
	*Instruction
}

type IInstructionClearActions interface {
	IInstruction
}

func (self *InstructionClearActions) Serialize(encoder *goloxi.Encoder) error {
	if err := self.Instruction.Serialize(encoder); err != nil {
		return err
	}

	encoder.Write(bytes.Repeat([]byte{0}, 4))

	binary.BigEndian.PutUint16(encoder.Bytes()[2:4], uint16(len(encoder.Bytes())))

	return nil
}

func DecodeInstructionClearActions(parent *Instruction, decoder *goloxi.Decoder) (*InstructionClearActions, error) {
	_instructionclearactions := &InstructionClearActions{Instruction: parent}
	if decoder.Length() < 4 {
		return nil, fmt.Errorf("InstructionClearActions packet too short: %d < 4", decoder.Length())
	}
	decoder.Skip(4)
	return _instructionclearactions, nil
}

func NewInstructionClearActions() *InstructionClearActions {
	obj := &InstructionClearActions{
		Instruction: NewInstruction(5),
	}
	return obj
}

type InstructionGotoTable struct {
	*Instruction
	TableId uint8
}

type IInstructionGotoTable interface {
	IInstruction
	GetTableId() uint8
}

func (self *InstructionGotoTable) GetTableId() uint8 {
	return self.TableId
}

func (self *InstructionGotoTable) SetTableId(v uint8) {
	self.TableId = v
}

func (self *InstructionGotoTable) Serialize(encoder *goloxi.Encoder) error {
	if err := self.Instruction.Serialize(encoder); err != nil {
		return err
	}

	encoder.PutUint8(uint8(self.TableId))
	encoder.Write(bytes.Repeat([]byte{0}, 3))

	binary.BigEndian.PutUint16(encoder.Bytes()[2:4], uint16(len(encoder.Bytes())))

	return nil
}

func DecodeInstructionGotoTable(parent *Instruction, decoder *goloxi.Decoder) (*InstructionGotoTable, error) {
	_instructiongototable := &InstructionGotoTable{Instruction: parent}
	if decoder.Length() < 4 {
		return nil, fmt.Errorf("InstructionGotoTable packet too short: %d < 4", decoder.Length())
	}
	_instructiongototable.TableId = uint8(decoder.ReadByte())
	decoder.Skip(3)
	return _instructiongototable, nil
}

func NewInstructionGotoTable() *InstructionGotoTable {
	obj := &InstructionGotoTable{
		Instruction: NewInstruction(1),
	}
	return obj
}

type InstructionMeter struct {
	*Instruction
	MeterId uint32
}

type IInstructionMeter interface {
	IInstruction
	GetMeterId() uint32
}

func (self *InstructionMeter) GetMeterId() uint32 {
	return self.MeterId
}

func (self *InstructionMeter) SetMeterId(v uint32) {
	self.MeterId = v
}

func (self *InstructionMeter) Serialize(encoder *goloxi.Encoder) error {
	if err := self.Instruction.Serialize(encoder); err != nil {
		return err
	}

	encoder.PutUint32(uint32(self.MeterId))

	binary.BigEndian.PutUint16(encoder.Bytes()[2:4], uint16(len(encoder.Bytes())))

	return nil
}

func DecodeInstructionMeter(parent *Instruction, decoder *goloxi.Decoder) (*InstructionMeter, error) {
	_instructionmeter := &InstructionMeter{Instruction: parent}
	if decoder.Length() < 4 {
		return nil, fmt.Errorf("InstructionMeter packet too short: %d < 4", decoder.Length())
	}
	_instructionmeter.MeterId = uint32(decoder.ReadUint32())
	return _instructionmeter, nil
}

func NewInstructionMeter() *InstructionMeter {
	obj := &InstructionMeter{
		Instruction: NewInstruction(6),
	}
	return obj
}

type InstructionWriteActions struct {
	*Instruction
	Actions []goloxi.IAction
}

type IInstructionWriteActions interface {
	IInstruction
	GetActions() []goloxi.IAction
}

func (self *InstructionWriteActions) GetActions() []goloxi.IAction {
	return self.Actions
}

func (self *InstructionWriteActions) SetActions(v []goloxi.IAction) {
	self.Actions = v
}

func (self *InstructionWriteActions) Serialize(encoder *goloxi.Encoder) error {
	if err := self.Instruction.Serialize(encoder); err != nil {
		return err
	}

	encoder.Write(bytes.Repeat([]byte{0}, 4))
	for _, obj := range self.Actions {
		if err := obj.Serialize(encoder); err != nil {
			return err
		}
	}

	binary.BigEndian.PutUint16(encoder.Bytes()[2:4], uint16(len(encoder.Bytes())))

	return nil
}

func DecodeInstructionWriteActions(parent *Instruction, decoder *goloxi.Decoder) (*InstructionWriteActions, error) {
	_instructionwriteactions := &InstructionWriteActions{Instruction: parent}
	if decoder.Length() < 4 {
		return nil, fmt.Errorf("InstructionWriteActions packet too short: %d < 4", decoder.Length())
	}
	decoder.Skip(4)

	for decoder.Length() >= 8 {
		item, err := DecodeAction(decoder)
		if err != nil {
			return nil, err
		}
		if item != nil {
			_instructionwriteactions.Actions = append(_instructionwriteactions.Actions, item)
		}
	}
	return _instructionwriteactions, nil
}

func NewInstructionWriteActions() *InstructionWriteActions {
	obj := &InstructionWriteActions{
		Instruction: NewInstruction(3),
	}
	return obj
}

type InstructionWriteMetadata struct {
	*Instruction
	Metadata     uint64
	MetadataMask uint64
}

type IInstructionWriteMetadata interface {
	IInstruction
	GetMetadata() uint64
	GetMetadataMask() uint64
}

func (self *InstructionWriteMetadata) GetMetadata() uint64 {
	return self.Metadata
}

func (self *InstructionWriteMetadata) SetMetadata(v uint64) {
	self.Metadata = v
}

func (self *InstructionWriteMetadata) GetMetadataMask() uint64 {
	return self.MetadataMask
}

func (self *InstructionWriteMetadata) SetMetadataMask(v uint64) {
	self.MetadataMask = v
}

func (self *InstructionWriteMetadata) Serialize(encoder *goloxi.Encoder) error {
	if err := self.Instruction.Serialize(encoder); err != nil {
		return err
	}

	encoder.Write(bytes.Repeat([]byte{0}, 4))
	encoder.PutUint64(uint64(self.Metadata))
	encoder.PutUint64(uint64(self.MetadataMask))

	binary.BigEndian.PutUint16(encoder.Bytes()[2:4], uint16(len(encoder.Bytes())))

	return nil
}

func DecodeInstructionWriteMetadata(parent *Instruction, decoder *goloxi.Decoder) (*InstructionWriteMetadata, error) {
	_instructionwritemetadata := &InstructionWriteMetadata{Instruction: parent}
	if decoder.Length() < 20 {
		return nil, fmt.Errorf("InstructionWriteMetadata packet too short: %d < 20", decoder.Length())
	}
	decoder.Skip(4)
	_instructionwritemetadata.Metadata = uint64(decoder.ReadUint64())
	_instructionwritemetadata.MetadataMask = uint64(decoder.ReadUint64())
	return _instructionwritemetadata, nil
}

func NewInstructionWriteMetadata() *InstructionWriteMetadata {
	obj := &InstructionWriteMetadata{
		Instruction: NewInstruction(2),
	}
	return obj
}
