// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package vom

import (
	"bytes"
	"fmt"
	"io"
	"reflect"

	"v.io/v23/vdl"
	"v.io/v23/verror"
)

var (
	errDumperClosed  = verror.Register(pkgPath+".errDumperClosed", verror.NoRetry, "{1:}{2:} vom: Dumper closed{:_}")
	errDumperFlushed = verror.Register(pkgPath+".errDumperFlushed", verror.NoRetry, "{1:}{2:} vom: Dumper flushed{:_}")
)

// Dump returns a human-readable dump of the given vom data, in the default
// string format.
func Dump(data []byte) (string, error) {
	var buf bytes.Buffer
	d := NewDumper(NewDumpWriter(&buf))
	_, err := d.Write(data)
	d.Close()
	return string(buf.Bytes()), err
}

// DumpWriter is the interface that describes how to write out dumps produced by
// the Dumper.  Implement this interface to customize dump output behavior.
type DumpWriter interface {
	// WriteAtom is called by the Dumper for each atom it decodes.
	WriteAtom(atom DumpAtom)
	// WriteStatus is called by the Dumper to indicate the status of the dumper.
	WriteStatus(status DumpStatus)
}

// NewDumpWriter returns a DumpWriter that outputs dumps to w, writing each atom
// and status on its own line, in their default string format.
func NewDumpWriter(w io.Writer) DumpWriter {
	return dumpWriter{w}
}

type dumpWriter struct {
	w io.Writer
}

func (w dumpWriter) WriteAtom(atom DumpAtom) {
	fmt.Fprintln(w.w, atom)
}

func (w dumpWriter) WriteStatus(status DumpStatus) {
	id := verror.ErrorID(status.Err)
	if status.MsgLen == 0 && status.MsgN == 0 && (id == errDumperFlushed.ID || id == errDumperClosed.ID) {
		// Don't output status when we're waiting to decode the next message, and
		// we're either flushed or closed, to avoid cluttering the output.
		return
	}
	fmt.Fprintln(w.w, status)
}

// Dumper produces dumps of vom data.  It implements the io.WriteCloser
// interface; Data is fed to the dumper via Write, and Close must be called at
// the end of usage to release resources.
//
// Dumps of vom data consist of a single stream of DumpAtom and DumpStatus.
// Each atom describes a single piece of the vom encoding; the vom encoding is
// composed of a stream of atoms.  The status describes the state of the dumper
// at that point in the stream.
type Dumper struct {
	// The Dumper only contains channels to communicate with the dumpWorker, which
	// does all the actual work.
	cmdChan   chan<- dumpCmd
	closeChan <-chan struct{}
}

var _ io.WriteCloser = (*Dumper)(nil)

// NewDumper returns a new Dumper, which writes dumps of vom data to w.
//
// Close must be called on the returned Dumper to release resources.
func NewDumper(w DumpWriter) *Dumper {
	cmd, close := make(chan dumpCmd), make(chan struct{})
	startDumpWorker(cmd, close, w)
	return &Dumper{cmd, close}
}

// Close flushes buffered data and releases resources.  Close must be called
// exactly once, when the dumper is no longer needed.
func (d *Dumper) Close() error {
	d.Flush()
	close(d.cmdChan)
	<-d.closeChan
	return nil
}

// Flush flushes buffered data, and causes the dumper to restart decoding at the
// start of a new message.  This is useful if the previous data in the stream
// was corrupt, and subsequent data will be for new vom messages.  Previously
// buffered type information remains intact.
func (d *Dumper) Flush() error {
	done := make(chan error)
	d.cmdChan <- dumpCmd{nil, done}
	err := <-done
	return err
}

// Status triggers an explicit dump of the current status of the dumper to the
// DumpWriter.  Status is normally generated at the end of each each decoded
// message; call Status to get extra information for partial dumps and errors.
func (d *Dumper) Status() {
	done := make(chan error)
	d.cmdChan <- dumpCmd{[]byte{}, done}
	<-done
}

