/*
 * 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/skydive-project/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
}
