package dagpb

// Code generated by go-ipld-prime gengo.  DO NOT EDIT.

import (
	ipld "github.com/ipld/go-ipld-prime"
	"github.com/ipld/go-ipld-prime/node/mixins"
	"github.com/ipld/go-ipld-prime/schema"
)

type _PBLink struct {
	Hash  _Link__Maybe
	Name  _String__Maybe
	Tsize _Int__Maybe
}
type PBLink = *_PBLink

func (n _PBLink) FieldHash() MaybeLink {
	return &n.Hash
}
func (n _PBLink) FieldName() MaybeString {
	return &n.Name
}
func (n _PBLink) FieldTsize() MaybeInt {
	return &n.Tsize
}

type _PBLink__Maybe struct {
	m schema.Maybe
	v PBLink
}
type MaybePBLink = *_PBLink__Maybe

func (m MaybePBLink) IsNull() bool {
	return m.m == schema.Maybe_Null
}
func (m MaybePBLink) IsAbsent() bool {
	return m.m == schema.Maybe_Absent
}
func (m MaybePBLink) Exists() bool {
	return m.m == schema.Maybe_Value
}
func (m MaybePBLink) AsNode() ipld.Node {
	switch m.m {
	case schema.Maybe_Absent:
		return ipld.Absent
	case schema.Maybe_Null:
		return ipld.Null
	case schema.Maybe_Value:
		return m.v
	default:
		panic("unreachable")
	}
}
func (m MaybePBLink) Must() PBLink {
	if !m.Exists() {
		panic("unbox of a maybe rejected")
	}
	return m.v
}

var (
	fieldName__PBLink_Hash  = _String{"Hash"}
	fieldName__PBLink_Name  = _String{"Name"}
	fieldName__PBLink_Tsize = _String{"Tsize"}
)
var _ ipld.Node = (PBLink)(&_PBLink{})
var _ schema.TypedNode = (PBLink)(&_PBLink{})

func (PBLink) ReprKind() ipld.ReprKind {
	return ipld.ReprKind_Map
}
func (n PBLink) LookupByString(key string) (ipld.Node, error) {
	switch key {
	case "Hash":
		if n.Hash.m == schema.Maybe_Absent {
			return ipld.Absent, nil
		}
		return n.Hash.v, nil
	case "Name":
		if n.Name.m == schema.Maybe_Absent {
			return ipld.Absent, nil
		}
		return n.Name.v, nil
	case "Tsize":
		if n.Tsize.m == schema.Maybe_Absent {
			return ipld.Absent, nil
		}
		return n.Tsize.v, nil
	default:
		return nil, schema.ErrNoSuchField{Type: nil /*TODO*/, Field: ipld.PathSegmentOfString(key)}
	}
}
func (n PBLink) LookupByNode(key ipld.Node) (ipld.Node, error) {
	ks, err := key.AsString()
	if err != nil {
		return nil, err
	}
	return n.LookupByString(ks)
}
func (PBLink) LookupByIndex(idx int) (ipld.Node, error) {
	return mixins.Map{"dagpb.PBLink"}.LookupByIndex(0)
}
func (n PBLink) LookupBySegment(seg ipld.PathSegment) (ipld.Node, error) {
	return n.LookupByString(seg.String())
}
func (n PBLink) MapIterator() ipld.MapIterator {
	return &_PBLink__MapItr{n, 0}
}

type _PBLink__MapItr struct {
	n   PBLink
	idx int
}

func (itr *_PBLink__MapItr) Next() (k ipld.Node, v ipld.Node, _ error) {
	if itr.idx >= 3 {
		return nil, nil, ipld.ErrIteratorOverread{}
	}
	switch itr.idx {
	case 0:
		k = &fieldName__PBLink_Hash
		if itr.n.Hash.m == schema.Maybe_Absent {
			v = ipld.Absent
			break
		}
		v = itr.n.Hash.v
	case 1:
		k = &fieldName__PBLink_Name
		if itr.n.Name.m == schema.Maybe_Absent {
			v = ipld.Absent
			break
		}
		v = itr.n.Name.v
	case 2:
		k = &fieldName__PBLink_Tsize
		if itr.n.Tsize.m == schema.Maybe_Absent {
			v = ipld.Absent
			break
		}
		v = itr.n.Tsize.v
	default:
		panic("unreachable")
	}
	itr.idx++
	return
}
func (itr *_PBLink__MapItr) Done() bool {
	return itr.idx >= 3
}

