-
Notifications
You must be signed in to change notification settings - Fork 193
/
property_bag_member_type.go
123 lines (100 loc) · 4.44 KB
/
property_bag_member_type.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*
* Copyright (c) Microsoft Corporation.
* Licensed under the MIT license.
*/
package conversions
import (
"fmt"
"strings"
"github.com/dave/dst"
"github.com/pkg/errors"
"github.com/Azure/azure-service-operator/v2/tools/generator/internal/astmodel"
)
// PropertyBagMemberType is a wrapper type for properties that are stored-in/recalled-from a PropertyBag
// Using this custom type allows us to cleanly define endpoints that read-from/write-to the property bag without needing
// to introduce special cases through the conversions package. Instead, code generation of the conversion steps now
// naturally falls out of the usual flow - the endpoints contain definitions, and handlers for those definitions pick up the context
// and generate the required code.
type PropertyBagMemberType struct {
// element is the wrapped type of the property
element astmodel.Type
}
// PropertyBagMemberType must implement Type
var _ astmodel.Type = &PropertyBagMemberType{}
// PropertyBagMemberType must implement MetaType
var _ astmodel.MetaType = &PropertyBagMemberType{}
// NewPropertyBagMemberType returns a new PropertyBagMemberType, ready for use by the conversion framework
// A bag item can't be optional, so if we're given an optional type we just unwrap it
func NewPropertyBagMemberType(element astmodel.Type) *PropertyBagMemberType {
e := element
if opt, ok := astmodel.AsOptionalType(e); ok {
// Unwrap the optional type
e = opt.Element()
}
return &PropertyBagMemberType{
element: e,
}
}
// Element returns the type contained by the bag item
func (b *PropertyBagMemberType) Element() astmodel.Type {
return b.element
}
// RequiredPackageReferences returns a set of packages imports required by the element we wrap
func (b *PropertyBagMemberType) RequiredPackageReferences() *astmodel.PackageReferenceSet {
return b.element.RequiredPackageReferences()
}
// References returns the names of all definitions that the element type we wrap references.
func (b *PropertyBagMemberType) References() astmodel.TypeNameSet {
return b.element.References()
}
// AsType renders as our contained type
func (b *PropertyBagMemberType) AsTypeExpr(codeGenerationContext *astmodel.CodeGenerationContext) (dst.Expr, error) {
result, err := b.element.AsTypeExpr(codeGenerationContext)
if err != nil {
return nil, errors.Wrapf(err, "creating inner expression for property bag type")
}
return result, nil
}
// AsDeclarations panics because this is a metatype that will never be rendered
func (b *PropertyBagMemberType) AsDeclarations(
codeGenerationContext *astmodel.CodeGenerationContext,
declContext astmodel.DeclarationContext,
) ([]dst.Decl, error) {
panic(errors.New("should never try to render a PropertyBagMemberType into declarations"))
}
// AsZero renders an expression for the "zero" value of the type
func (b *PropertyBagMemberType) AsZero(definitions astmodel.TypeDefinitionSet, ctx *astmodel.CodeGenerationContext) dst.Expr {
return b.element.AsZero(definitions, ctx)
}
// Equals returns true if the passed type is a PropertyBagMemberType with the same element this one, false otherwise
func (b *PropertyBagMemberType) Equals(t astmodel.Type, override astmodel.EqualityOverrides) bool {
other, ok := t.(*PropertyBagMemberType)
return ok && other.element.Equals(b.element, override)
}
// String returns a string representing the type
func (b *PropertyBagMemberType) String() string {
return fmt.Sprintf("PropertyBagMemberType(%s)", b.element.String())
}
// WriteDebugDescription adds a description of the current type to the passed builder
// builder receives the full description, including nested definitions
// definitions is a dictionary for resolving named definitions
func (b *PropertyBagMemberType) WriteDebugDescription(builder *strings.Builder, currentPackage astmodel.InternalPackageReference) {
builder.WriteString("Bag[")
b.element.WriteDebugDescription(builder, currentPackage)
builder.WriteString("]")
}
// Unwrap returns the type contained within the wrapper type
func (b *PropertyBagMemberType) Unwrap() astmodel.Type {
return b.element
}
// AsPropertyBagMemberType unwraps any wrappers around the provided type and returns either the underlying PropertyBagMemberType and true,
// or nil and false.
func AsPropertyBagMemberType(aType astmodel.Type) (*PropertyBagMemberType, bool) {
if obj, ok := aType.(*PropertyBagMemberType); ok {
return obj, true
}
if wrapper, ok := aType.(astmodel.MetaType); ok {
return AsPropertyBagMemberType(wrapper.Unwrap())
}
return nil, false
}