| // 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 %} |