func (PBLink) ListIterator() ipld.ListIterator {
	return nil
}
func (PBLink) Length() int {
	return 3
}
func (PBLink) IsAbsent() bool {
	return false
}
func (PBLink) IsNull() bool {
	return false
}
func (PBLink) AsBool() (bool, error) {
	return mixins.Map{"dagpb.PBLink"}.AsBool()
}
func (PBLink) AsInt() (int, error) {
	return mixins.Map{"dagpb.PBLink"}.AsInt()
}
func (PBLink) AsFloat() (float64, error) {
	return mixins.Map{"dagpb.PBLink"}.AsFloat()
}
func (PBLink) AsString() (string, error) {
	return mixins.Map{"dagpb.PBLink"}.AsString()
}
func (PBLink) AsBytes() ([]byte, error) {
	return mixins.Map{"dagpb.PBLink"}.AsBytes()
}
func (PBLink) AsLink() (ipld.Link, error) {
	return mixins.Map{"dagpb.PBLink"}.AsLink()
}
func (PBLink) Prototype() ipld.NodePrototype {
	return _PBLink__Prototype{}
}

type _PBLink__Prototype struct{}

func (_PBLink__Prototype) NewBuilder() ipld.NodeBuilder {
	var nb _PBLink__Builder
	nb.Reset()
	return &nb
}

type _PBLink__Builder struct {
	_PBLink__Assembler
}

func (nb *_PBLink__Builder) Build() ipld.Node {
	if *nb.m != schema.Maybe_Value {
		panic("invalid state: cannot call Build on an assembler that's not finished")
	}
	return nb.w
}
func (nb *_PBLink__Builder) Reset() {
	var w _PBLink
	var m schema.Maybe
	*nb = _PBLink__Builder{_PBLink__Assembler{w: &w, m: &m}}
}

type _PBLink__Assembler struct {
	w     *_PBLink
	m     *schema.Maybe
	state maState
	s     int
	f     int

	cm       schema.Maybe
	ca_Hash  _Link__Assembler
	ca_Name  _String__Assembler
	ca_Tsize _Int__Assembler
}

func (na *_PBLink__Assembler) reset() {
	na.state = maState_initial
	na.s = 0
	na.ca_Hash.reset()
	na.ca_Name.reset()
	na.ca_Tsize.reset()
}

var (
	fieldBit__PBLink_Hash        = 1 << 0
	fieldBit__PBLink_Name        = 1 << 1
	fieldBit__PBLink_Tsize       = 1 << 2
	fieldBits__PBLink_sufficient = 0
)