// Write implements the io.Writer interface method.  This is the mechanism by
// which data is fed into the dumper.
func (d *Dumper) Write(data []byte) (int, error) {
	if len(data) == 0 {
		// Nil data means Flush, and non-nil empty data means Status, so we must
		// ensure that normal writes never send 0-length data.
		return 0, nil
	}
	done := make(chan error)
	d.cmdChan <- dumpCmd{data, done}
	err := <-done
	return len(data), err
}

type dumpCmd struct {
	// data holds Write data, except nil means Flush, and empty means Status.
	data []byte
	// done is closed when the worker has finished the command.
	done chan error
}

// dumpWorker does all the actual work, in its own goroutine.  Commands are sent
// from the Dumper to the worker via the cmdChan, and the closeChan is closed
// when the worker has exited its goroutine.
//
// We run the worker in a separate goroutine to keep the dumping logic simple
// and synchronous; the worker essentially runs the regular vom decoder logic,
// annotated with extra dump information.  In theory we could implement the
// dumper without any extra goroutines, but that would require implementing a
// vom decoder that explicitly maintained the decoding stack (rather than simple
// recursive calls), which doesn't seem worth it.
//
// The reason we re-implement the vom decoding logic in the work rather than
// just adding the appropriate annotations to the regular vom decoder is for
// performance; we don't want to bloat the regular decoder with lots of dump
// annotations.
type dumpWorker struct {
	cmdChan   <-chan dumpCmd
	closeChan chan<- struct{}

	// We hold regular decoding state, and output dump information to w.
	w       DumpWriter
	buf     *decbuf
	typeDec *TypeDecoder
	status  DumpStatus
	version Version

	// Each Write call on the Dumper is passed to us on the cmdChan.  When we get
	// around to processing the Write data, we buffer any extra data, and hold on
	// to the done channel so that we can close it when all the data is processed.
	data      bytes.Buffer
	lastWrite chan<- error

	// Hold on to the done channel for Flush commands, so that we can close it
	// when the worker actually finishes decoding the current message.
	lastFlush chan<- error
}

func startDumpWorker(cmd <-chan dumpCmd, close chan<- struct{}, w DumpWriter) {
	worker := &dumpWorker{
		cmdChan:   cmd,
		closeChan: close,
		w:         w,
		typeDec:   newTypeDecoderInternal(nil),
	}
	worker.buf = newDecbuf(worker)
	go worker.decodeLoop()
}

// Read implements the io.Reader method, and is our synchronization strategy.
// The worker decodeLoop is running in its own goroutine, and keeps trying to
// decode vom messages.  When the decoder runs out of data, it will trigger a
// Read call.
//
// Thus we're guaranteed that when Read is called, the worker decodeLoop is
// blocked waiting on the results.  This gives us a natural place to process all
// commands, and consume more data from Write calls.
func (d *dumpWorker) Read(data []byte) (int, error) {
	// If we have any data buffered up, just return it.
	if n, _ := d.data.Read(data); n > 0 || len(data) == 0 {
		return n, nil
	}
	// Otherwise we're done with all the buffered data.  Signal the last Write
	// call that all data has been processed.
	d.lastWriteDone(nil)
	// Wait for commands on the the cmd channel.
	for {
		select {
		case cmd, ok := <-d.cmdChan:
			if !ok {
				// Close called, return our special closed error.
				return 0, verror.New(errDumperClosed, nil)
			}
			switch {
			case cmd.data == nil:
				// Flush called, return our special flushed error.  The Flush is done
				// when the decoderLoop starts with a new message.
				d.lastFlush = cmd.done
				return 0, verror.New(errDumperFlushed, nil)
			case len(cmd.data) == 0:
				// Status called.
				d.writeStatus(nil, false)
				cmd.done <- nil
				close(cmd.done)
			default:
				// Write called.  Copy as much as we can into data, writing leftover
				// into our buffer.  Hold on to the cmd.done channel, so we can close it
				// when the data has all been read.
				n := copy(data, cmd.data)
				if n < len(cmd.data) {
					d.data.Write(cmd.data[n:])
				}
				d.lastWrite = cmd.done
				return n, nil
			}
		}
	}
}

