blob: cc2865beaa7ce4c4d9674a28a113d8ef4fdfae88 [file] [log] [blame]
// Copyright 2021 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 fidlgen_cpp
import (
"go.fuchsia.dev/fuchsia/tools/fidl/lib/fidlgen"
)
type Union struct {
Attributes
fidlgen.Strictness
fidlgen.Resourceness
nameVariants
CodingTableType string
TagEnum nameVariants
TagUnknown nameVariants
TagInvalid nameVariants
WireOrdinalEnum name
WireInvalidOrdinal name
Members []UnionMember
InlineSize int
MaxHandles int
MaxOutOfLine int
Result *Result
HasPointer bool
}
func (Union) Kind() declKind {
return Kinds.Union
}
var _ Kinded = (*Union)(nil)
var _ namespaced = (*Union)(nil)
type UnionMember struct {
Attributes
nameVariants
Ordinal uint64
Type Type
StorageName name
TagName nameVariants
WireOrdinalName name
Offset int
HandleInformation *HandleInformation
}
func (um UnionMember) UpperCamelCaseName() string {
return fidlgen.ToUpperCamelCase(um.Name())
}
func (um UnionMember) NameAndType() (string, Type) {
return um.Name(), um.Type
}
func (c *compiler) compileUnion(val fidlgen.Union) Union {
name := c.compileNameVariants(val.Name)
codingTableType := c.compileCodingTableType(val.Name)
tagEnum := name.nest("Tag")
wireOrdinalEnum := name.Wire.nest("Ordinal")
u := Union{
Attributes: Attributes{val.Attributes},
Strictness: val.Strictness,
Resourceness: val.Resourceness,
nameVariants: name,
CodingTableType: codingTableType,
TagEnum: tagEnum,
TagUnknown: tagEnum.nest("kUnknown"),
TagInvalid: tagEnum.nest("Invalid"),
WireOrdinalEnum: wireOrdinalEnum,
WireInvalidOrdinal: wireOrdinalEnum.nest("Invalid"),
InlineSize: val.TypeShapeV1.InlineSize,
MaxHandles: val.TypeShapeV1.MaxHandles,
MaxOutOfLine: val.TypeShapeV1.MaxOutOfLine,
HasPointer: val.TypeShapeV1.Depth > 0,
}
for _, mem := range val.Members {
if mem.Reserved {
continue
}
name := unionMemberContext.transform(mem.Name)
tag := unionMemberTagContext.transform(mem.Name)
u.Members = append(u.Members, UnionMember{
Attributes: Attributes{mem.Attributes},
Ordinal: uint64(mem.Ordinal),
Type: c.compileType(mem.Type),
nameVariants: name,
StorageName: name.appendName("_").Natural,
TagName: u.TagEnum.nestVariants(tag),
WireOrdinalName: u.WireOrdinalEnum.nest(tag.Wire.Name()),
Offset: mem.Offset,
HandleInformation: c.fieldHandleInformation(&mem.Type),
})
}
if val.MethodResult != nil {
result := Result{
ResultDecl: u.nameVariants,
ValueStructDecl: u.Members[0].Type.nameVariants,
ErrorDecl: u.Members[1].Type.nameVariants,
}
c.resultForStruct[val.MethodResult.ValueType.Identifier] = &result
c.resultForUnion[val.Name] = &result
u.Result = &result
}
return u
}