/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package model

import (
	"context"
	stdErrors "errors"
	"fmt"

	"github.com/pkg/errors"
	"github.com/rs/zerolog"

	. "github.com/apache/plc4x/plc4go/spi/codegen/fields"
	. "github.com/apache/plc4x/plc4go/spi/codegen/io"
	"github.com/apache/plc4x/plc4go/spi/utils"
)

// Code generated by code-generation. DO NOT EDIT.

// ApduDataExt is the corresponding interface of ApduDataExt
// 03_03_07 Application Layer v01.06.02 AS Page 9ff
type ApduDataExt interface {
	ApduDataExtContract
	ApduDataExtRequirements
	fmt.Stringer
	utils.LengthAware
	utils.Serializable
	utils.Copyable
	// IsApduDataExt is a marker method to prevent unintentional type checks (interfaces of same signature)
	IsApduDataExt()
	// CreateBuilder creates a ApduDataExtBuilder
	CreateApduDataExtBuilder() ApduDataExtBuilder
}

// ApduDataExtContract provides a set of functions which can be overwritten by a sub struct
type ApduDataExtContract interface {
	// IsApduDataExt is a marker method to prevent unintentional type checks (interfaces of same signature)
	IsApduDataExt()
	// CreateBuilder creates a ApduDataExtBuilder
	CreateApduDataExtBuilder() ApduDataExtBuilder
}

// ApduDataExtRequirements provides a set of functions which need to be implemented by a sub struct
type ApduDataExtRequirements interface {
	GetLengthInBits(ctx context.Context) uint16
	GetLengthInBytes(ctx context.Context) uint16
	// GetExtApciType returns ExtApciType (discriminator field)
	GetExtApciType() uint8
}

// _ApduDataExt is the data-structure of this message
type _ApduDataExt struct {
	_SubType interface {
		ApduDataExtContract
		ApduDataExtRequirements
	}
}

var _ ApduDataExtContract = (*_ApduDataExt)(nil)

// NewApduDataExt factory function for _ApduDataExt
func NewApduDataExt() *_ApduDataExt {
	return &_ApduDataExt{}
}

///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
/////////////////////// Builder
///////////////////////