// decodeLoop runs a loop synchronously decoding messages.  Calls to read from
// d.buf will eventually result in a call to d.Read, which allows us to handle
// special commands like Close, Flush and Status synchronously.
func (d *dumpWorker) decodeLoop() {
	for {
		err := d.decodeNextValue()
		d.writeStatus(err, true)
		switch {
		case verror.ErrorID(err) == errDumperClosed.ID:
			d.lastWriteDone(err)
			d.lastFlushDone(err)
			close(d.closeChan)
			return
		case err != nil:
			// Any error causes us to flush our buffers; otherwise we run the risk of
			// an infinite loop.
			d.buf.Reset()
			d.data.Reset()
			d.lastWriteDone(err)
			d.lastFlushDone(err)
		}
	}
}

func (d *dumpWorker) lastWriteDone(err error) {
	if d.lastWrite != nil {
		d.lastWrite <- err
		close(d.lastWrite)
		d.lastWrite = nil
	}
}

func (d *dumpWorker) lastFlushDone(err error) {
	if d.lastFlush != nil {
		d.lastFlush <- err
		close(d.lastFlush)
		d.lastFlush = nil
	}
}

// DumpStatus represents the state of the dumper.  It is written to the
// DumpWriter at the end of decoding each value, and may also be triggered
// explicitly via Dumper.Status calls to get information for partial dumps.
type DumpStatus struct {
	MsgId      int64
	MsgLen     int
	MsgN       int
	Buf        []byte
	Debug      string
	RefTypes   []*vdl.Type
	RefAnyLens []uint64
	Value      *vdl.Value
	Err        error
}

func (s DumpStatus) String() string {
	ret := fmt.Sprintf("DumpStatus{MsgId: %d", s.MsgId)
	if s.MsgLen != 0 {
		ret += fmt.Sprintf(", MsgLen: %d", s.MsgLen)
	}
	if s.MsgN != 0 {
		ret += fmt.Sprintf(", MsgN: %d", s.MsgN)
	}
	if len := len(s.Buf); len > 0 {
		ret += fmt.Sprintf(`, Buf(%d): "%x"`, len, s.Buf)
	}
	if s.Debug != "" {
		ret += fmt.Sprintf(", Debug: %q", s.Debug)
	}
	if s.Value.IsValid() {
		ret += fmt.Sprintf(", Value: %v", s.Value)
	}
	if s.Err != nil {
		ret += fmt.Sprintf(", Err: %v", s.Err)
	}
	return ret + "}"
}

func (a DumpAtom) String() string {
	dataFmt := "%20v"
	if _, isString := a.Data.Interface().(string); isString {
		dataFmt = "%20q"
	}
	ret := fmt.Sprintf("%-20x %-15v "+dataFmt, a.Bytes, a.Kind, a.Data.Interface())
	if a.Debug != "" {
		ret += fmt.Sprintf(" [%s]", a.Debug)
	}
	return ret
}

// writeStatus writes the current decoding status to the the DumpWriter.  It is
// called automatically after every message is decoded, and also on every error
// encountered during decoding.  It is also triggered by manual calls to
// Dumper.Status.
func (d *dumpWorker) writeStatus(err error, doneDecoding bool) {
	if doneDecoding {
		d.status.Err = err
		if err == nil {
			// Successful decoding, don't include the last "waiting..." debug message.
			d.status.Debug = ""
		}
	}
	// If we're stuck in the middle of a Read, the data we have so far is in the
	// decbuf.  Grab the data here for debugging.
	if buflen := d.buf.end - d.buf.beg; buflen > 0 {
		d.status.Buf = make([]byte, buflen)
		copy(d.status.Buf, d.buf.buf[d.buf.beg:d.buf.end])
	} else {
		d.status.Buf = nil
	}
	d.w.WriteStatus(d.status)
	if doneDecoding {
		d.status = DumpStatus{}
	}
}