func (na *_PBLink__Assembler) BeginMap(int) (ipld.MapAssembler, error) {
	switch *na.m {
	case schema.Maybe_Value, schema.Maybe_Null:
		panic("invalid state: cannot assign into assembler that's already finished")
	case midvalue:
		panic("invalid state: it makes no sense to 'begin' twice on the same assembler!")
	}
	*na.m = midvalue
	if na.w == nil {
		na.w = &_PBLink{}
	}
	return na, nil
}
func (_PBLink__Assembler) BeginList(sizeHint int) (ipld.ListAssembler, error) {
	return mixins.MapAssembler{"dagpb.PBLink"}.BeginList(0)
}
func (na *_PBLink__Assembler) AssignNull() error {
	switch *na.m {
	case allowNull:
		*na.m = schema.Maybe_Null
		return nil
	case schema.Maybe_Absent:
		return mixins.MapAssembler{"dagpb.PBLink"}.AssignNull()
	case schema.Maybe_Value, schema.Maybe_Null:
		panic("invalid state: cannot assign into assembler that's already finished")
	case midvalue:
		panic("invalid state: cannot assign null into an assembler that's already begun working on recursive structures!")
	}
	panic("unreachable")
}
func (_PBLink__Assembler) AssignBool(bool) error {
	return mixins.MapAssembler{"dagpb.PBLink"}.AssignBool(false)
}
func (_PBLink__Assembler) AssignInt(int) error {
	return mixins.MapAssembler{"dagpb.PBLink"}.AssignInt(0)
}
func (_PBLink__Assembler) AssignFloat(float64) error {
	return mixins.MapAssembler{"dagpb.PBLink"}.AssignFloat(0)
}
func (_PBLink__Assembler) AssignString(string) error {
	return mixins.MapAssembler{"dagpb.PBLink"}.AssignString("")
}
func (_PBLink__Assembler) AssignBytes([]byte) error {
	return mixins.MapAssembler{"dagpb.PBLink"}.AssignBytes(nil)
}
func (_PBLink__Assembler) AssignLink(ipld.Link) error {
	return mixins.MapAssembler{"dagpb.PBLink"}.AssignLink(nil)
}
func (na *_PBLink__Assembler) AssignNode(v ipld.Node) error {
	if v.IsNull() {
		return na.AssignNull()
	}
	if v2, ok := v.(*_PBLink); ok {
		switch *na.m {
		case schema.Maybe_Value, schema.Maybe_Null:
			panic("invalid state: cannot assign into assembler that's already finished")
		case midvalue:
			panic("invalid state: cannot assign null into an assembler that's already begun working on recursive structures!")
		}
		if na.w == nil {
			na.w = v2
			*na.m = schema.Maybe_Value
			return nil
		}
		*na.w = *v2
		*na.m = schema.Maybe_Value
		return nil
	}
	if v.ReprKind() != ipld.ReprKind_Map {
		return ipld.ErrWrongKind{TypeName: "dagpb.PBLink", MethodName: "AssignNode", AppropriateKind: ipld.ReprKindSet_JustMap, ActualKind: v.ReprKind()}
	}
	itr := v.MapIterator()
	for !itr.Done() {
		k, v, err := itr.Next()
		if err != nil {
			return err
		}
		if err := na.AssembleKey().AssignNode(k); err != nil {
			return err
		}
		if err := na.AssembleValue().AssignNode(v); err != nil {
			return err
		}
	}
	return na.Finish()
}
func (_PBLink__Assembler) Prototype() ipld.NodePrototype {
	return _PBLink__Prototype{}
}
func (ma *_PBLink__Assembler) valueFinishTidy() bool {
	switch ma.f {
	case 0:
		switch ma.w.Hash.m {
		case schema.Maybe_Value:
			ma.w.Hash.v = ma.ca_Hash.w
			ma.state = maState_initial
			return true
		default:
			return false
		}
	case 1:
		switch ma.w.Name.m {
		case schema.Maybe_Value:
			ma.w.Name.v = ma.ca_Name.w
			ma.state = maState_initial
			return true
		default:
			return false
		}
	case 2:
		switch ma.w.Tsize.m {
		case schema.Maybe_Value:
			ma.w.Tsize.v = ma.ca_Tsize.w
			ma.state = maState_initial
			return true
		default:
			return false
		}
	default:
		panic("unreachable")
	}
}
func (ma *_PBLink__Assembler) AssembleEntry(k string) (ipld.NodeAssembler, error) {
	switch ma.state {
	case maState_initial:
		// carry on
	case maState_midKey:
		panic("invalid state: AssembleEntry cannot be called when in the middle of assembling another key")
	case maState_expectValue:
		panic("invalid state: AssembleEntry cannot be called when expecting start of value assembly")
	case maState_midValue:
		if !ma.valueFinishTidy() {
			panic("invalid state: AssembleEntry cannot be called when in the middle of assembling a value")
		} // if tidy success: carry on
	case maState_finished:
		panic("invalid state: AssembleEntry cannot be called on an assembler that's already finished")
	}
	switch k {
	case "Hash":
		if ma.s&fieldBit__PBLink_Hash != 0 {
			return nil, ipld.ErrRepeatedMapKey{&fieldName__PBLink_Hash}
		}
		ma.s += fieldBit__PBLink_Hash
		ma.state = maState_midValue
		ma.f = 0
		ma.ca_Hash.w = ma.w.Hash.v
		ma.ca_Hash.m = &ma.w.Hash.m
		return &ma.ca_Hash, nil
	case "Name":
		if ma.s&fieldBit__PBLink_Name != 0 {
			return nil, ipld.ErrRepeatedMapKey{&fieldName__PBLink_Name}
		}
		ma.s += fieldBit__PBLink_Name
		ma.state = maState_midValue
		ma.f = 1
		ma.ca_Name.w = ma.w.Name.v
		ma.ca_Name.m = &ma.w.Name.m
		return &ma.ca_Name, nil
	case "Tsize":
		if ma.s&fieldBit__PBLink_Tsize != 0 {
			return nil, ipld.ErrRepeatedMapKey{&fieldName__PBLink_Tsize}
		}
		ma.s += fieldBit__PBLink_Tsize
		ma.state = maState_midValue
		ma.f = 2
		ma.ca_Tsize.w = ma.w.Tsize.v
		ma.ca_Tsize.m = &ma.w.Tsize.m
		return &ma.ca_Tsize, nil
	default:
		return nil, ipld.ErrInvalidKey{TypeName: "dagpb.PBLink", Key: &_String{k}}
	}
}
func (ma *_PBLink__Assembler) AssembleKey() ipld.NodeAssembler {
	switch ma.state {
	case maState_initial:
		// carry on
	case maState_midKey:
		panic("invalid state: AssembleKey cannot be called when in the middle of assembling another key")
	case maState_expectValue:
		panic("invalid state: AssembleKey cannot be called when expecting start of value assembly")
	case maState_midValue:
		if !ma.valueFinishTidy() {
			panic("invalid state: AssembleKey cannot be called when in the middle of assembling a value")
		} // if tidy success: carry on
	case maState_finished:
		panic("invalid state: AssembleKey cannot be called on an assembler that's already finished")
	}
	ma.state = maState_midKey
	return (*_PBLink__KeyAssembler)(ma)
}
func (ma *_PBLink__Assembler) AssembleValue() ipld.NodeAssembler {
	switch ma.state {
	case maState_initial:
		panic("invalid state: AssembleValue cannot be called when no key is primed")
	case maState_midKey:
		panic("invalid state: AssembleValue cannot be called when in the middle of assembling a key")
	case maState_expectValue:
		// carry on
	case maState_midValue:
		panic("invalid state: AssembleValue cannot be called when in the middle of assembling another value")
	case maState_finished:
		panic("invalid state: AssembleValue cannot be called on an assembler that's already finished")
	}
	ma.state = maState_midValue
	switch ma.f {
	case 0:
		ma.ca_Hash.w = ma.w.Hash.v
		ma.ca_Hash.m = &ma.w.Hash.m
		return &ma.ca_Hash
	case 1:
		ma.ca_Name.w = ma.w.Name.v
		ma.ca_Name.m = &ma.w.Name.m
		return &ma.ca_Name
	case 2:
		ma.ca_Tsize.w = ma.w.Tsize.v
		ma.ca_Tsize.m = &ma.w.Tsize.m
		return &ma.ca_Tsize
	default:
		panic("unreachable")
	}
}
func (ma *_PBLink__Assembler) Finish() error {
	switch ma.state {
	case maState_initial:
		// carry on
	case maState_midKey:
		panic("invalid state: Finish cannot be called when in the middle of assembling a key")
	case maState_expectValue:
		panic("invalid state: Finish cannot be called when expecting start of value assembly")
	case maState_midValue:
		if !ma.valueFinishTidy() {
			panic("invalid state: Finish cannot be called when in the middle of assembling a value")
		} // if tidy success: carry on
	case maState_finished:
		panic("invalid state: Finish cannot be called on an assembler that's already finished")
	}
	//FIXME check if all required fields are set
	ma.state = maState_finished
	*ma.m = schema.Maybe_Value
	return nil
}
func (ma *_PBLink__Assembler) KeyPrototype() ipld.NodePrototype {
	return _String__Prototype{}
}
func (ma *_PBLink__Assembler) ValuePrototype(k string) ipld.NodePrototype {
	panic("todo structbuilder mapassembler valueprototype")
}

