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 _PBLinks struct {
	x []_PBLink
}
type PBLinks = *_PBLinks
type _PBLinks__Maybe struct {
	m schema.Maybe
	v PBLinks
}
type MaybePBLinks = *_PBLinks__Maybe

func (m MaybePBLinks) IsNull() bool {
	return m.m == schema.Maybe_Null
}
func (m MaybePBLinks) IsAbsent() bool {
	return m.m == schema.Maybe_Absent
}
func (m MaybePBLinks) Exists() bool {
	return m.m == schema.Maybe_Value
}
func (m MaybePBLinks) 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 MaybePBLinks) Must() PBLinks {
	if !m.Exists() {
		panic("unbox of a maybe rejected")
	}
	return m.v
}

var _ ipld.Node = (PBLinks)(&_PBLinks{})
var _ schema.TypedNode = (PBLinks)(&_PBLinks{})

func (PBLinks) ReprKind() ipld.ReprKind {
	return ipld.ReprKind_List
}
func (PBLinks) LookupByString(string) (ipld.Node, error) {
	return mixins.List{"dagpb.PBLinks"}.LookupByString("")
}
func (n PBLinks) LookupByNode(k ipld.Node) (ipld.Node, error) {
	idx, err := k.AsInt()
	if err != nil {
		return nil, err
	}
	return n.LookupByIndex(idx)
}
func (n PBLinks) LookupByIndex(idx int) (ipld.Node, error) {
	if n.Length() <= idx {
		return nil, ipld.ErrNotExists{ipld.PathSegmentOfInt(idx)}
	}
	v := &n.x[idx]
	return v, nil
}
func (n PBLinks) LookupBySegment(seg ipld.PathSegment) (ipld.Node, error) {
	i, err := seg.Index()
	if err != nil {
		return nil, ipld.ErrInvalidSegmentForList{TypeName: "dagpb.PBLinks", TroubleSegment: seg, Reason: err}
	}
	return n.LookupByIndex(i)
}
func (PBLinks) MapIterator() ipld.MapIterator {
	return nil
}
func (n PBLinks) ListIterator() ipld.ListIterator {
	return &_PBLinks__ListItr{n, 0}
}

type _PBLinks__ListItr struct {
	n   PBLinks
	idx int
}

func (itr *_PBLinks__ListItr) Next() (idx int, v ipld.Node, _ error) {
	if itr.idx >= len(itr.n.x) {
		return -1, nil, ipld.ErrIteratorOverread{}
	}
	idx = itr.idx
	x := &itr.n.x[itr.idx]
	v = x
	itr.idx++
	return
}
func (itr *_PBLinks__ListItr) Done() bool {
	return itr.idx >= len(itr.n.x)
}

func (n PBLinks) Length() int {
	return len(n.x)
}
func (PBLinks) IsAbsent() bool {
	return false
}
func (PBLinks) IsNull() bool {
	return false
}
func (PBLinks) AsBool() (bool, error) {
	return mixins.List{"dagpb.PBLinks"}.AsBool()
}
func (PBLinks) AsInt() (int, error) {
	return mixins.List{"dagpb.PBLinks"}.AsInt()
}
func (PBLinks) AsFloat() (float64, error) {
	return mixins.List{"dagpb.PBLinks"}.AsFloat()
}
func (PBLinks) AsString() (string, error) {
	return mixins.List{"dagpb.PBLinks"}.AsString()
}
func (PBLinks) AsBytes() ([]byte, error) {
	return mixins.List{"dagpb.PBLinks"}.AsBytes()
}
func (PBLinks) AsLink() (ipld.Link, error) {
	return mixins.List{"dagpb.PBLinks"}.AsLink()
}
func (PBLinks) Prototype() ipld.NodePrototype {
	return _PBLinks__Prototype{}
}

type _PBLinks__Prototype struct{}

func (_PBLinks__Prototype) NewBuilder() ipld.NodeBuilder {
	var nb _PBLinks__Builder
	nb.Reset()
	return &nb
}

type _PBLinks__Builder struct {
	_PBLinks__Assembler
}

func (nb *_PBLinks__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 *_PBLinks__Builder) Reset() {
	var w _PBLinks
	var m schema.Maybe
	*nb = _PBLinks__Builder{_PBLinks__Assembler{w: &w, m: &m}}
}

type _PBLinks__Assembler struct {
	w     *_PBLinks
	m     *schema.Maybe
	state laState

	cm schema.Maybe
	va _PBLink__Assembler
}

