blob: b2d5ebfe3245f2241c5c775f514fffb9c5ba4eb9 [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 ampersandIfNullable = `
{{- define "AmpersandIfNullable" -}}
{{- $info := . -}}
{{- if $info.IsNullable -}}
&
{{- end -}}
{{- end -}}
`
const fieldDecodingTmplText = `
{{- define "FieldDecodingTmpl" -}}
{{- $info := . -}}
{{- if $info.IsPointer -}}
pointer, err := decoder.ReadPointer()
if err != nil {
return err
}
if pointer == 0 {
{{- if $info.IsNullable}}
{{$info.Identifier}} = nil
{{- else if $info.IsUnion}}
return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null union pointer"}
{{- else}}
return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
{{- end }}
} else {
{{ template "NonNullableFieldDecodingTmpl" $info }}
}
{{- else -}}
{{ template "NonNullableFieldDecodingTmpl" $info }}
{{- end -}}
{{- end -}}
`
const nonNullableFieldDecodingTmplText = `
{{- define "NonNullableFieldDecodingTmpl" -}}
{{- $info := . -}}
{{- if or $info.IsEnum $info.IsSimple -}}
value, err := decoder.{{$info.ReadFunction}}()
if err != nil {
return err
}
{{if $info.IsSimple -}}
{{$info.Identifier}} = value
{{- else -}}
{{$info.Identifier}} = {{$info.GoType}}(value)
{{- end -}}
{{- else if $info.IsHandle -}}
handle, err := decoder.{{$info.ReadFunction}}()
if err != nil {
return err
}
if handle.IsValid() {
{{- if $info.IsNullable -}}
{{$info.Identifier}} = &handle
} else {
{{$info.Identifier}} = nil
{{- else -}}
{{$info.Identifier}} = handle
} else {
return &bindings.ValidationError{bindings.UnexpectedInvalidHandle, "unexpected invalid handle"}
{{- end -}}
}
{{- else if $info.IsStruct -}}
{{- if $info.IsNullable -}}
{{$info.Identifier}} = new({{$info.GoType}})
{{end -}}
if err := {{$info.Identifier}}.Decode(decoder); err != nil {
return err
}
{{- else if $info.IsUnion -}}
{{- if $info.IsPointer -}}
if err := decoder.StartNestedUnion(); err != nil {
return err
}
{{end -}}
var err error
{{$info.Identifier}}, err = Decode{{$info.GoType}}(decoder)
if err != nil {
return err
}
{{- if not $info.IsNullable}}
if {{$info.Identifier}} == nil {
return &bindings.ValidationError{bindings.UnexpectedNullUnion, "unexpected null union"}
}
{{- end -}}
{{- if $info.IsPointer}}
decoder.Finish()
{{- end -}}
{{- else if $info.IsInterface -}}
handle, err := decoder.{{$info.ReadFunction}}()
if err != nil {
return err
}
if handle.IsValid() {
handleOwner := bindings.NewMessagePipeHandleOwner(handle)
{{- if $info.IsInterfaceRequest}}
{{$info.Identifier}} = {{template "AmpersandIfNullable" $info}}{{$info.GoType}}_Request{handleOwner}
{{- else}}
{{$info.Identifier}} = {{template "AmpersandIfNullable" $info}}{{$info.GoType}}_Pointer{handleOwner}
{{- end -}}
} else {
{{- if $info.IsNullable}}
{{$info.Identifier}} = nil
{{- else}}
return &bindings.ValidationError{bindings.UnexpectedInvalidHandle, "unexpected invalid handle"}
{{- end -}}
}
{{- else if $info.IsArray -}}
{{ $elInfo := $info.ElementEncodingInfo -}}
len0, err := decoder.StartArray({{$elInfo.BitSize}})
if err != nil {
return err
}
{{$info.Identifier}} = make({{$info.GoType}}, len0)
for i := uint32(0); i < len0; i++ {
{{ template "FieldDecodingTmpl" $elInfo }}
{{$info.Identifier}}[i] = {{$elInfo.Identifier}}
}
if err := decoder.Finish(); err != nil {
return nil
}
{{- else if $info.IsMap -}}
{{ $keyInfo := $info.KeyEncodingInfo -}}
{{ $keyElId := $info.KeyEncodingInfo.ElementEncodingInfo.Identifier -}}
{{ $valueInfo := $info.ValueEncodingInfo -}}
{{ $valueElId := $info.ValueEncodingInfo.ElementEncodingInfo.Identifier -}}
{{$info.Identifier}} = new({{$info.GoType}})
if err := decoder.StartMap(); err != nil {
return err
}
var {{$keyInfo.Identifier}} {{$keyInfo.GoType}}
{
{{ template "FieldDecodingTmpl" $keyInfo }}
}
var {{$valueInfo.Identifier}} {{$valueInfo.GoType}}
{
{{ template "FieldDecodingTmpl" $valueInfo }}
}
if err := decoder.Finish(); err != nil {
return nil
}
if len({{$keyInfo.Identifier}}) == len({{$valueInfo.Identifier}}) {
return &bindings.ValidationError{bindings.DifferentSizedArraysInMap,
fmt.Sprintf("Number of keys %d is different from number of values %d",
len({{$keyInfo.Identifier}}), len({{$valueInfo.Identifier}}))}
}
for i := 0; i < len({{$keyInfo.Identifier}}); i++ {
(*{{$info.Identifier}})[{{$keyInfo.Identifier}}[i]] = {{$valueInfo.Identifier}}[i]
}
{{- end -}}
{{- end -}}
`
func initDecodingTemplates() {
template.Must(goFileTmpl.Parse(nonNullableFieldDecodingTmplText))
template.Must(goFileTmpl.Parse(fieldDecodingTmplText))
template.Must(goFileTmpl.Parse(ampersandIfNullable))
}