blob: 6cdbd2e8d4cf9c0cdaa55daffc0965a55e2b154b [file] [log] [blame]
// Copyright 2015 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.
{% import "encoding_macros.tmpl" as encoding_macros %}
{% import "runtime_type_macros.tmpl" as runtime_type_macros %}
{% macro define(union, typepkg, package, exported=True) %}
type {{union|name(exported)}} interface {
Tag() uint32
Interface() interface{}
__Reflect(__{{union|name(exported)}}Reflect)
Encode(encoder *bindings.Encoder) error
}
{{runtime_type_macros.maybeWriteStaticMojomTypeAccessor(typepkg, union)}}
type __{{union|name(exported)}}Reflect struct {
{% for field in union.fields %}
{{field|name(exported)}} {{field.kind|go_type}}
{% endfor %}
}
func Decode{{union|name(exported)}}(decoder *bindings.Decoder) ({{union|name(exported)}}, error) {
size, tag, err := decoder.ReadUnionHeader()
if err != nil {
return nil, err
}
if size == 0 {
decoder.SkipUnionValue()
return nil, nil
}
switch tag {
{% for field in union.fields %}
case {{field.ordinal}}:
var value {{union|name(exported)}}{{field|name(exported)}}
if err := value.decodeInternal(decoder); err != nil {
return nil, err
}
decoder.FinishReadingUnionValue()
return &value, nil
{% endfor %}
}
decoder.SkipUnionValue()
return &{{union|name(exported)}}Unknown{tag: tag}, nil
}
{% set struct_name = union|name(exported) + 'Unknown' %}
type {{struct_name}} struct { tag uint32 }
func (u *{{struct_name}}) Tag() uint32 { return u.tag }
func (u *{{struct_name}}) Interface() interface{} { return nil }
func (u *{{struct_name}}) __Reflect(__{{union|name(exported)}}Reflect) {}
func (u *{{struct_name}}) Encode(encoder *bindings.Encoder) error {
return fmt.Errorf("Trying to serialize an unknown {{union|name(exported)}}. There is no sane way to do that!");
}
{% for field in union.fields %}
{%- set struct_name = union|name(exported) + field|name(exported) %}
type {{struct_name}} struct { Value {{field.kind|go_type}} }
func (u *{{struct_name}}) Tag() uint32 { return {{field.ordinal}} }
func (u *{{struct_name}}) Interface() interface{} { return u.Value }
func (u *{{struct_name}}) __Reflect(__{{union|name(exported)}}Reflect) {}
func (u *{{struct_name}}) Encode(encoder *bindings.Encoder) error {
encoder.WriteUnionHeader(u.Tag())
{{encode_union_field('u.Value', field.kind)|tab_indent()}}
encoder.FinishWritingUnionValue()
return nil
}
func (u *{{struct_name}}) decodeInternal(decoder *bindings.Decoder) error {
{{decode_union_field('u.Value', field.kind)|tab_indent()}}
return nil
}
{{runtime_type_macros.maybeWriteMojomTypeAccessor(typepkg, union, struct_name)}}
{% endfor %}
{% endmacro %}
{% macro encode_union_field(value, kind) %}
{% if kind|is_union %}
if err := encoder.WritePointer(); err != nil {
return err
}
encoder.StartNestedUnion()
{{encoding_macros.encode(value, kind)}}
encoder.Finish()
{% else %}
{{encoding_macros.encode(value, kind)}}
{% endif %}
{% endmacro %}
{% macro decode_union_field(value, kind) %}
{% if kind|is_union %}
if pointer, err := decoder.ReadPointer(); err != nil || pointer == 0 {
if err != nil {
return err
}
{% if kind|is_nullable %}
{{value}} = nil
return nil
{% else %}
return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null union pointer"}
{% endif %}
}
if err := decoder.StartNestedUnion(); err != nil {
return err
}
{{encoding_macros.decode(value, kind)}}
decoder.Finish()
{% else %}
{{encoding_macros.decode(value, kind)}}
{% endif %}
{% endmacro %}