// prepareAtom sets the status.Debug message, and prepares the decbuf so that
// subsequent writeAtom calls can easily capture all data that's been read.
func (d *dumpWorker) prepareAtom(format string, v ...interface{}) {
	d.status.Debug = fmt.Sprintf(format, v...)
	d.buf.moveDataToFront()
}

// writeAtom writes an atom describing the chunk of data we just decoded.  In
// order to capture the data that was read, we rely on prepareAtom being called
// before the writeAtom call.
//
// The mechanism to capture the data is subtle.  In prepareAtom we moved all
// decbuf data to the front, setting decbuf.beg to 0.  Here we assume that all
// data in the decbuf up to the new value of decbuf.beg is what was read.
//
// This is tricky, and somewhat error-prone.  We're using this strategy so that
// we can share the raw decoding logic with the real decoder, while still
// keeping the raw decoding logic reasonably compact and fast.
func (d *dumpWorker) writeAtom(kind DumpKind, data Primitive, format string, v ...interface{}) {
	var bytes []byte
	if len := d.buf.beg; len > 0 {
		bytes = make([]byte, len)
		copy(bytes, d.buf.buf[:len])
	}
	d.w.WriteAtom(DumpAtom{
		Kind:  kind,
		Bytes: bytes,
		Data:  data,
		Debug: fmt.Sprintf(format, v...),
	})
	d.status.MsgN += len(bytes)
	d.buf.moveDataToFront()
}

func (d *dumpWorker) decodeNextValue() error {
	// Decode type messages until we get to the type of the next value.
	valType, err := d.decodeValueType()
	if err != nil {
		return err
	}
	// Decode value message.
	d.status.Value = vdl.ZeroValue(valType)
	target, err := vdl.ValueTarget(d.status.Value)
	if err != nil {
		return err
	}
	return d.decodeValueMsg(valType, target)
}

func (d *dumpWorker) decodeValueType() (*vdl.Type, error) {
	for {
		// Decode the version byte. To make the dumper easier to use on partial
		// data, the version byte is optional, and is allowed to appear before any
		// type or value message. Note that this relies on 0x80 not being a valid
		// first byte of regular messages.
		if d.version == 0 {
			d.prepareAtom("waiting for version byte")
			switch versionByte, err := d.buf.PeekByte(); {
			case err != nil:
				return nil, err
			case versionByte == byte(Version80) || versionByte == byte(Version81):
				d.version = Version(versionByte)
				d.buf.Skip(1)
				d.writeAtom(DumpKindVersion, PrimitivePByte{versionByte}, "vom version %x", versionByte)
				d.writeStatus(nil, true)
			}
		}
		d.prepareAtom("waiting for message ID or control code")
		id, cr, err := binaryDecodeIntWithControl(d.buf)
		if err != nil {
			return nil, err
		}
		var incompleteType bool
		switch cr {
		case 0:
			// no control code
		case WireCtrlTypeIncomplete:
			incompleteType = true
			d.writeAtom(DumpKindControl, PrimitivePControl{ControlKindIncompleteType}, "incomplete type")
			d.prepareAtom("waiting for message ID")
			id, err = binaryDecodeInt(d.buf)
			if err != nil {
				return nil, err
			}
		default:
			return nil, fmt.Errorf("unexpected control code %x", cr)
		}
		d.writeAtom(DumpKindMsgId, PrimitivePInt{id}, "")
		d.status.MsgId = id
		switch {
		case id == 0:
			return nil, verror.New(errDecodeZeroTypeID, nil)
		case id > 0:
			// This is a value message, the typeID is +id.
			tid := TypeId(+id)
			tt, err := d.typeDec.lookupType(tid)
			if err != nil {
				d.writeAtom(DumpKindValueMsg, PrimitivePUint{uint64(tid)}, "%v", err)
				return nil, err
			}
			d.writeAtom(DumpKindValueMsg, PrimitivePUint{uint64(tid)}, "%v", tt)
			return tt, nil
		}
		// This is a type message, the typeID is -id.
		tid := TypeId(-id)
		d.writeAtom(DumpKindTypeMsg, PrimitivePUint{uint64(tid)}, "")
		// Decode the wireType like a regular value, and store it in typeDec.  The
		// type will actually be built when a value message arrives using this tid.
		var wt wireType
		target, err := vdl.ReflectTarget(reflect.ValueOf(&wt))
		if err != nil {
			return nil, err
		}
		if err := d.decodeValueMsg(wireTypeType, target); err != nil {
			return nil, err
		}
		if err := d.typeDec.addWireType(tid, wt); err != nil {
			return nil, err
		}
		if !incompleteType {
			if err := d.typeDec.buildType(tid); d.version >= Version81 && err != nil {
				return nil, err
			}
		}
		d.writeStatus(nil, true)
	}
}

