blob: ba45aa63480800eabfb92b77f6e9d09674d1d6c4 [file] [log] [blame]
// Copyright 2019 The Fuchsia 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 codegen
const unionTmpl = `
{{- define "UnionDefinition" -}}
type {{ .TagName }} uint64
const (
{{- if .IsFlexible }}
{{ $.Name }}_unknownData = 0 // 0x00000000
{{- end }}
{{- range .Members }}
{{ $.Name }}{{ .Name }} = {{ .Ordinal }} // {{ .Ordinal | printf "%#08x" }}
{{- end }}
)
{{range .DocComments}}
//{{ . }}
{{- end}}
type {{ .Name }} struct {
{{ .TagName }} ` + "`{{.Tags}}`" + `
{{- if .IsFlexible }}
I_unknownData interface{}
{{- end }}
{{- range .Members }}
{{- range .DocComments}}
//{{ . }}
{{- end}}
{{ .Name }} {{ .Type }} ` + "`{{.Tags}}`" + `
{{- end }}
}
{{- /*
The reset() method below zeroes out all existing variant data, but does not
clear the tag value. This method is meant to be used internally by Set...()-like
methods to "reset" the union container back to a fully zeroed state before
setting a new variant. Failing to do this will result in newly constructed
unions and modified-in-place unions with ostensibly the same variant to fail
equality checks.
*/}}
func (_m *{{ .Name }}) reset() {
switch _m.{{ .TagName }} {
{{- range .Members }}
case {{ .Ordinal }}:
var _zeroed {{ .Type }}
_m.{{ .Name }} = _zeroed
{{- end }}
{{- if .IsFlexible }}
default:
var _zeroed interface{}
_m.I_unknownData = _zeroed
{{- end }}
}
}
func (_m *{{ .Name }}) Which() {{ .TagName }} {
{{- if .IsStrict }}
return _m.{{ .TagName }}
{{- else }}
switch _m.{{ .TagName }} {
{{- range .Members }}
case {{ .Ordinal }}:
return {{ $.Name }}{{ .Name }}
{{- end }}
default:
return {{ $.Name }}_unknownData
}
{{- end }}
}
func (_m *{{ .Name }}) Ordinal() uint64 {
return uint64(_m.{{ .TagName }})
}
{{- range .Members }}
func (_m *{{ $.Name }}) Set{{ .Name }}({{ .PrivateName }} {{ .Type }}) {
_m.reset()
_m.{{ $.TagName }} = {{ $.Name }}{{ .Name }}
_m.{{ .Name }} = {{ .PrivateName }}
}
func {{ $.Name }}With{{ .Name }}({{ .PrivateName }} {{ .Type }}) {{ $.Name }} {
var _u {{ $.Name }}
_u.Set{{ .Name }}({{ .PrivateName }})
return _u
}
{{- end }}
{{- if .IsFlexible }}
func (_m *{{ .Name }}) GetUnknownData() {{ .UnknownDataType }} {
return _m.I_unknownData.({{ .UnknownDataType }})
}
{{- end }}
{{/* Note that there is no SetUnknownData() function. If you really need to set the I_unknownData
field (e.g. for testing), use Go's reflect package. */}}
{{- end -}}
`