// This program generates some repetative method implementations
// for the many types of list capnp provides.
package main

import (
	"bufio"
	"fmt"
	"os"
	"os/exec"
	"text/template"
)

func chkfatal(err error) {
	if err != nil {
		panic(err)
	}
}

var tpl = template.Must(template.New("list-gen").Parse(`
func (l {{.}}) IsValid() bool {
	return List(l).IsValid()
}

func (l {{.}}) Len() int {
	return List(l).Len()
}

func (l {{.}}) EncodeAsPtr(seg *Segment) Ptr {
	return List(l).EncodeAsPtr(seg)
}

func ({{.}}) DecodeFromPtr(p Ptr) {{.}} {
	return {{.}}(List{}.DecodeFromPtr(p))
}

func (l {{.}}) Message() *Message {
	return List(l).Message()
}

func (l {{.}}) Segment() *Segment {
	return List(l).Segment()
}

func (l {{.}}) ToPtr() Ptr {
	return List(l).ToPtr()
}

func (l {{.}}) primitiveElem(i int, expectedSize ObjectSize) (address, error) {
	return List(l).primitiveElem(i, expectedSize)
}
`))

func main() {
	listTypes := []string{
		"VoidList",
		"BitList",
		"Float32List",
		"Float64List",
		"TextList",
		"DataList",
		"PointerList",
		"EnumList[T]",
		"StructList[T]",
		"CapList[T]",
	}
	for _, bits := range []int{8, 16, 32, 64} {
		listTypes = append(listTypes, []string{
			fmt.Sprintf("Int%vList", bits),
			fmt.Sprintf("UInt%vList", bits),
		}...)
	}

	f, err := os.Create("list-gen.go")
	chkfatal(err)

	bw := bufio.NewWriter(f)
	bw.WriteString(`
		// Code generated by ./internal/gen/gen.go. DO NOT EDIT.

		package capnp
	`)
	for _, typ := range listTypes {
		chkfatal(tpl.Execute(bw, typ))
	}
	chkfatal(bw.Flush())
	chkfatal(f.Close())
	chkfatal(exec.Command("gofmt", "-w", "list-gen.go").Run())
}