type _PBLink__KeyAssembler _PBLink__Assembler

func (_PBLink__KeyAssembler) BeginMap(sizeHint int) (ipld.MapAssembler, error) {
	return mixins.StringAssembler{"dagpb.PBLink.KeyAssembler"}.BeginMap(0)
}
func (_PBLink__KeyAssembler) BeginList(sizeHint int) (ipld.ListAssembler, error) {
	return mixins.StringAssembler{"dagpb.PBLink.KeyAssembler"}.BeginList(0)
}
func (na *_PBLink__KeyAssembler) AssignNull() error {
	return mixins.StringAssembler{"dagpb.PBLink.KeyAssembler"}.AssignNull()
}
func (_PBLink__KeyAssembler) AssignBool(bool) error {
	return mixins.StringAssembler{"dagpb.PBLink.KeyAssembler"}.AssignBool(false)
}
func (_PBLink__KeyAssembler) AssignInt(int) error {
	return mixins.StringAssembler{"dagpb.PBLink.KeyAssembler"}.AssignInt(0)
}
func (_PBLink__KeyAssembler) AssignFloat(float64) error {
	return mixins.StringAssembler{"dagpb.PBLink.KeyAssembler"}.AssignFloat(0)
}
func (ka *_PBLink__KeyAssembler) AssignString(k string) error {
	if ka.state != maState_midKey {
		panic("misuse: KeyAssembler held beyond its valid lifetime")
	}
	switch k {
	case "Hash":
		if ka.s&fieldBit__PBLink_Hash != 0 {
			return ipld.ErrRepeatedMapKey{&fieldName__PBLink_Hash}
		}
		ka.s += fieldBit__PBLink_Hash
		ka.state = maState_expectValue
		ka.f = 0
	case "Name":
		if ka.s&fieldBit__PBLink_Name != 0 {
			return ipld.ErrRepeatedMapKey{&fieldName__PBLink_Name}
		}
		ka.s += fieldBit__PBLink_Name
		ka.state = maState_expectValue
		ka.f = 1
	case "Tsize":
		if ka.s&fieldBit__PBLink_Tsize != 0 {
			return ipld.ErrRepeatedMapKey{&fieldName__PBLink_Tsize}
		}
		ka.s += fieldBit__PBLink_Tsize
		ka.state = maState_expectValue
		ka.f = 2
	default:
		return ipld.ErrInvalidKey{TypeName: "dagpb.PBLink", Key: &_String{k}}
	}
	return nil
}
func (_PBLink__KeyAssembler) AssignBytes([]byte) error {
	return mixins.StringAssembler{"dagpb.PBLink.KeyAssembler"}.AssignBytes(nil)
}
func (_PBLink__KeyAssembler) AssignLink(ipld.Link) error {
	return mixins.StringAssembler{"dagpb.PBLink.KeyAssembler"}.AssignLink(nil)
}
func (ka *_PBLink__KeyAssembler) AssignNode(v ipld.Node) error {
	if v2, err := v.AsString(); err != nil {
		return err
	} else {
		return ka.AssignString(v2)
	}
}
func (_PBLink__KeyAssembler) Prototype() ipld.NodePrototype {
	return _String__Prototype{}
}
func (PBLink) Type() schema.Type {
	return nil /*TODO:typelit*/
}
func (n PBLink) Representation() ipld.Node {
	return (*_PBLink__Repr)(n)
}