// ApduDataExtBuilder is a builder for ApduDataExt
type ApduDataExtBuilder interface {
	utils.Copyable
	// WithMandatoryFields adds all mandatory fields (convenience for using multiple builder calls)
	WithMandatoryFields() ApduDataExtBuilder
	// AsApduDataExtOpenRoutingTableRequest converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtOpenRoutingTableRequest() ApduDataExtOpenRoutingTableRequestBuilder
	// AsApduDataExtReadRoutingTableRequest converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtReadRoutingTableRequest() ApduDataExtReadRoutingTableRequestBuilder
	// AsApduDataExtReadRoutingTableResponse converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtReadRoutingTableResponse() ApduDataExtReadRoutingTableResponseBuilder
	// AsApduDataExtWriteRoutingTableRequest converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtWriteRoutingTableRequest() ApduDataExtWriteRoutingTableRequestBuilder
	// AsApduDataExtReadRouterMemoryRequest converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtReadRouterMemoryRequest() ApduDataExtReadRouterMemoryRequestBuilder
	// AsApduDataExtReadRouterMemoryResponse converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtReadRouterMemoryResponse() ApduDataExtReadRouterMemoryResponseBuilder
	// AsApduDataExtWriteRouterMemoryRequest converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtWriteRouterMemoryRequest() ApduDataExtWriteRouterMemoryRequestBuilder
	// AsApduDataExtReadRouterStatusRequest converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtReadRouterStatusRequest() ApduDataExtReadRouterStatusRequestBuilder
	// AsApduDataExtReadRouterStatusResponse converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtReadRouterStatusResponse() ApduDataExtReadRouterStatusResponseBuilder
	// AsApduDataExtWriteRouterStatusRequest converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtWriteRouterStatusRequest() ApduDataExtWriteRouterStatusRequestBuilder
	// AsApduDataExtMemoryBitWrite converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtMemoryBitWrite() ApduDataExtMemoryBitWriteBuilder
	// AsApduDataExtAuthorizeRequest converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtAuthorizeRequest() ApduDataExtAuthorizeRequestBuilder
	// AsApduDataExtAuthorizeResponse converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtAuthorizeResponse() ApduDataExtAuthorizeResponseBuilder
	// AsApduDataExtKeyWrite converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtKeyWrite() ApduDataExtKeyWriteBuilder
	// AsApduDataExtKeyResponse converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtKeyResponse() ApduDataExtKeyResponseBuilder
	// AsApduDataExtPropertyValueRead converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtPropertyValueRead() ApduDataExtPropertyValueReadBuilder
	// AsApduDataExtPropertyValueResponse converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtPropertyValueResponse() ApduDataExtPropertyValueResponseBuilder
	// AsApduDataExtPropertyValueWrite converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtPropertyValueWrite() ApduDataExtPropertyValueWriteBuilder
	// AsApduDataExtPropertyDescriptionRead converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtPropertyDescriptionRead() ApduDataExtPropertyDescriptionReadBuilder
	// AsApduDataExtPropertyDescriptionResponse converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtPropertyDescriptionResponse() ApduDataExtPropertyDescriptionResponseBuilder
	// AsApduDataExtNetworkParameterRead converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtNetworkParameterRead() ApduDataExtNetworkParameterReadBuilder
	// AsApduDataExtNetworkParameterResponse converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtNetworkParameterResponse() ApduDataExtNetworkParameterResponseBuilder
	// AsApduDataExtIndividualAddressSerialNumberRead converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtIndividualAddressSerialNumberRead() ApduDataExtIndividualAddressSerialNumberReadBuilder
	// AsApduDataExtIndividualAddressSerialNumberResponse converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtIndividualAddressSerialNumberResponse() ApduDataExtIndividualAddressSerialNumberResponseBuilder
	// AsApduDataExtIndividualAddressSerialNumberWrite converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtIndividualAddressSerialNumberWrite() ApduDataExtIndividualAddressSerialNumberWriteBuilder
	// AsApduDataExtDomainAddressWrite converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtDomainAddressWrite() ApduDataExtDomainAddressWriteBuilder
	// AsApduDataExtDomainAddressRead converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtDomainAddressRead() ApduDataExtDomainAddressReadBuilder
	// AsApduDataExtDomainAddressResponse converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtDomainAddressResponse() ApduDataExtDomainAddressResponseBuilder
	// AsApduDataExtDomainAddressSelectiveRead converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtDomainAddressSelectiveRead() ApduDataExtDomainAddressSelectiveReadBuilder
	// AsApduDataExtNetworkParameterWrite converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtNetworkParameterWrite() ApduDataExtNetworkParameterWriteBuilder
	// AsApduDataExtLinkRead converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtLinkRead() ApduDataExtLinkReadBuilder
	// AsApduDataExtLinkResponse converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtLinkResponse() ApduDataExtLinkResponseBuilder
	// AsApduDataExtLinkWrite converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtLinkWrite() ApduDataExtLinkWriteBuilder
	// AsApduDataExtGroupPropertyValueRead converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtGroupPropertyValueRead() ApduDataExtGroupPropertyValueReadBuilder
	// AsApduDataExtGroupPropertyValueResponse converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtGroupPropertyValueResponse() ApduDataExtGroupPropertyValueResponseBuilder
	// AsApduDataExtGroupPropertyValueWrite converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtGroupPropertyValueWrite() ApduDataExtGroupPropertyValueWriteBuilder
	// AsApduDataExtGroupPropertyValueInfoReport converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtGroupPropertyValueInfoReport() ApduDataExtGroupPropertyValueInfoReportBuilder
	// AsApduDataExtDomainAddressSerialNumberRead converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtDomainAddressSerialNumberRead() ApduDataExtDomainAddressSerialNumberReadBuilder
	// AsApduDataExtDomainAddressSerialNumberResponse converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtDomainAddressSerialNumberResponse() ApduDataExtDomainAddressSerialNumberResponseBuilder
	// AsApduDataExtDomainAddressSerialNumberWrite converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtDomainAddressSerialNumberWrite() ApduDataExtDomainAddressSerialNumberWriteBuilder
	// AsApduDataExtFileStreamInfoReport converts this build to a subType of ApduDataExt. It is always possible to return to current builder using Done()
	AsApduDataExtFileStreamInfoReport() ApduDataExtFileStreamInfoReportBuilder
	// Build builds the ApduDataExt or returns an error if something is wrong
	PartialBuild() (ApduDataExtContract, error)
	// MustBuild does the same as Build but panics on error
	PartialMustBuild() ApduDataExtContract
	// Build builds the ApduDataExt or returns an error if something is wrong
	Build() (ApduDataExt, error)
	// MustBuild does the same as Build but panics on error
	MustBuild() ApduDataExt
}

// NewApduDataExtBuilder() creates a ApduDataExtBuilder
func NewApduDataExtBuilder() ApduDataExtBuilder {
	return &_ApduDataExtBuilder{_ApduDataExt: new(_ApduDataExt)}
}

type _ApduDataExtChildBuilder interface {
	utils.Copyable
	setParent(ApduDataExtContract)
	buildForApduDataExt() (ApduDataExt, error)
}