// decodeValueMsg decodes the rest of the message assuming type t, handling the
// optional message length.
func (d *dumpWorker) decodeValueMsg(tt *vdl.Type, target vdl.Target) error {
	if d.version >= Version81 && (containsAny(tt) || containsTypeObject(tt)) {
		d.prepareAtom("waiting for reference type ids")
		tidsLen, err := binaryDecodeLen(d.buf)
		if err != nil {
			return err
		}
		d.writeAtom(DumpKindTypeIdsLen, PrimitivePUint{uint64(tidsLen)}, "")
		d.status.RefTypes = make([]*vdl.Type, tidsLen)
		for i := range d.status.RefTypes {
			d.prepareAtom("waiting for type id")
			tid, err := binaryDecodeUint(d.buf)
			if err != nil {
				return err
			}
			d.status.RefTypes[i], err = d.typeDec.lookupType(TypeId(tid))
			d.writeAtom(DumpKindTypeId, PrimitivePUint{tid}, "")
		}
		if containsAny(tt) {
			d.prepareAtom("waiting for any length list length")
			anyLensLen, err := binaryDecodeLen(d.buf)
			if err != nil {
				return err
			}
			d.writeAtom(DumpKindAnyLensLen, PrimitivePUint{uint64(anyLensLen)}, "")
			d.status.RefAnyLens = make([]uint64, anyLensLen)
			for i := 0; i < anyLensLen; i++ {
				d.prepareAtom("waiting for any len")
				anyMsgLen, err := binaryDecodeUint(d.buf)
				if err != nil {
					return err
				}
				d.status.RefAnyLens[i] = anyMsgLen
				d.writeAtom(DumpKindAnyMsgLen, PrimitivePUint{anyMsgLen}, "")
			}
		}
	}
	if hasChunkLen(tt) {
		d.prepareAtom("waiting for message len")
		msgLen, err := binaryDecodeLen(d.buf)
		if err != nil {
			return err
		}
		d.writeAtom(DumpKindMsgLen, PrimitivePUint{uint64(msgLen)}, "")
		d.status.MsgLen = msgLen
		d.status.MsgN = 0 // Make MsgN match up with MsgLen when successful.
		d.buf.SetLimit(msgLen)
	}
	err := d.decodeValue(tt, target)
	leftover := d.buf.RemoveLimit()
	switch {
	case err != nil:
		return err
	case leftover > 0:
		return verror.New(errLeftOverBytes, nil, leftover)
	}
	return nil
}

