blob: 27856046abc9d139d3c5fdb5f5369114ddee8ff8 [file] [log] [blame]
// Copyright 2016 The Chromium 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 templates
import (
"text/template"
)
const structTmplText = `
{{- define "Struct" -}}
{{$struct := . -}}
{{ template "StructDecl" $struct }}
{{ template "StructEncodingTmpl" $struct }}
{{ template "StructVersions" $struct }}
{{ template "StructDecodingTmpl" $struct }}
{{- end -}}
`
const structDeclTmplText = `
{{- define "StructDecl" -}}
{{$struct := . -}}
type {{$struct.Name}} struct {
{{- range $field := $struct.Fields}}
{{$field.Name}} {{$field.Type}}
{{- end}}
}
{{- end -}}
`
const structEncodingTmplText = `
{{- define "StructEncodingTmpl" -}}
{{ $struct := . }}
func (s *{{$struct.Name}}) Encode(encoder *bindings.Encoder) error {
encoder.StartStruct({{$struct.CurVersionSize}}, {{$struct.CurVersionNumber}})
{{- range $field := $struct.Fields}}
{{ template "FieldEncodingTmpl" $field.EncodingInfo }}
{{- end}}
if err := encoder.Finish(); err != nil {
return err
}
return nil
}
{{- end -}}
`
const structVersions = `
{{- define "StructVersions" -}}
{{- $struct := . -}}
var {{$struct.PrivateName}}_Versions []bindings.DataHeader = []bindings.DataHeader{
{{- range $version := $struct.Versions}}
bindings.DataHeader{ {{$version.NumBytes}}, {{$version.Version}} },
{{- end}}
}
{{- end -}}
`
const structDecodingTmplText = `
{{- define "StructDecodingTmpl" -}}
{{- $struct := . -}}
func (s *{{$struct.Name}}) Decode(decoder *bindings.Decoder) error {
header, err := decoder.StartStruct()
if err != nil {
return err
}
index := sort.Search(len({{$struct.PrivateName}}_Versions), func(i int) bool {
return {{$struct.PrivateName}}_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
})
if index < len({{$struct.PrivateName}}_Versions) {
if {{$struct.PrivateName}}_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
index--
}
expectedSize := {{$struct.PrivateName}}_Versions[index].Size
if expectedSize != header.Size {
return &bindings.ValidationError{bindings.UnexpectedStructHeader,
fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
}
}
}
{{- range $field := $struct.Fields}}
if header.ElementsOrVersion >= {{$field.MinVersion}} {
{{ template "FieldDecodingTmpl" $field.EncodingInfo }}
}
{{- end}}
}
{{- end -}}
`
func initStructTemplates() {
template.Must(goFileTmpl.Parse(structEncodingTmplText))
template.Must(goFileTmpl.Parse(structDeclTmplText))
template.Must(goFileTmpl.Parse(structVersions))
template.Must(goFileTmpl.Parse(structDecodingTmplText))
template.Must(goFileTmpl.Parse(structTmplText))
}