type _PBLink__Repr _PBLink

var (
	fieldName__PBLink_Hash_serial  = _String{"Hash"}
	fieldName__PBLink_Name_serial  = _String{"Name"}
	fieldName__PBLink_Tsize_serial = _String{"Tsize"}
)
var _ ipld.Node = &_PBLink__Repr{}

func (_PBLink__Repr) ReprKind() ipld.ReprKind {
	return ipld.ReprKind_Map
}
func (n *_PBLink__Repr) LookupByString(key string) (ipld.Node, error) {
	switch key {
	case "Hash":
		if n.Hash.m == schema.Maybe_Absent {
			return ipld.Absent, ipld.ErrNotExists{ipld.PathSegmentOfString(key)}
		}
		return n.Hash.v.Representation(), nil
	case "Name":
		if n.Name.m == schema.Maybe_Absent {
			return ipld.Absent, ipld.ErrNotExists{ipld.PathSegmentOfString(key)}
		}
		return n.Name.v.Representation(), nil
	case "Tsize":
		if n.Tsize.m == schema.Maybe_Absent {
			return ipld.Absent, ipld.ErrNotExists{ipld.PathSegmentOfString(key)}
		}
		return n.Tsize.v.Representation(), nil
	default:
		return nil, schema.ErrNoSuchField{Type: nil /*TODO*/, Field: ipld.PathSegmentOfString(key)}
	}
}
func (n *_PBLink__Repr) LookupByNode(key ipld.Node) (ipld.Node, error) {
	ks, err := key.AsString()
	if err != nil {
		return nil, err
	}
	return n.LookupByString(ks)
}
func (_PBLink__Repr) LookupByIndex(idx int) (ipld.Node, error) {
	return mixins.Map{"dagpb.PBLink.Repr"}.LookupByIndex(0)
}
func (n _PBLink__Repr) LookupBySegment(seg ipld.PathSegment) (ipld.Node, error) {
	return n.LookupByString(seg.String())
}
func (n *_PBLink__Repr) MapIterator() ipld.MapIterator {
	end := 3
	if n.Tsize.m == schema.Maybe_Absent {
		end = 2
	} else {
		goto done
	}
	if n.Name.m == schema.Maybe_Absent {
		end = 1
	} else {
		goto done
	}
	if n.Hash.m == schema.Maybe_Absent {
		end = 0
	} else {
		goto done
	}
done:
	return &_PBLink__ReprMapItr{n, 0, end}
}

type _PBLink__ReprMapItr struct {
	n   *_PBLink__Repr
	idx int
	end int
}

func (itr *_PBLink__ReprMapItr) Next() (k ipld.Node, v ipld.Node, _ error) {
advance:
	if itr.idx >= 3 {
		return nil, nil, ipld.ErrIteratorOverread{}
	}
	switch itr.idx {
	case 0:
		k = &fieldName__PBLink_Hash_serial
		if itr.n.Hash.m == schema.Maybe_Absent {
			itr.idx++
			goto advance
		}
		v = itr.n.Hash.v.Representation()
	case 1:
		k = &fieldName__PBLink_Name_serial
		if itr.n.Name.m == schema.Maybe_Absent {
			itr.idx++
			goto advance
		}
		v = itr.n.Name.v.Representation()
	case 2:
		k = &fieldName__PBLink_Tsize_serial
		if itr.n.Tsize.m == schema.Maybe_Absent {
			itr.idx++
			goto advance
		}
		v = itr.n.Tsize.v.Representation()
	default:
		panic("unreachable")
	}
	itr.idx++
	return
}
func (itr *_PBLink__ReprMapItr) Done() bool {
	return itr.idx >= itr.end
}
func (_PBLink__Repr) ListIterator() ipld.ListIterator {
	return nil
}
func (rn *_PBLink__Repr) Length() int {
	l := 3
	if rn.Hash.m == schema.Maybe_Absent {
		l--
	}
	if rn.Name.m == schema.Maybe_Absent {
		l--
	}
	if rn.Tsize.m == schema.Maybe_Absent {
		l--
	}
	return l
}
func (_PBLink__Repr) IsAbsent() bool {
	return false
}
func (_PBLink__Repr) IsNull() bool {
	return false
}
func (_PBLink__Repr) AsBool() (bool, error) {
	return mixins.Map{"dagpb.PBLink.Repr"}.AsBool()
}
func (_PBLink__Repr) AsInt() (int, error) {
	return mixins.Map{"dagpb.PBLink.Repr"}.AsInt()
}
func (_PBLink__Repr) AsFloat() (float64, error) {
	return mixins.Map{"dagpb.PBLink.Repr"}.AsFloat()
}
func (_PBLink__Repr) AsString() (string, error) {
	return mixins.Map{"dagpb.PBLink.Repr"}.AsString()
}
func (_PBLink__Repr) AsBytes() ([]byte, error) {
	return mixins.Map{"dagpb.PBLink.Repr"}.AsBytes()
}
func (_PBLink__Repr) AsLink() (ipld.Link, error) {
	return mixins.Map{"dagpb.PBLink.Repr"}.AsLink()
}
func (_PBLink__Repr) Prototype() ipld.NodePrototype {
	return _PBLink__ReprPrototype{}
}

