<commit_before>package main

import (
	"github.com/crabmusket/gosunspec/smdx"
	"io/ioutil"
	"log"
	"os"
	"strings"
	"text/template"
)

const preamble = `// NOTICE
// This file was automatically generated by ../generators/core.go. Do not edit it!
// You can regenerate it by running 'go generate ./core' from the directory above.

package core
`

const model = `
type {{.Name}} struct {
}
`

func main() {
	outputFilename := "../core/models.go.tmp"
	outputFile, err := os.OpenFile(outputFilename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
	if err != nil {
		log.Fatal(err)
	}
	defer outputFile.Close()

	smdxDir := "../models/smdx/"
	files, err := ioutil.ReadDir(smdxDir)
	if err != nil {
		log.Fatal(err)
	}

	_, err = outputFile.WriteString(preamble)
	if err != nil {
		log.Fatal(err)
	}

	modelTemplate := template.Must(template.New("model").Parse(model))

	for _, file := range files {
		if strings.HasPrefix(file.Name(), "smdx_") {
			smdxFile, err := os.OpenFile(smdxDir+file.Name(), os.O_RDONLY, 0644)
			if err != nil {
				log.Fatal(err)
			}

			def, err := smdx.FromXML(smdxFile)
			if err != nil {
				smdxFile.Close()
				log.Fatal(err)
			}

			if len(def.Models) < 1 {
				smdxFile.Close()
				continue
			}

			for _, model := range def.Models {
				modelId := "Model" + model.Id

				modelTemplate.Execute(outputFile, map[string]string{
					"Name": modelId,
				})
			}

			smdxFile.Close()
		}
	}
}<commit_msg>Create populated structures for all model types.<commit_after>package main

import (
	"github.com/crabmusket/gosunspec/smdx"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"strings"
	"text/template"
)

const preamble = `// NOTICE
// This file was automatically generated by ../generators/core.go. Do not edit it!
// You can regenerate it by running 'go generate ./core' from the directory above.

package core
`

const model = `
{{define "point"}}{{.Id}} {{.Type|goType}} ` + "`" + `sunspec:"offset={{.Offset}}{{if gt .Length 0}},len={{.Length}}{{end}}{{if ne .ScaleFactor ""}},sf={{.ScaleFactor}}{{end}}{{if ne .Access ""}},access={{.Access}}{{end}}"` + "`" + `{{end}}
{{$model := .Model }}

// Block{{.Model.Id}} - {{.Strings.ModelStrings.Label}} - {{.Strings.ModelStrings.Description}}
{{range (repeatingBlocks .Model)}}
type Block{{$model.Id}}Repeat struct {
	{{range .Points}}{{template "point" .}}
{{end}}
}
{{end}}

type Block{{.Model.Id}} struct {
{{range (fixedBlocks .Model)}}
{{range .Points}}    {{template "point" .}}
{{end}}
	{{end}}
{{range (repeatingBlocks .Model)}}
  Repeats []Block{{$model.Id}}Repeat
{{end}}
}

func (self *Block{{.Model.Id}}) GetId() ModelId {
  return {{.Model.Id}}
}
`

func main() {
	outputFilename := "../core/models.go.tmp"
	outputFile, err := os.OpenFile(outputFilename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
	if err != nil {
		log.Fatal(err)
	}
	defer outputFile.Close()

	smdxDir := "../models/smdx/"
	files, err := ioutil.ReadDir(smdxDir)
	if err != nil {
		log.Fatal(err)
	}

	_, err = outputFile.WriteString(preamble)
	if err != nil {
		log.Fatal(err)
	}

	t := template.New("model")
	t.Funcs(map[string]interface{}{
		"goType": func(sstype string) string {
			switch sstype {
			case "uint16", "uint32", "uint64", "int16", "float32", "int32", "int64":
				return sstype
			case "sunssf":
				return "ScaleFactor"
			case "eui48":
				return strings.ToUpper(sstype)
			default:
				return strings.Title(sstype)
			}
		},
		"repeatingBlocks": func(m smdx.ModelElement) []smdx.BlockElement {
			if len(m.Blocks) == 1 && m.Blocks[0].Type == "repeating" {
				return m.Blocks
			} else if len(m.Blocks) > 1 {
				return m.Blocks[1:]
			} else {
				return []smdx.BlockElement{}
			}
		},
		"fixedBlocks": func(m smdx.ModelElement) []smdx.BlockElement {
			if len(m.Blocks) > 0 && m.Blocks[0].Type != "repeating" {
				return m.Blocks[0:1]
			} else {
				return []smdx.BlockElement{}
			}
		},
	})
	modelTemplate := template.Must(t.Parse(model))

	for _, file := range files {
		if strings.HasPrefix(file.Name(), "smdx_") {
			smdxFile, err := os.OpenFile(smdxDir+file.Name(), os.O_RDONLY, 0644)
			if err != nil {
				log.Fatal(err)
			}

			def, err := smdx.FromXML(smdxFile)
			if err != nil {
				smdxFile.Close()
				log.Fatal(err)
			}

			if len(def.Models) < 1 {
				smdxFile.Close()
				continue
			}

			for _, model := range def.Models {

				err := modelTemplate.Execute(outputFile, map[string]interface{}{
					"Model":   model,
					"Strings": def.Strings[0],
				})
				if err != nil {
					log.Fatalf("template execution failed: %v", err)
				}
			}

			smdxFile.Close()
		}
	}

	outputFile.Close()
	cmd := exec.Command("/bin/sh", "-c", "gofmt -w "+outputFilename)
	if err := cmd.Run(); err != nil {
		log.Fatalf("gofmt failed: %v", err)
	}
	if err := os.Rename("../core/models.go.tmp", "../core/models.go"); err != nil {
		log.Fatalf("replacing models.go failed: %v", err)
	}
}
{'fraction_non_alphanumeric': 0.18905574984571075, 'fraction_numerical': 0.009051635465953507, 'mean_word_length': 3.360538116591928, 'pattern_counts': {'":': 9, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1258729', 'n_tokens_mistral': 2089, 'n_tokens_neox': 1819, 'n_words': 390}