// decodeValue decodes the rest of the message assuming type tt.
func (d *dumpWorker) decodeValue(tt *vdl.Type, target vdl.Target) error {
	ttFrom := tt
	if tt.Kind() == vdl.Optional {
		d.prepareAtom("waiting for optional control byte")
		// If the type is optional, we expect to see either WireCtrlNil or the actual
		// value, but not both.  And thus, we can just peek for the WireCtrlNil here.
		switch ctrl, err := binaryPeekControl(d.buf); {
		case err != nil:
			return err
		case ctrl == WireCtrlNil:
			d.buf.Skip(1)
			d.writeAtom(DumpKindControl, PrimitivePControl{ControlKindNil}, "%v is nil", ttFrom)
			return target.FromNil(ttFrom)
		}
		tt = tt.Elem()
	}
	if tt.IsBytes() {
		d.prepareAtom("waiting for bytes len")
		len, err := binaryDecodeLenOrArrayLen(d.buf, ttFrom)
		if err != nil {
			return err
		}
		d.writeAtom(DumpKindByteLen, PrimitivePUint{uint64(len)}, "bytes len")
		d.prepareAtom("waiting for bytes data")
		bytes, err := d.buf.ReadSmall(len)
		if err != nil {
			return err
		}
		str := string(bytes) // copy bytes before writeAtom overwrites the buffer.
		d.writeAtom(DumpKindPrimValue, PrimitivePString{str}, "bytes")
		return target.FromBytes([]byte(str), ttFrom)
	}
	switch kind := tt.Kind(); kind {
	case vdl.Bool:
		d.prepareAtom("waiting for bool value")
		var v bool
		var err error
		switch d.version {
		case Version80:
			v, err = binaryDecodeBool(d.buf)
		default:
			var uv uint64
			uv, err = binaryDecodeUint(d.buf)
			v = (uv == 1)
		}
		if err != nil {
			return err
		}
		d.writeAtom(DumpKindPrimValue, PrimitivePBool{v}, "bool")
		return target.FromBool(v, ttFrom)
	case vdl.Byte:
		d.prepareAtom("waiting for byte value")
		var v byte
		var err error
		switch d.version {
		case Version80:
			v, err = d.buf.ReadByte()
		default:
			var uv uint64
			uv, err = binaryDecodeUint(d.buf)
			v = byte(uv)
		}
		if err != nil {
			return err
		}
		d.writeAtom(DumpKindPrimValue, PrimitivePByte{v}, "byte")
		return target.FromUint(uint64(v), ttFrom)
	case vdl.Uint16, vdl.Uint32, vdl.Uint64:
		d.prepareAtom("waiting for uint value")
		v, err := binaryDecodeUint(d.buf)
		if err != nil {
			return err
		}
		d.writeAtom(DumpKindPrimValue, PrimitivePUint{v}, "uint")
		return target.FromUint(v, ttFrom)
	case vdl.Int8, vdl.Int16, vdl.Int32, vdl.Int64:
		d.prepareAtom("waiting for int value")
		v, err := binaryDecodeInt(d.buf)
		if err != nil {
			return err
		}
		d.writeAtom(DumpKindPrimValue, PrimitivePInt{v}, "int")
		return target.FromInt(v, ttFrom)
	case vdl.Float32, vdl.Float64:
		d.prepareAtom("waiting for float value")
		v, err := binaryDecodeFloat(d.buf)
		if err != nil {
			return err
		}
		d.writeAtom(DumpKindPrimValue, PrimitivePFloat{v}, "float")
		return target.FromFloat(v, ttFrom)
	case vdl.String:
		d.prepareAtom("waiting for string len")
		len, err := binaryDecodeLen(d.buf)
		if err != nil {
			return err
		}
		d.writeAtom(DumpKindByteLen, PrimitivePUint{uint64(len)}, "string len")
		d.prepareAtom("waiting for string data")
		bytes, err := d.buf.ReadSmall(len)
		if err != nil {
			return err
		}
		str := string(bytes) // copy bytes before writeAtom overwrites the buffer.
		d.writeAtom(DumpKindPrimValue, PrimitivePString{str}, "string")
		return target.FromString(str, ttFrom)
	case vdl.Enum:
		d.prepareAtom("waiting for enum index")
		index, err := binaryDecodeUint(d.buf)
		if err != nil {
			return err
		}
		if index >= uint64(tt.NumEnumLabel()) {
			d.writeAtom(DumpKindIndex, PrimitivePUint{index}, "out of range for %v", tt)
			return verror.New(errIndexOutOfRange, nil)
		}
		label := tt.EnumLabel(int(index))
		d.writeAtom(DumpKindIndex, PrimitivePUint{index}, "%v.%v", tt.Name(), label)
		return target.FromEnumLabel(label, ttFrom)
	case vdl.TypeObject:
		d.prepareAtom("waiting for typeobject ID")
		id, err := binaryDecodeUint(d.buf)
		if err != nil {
			return err
		}
		var typeobj *vdl.Type
		switch d.version {
		case Version80:
			typeobj, err = d.typeDec.lookupType(TypeId(id))
		default:
			if id >= uint64(len(d.status.RefTypes)) {
				return fmt.Errorf("type index %d out of bounds", id)
			}
			typeobj = d.status.RefTypes[id]
		}
		if err != nil {
			d.writeAtom(DumpKindTypeId, PrimitivePUint{id}, "%v", err)
			return err
		}
		d.writeAtom(DumpKindTypeId, PrimitivePUint{id}, "%v", typeobj)
		return target.FromTypeObject(typeobj)
	case vdl.Array, vdl.List:
		d.prepareAtom("waiting for list len")
		len, err := binaryDecodeLenOrArrayLen(d.buf, tt)
		if err != nil {
			return err
		}
		d.writeAtom(DumpKindValueLen, PrimitivePUint{uint64(len)}, "list len")
		listTarget, err := target.StartList(ttFrom, len)
		if err != nil {
			return err
		}
		for ix := 0; ix < len; ix++ {
			elem, err := listTarget.StartElem(ix)
			if err != nil {
				return err
			}
			if err := d.decodeValue(tt.Elem(), elem); err != nil {
				return err
			}
			if err := listTarget.FinishElem(elem); err != nil {
				return err
			}
		}
		return target.FinishList(listTarget)
	case vdl.Set:
		d.prepareAtom("waiting for set len")
		len, err := binaryDecodeLen(d.buf)
		if err != nil {
			return err
		}
		d.writeAtom(DumpKindValueLen, PrimitivePUint{uint64(len)}, "set len")
		setTarget, err := target.StartSet(ttFrom, len)
		if err != nil {
			return err
		}
		for ix := 0; ix < len; ix++ {
			key, err := setTarget.StartKey()
			if err != nil {
				return err
			}
			if err := d.decodeValue(tt.Key(), key); err != nil {
				return err
			}
			if err := setTarget.FinishKey(key); err != nil {
				return err
			}
		}
		return target.FinishSet(setTarget)
	case vdl.Map:
		d.prepareAtom("waiting for map len")
		len, err := binaryDecodeLen(d.buf)
		if err != nil {
			return err
		}
		d.writeAtom(DumpKindValueLen, PrimitivePUint{uint64(len)}, "map len")
		mapTarget, err := target.StartMap(ttFrom, len)
		if err != nil {
			return err
		}
		for ix := 0; ix < len; ix++ {
			key, err := mapTarget.StartKey()
			if err != nil {
				return err
			}
			if err := d.decodeValue(tt.Key(), key); err != nil {
				return err
			}
			field, err := mapTarget.FinishKeyStartField(key)
			if err != nil {
				return err
			}
			if err := d.decodeValue(tt.Elem(), field); err != nil {
				return err
			}
			if err := mapTarget.FinishField(key, field); err != nil {
				return err
			}
		}
		return target.FinishMap(mapTarget)
	case vdl.Struct:
		fieldsTarget, err := target.StartFields(ttFrom)
		if err != nil {
			return err
		}
		// Loop through decoding the 0-based field index and corresponding field.
		for {
			d.prepareAtom("waiting for struct field index")
			index, ctrl, err := binaryDecodeUintWithControl(d.buf)
			switch {
			case err != nil:
				return err
			case ctrl == WireCtrlEnd:
				d.writeAtom(DumpKindControl, PrimitivePControl{ControlKindEnd}, "%v END", tt.Name())
				return target.FinishFields(fieldsTarget)
			case ctrl != 0:
				return verror.New(errUnexpectedControlByte, nil, ctrl)
			case index >= uint64(tt.NumField()):
				d.writeAtom(DumpKindIndex, PrimitivePUint{index}, "out of range for %v", tt)
				return verror.New(errIndexOutOfRange, nil)
			}
			ttfield := tt.Field(int(index))
			d.writeAtom(DumpKindIndex, PrimitivePUint{index}, "%v.%v", tt.Name(), ttfield.Name)
			key, field, err := fieldsTarget.StartField(ttfield.Name)
			if err != nil {
				return err
			}
			if err := d.decodeValue(ttfield.Type, field); err != nil {
				return err
			}
			if err := fieldsTarget.FinishField(key, field); err != nil {
				return err
			}
		}
	case vdl.Union:
		fieldsTarget, err := target.StartFields(ttFrom)
		if err != nil {
			return err
		}
		d.prepareAtom("waiting for union field index")
		index, err := binaryDecodeUint(d.buf)
		switch {
		case err != nil:
			return err
		case index >= uint64(tt.NumField()):
			d.writeAtom(DumpKindIndex, PrimitivePUint{index}, "out of range for %v", tt)
			return verror.New(errIndexOutOfRange, nil)
		}
		ttfield := tt.Field(int(index))
		if tt == wireTypeType {
			// Pretty-print for wire type definition messages.
			d.writeAtom(DumpKindWireTypeIndex, PrimitivePUint{index}, "%v", ttfield.Type.Name())
		} else {
			d.writeAtom(DumpKindIndex, PrimitivePUint{index}, "%v.%v", tt.Name(), ttfield.Name)
		}
		key, field, err := fieldsTarget.StartField(ttfield.Name)
		if err != nil {
			return err
		}
		if err := d.decodeValue(ttfield.Type, field); err != nil {
			return err
		}
		if err := fieldsTarget.FinishField(key, field); err != nil {
			return err
		}
		return target.FinishFields(fieldsTarget)
	case vdl.Any:
		d.prepareAtom("waiting for any typeID")
		switch id, ctrl, err := binaryDecodeUintWithControl(d.buf); {
		case err != nil:
			return err
		case ctrl == WireCtrlNil:
			d.writeAtom(DumpKindControl, PrimitivePControl{ControlKindNil}, "any(nil)")
			return target.FromNil(vdl.AnyType)
		case ctrl != 0:
			return verror.New(errUnexpectedControlByte, nil, ctrl)
		default:
			var err error
			var elemType *vdl.Type
			switch d.version {
			case Version80:
				elemType, err = d.typeDec.lookupType(TypeId(id))
			default:
				if id >= uint64(len(d.status.RefTypes)) {
					return fmt.Errorf("type index %d out of bounds", id)
				}
				elemType = d.status.RefTypes[id]
			}
			if err != nil {
				d.writeAtom(DumpKindTypeId, PrimitivePUint{id}, "%v", err)
				return err
			}
			d.writeAtom(DumpKindTypeId, PrimitivePUint{id}, "%v", elemType)
			if d.version >= Version81 {
				d.prepareAtom("waiting for any message length index")
				switch index, ctrl, err := binaryDecodeUintWithControl(d.buf); {
				case err != nil:
					return err
				case ctrl != 0:
					return verror.New(errUnexpectedControlByte, nil, ctrl)
				default:
					if index >= uint64(len(d.status.RefAnyLens)) {
						return fmt.Errorf("any len index %d out of bounds", index)
					}
					d.writeAtom(DumpKindAnyMsgLen, PrimitivePUint{index}, "len %v", d.status.RefAnyLens[index])
					return d.decodeValue(elemType, target)
				}
			}
			return d.decodeValue(elemType, target)
		}
	default:
		panic(verror.New(errDecodeValueUnhandledType, nil, tt))
	}
}