type _PBLink__ReprPrototype struct{}

func (_PBLink__ReprPrototype) NewBuilder() ipld.NodeBuilder {
	var nb _PBLink__ReprBuilder
	nb.Reset()
	return &nb
}

type _PBLink__ReprBuilder struct {
	_PBLink__ReprAssembler
}

func (nb *_PBLink__ReprBuilder) Build() ipld.Node {
	if *nb.m != schema.Maybe_Value {
		panic("invalid state: cannot call Build on an assembler that's not finished")
	}
	return nb.w
}
func (nb *_PBLink__ReprBuilder) Reset() {
	var w _PBLink
	var m schema.Maybe
	*nb = _PBLink__ReprBuilder{_PBLink__ReprAssembler{w: &w, m: &m}}
}

type _PBLink__ReprAssembler struct {
	w     *_PBLink
	m     *schema.Maybe
	state maState
	s     int
	f     int

	cm       schema.Maybe
	ca_Hash  _Link__ReprAssembler
	ca_Name  _String__ReprAssembler
	ca_Tsize _Int__ReprAssembler
}

func (na *_PBLink__ReprAssembler) reset() {
	na.state = maState_initial
	na.s = 0
	na.ca_Hash.reset()
	na.ca_Name.reset()
	na.ca_Tsize.reset()
}
func (na *_PBLink__ReprAssembler) BeginMap(int) (ipld.MapAssembler, error) {
	switch *na.m {
	case schema.Maybe_Value, schema.Maybe_Null:
		panic("invalid state: cannot assign into assembler that's already finished")
	case midvalue:
		panic("invalid state: it makes no sense to 'begin' twice on the same assembler!")
	}
	*na.m = midvalue
	if na.w == nil {
		na.w = &_PBLink{}
	}
	return na, nil
}
func (_PBLink__ReprAssembler) BeginList(sizeHint int) (ipld.ListAssembler, error) {
	return mixins.MapAssembler{"dagpb.PBLink.Repr"}.BeginList(0)
}
func (na *_PBLink__ReprAssembler) AssignNull() error {
	switch *na.m {
	case allowNull:
		*na.m = schema.Maybe_Null
		return nil
	case schema.Maybe_Absent:
		return mixins.MapAssembler{"dagpb.PBLink.Repr.Repr"}.AssignNull()
	case schema.Maybe_Value, schema.Maybe_Null:
		panic("invalid state: cannot assign into assembler that's already finished")
	case midvalue:
		panic("invalid state: cannot assign null into an assembler that's already begun working on recursive structures!")
	}
	panic("unreachable")
}
func (_PBLink__ReprAssembler) AssignBool(bool) error {
	return mixins.MapAssembler{"dagpb.PBLink.Repr"}.AssignBool(false)
}
func (_PBLink__ReprAssembler) AssignInt(int) error {
	return mixins.MapAssembler{"dagpb.PBLink.Repr"}.AssignInt(0)
}
func (_PBLink__ReprAssembler) AssignFloat(float64) error {
	return mixins.MapAssembler{"dagpb.PBLink.Repr"}.AssignFloat(0)
}
func (_PBLink__ReprAssembler) AssignString(string) error {
	return mixins.MapAssembler{"dagpb.PBLink.Repr"}.AssignString("")
}
func (_PBLink__ReprAssembler) AssignBytes([]byte) error {
	return mixins.MapAssembler{"dagpb.PBLink.Repr"}.AssignBytes(nil)
}
func (_PBLink__ReprAssembler) AssignLink(ipld.Link) error {
	return mixins.MapAssembler{"dagpb.PBLink.Repr"}.AssignLink(nil)
}
func (na *_PBLink__ReprAssembler) AssignNode(v ipld.Node) error {
	if v.IsNull() {
		return na.AssignNull()
	}
	if v2, ok := v.(*_PBLink); ok {
		switch *na.m {
		case schema.Maybe_Value, schema.Maybe_Null:
			panic("invalid state: cannot assign into assembler that's already finished")
		case midvalue:
			panic("invalid state: cannot assign null into an assembler that's already begun working on recursive structures!")
		}
		if na.w == nil {
			na.w = v2
			*na.m = schema.Maybe_Value
			return nil
		}
		*na.w = *v2
		*na.m = schema.Maybe_Value
		return nil
	}
	if v.ReprKind() != ipld.ReprKind_Map {
		return ipld.ErrWrongKind{TypeName: "dagpb.PBLink.Repr", MethodName: "AssignNode", AppropriateKind: ipld.ReprKindSet_JustMap, ActualKind: v.ReprKind()}
	}
	itr := v.MapIterator()
	for !itr.Done() {
		k, v, err := itr.Next()
		if err != nil {
			return err
		}
		if err := na.AssembleKey().AssignNode(k); err != nil {
			return err
		}
		if err := na.AssembleValue().AssignNode(v); err != nil {
			return err
		}
	}
	return na.Finish()
}
func (_PBLink__ReprAssembler) Prototype() ipld.NodePrototype {
	return _PBLink__ReprPrototype{}
}
func (ma *_PBLink__ReprAssembler) valueFinishTidy() bool {
	switch ma.f {
	case 0:
		switch ma.w.Hash.m {
		case schema.Maybe_Value:
			ma.w.Hash.v = ma.ca_Hash.w
			ma.state = maState_initial
			return true
		default:
			return false
		}
	case 1:
		switch ma.w.Name.m {
		case schema.Maybe_Value:
			ma.w.Name.v = ma.ca_Name.w
			ma.state = maState_initial
			return true
		default:
			return false
		}
	case 2:
		switch ma.w.Tsize.m {
		case schema.Maybe_Value:
			ma.w.Tsize.v = ma.ca_Tsize.w
			ma.state = maState_initial
			return true
		default:
			return false
		}
	default:
		panic("unreachable")
	}
}
func (ma *_PBLink__ReprAssembler) AssembleEntry(k string) (ipld.NodeAssembler, error) {
	switch ma.state {
	case maState_initial:
		// carry on
	case maState_midKey:
		panic("invalid state: AssembleEntry cannot be called when in the middle of assembling another key")
	case maState_expectValue:
		panic("invalid state: AssembleEntry cannot be called when expecting start of value assembly")
	case maState_midValue:
		if !ma.valueFinishTidy() {
			panic("invalid state: AssembleEntry cannot be called when in the middle of assembling a value")
		} // if tidy success: carry on
	case maState_finished:
		panic("invalid state: AssembleEntry cannot be called on an assembler that's already finished")
	}
	switch k {
	case "Hash":
		if ma.s&fieldBit__PBLink_Hash != 0 {
			return nil, ipld.ErrRepeatedMapKey{&fieldName__PBLink_Hash_serial}
		}
		ma.s += fieldBit__PBLink_Hash
		ma.state = maState_midValue
		ma.f = 0
		ma.ca_Hash.w = ma.w.Hash.v
		ma.ca_Hash.m = &ma.w.Hash.m

		return &ma.ca_Hash, nil
	case "Name":
		if ma.s&fieldBit__PBLink_Name != 0 {
			return nil, ipld.ErrRepeatedMapKey{&fieldName__PBLink_Name_serial}
		}
		ma.s += fieldBit__PBLink_Name
		ma.state = maState_midValue
		ma.f = 1
		ma.ca_Name.w = ma.w.Name.v
		ma.ca_Name.m = &ma.w.Name.m

		return &ma.ca_Name, nil
	case "Tsize":
		if ma.s&fieldBit__PBLink_Tsize != 0 {
			return nil, ipld.ErrRepeatedMapKey{&fieldName__PBLink_Tsize_serial}
		}
		ma.s += fieldBit__PBLink_Tsize
		ma.state = maState_midValue
		ma.f = 2
		ma.ca_Tsize.w = ma.w.Tsize.v
		ma.ca_Tsize.m = &ma.w.Tsize.m

		return &ma.ca_Tsize, nil
	default:
		return nil, ipld.ErrInvalidKey{TypeName: "dagpb.PBLink.Repr", Key: &_String{k}}
	}
}
func (ma *_PBLink__ReprAssembler) AssembleKey() ipld.NodeAssembler {
	switch ma.state {
	case maState_initial:
		// carry on
	case maState_midKey:
		panic("invalid state: AssembleKey cannot be called when in the middle of assembling another key")
	case maState_expectValue:
		panic("invalid state: AssembleKey cannot be called when expecting start of value assembly")
	case maState_midValue:
		if !ma.valueFinishTidy() {
			panic("invalid state: AssembleKey cannot be called when in the middle of assembling a value")
		} // if tidy success: carry on
	case maState_finished:
		panic("invalid state: AssembleKey cannot be called on an assembler that's already finished")
	}
	ma.state = maState_midKey
	return (*_PBLink__ReprKeyAssembler)(ma)
}
func (ma *_PBLink__ReprAssembler) AssembleValue() ipld.NodeAssembler {
	switch ma.state {
	case maState_initial:
		panic("invalid state: AssembleValue cannot be called when no key is primed")
	case maState_midKey:
		panic("invalid state: AssembleValue cannot be called when in the middle of assembling a key")
	case maState_expectValue:
		// carry on
	case maState_midValue:
		panic("invalid state: AssembleValue cannot be called when in the middle of assembling another value")
	case maState_finished:
		panic("invalid state: AssembleValue cannot be called on an assembler that's already finished")
	}
	ma.state = maState_midValue
	switch ma.f {
	case 0:
		ma.ca_Hash.w = ma.w.Hash.v
		ma.ca_Hash.m = &ma.w.Hash.m

		return &ma.ca_Hash
	case 1:
		ma.ca_Name.w = ma.w.Name.v
		ma.ca_Name.m = &ma.w.Name.m

		return &ma.ca_Name
	case 2:
		ma.ca_Tsize.w = ma.w.Tsize.v
		ma.ca_Tsize.m = &ma.w.Tsize.m

		return &ma.ca_Tsize
	default:
		panic("unreachable")
	}
}
func (ma *_PBLink__ReprAssembler) Finish() error {
	switch ma.state {
	case maState_initial:
		// carry on
	case maState_midKey:
		panic("invalid state: Finish cannot be called when in the middle of assembling a key")
	case maState_expectValue:
		panic("invalid state: Finish cannot be called when expecting start of value assembly")
	case maState_midValue:
		if !ma.valueFinishTidy() {
			panic("invalid state: Finish cannot be called when in the middle of assembling a value")
		} // if tidy success: carry on
	case maState_finished:
		panic("invalid state: Finish cannot be called on an assembler that's already finished")
	}
	//FIXME check if all required fields are set
	ma.state = maState_finished
	*ma.m = schema.Maybe_Value
	return nil
}
func (ma *_PBLink__ReprAssembler) KeyPrototype() ipld.NodePrototype {
	return _String__Prototype{}
}
func (ma *_PBLink__ReprAssembler) ValuePrototype(k string) ipld.NodePrototype {
	panic("todo structbuilder mapassembler repr valueprototype")
}

