blob: da6bc7c47accd075a7cae5bcd86aa335b1b6212a [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 summarize
import (
"fmt"
"go.fuchsia.dev/fuchsia/tools/fidl/lib/fidlgen"
)
/*
Implementations of properties shared between multple Element types. If an
Element type needs a property, a property type is embedded into its type. For
an example, see below how isMember embeds named.
*/
// named is something that has a name.
type named struct {
// name is a fully qualified name. It is generic, as sometimes it is a
// compound identifier and sometimes "just" an identifier.
name Name
// parent is nonempty for members.
parent fidlgen.EncodedCompoundIdentifier
}
func newNamed(name fidlgen.EncodedCompoundIdentifier) named {
return named{name: Name(name)}
}
func (l named) Serialize() ElementStr {
var e ElementStr
e.Name = l.Name()
return e
}
func (l named) Name() Name {
if l.parent != "" {
return Name(fmt.Sprintf("%v.%v", l.parent, l.name))
}
return l.name
}
// isMember is something that is a member.
type isMember struct {
named
parentType fidlgen.DeclType
}
// newIsMember creates a new element that represents a member.
func newIsMember(
parentName fidlgen.EncodedCompoundIdentifier,
name fidlgen.Identifier,
parentType fidlgen.DeclType) isMember {
return isMember{
named: named{parent: parentName, name: Name(name)},
parentType: parentType,
}
}
// String implements Element.
func (i isMember) String() string {
return i.Serialize().String()
}
func (i isMember) Serialize() ElementStr {
e := i.named.Serialize()
e.Kind = Kind(fmt.Sprintf("%v/member", i.parentType))
return e
}
func (m isMember) Member() bool {
return true
}
// notMember is something that is not a member.
type notMember struct{}
func (m notMember) Member() bool {
return false
}
// aggregate is the base Element for anything that looks like a struct, API-wise.
type aggregate struct {
named
notMember
// Not all aggregates have strictness. Union has it, but tables and
// structs don't, for example. So we allow Strictness to be a
// tri-state.
Strictness
resourceness fidlgen.Resourceness
typeName fidlgen.DeclType
}
func newAggregateWithStrictness(
name fidlgen.EncodedCompoundIdentifier,
resourceness fidlgen.Resourceness,
typeName fidlgen.DeclType,
s fidlgen.Strictness) aggregate {
a := newAggregate(name, resourceness, typeName)
a.Strictness = strictness(s)
return a
}
func newAggregate(
name fidlgen.EncodedCompoundIdentifier,
resourceness fidlgen.Resourceness,
typeName fidlgen.DeclType) aggregate {
return aggregate{
named: named{name: Name(name)},
resourceness: resourceness,
typeName: typeName,
}
}
// String implements Element.
func (s aggregate) String() string {
return s.Serialize().String()
}
func resourceness(resourceness fidlgen.Resourceness) Resourceness {
if resourceness {
return isResource
}
return isValue
}
func (s aggregate) Serialize() ElementStr {
e := s.named.Serialize()
e.Resourceness = resourceness(s.resourceness)
e.Strictness = s.Strictness
e.Kind = Kind(s.typeName)
return e
}
// member is an element of an aggregate (e.g. field of a struct).
type member struct {
m isMember
memberType fidlgen.Type
}
// newMember creates a new aggregate member element.
func newMember(
parentName fidlgen.EncodedCompoundIdentifier,
name fidlgen.Identifier,
memberType fidlgen.Type,
declType fidlgen.DeclType) member {
return member{
m: newIsMember(parentName, name, declType),
memberType: memberType,
}
}
// String implements Element.
func (s member) String() string {
return s.Serialize().String()
}
// Member implements Element.
func (s member) Member() bool {
return s.m.Member()
}
// Name implements Element.
func (s member) Name() Name {
return s.m.Name()
}
func (s member) Serialize() ElementStr {
e := s.m.Serialize()
e.Decl = fidlTypeString(s.memberType)
return e
}