func (na *_PBLinks__Assembler) reset() {
	na.state = laState_initial
	na.va.reset()
}
func (_PBLinks__Assembler) BeginMap(sizeHint int) (ipld.MapAssembler, error) {
	return mixins.ListAssembler{"dagpb.PBLinks"}.BeginMap(0)
}
func (na *_PBLinks__Assembler) BeginList(sizeHint int) (ipld.ListAssembler, 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 sizeHint < 0 {
		sizeHint = 0
	}
	if na.w == nil {
		na.w = &_PBLinks{}
	}
	if sizeHint > 0 {
		na.w.x = make([]_PBLink, 0, sizeHint)
	}
	return na, nil
}
func (na *_PBLinks__Assembler) AssignNull() error {
	switch *na.m {
	case allowNull:
		*na.m = schema.Maybe_Null
		return nil
	case schema.Maybe_Absent:
		return mixins.ListAssembler{"dagpb.PBLinks"}.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 (_PBLinks__Assembler) AssignBool(bool) error {
	return mixins.ListAssembler{"dagpb.PBLinks"}.AssignBool(false)
}
func (_PBLinks__Assembler) AssignInt(int) error {
	return mixins.ListAssembler{"dagpb.PBLinks"}.AssignInt(0)
}
func (_PBLinks__Assembler) AssignFloat(float64) error {
	return mixins.ListAssembler{"dagpb.PBLinks"}.AssignFloat(0)
}
func (_PBLinks__Assembler) AssignString(string) error {
	return mixins.ListAssembler{"dagpb.PBLinks"}.AssignString("")
}
func (_PBLinks__Assembler) AssignBytes([]byte) error {
	return mixins.ListAssembler{"dagpb.PBLinks"}.AssignBytes(nil)
}
func (_PBLinks__Assembler) AssignLink(ipld.Link) error {
	return mixins.ListAssembler{"dagpb.PBLinks"}.AssignLink(nil)
}
func (na *_PBLinks__Assembler) AssignNode(v ipld.Node) error {
	if v.IsNull() {
		return na.AssignNull()
	}
	if v2, ok := v.(*_PBLinks); 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_List {
		return ipld.ErrWrongKind{TypeName: "dagpb.PBLinks", MethodName: "AssignNode", AppropriateKind: ipld.ReprKindSet_JustList, ActualKind: v.ReprKind()}
	}
	itr := v.ListIterator()
	for !itr.Done() {
		_, v, err := itr.Next()
		if err != nil {
			return err
		}
		if err := na.AssembleValue().AssignNode(v); err != nil {
			return err
		}
	}
	return na.Finish()
}
func (_PBLinks__Assembler) Prototype() ipld.NodePrototype {
	return _PBLinks__Prototype{}
}
func (la *_PBLinks__Assembler) valueFinishTidy() bool {
	switch la.cm {
	case schema.Maybe_Value:
		la.va.w = nil
		la.cm = schema.Maybe_Absent
		la.state = laState_initial
		la.va.reset()
		return true
	default:
		return false
	}
}
func (la *_PBLinks__Assembler) AssembleValue() ipld.NodeAssembler {
	switch la.state {
	case laState_initial:
		// carry on
	case laState_midValue:
		if !la.valueFinishTidy() {
			panic("invalid state: AssembleValue cannot be called when still in the middle of assembling the previous value")
		} // if tidy success: carry on
	case laState_finished:
		panic("invalid state: AssembleValue cannot be called on an assembler that's already finished")
	}
	la.w.x = append(la.w.x, _PBLink{})
	la.state = laState_midValue
	row := &la.w.x[len(la.w.x)-1]
	la.va.w = row
	la.va.m = &la.cm
	return &la.va
}
func (la *_PBLinks__Assembler) Finish() error {
	switch la.state {
	case laState_initial:
		// carry on
	case laState_midValue:
		if !la.valueFinishTidy() {
			panic("invalid state: Finish cannot be called when in the middle of assembling a value")
		} // if tidy success: carry on
	case laState_finished:
		panic("invalid state: Finish cannot be called on an assembler that's already finished")
	}
	la.state = laState_finished
	*la.m = schema.Maybe_Value
	return nil
}
func (la *_PBLinks__Assembler) ValuePrototype(_ int) ipld.NodePrototype {
	return _PBLink__Prototype{}
}
func (PBLinks) Type() schema.Type {
	return nil /*TODO:typelit*/
}
func (n PBLinks) Representation() ipld.Node {
	return (*_PBLinks__Repr)(n)
}

type _PBLinks__Repr _PBLinks

var _ ipld.Node = &_PBLinks__Repr{}

func (_PBLinks__Repr) ReprKind() ipld.ReprKind {
	return ipld.ReprKind_List
}
func (_PBLinks__Repr) LookupByString(string) (ipld.Node, error) {
	return mixins.List{"dagpb.PBLinks.Repr"}.LookupByString("")
}
func (nr *_PBLinks__Repr) LookupByNode(k ipld.Node) (ipld.Node, error) {
	v, err := (PBLinks)(nr).LookupByNode(k)
	if err != nil || v == ipld.Null {
		return v, err
	}
	return v.(PBLink).Representation(), nil
}
func (nr *_PBLinks__Repr) LookupByIndex(idx int) (ipld.Node, error) {
	v, err := (PBLinks)(nr).LookupByIndex(idx)
	if err != nil || v == ipld.Null {
		return v, err
	}
	return v.(PBLink).Representation(), nil
}
func (n _PBLinks__Repr) LookupBySegment(seg ipld.PathSegment) (ipld.Node, error) {
	i, err := seg.Index()
	if err != nil {
		return nil, ipld.ErrInvalidSegmentForList{TypeName: "dagpb.PBLinks.Repr", TroubleSegment: seg, Reason: err}
	}
	return n.LookupByIndex(i)
}
func (_PBLinks__Repr) MapIterator() ipld.MapIterator {
	return nil
}
func (nr *_PBLinks__Repr) ListIterator() ipld.ListIterator {
	return &_PBLinks__ReprListItr{(PBLinks)(nr), 0}
}

type _PBLinks__ReprListItr _PBLinks__ListItr

func (itr *_PBLinks__ReprListItr) Next() (idx int, v ipld.Node, err error) {
	idx, v, err = (*_PBLinks__ListItr)(itr).Next()
	if err != nil || v == ipld.Null {
		return
	}
	return idx, v.(PBLink).Representation(), nil
}
func (itr *_PBLinks__ReprListItr) Done() bool {
	return (*_PBLinks__ListItr)(itr).Done()
}

func (rn *_PBLinks__Repr) Length() int {
	return len(rn.x)
}
func (_PBLinks__Repr) IsAbsent() bool {
	return false
}
func (_PBLinks__Repr) IsNull() bool {
	return false
}
func (_PBLinks__Repr) AsBool() (bool, error) {
	return mixins.List{"dagpb.PBLinks.Repr"}.AsBool()
}
func (_PBLinks__Repr) AsInt() (int, error) {
	return mixins.List{"dagpb.PBLinks.Repr"}.AsInt()
}
func (_PBLinks__Repr) AsFloat() (float64, error) {
	return mixins.List{"dagpb.PBLinks.Repr"}.AsFloat()
}
func (_PBLinks__Repr) AsString() (string, error) {
	return mixins.List{"dagpb.PBLinks.Repr"}.AsString()
}
func (_PBLinks__Repr) AsBytes() ([]byte, error) {
	return mixins.List{"dagpb.PBLinks.Repr"}.AsBytes()
}
func (_PBLinks__Repr) AsLink() (ipld.Link, error) {
	return mixins.List{"dagpb.PBLinks.Repr"}.AsLink()
}
func (_PBLinks__Repr) Prototype() ipld.NodePrototype {
	return _PBLinks__ReprPrototype{}
}

type _PBLinks__ReprPrototype struct{}

func (_PBLinks__ReprPrototype) NewBuilder() ipld.NodeBuilder {
	var nb _PBLinks__ReprBuilder
	nb.Reset()
	return &nb
}

type _PBLinks__ReprBuilder struct {
	_PBLinks__ReprAssembler
}

func (nb *_PBLinks__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 *_PBLinks__ReprBuilder) Reset() {
	var w _PBLinks
	var m schema.Maybe
	*nb = _PBLinks__ReprBuilder{_PBLinks__ReprAssembler{w: &w, m: &m}}
}

type _PBLinks__ReprAssembler struct {
	w     *_PBLinks
	m     *schema.Maybe
	state laState

	cm schema.Maybe
	va _PBLink__ReprAssembler
}

func (na *_PBLinks__ReprAssembler) reset() {
	na.state = laState_initial
	na.va.reset()
}
func (_PBLinks__ReprAssembler) BeginMap(sizeHint int) (ipld.MapAssembler, error) {
	return mixins.ListAssembler{"dagpb.PBLinks.Repr"}.BeginMap(0)
}
func (na *_PBLinks__ReprAssembler) BeginList(sizeHint int) (ipld.ListAssembler, 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 sizeHint < 0 {
		sizeHint = 0
	}
	if na.w == nil {
		na.w = &_PBLinks{}
	}
	if sizeHint > 0 {
		na.w.x = make([]_PBLink, 0, sizeHint)
	}
	return na, nil
}
func (na *_PBLinks__ReprAssembler) AssignNull() error {
	switch *na.m {
	case allowNull:
		*na.m = schema.Maybe_Null
		return nil
	case schema.Maybe_Absent:
		return mixins.ListAssembler{"dagpb.PBLinks.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 (_PBLinks__ReprAssembler) AssignBool(bool) error {
	return mixins.ListAssembler{"dagpb.PBLinks.Repr"}.AssignBool(false)
}
func (_PBLinks__ReprAssembler) AssignInt(int) error {
	return mixins.ListAssembler{"dagpb.PBLinks.Repr"}.AssignInt(0)
}
func (_PBLinks__ReprAssembler) AssignFloat(float64) error {
	return mixins.ListAssembler{"dagpb.PBLinks.Repr"}.AssignFloat(0)
}
func (_PBLinks__ReprAssembler) AssignString(string) error {
	return mixins.ListAssembler{"dagpb.PBLinks.Repr"}.AssignString("")
}
func (_PBLinks__ReprAssembler) AssignBytes([]byte) error {
	return mixins.ListAssembler{"dagpb.PBLinks.Repr"}.AssignBytes(nil)
}
func (_PBLinks__ReprAssembler) AssignLink(ipld.Link) error {
	return mixins.ListAssembler{"dagpb.PBLinks.Repr"}.AssignLink(nil)
}
func (na *_PBLinks__ReprAssembler) AssignNode(v ipld.Node) error {
	if v.IsNull() {
		return na.AssignNull()
	}
	if v2, ok := v.(*_PBLinks); 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_List {
		return ipld.ErrWrongKind{TypeName: "dagpb.PBLinks.Repr", MethodName: "AssignNode", AppropriateKind: ipld.ReprKindSet_JustList, ActualKind: v.ReprKind()}
	}
	itr := v.ListIterator()
	for !itr.Done() {
		_, v, err := itr.Next()
		if err != nil {
			return err
		}
		if err := na.AssembleValue().AssignNode(v); err != nil {
			return err
		}
	}
	return na.Finish()
}
func (_PBLinks__ReprAssembler) Prototype() ipld.NodePrototype {
	return _PBLinks__ReprPrototype{}
}
func (la *_PBLinks__ReprAssembler) valueFinishTidy() bool {
	switch la.cm {
	case schema.Maybe_Value:
		la.va.w = nil
		la.cm = schema.Maybe_Absent
		la.state = laState_initial
		la.va.reset()
		return true
	default:
		return false
	}
}
func (la *_PBLinks__ReprAssembler) AssembleValue() ipld.NodeAssembler {
	switch la.state {
	case laState_initial:
		// carry on
	case laState_midValue:
		if !la.valueFinishTidy() {
			panic("invalid state: AssembleValue cannot be called when still in the middle of assembling the previous value")
		} // if tidy success: carry on
	case laState_finished:
		panic("invalid state: AssembleValue cannot be called on an assembler that's already finished")
	}
	la.w.x = append(la.w.x, _PBLink{})
	la.state = laState_midValue
	row := &la.w.x[len(la.w.x)-1]
	la.va.w = row
	la.va.m = &la.cm
	return &la.va
}
func (la *_PBLinks__ReprAssembler) Finish() error {
	switch la.state {
	case laState_initial:
		// carry on
	case laState_midValue:
		if !la.valueFinishTidy() {
			panic("invalid state: Finish cannot be called when in the middle of assembling a value")
		} // if tidy success: carry on
	case laState_finished:
		panic("invalid state: Finish cannot be called on an assembler that's already finished")
	}
	la.state = laState_finished
	*la.m = schema.Maybe_Value
	return nil
}
func (la *_PBLinks__ReprAssembler) ValuePrototype(_ int) ipld.NodePrototype {
	return _PBLink__ReprPrototype{}
}