type _ApduDataExtBuilder struct {
	*_ApduDataExt

	childBuilder _ApduDataExtChildBuilder

	collectedErr []error
}

var _ (ApduDataExtBuilder) = (*_ApduDataExtBuilder)(nil)

func (b *_ApduDataExtBuilder) WithMandatoryFields() ApduDataExtBuilder {
	return b
}

func (b *_ApduDataExtBuilder) PartialBuild() (ApduDataExtContract, error) {
	if err := stdErrors.Join(b.collectedErr...); err != nil {
		return nil, errors.Wrap(err, "error occurred during build")
	}
	return b._ApduDataExt.deepCopy(), nil
}

func (b *_ApduDataExtBuilder) PartialMustBuild() ApduDataExtContract {
	build, err := b.PartialBuild()
	if err != nil {
		panic(err)
	}
	return build
}

func (b *_ApduDataExtBuilder) AsApduDataExtOpenRoutingTableRequest() ApduDataExtOpenRoutingTableRequestBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtOpenRoutingTableRequestBuilder); ok {
		return cb
	}
	cb := NewApduDataExtOpenRoutingTableRequestBuilder().(*_ApduDataExtOpenRoutingTableRequestBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtReadRoutingTableRequest() ApduDataExtReadRoutingTableRequestBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtReadRoutingTableRequestBuilder); ok {
		return cb
	}
	cb := NewApduDataExtReadRoutingTableRequestBuilder().(*_ApduDataExtReadRoutingTableRequestBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtReadRoutingTableResponse() ApduDataExtReadRoutingTableResponseBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtReadRoutingTableResponseBuilder); ok {
		return cb
	}
	cb := NewApduDataExtReadRoutingTableResponseBuilder().(*_ApduDataExtReadRoutingTableResponseBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtWriteRoutingTableRequest() ApduDataExtWriteRoutingTableRequestBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtWriteRoutingTableRequestBuilder); ok {
		return cb
	}
	cb := NewApduDataExtWriteRoutingTableRequestBuilder().(*_ApduDataExtWriteRoutingTableRequestBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtReadRouterMemoryRequest() ApduDataExtReadRouterMemoryRequestBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtReadRouterMemoryRequestBuilder); ok {
		return cb
	}
	cb := NewApduDataExtReadRouterMemoryRequestBuilder().(*_ApduDataExtReadRouterMemoryRequestBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtReadRouterMemoryResponse() ApduDataExtReadRouterMemoryResponseBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtReadRouterMemoryResponseBuilder); ok {
		return cb
	}
	cb := NewApduDataExtReadRouterMemoryResponseBuilder().(*_ApduDataExtReadRouterMemoryResponseBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtWriteRouterMemoryRequest() ApduDataExtWriteRouterMemoryRequestBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtWriteRouterMemoryRequestBuilder); ok {
		return cb
	}
	cb := NewApduDataExtWriteRouterMemoryRequestBuilder().(*_ApduDataExtWriteRouterMemoryRequestBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtReadRouterStatusRequest() ApduDataExtReadRouterStatusRequestBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtReadRouterStatusRequestBuilder); ok {
		return cb
	}
	cb := NewApduDataExtReadRouterStatusRequestBuilder().(*_ApduDataExtReadRouterStatusRequestBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtReadRouterStatusResponse() ApduDataExtReadRouterStatusResponseBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtReadRouterStatusResponseBuilder); ok {
		return cb
	}
	cb := NewApduDataExtReadRouterStatusResponseBuilder().(*_ApduDataExtReadRouterStatusResponseBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtWriteRouterStatusRequest() ApduDataExtWriteRouterStatusRequestBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtWriteRouterStatusRequestBuilder); ok {
		return cb
	}
	cb := NewApduDataExtWriteRouterStatusRequestBuilder().(*_ApduDataExtWriteRouterStatusRequestBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtMemoryBitWrite() ApduDataExtMemoryBitWriteBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtMemoryBitWriteBuilder); ok {
		return cb
	}
	cb := NewApduDataExtMemoryBitWriteBuilder().(*_ApduDataExtMemoryBitWriteBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtAuthorizeRequest() ApduDataExtAuthorizeRequestBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtAuthorizeRequestBuilder); ok {
		return cb
	}
	cb := NewApduDataExtAuthorizeRequestBuilder().(*_ApduDataExtAuthorizeRequestBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtAuthorizeResponse() ApduDataExtAuthorizeResponseBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtAuthorizeResponseBuilder); ok {
		return cb
	}
	cb := NewApduDataExtAuthorizeResponseBuilder().(*_ApduDataExtAuthorizeResponseBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtKeyWrite() ApduDataExtKeyWriteBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtKeyWriteBuilder); ok {
		return cb
	}
	cb := NewApduDataExtKeyWriteBuilder().(*_ApduDataExtKeyWriteBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtKeyResponse() ApduDataExtKeyResponseBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtKeyResponseBuilder); ok {
		return cb
	}
	cb := NewApduDataExtKeyResponseBuilder().(*_ApduDataExtKeyResponseBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtPropertyValueRead() ApduDataExtPropertyValueReadBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtPropertyValueReadBuilder); ok {
		return cb
	}
	cb := NewApduDataExtPropertyValueReadBuilder().(*_ApduDataExtPropertyValueReadBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtPropertyValueResponse() ApduDataExtPropertyValueResponseBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtPropertyValueResponseBuilder); ok {
		return cb
	}
	cb := NewApduDataExtPropertyValueResponseBuilder().(*_ApduDataExtPropertyValueResponseBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtPropertyValueWrite() ApduDataExtPropertyValueWriteBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtPropertyValueWriteBuilder); ok {
		return cb
	}
	cb := NewApduDataExtPropertyValueWriteBuilder().(*_ApduDataExtPropertyValueWriteBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtPropertyDescriptionRead() ApduDataExtPropertyDescriptionReadBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtPropertyDescriptionReadBuilder); ok {
		return cb
	}
	cb := NewApduDataExtPropertyDescriptionReadBuilder().(*_ApduDataExtPropertyDescriptionReadBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtPropertyDescriptionResponse() ApduDataExtPropertyDescriptionResponseBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtPropertyDescriptionResponseBuilder); ok {
		return cb
	}
	cb := NewApduDataExtPropertyDescriptionResponseBuilder().(*_ApduDataExtPropertyDescriptionResponseBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtNetworkParameterRead() ApduDataExtNetworkParameterReadBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtNetworkParameterReadBuilder); ok {
		return cb
	}
	cb := NewApduDataExtNetworkParameterReadBuilder().(*_ApduDataExtNetworkParameterReadBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtNetworkParameterResponse() ApduDataExtNetworkParameterResponseBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtNetworkParameterResponseBuilder); ok {
		return cb
	}
	cb := NewApduDataExtNetworkParameterResponseBuilder().(*_ApduDataExtNetworkParameterResponseBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtIndividualAddressSerialNumberRead() ApduDataExtIndividualAddressSerialNumberReadBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtIndividualAddressSerialNumberReadBuilder); ok {
		return cb
	}
	cb := NewApduDataExtIndividualAddressSerialNumberReadBuilder().(*_ApduDataExtIndividualAddressSerialNumberReadBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtIndividualAddressSerialNumberResponse() ApduDataExtIndividualAddressSerialNumberResponseBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtIndividualAddressSerialNumberResponseBuilder); ok {
		return cb
	}
	cb := NewApduDataExtIndividualAddressSerialNumberResponseBuilder().(*_ApduDataExtIndividualAddressSerialNumberResponseBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtIndividualAddressSerialNumberWrite() ApduDataExtIndividualAddressSerialNumberWriteBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtIndividualAddressSerialNumberWriteBuilder); ok {
		return cb
	}
	cb := NewApduDataExtIndividualAddressSerialNumberWriteBuilder().(*_ApduDataExtIndividualAddressSerialNumberWriteBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtDomainAddressWrite() ApduDataExtDomainAddressWriteBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtDomainAddressWriteBuilder); ok {
		return cb
	}
	cb := NewApduDataExtDomainAddressWriteBuilder().(*_ApduDataExtDomainAddressWriteBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtDomainAddressRead() ApduDataExtDomainAddressReadBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtDomainAddressReadBuilder); ok {
		return cb
	}
	cb := NewApduDataExtDomainAddressReadBuilder().(*_ApduDataExtDomainAddressReadBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtDomainAddressResponse() ApduDataExtDomainAddressResponseBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtDomainAddressResponseBuilder); ok {
		return cb
	}
	cb := NewApduDataExtDomainAddressResponseBuilder().(*_ApduDataExtDomainAddressResponseBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtDomainAddressSelectiveRead() ApduDataExtDomainAddressSelectiveReadBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtDomainAddressSelectiveReadBuilder); ok {
		return cb
	}
	cb := NewApduDataExtDomainAddressSelectiveReadBuilder().(*_ApduDataExtDomainAddressSelectiveReadBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtNetworkParameterWrite() ApduDataExtNetworkParameterWriteBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtNetworkParameterWriteBuilder); ok {
		return cb
	}
	cb := NewApduDataExtNetworkParameterWriteBuilder().(*_ApduDataExtNetworkParameterWriteBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtLinkRead() ApduDataExtLinkReadBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtLinkReadBuilder); ok {
		return cb
	}
	cb := NewApduDataExtLinkReadBuilder().(*_ApduDataExtLinkReadBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtLinkResponse() ApduDataExtLinkResponseBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtLinkResponseBuilder); ok {
		return cb
	}
	cb := NewApduDataExtLinkResponseBuilder().(*_ApduDataExtLinkResponseBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtLinkWrite() ApduDataExtLinkWriteBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtLinkWriteBuilder); ok {
		return cb
	}
	cb := NewApduDataExtLinkWriteBuilder().(*_ApduDataExtLinkWriteBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtGroupPropertyValueRead() ApduDataExtGroupPropertyValueReadBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtGroupPropertyValueReadBuilder); ok {
		return cb
	}
	cb := NewApduDataExtGroupPropertyValueReadBuilder().(*_ApduDataExtGroupPropertyValueReadBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtGroupPropertyValueResponse() ApduDataExtGroupPropertyValueResponseBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtGroupPropertyValueResponseBuilder); ok {
		return cb
	}
	cb := NewApduDataExtGroupPropertyValueResponseBuilder().(*_ApduDataExtGroupPropertyValueResponseBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtGroupPropertyValueWrite() ApduDataExtGroupPropertyValueWriteBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtGroupPropertyValueWriteBuilder); ok {
		return cb
	}
	cb := NewApduDataExtGroupPropertyValueWriteBuilder().(*_ApduDataExtGroupPropertyValueWriteBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtGroupPropertyValueInfoReport() ApduDataExtGroupPropertyValueInfoReportBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtGroupPropertyValueInfoReportBuilder); ok {
		return cb
	}
	cb := NewApduDataExtGroupPropertyValueInfoReportBuilder().(*_ApduDataExtGroupPropertyValueInfoReportBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtDomainAddressSerialNumberRead() ApduDataExtDomainAddressSerialNumberReadBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtDomainAddressSerialNumberReadBuilder); ok {
		return cb
	}
	cb := NewApduDataExtDomainAddressSerialNumberReadBuilder().(*_ApduDataExtDomainAddressSerialNumberReadBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtDomainAddressSerialNumberResponse() ApduDataExtDomainAddressSerialNumberResponseBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtDomainAddressSerialNumberResponseBuilder); ok {
		return cb
	}
	cb := NewApduDataExtDomainAddressSerialNumberResponseBuilder().(*_ApduDataExtDomainAddressSerialNumberResponseBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtDomainAddressSerialNumberWrite() ApduDataExtDomainAddressSerialNumberWriteBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtDomainAddressSerialNumberWriteBuilder); ok {
		return cb
	}
	cb := NewApduDataExtDomainAddressSerialNumberWriteBuilder().(*_ApduDataExtDomainAddressSerialNumberWriteBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) AsApduDataExtFileStreamInfoReport() ApduDataExtFileStreamInfoReportBuilder {
	if cb, ok := b.childBuilder.(ApduDataExtFileStreamInfoReportBuilder); ok {
		return cb
	}
	cb := NewApduDataExtFileStreamInfoReportBuilder().(*_ApduDataExtFileStreamInfoReportBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_ApduDataExtBuilder) Build() (ApduDataExt, error) {
	v, err := b.PartialBuild()
	if err != nil {
		return nil, errors.Wrap(err, "error occurred during partial build")
	}
	if b.childBuilder == nil {
		return nil, errors.New("no child builder present")
	}
	b.childBuilder.setParent(v)
	return b.childBuilder.buildForApduDataExt()
}

func (b *_ApduDataExtBuilder) MustBuild() ApduDataExt {
	build, err := b.Build()
	if err != nil {
		panic(err)
	}
	return build
}

func (b *_ApduDataExtBuilder) DeepCopy() any {
	_copy := b.CreateApduDataExtBuilder().(*_ApduDataExtBuilder)
	_copy.childBuilder = b.childBuilder.DeepCopy().(_ApduDataExtChildBuilder)
	_copy.childBuilder.setParent(_copy)
	if b.collectedErr != nil {
		copy(_copy.collectedErr, b.collectedErr)
	}
	return _copy
}

// CreateApduDataExtBuilder creates a ApduDataExtBuilder
func (b *_ApduDataExt) CreateApduDataExtBuilder() ApduDataExtBuilder {
	if b == nil {
		return NewApduDataExtBuilder()
	}
	return &_ApduDataExtBuilder{_ApduDataExt: b.deepCopy()}
}

///////////////////////
///////////////////////
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////

// Deprecated: use the interface for direct cast
func CastApduDataExt(structType any) ApduDataExt {
	if casted, ok := structType.(ApduDataExt); ok {
		return casted
	}
	if casted, ok := structType.(*ApduDataExt); ok {
		return *casted
	}
	return nil
}

func (m *_ApduDataExt) GetTypeName() string {
	return "ApduDataExt"
}

func (m *_ApduDataExt) getLengthInBits(ctx context.Context) uint16 {
	lengthInBits := uint16(0)
	// Discriminator Field (extApciType)
	lengthInBits += 6

	return lengthInBits
}

func (m *_ApduDataExt) GetLengthInBits(ctx context.Context) uint16 {
	return m._SubType.GetLengthInBits(ctx)
}

func (m *_ApduDataExt) GetLengthInBytes(ctx context.Context) uint16 {
	return m._SubType.GetLengthInBits(ctx) / 8
}

func ApduDataExtParse[T ApduDataExt](ctx context.Context, theBytes []byte, length uint8) (T, error) {
	return ApduDataExtParseWithBuffer[T](ctx, utils.NewReadBufferByteBased(theBytes), length)
}

func ApduDataExtParseWithBufferProducer[T ApduDataExt](length uint8) func(ctx context.Context, readBuffer utils.ReadBuffer) (T, error) {
	return func(ctx context.Context, readBuffer utils.ReadBuffer) (T, error) {
		v, err := ApduDataExtParseWithBuffer[T](ctx, readBuffer, length)
		if err != nil {
			var zero T
			return zero, err
		}
		return v, nil
	}
}

func ApduDataExtParseWithBuffer[T ApduDataExt](ctx context.Context, readBuffer utils.ReadBuffer, length uint8) (T, error) {
	v, err := (new(_ApduDataExt)).parse(ctx, readBuffer, length)
	if err != nil {
		var zero T
		return zero, err
	}
	vc, ok := v.(T)
	if !ok {
		var zero T
		return zero, errors.Errorf("Unexpected type %T. Expected type %T", v, *new(T))
	}
	return vc, nil
}

func (m *_ApduDataExt) parse(ctx context.Context, readBuffer utils.ReadBuffer, length uint8) (__apduDataExt ApduDataExt, err error) {
	positionAware := readBuffer
	_ = positionAware
	if pullErr := readBuffer.PullContext("ApduDataExt"); pullErr != nil {
		return nil, errors.Wrap(pullErr, "Error pulling for ApduDataExt")
	}
	currentPos := positionAware.GetPos()
	_ = currentPos

	extApciType, err := ReadDiscriminatorField[uint8](ctx, "extApciType", ReadUnsignedByte(readBuffer, uint8(6)))
	if err != nil {
		return nil, errors.Wrap(err, fmt.Sprintf("Error parsing 'extApciType' field"))
	}

	// Switch Field (Depending on the discriminator values, passes the instantiation to a sub-type)
	var _child ApduDataExt
	switch {
	case extApciType == 0x00: // ApduDataExtOpenRoutingTableRequest
		if _child, err = new(_ApduDataExtOpenRoutingTableRequest).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtOpenRoutingTableRequest for type-switch of ApduDataExt")
		}
	case extApciType == 0x01: // ApduDataExtReadRoutingTableRequest
		if _child, err = new(_ApduDataExtReadRoutingTableRequest).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtReadRoutingTableRequest for type-switch of ApduDataExt")
		}
	case extApciType == 0x02: // ApduDataExtReadRoutingTableResponse
		if _child, err = new(_ApduDataExtReadRoutingTableResponse).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtReadRoutingTableResponse for type-switch of ApduDataExt")
		}
	case extApciType == 0x03: // ApduDataExtWriteRoutingTableRequest
		if _child, err = new(_ApduDataExtWriteRoutingTableRequest).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtWriteRoutingTableRequest for type-switch of ApduDataExt")
		}
	case extApciType == 0x08: // ApduDataExtReadRouterMemoryRequest
		if _child, err = new(_ApduDataExtReadRouterMemoryRequest).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtReadRouterMemoryRequest for type-switch of ApduDataExt")
		}
	case extApciType == 0x09: // ApduDataExtReadRouterMemoryResponse
		if _child, err = new(_ApduDataExtReadRouterMemoryResponse).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtReadRouterMemoryResponse for type-switch of ApduDataExt")
		}
	case extApciType == 0x0A: // ApduDataExtWriteRouterMemoryRequest
		if _child, err = new(_ApduDataExtWriteRouterMemoryRequest).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtWriteRouterMemoryRequest for type-switch of ApduDataExt")
		}
	case extApciType == 0x0D: // ApduDataExtReadRouterStatusRequest
		if _child, err = new(_ApduDataExtReadRouterStatusRequest).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtReadRouterStatusRequest for type-switch of ApduDataExt")
		}
	case extApciType == 0x0E: // ApduDataExtReadRouterStatusResponse
		if _child, err = new(_ApduDataExtReadRouterStatusResponse).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtReadRouterStatusResponse for type-switch of ApduDataExt")
		}
	case extApciType == 0x0F: // ApduDataExtWriteRouterStatusRequest
		if _child, err = new(_ApduDataExtWriteRouterStatusRequest).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtWriteRouterStatusRequest for type-switch of ApduDataExt")
		}
	case extApciType == 0x10: // ApduDataExtMemoryBitWrite
		if _child, err = new(_ApduDataExtMemoryBitWrite).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtMemoryBitWrite for type-switch of ApduDataExt")
		}
	case extApciType == 0x11: // ApduDataExtAuthorizeRequest
		if _child, err = new(_ApduDataExtAuthorizeRequest).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtAuthorizeRequest for type-switch of ApduDataExt")
		}
	case extApciType == 0x12: // ApduDataExtAuthorizeResponse
		if _child, err = new(_ApduDataExtAuthorizeResponse).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtAuthorizeResponse for type-switch of ApduDataExt")
		}
	case extApciType == 0x13: // ApduDataExtKeyWrite
		if _child, err = new(_ApduDataExtKeyWrite).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtKeyWrite for type-switch of ApduDataExt")
		}
	case extApciType == 0x14: // ApduDataExtKeyResponse
		if _child, err = new(_ApduDataExtKeyResponse).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtKeyResponse for type-switch of ApduDataExt")
		}
	case extApciType == 0x15: // ApduDataExtPropertyValueRead
		if _child, err = new(_ApduDataExtPropertyValueRead).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtPropertyValueRead for type-switch of ApduDataExt")
		}
	case extApciType == 0x16: // ApduDataExtPropertyValueResponse
		if _child, err = new(_ApduDataExtPropertyValueResponse).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtPropertyValueResponse for type-switch of ApduDataExt")
		}
	case extApciType == 0x17: // ApduDataExtPropertyValueWrite
		if _child, err = new(_ApduDataExtPropertyValueWrite).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtPropertyValueWrite for type-switch of ApduDataExt")
		}
	case extApciType == 0x18: // ApduDataExtPropertyDescriptionRead
		if _child, err = new(_ApduDataExtPropertyDescriptionRead).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtPropertyDescriptionRead for type-switch of ApduDataExt")
		}
	case extApciType == 0x19: // ApduDataExtPropertyDescriptionResponse
		if _child, err = new(_ApduDataExtPropertyDescriptionResponse).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtPropertyDescriptionResponse for type-switch of ApduDataExt")
		}
	case extApciType == 0x1A: // ApduDataExtNetworkParameterRead
		if _child, err = new(_ApduDataExtNetworkParameterRead).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtNetworkParameterRead for type-switch of ApduDataExt")
		}
	case extApciType == 0x1B: // ApduDataExtNetworkParameterResponse
		if _child, err = new(_ApduDataExtNetworkParameterResponse).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtNetworkParameterResponse for type-switch of ApduDataExt")
		}
	case extApciType == 0x1C: // ApduDataExtIndividualAddressSerialNumberRead
		if _child, err = new(_ApduDataExtIndividualAddressSerialNumberRead).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtIndividualAddressSerialNumberRead for type-switch of ApduDataExt")
		}
	case extApciType == 0x1D: // ApduDataExtIndividualAddressSerialNumberResponse
		if _child, err = new(_ApduDataExtIndividualAddressSerialNumberResponse).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtIndividualAddressSerialNumberResponse for type-switch of ApduDataExt")
		}
	case extApciType == 0x1E: // ApduDataExtIndividualAddressSerialNumberWrite
		if _child, err = new(_ApduDataExtIndividualAddressSerialNumberWrite).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtIndividualAddressSerialNumberWrite for type-switch of ApduDataExt")
		}
	case extApciType == 0x20: // ApduDataExtDomainAddressWrite
		if _child, err = new(_ApduDataExtDomainAddressWrite).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtDomainAddressWrite for type-switch of ApduDataExt")
		}
	case extApciType == 0x21: // ApduDataExtDomainAddressRead
		if _child, err = new(_ApduDataExtDomainAddressRead).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtDomainAddressRead for type-switch of ApduDataExt")
		}
	case extApciType == 0x22: // ApduDataExtDomainAddressResponse
		if _child, err = new(_ApduDataExtDomainAddressResponse).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtDomainAddressResponse for type-switch of ApduDataExt")
		}
	case extApciType == 0x23: // ApduDataExtDomainAddressSelectiveRead
		if _child, err = new(_ApduDataExtDomainAddressSelectiveRead).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtDomainAddressSelectiveRead for type-switch of ApduDataExt")
		}
	case extApciType == 0x24: // ApduDataExtNetworkParameterWrite
		if _child, err = new(_ApduDataExtNetworkParameterWrite).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtNetworkParameterWrite for type-switch of ApduDataExt")
		}
	case extApciType == 0x25: // ApduDataExtLinkRead
		if _child, err = new(_ApduDataExtLinkRead).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtLinkRead for type-switch of ApduDataExt")
		}
	case extApciType == 0x26: // ApduDataExtLinkResponse
		if _child, err = new(_ApduDataExtLinkResponse).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtLinkResponse for type-switch of ApduDataExt")
		}
	case extApciType == 0x27: // ApduDataExtLinkWrite
		if _child, err = new(_ApduDataExtLinkWrite).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtLinkWrite for type-switch of ApduDataExt")
		}
	case extApciType == 0x28: // ApduDataExtGroupPropertyValueRead
		if _child, err = new(_ApduDataExtGroupPropertyValueRead).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtGroupPropertyValueRead for type-switch of ApduDataExt")
		}
	case extApciType == 0x29: // ApduDataExtGroupPropertyValueResponse
		if _child, err = new(_ApduDataExtGroupPropertyValueResponse).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtGroupPropertyValueResponse for type-switch of ApduDataExt")
		}
	case extApciType == 0x2A: // ApduDataExtGroupPropertyValueWrite
		if _child, err = new(_ApduDataExtGroupPropertyValueWrite).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtGroupPropertyValueWrite for type-switch of ApduDataExt")
		}
	case extApciType == 0x2B: // ApduDataExtGroupPropertyValueInfoReport
		if _child, err = new(_ApduDataExtGroupPropertyValueInfoReport).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtGroupPropertyValueInfoReport for type-switch of ApduDataExt")
		}
	case extApciType == 0x2C: // ApduDataExtDomainAddressSerialNumberRead
		if _child, err = new(_ApduDataExtDomainAddressSerialNumberRead).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtDomainAddressSerialNumberRead for type-switch of ApduDataExt")
		}
	case extApciType == 0x2D: // ApduDataExtDomainAddressSerialNumberResponse
		if _child, err = new(_ApduDataExtDomainAddressSerialNumberResponse).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtDomainAddressSerialNumberResponse for type-switch of ApduDataExt")
		}
	case extApciType == 0x2E: // ApduDataExtDomainAddressSerialNumberWrite
		if _child, err = new(_ApduDataExtDomainAddressSerialNumberWrite).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtDomainAddressSerialNumberWrite for type-switch of ApduDataExt")
		}
	case extApciType == 0x30: // ApduDataExtFileStreamInfoReport
		if _child, err = new(_ApduDataExtFileStreamInfoReport).parse(ctx, readBuffer, m, length); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type ApduDataExtFileStreamInfoReport for type-switch of ApduDataExt")
		}
	default:
		return nil, errors.Errorf("Unmapped type for parameters [extApciType=%v]", extApciType)
	}

	if closeErr := readBuffer.CloseContext("ApduDataExt"); closeErr != nil {
		return nil, errors.Wrap(closeErr, "Error closing for ApduDataExt")
	}

	return _child, nil
}

