You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: ack_frame.go
    path of file: ./repos/scan4all/vendor/github.com/quic-go/quic-go/internal/wire
    
    the code of the file until where you have to start completion: package wire

import (
	"bytes"
	"errors"
	"sort"
	"time"

	"github.com/quic-go/quic-go/internal/protocol"
	"github.com/quic-go/quic-go/internal/utils"
	"github.com/quic-go/quic-go/quicvarint"
)

var errInvalidAckRanges = errors.New("AckFrame: ACK frame contains invalid ACK ranges")

// An AckFrame is an ACK frame
type AckFrame struct {
	AckRanges []AckRange // has to be ordered. The highest ACK range goes first, the lowest ACK range goes last
	DelayTime time.Duration

	ECT0, ECT1, ECNCE uint64
}

// parseAckFrame reads an ACK frame
func parseAckFrame(frame *AckFrame, r *bytes.Reader, typ uint64, ackDelayExponent uint8, _ protocol.VersionNumber) error {
	ecn := typ == ackECNFrameType

	la, err := quicvarint.Read(r)
	if err != nil {
		return err
	}
	largestAcked := protocol.PacketNumber(la)
	delay, err := quicvarint.Read(r)
	if err != nil {
		return err
	}

	delayTime := time.Duration(delay*1<<ackDelayExponent) * time.Microsecond
	if delayTime < 0 {
		// If the delay time overflows, set it to the maximum encodable value.
		delayTime = utils.InfDuration
	}
	frame.DelayTime = delayTime

	numBlocks, err := quicvarint.Read(r)
	if err != nil {
		return err
	}

	// read the first ACK range
	ab, err := quicvarint.Read(r)
	if err != nil {
		return err
	}
	ackBlock := protocol.PacketNumber(ab)
	if ackBlock > largestAcked {
		return errors.New("invalid first ACK range")
	}
	smallest := largestAcked - ackB
    
func parseAckFrame(frame *AckFrame, r *bytes.Reader, typ uint64, ackDelayExponent uint8, _ protocol.VersionNumber) error {
	ecn := typ == ackECNFrameType

	la, err := quicvarint.Read(r)
	if err != nil {
		return err
	}
	largestAcked := protocol.PacketNumber(la)
	delay, err := quicvarint.Read(r)
	if err != nil {
		return err
	}

	delayTime := time.Duration(delay*1<<ackDelayExponent) * time.Microsecond
	if delayTime < 0 {
		// If the delay time overflows, set it to the maximum encodable value.
		delayTime = utils.InfDuration
	}
	frame.DelayTime = delayTime

	numBlocks, err := quicvarint.Read(r)
	if err != nil {
		return err
	}

	// read the first ACK range
	ab, err := quicvarint.Read(r)
	if err != nil {
		return err
	}
	ackBlock := protocol.PacketNumber(ab)
	if ackBlock > largestAcked {
		return errors.New("invalid first ACK range")
	}
	smallest := largestAcked - ackBlock

	// read all the other ACK ranges
	frame.AckRanges = append(frame.AckRanges, AckRange{Smallest: smallest, Largest: largestAcked})
	for i := uint64(0); i < numBlocks; i++ {
		g, err := quicvarint.Read(r)
		if err != nil {
			return err
		}
		gap := protocol.PacketNumber(g)
		if smallest < gap+2 {
			return errInvalidAckRanges
		}
		largest := smallest - gap - 2

		ab, err := quicvarint.Read(r)
		if err != nil {
			return err
		}
		ackBlock := protocol.PacketNumber(ab)

		if ackBlock > largest {
			return errInvalidAckRanges
		}
		smallest = largest - ackBlock
		frame.AckRanges = append(frame.AckRanges, AckRange{Smallest: smallest, Largest: largest})
	}

	if !frame.validateAckRanges() {
		return errInvalidAckRanges
	}

	if ecn {
		ect0, err := quicvarint.Read(r)
		if err != nil {
			return err
		}
		frame.ECT0 = ect0
		ect1, err := quicvarint.Read(r)
		if err != nil {
			return err
		}
		frame.ECT1 = ect1
		ecnce, err := quicvarint.Read(r)
		if err != nil {
			return err
		}
		frame.ECNCE = ecnce
	}

	return nil
}