type _PBLink__ReprKeyAssembler _PBLink__ReprAssembler

func (_PBLink__ReprKeyAssembler) BeginMap(sizeHint int) (ipld.MapAssembler, error) {
	return mixins.StringAssembler{"dagpb.PBLink.Repr.KeyAssembler"}.BeginMap(0)
}
func (_PBLink__ReprKeyAssembler) BeginList(sizeHint int) (ipld.ListAssembler, error) {
	return mixins.StringAssembler{"dagpb.PBLink.Repr.KeyAssembler"}.BeginList(0)
}
func (na *_PBLink__ReprKeyAssembler) AssignNull() error {
	return mixins.StringAssembler{"dagpb.PBLink.Repr.KeyAssembler"}.AssignNull()
}
func (_PBLink__ReprKeyAssembler) AssignBool(bool) error {
	return mixins.StringAssembler{"dagpb.PBLink.Repr.KeyAssembler"}.AssignBool(false)
}
func (_PBLink__ReprKeyAssembler) AssignInt(int) error {
	return mixins.StringAssembler{"dagpb.PBLink.Repr.KeyAssembler"}.AssignInt(0)
}
func (_PBLink__ReprKeyAssembler) AssignFloat(float64) error {
	return mixins.StringAssembler{"dagpb.PBLink.Repr.KeyAssembler"}.AssignFloat(0)
}
func (ka *_PBLink__ReprKeyAssembler) AssignString(k string) error {
	if ka.state != maState_midKey {
		panic("misuse: KeyAssembler held beyond its valid lifetime")
	}
	switch k {
	case "Hash":
		if ka.s&fieldBit__PBLink_Hash != 0 {
			return ipld.ErrRepeatedMapKey{&fieldName__PBLink_Hash_serial}
		}
		ka.s += fieldBit__PBLink_Hash
		ka.state = maState_expectValue
		ka.f = 0
	case "Name":
		if ka.s&fieldBit__PBLink_Name != 0 {
			return ipld.ErrRepeatedMapKey{&fieldName__PBLink_Name_serial}
		}
		ka.s += fieldBit__PBLink_Name
		ka.state = maState_expectValue
		ka.f = 1
	case "Tsize":
		if ka.s&fieldBit__PBLink_Tsize != 0 {
			return ipld.ErrRepeatedMapKey{&fieldName__PBLink_Tsize_serial}
		}
		ka.s += fieldBit__PBLink_Tsize
		ka.state = maState_expectValue
		ka.f = 2
	default:
		return ipld.ErrInvalidKey{TypeName: "dagpb.PBLink.Repr", Key: &_String{k}}
	}
	return nil
}
func (_PBLink__ReprKeyAssembler) AssignBytes([]byte) error {
	return mixins.StringAssembler{"dagpb.PBLink.Repr.KeyAssembler"}.AssignBytes(nil)
}
func (_PBLink__ReprKeyAssembler) AssignLink(ipld.Link) error {
	return mixins.StringAssembler{"dagpb.PBLink.Repr.KeyAssembler"}.AssignLink(nil)
}
func (ka *_PBLink__ReprKeyAssembler) AssignNode(v ipld.Node) error {
	if v2, err := v.AsString(); err != nil {
		return err
	} else {
		return ka.AssignString(v2)
	}
}
func (_PBLink__ReprKeyAssembler) Prototype() ipld.NodePrototype {
	return _String__Prototype{}
}