func (pm *_ApduDataExt) serializeParent(ctx context.Context, writeBuffer utils.WriteBuffer, child ApduDataExt, serializeChildFunction func() error) error {
	// We redirect all calls through client as some methods are only implemented there
	m := child
	_ = m
	positionAware := writeBuffer
	_ = positionAware
	log := zerolog.Ctx(ctx)
	_ = log
	if pushErr := writeBuffer.PushContext("ApduDataExt"); pushErr != nil {
		return errors.Wrap(pushErr, "Error pushing for ApduDataExt")
	}

	if err := WriteDiscriminatorField(ctx, "extApciType", m.GetExtApciType(), WriteUnsignedByte(writeBuffer, 6)); err != nil {
		return errors.Wrap(err, "Error serializing 'extApciType' field")
	}

	// Switch field (Depending on the discriminator values, passes the serialization to a sub-type)
	if _typeSwitchErr := serializeChildFunction(); _typeSwitchErr != nil {
		return errors.Wrap(_typeSwitchErr, "Error serializing sub-type field")
	}

	if popErr := writeBuffer.PopContext("ApduDataExt"); popErr != nil {
		return errors.Wrap(popErr, "Error popping for ApduDataExt")
	}
	return nil
}

func (m *_ApduDataExt) IsApduDataExt() {}

func (m *_ApduDataExt) DeepCopy() any {
	return m.deepCopy()
}

func (m *_ApduDataExt) deepCopy() *_ApduDataExt {
	if m == nil {
		return nil
	}
	_ApduDataExtCopy := &_ApduDataExt{
		nil, // will be set by child
	}
	return _ApduDataExtCopy
}
