blob: 292f8a27a3b2a712d47b67e791c3a5affc825c50 [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
AnonymousChildren []ScopedLayout
TagEnum nameVariants
TagUnknown nameVariants
TagInvalid nameVariants
WireOrdinalEnum name
WireInvalidOrdinal name
Members []UnionMember
BackingBufferTypeV1 string
BackingBufferTypeV2 string
Result *Result
TypeShapeV1 TypeShape
TypeShapeV2 TypeShape
}
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},
TypeShapeV1: TypeShape{val.TypeShapeV1},
TypeShapeV2: TypeShape{val.TypeShapeV2},
AnonymousChildren: c.getAnonymousChildren(val.Layout),
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"),
BackingBufferTypeV1: computeAllocation(
TypeShape{val.TypeShapeV1}.MaxTotalSize(), boundednessBounded).
BackingBufferType(),
BackingBufferTypeV2: computeAllocation(
TypeShape{val.TypeShapeV2}.MaxTotalSize(), boundednessBounded).
BackingBufferType(),
}
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("_").HLCPP,
TagName: u.TagEnum.nestVariants(tag),
WireOrdinalName: u.WireOrdinalEnum.nest(tag.Wire.Name()),
Offset: mem.Offset,
HandleInformation: c.fieldHandleInformation(&mem.Type),
})
}
return &u
}
func (c *compiler) compileResult(s *Struct, m *fidlgen.Method) *Result {
valueType, errType := c.compileType(*m.ValueType), c.compileType(*m.ErrorType)
result := Result{
ResultDecl: c.compileNameVariants(m.ResultType.Identifier),
ValueStructDecl: valueType.nameVariants,
Value: valueType,
ErrorDecl: errType.nameVariants,
Error: errType,
}
var memberTypeNames []name
if !s.isEmptyStruct {
for _, sm := range s.Members {
memberTypeNames = append(memberTypeNames, sm.Type.HLCPP)
result.ValueMembers = append(result.ValueMembers, sm.AsParameter())
}
}
result.ValueTupleDecl = makeTupleName(memberTypeNames)
if len(memberTypeNames) == 0 {
result.ValueDecl = makeName("void")
} else if len(memberTypeNames) == 1 {
result.ValueDecl = s.Members[0].Type.HLCPP
} else {
result.ValueDecl = result.ValueTupleDecl
}
c.resultForUnion[m.ResultType.Identifier] = &result
return &result
}