pulumi/pkg/tools/lumidl/types.go
joeduffy 35aa6b7559 Rename pulumi/lumi to pulumi/pulumi-fabric
We are renaming Lumi to Pulumi Fabric.  This change simply renames the
pulumi/lumi repo to pulumi/pulumi-fabric, without the CLI tools and other
changes that will follow soon afterwards.
2017-08-02 09:25:22 -07:00

101 lines
2.6 KiB
Go

// Copyright 2016-2017, Pulumi Corporation. All rights reserved.
package lumidl
import (
"go/types"
"reflect"
"github.com/pulumi/pulumi-fabric/pkg/resource/idl"
"github.com/pulumi/pulumi-fabric/pkg/util/contract"
)
func IsPrimitive(t types.Type) bool {
if basic, isbasic := t.(*types.Basic); isbasic {
switch basic.Kind() {
case types.Bool, types.Float64, types.String:
return true
}
}
return false
}
// IsEntity checks whether a type is an entity that can be used by-reference (asset, resource, etc).
func IsEntity(obj *types.TypeName, t types.Type) bool {
if res, _ := IsResource(obj, t); res {
return true
}
spec, _ := IsSpecial(obj)
return spec
}
// IsResource checks whether a type is a special IDL resource. If yes, it returns true for the first boolean, and the
// second boolean indicates whether the resource is named or not.
func IsResource(obj *types.TypeName, t types.Type) (bool, bool) {
contract.Assert(obj != nil)
// If this is a resource type itself, then we're done.
if isres, isname := IsSpecialResource(obj); isres {
return isres, isname
}
// If a named type, fetch the underlying.
if n, is := t.(*types.Named); is {
t = n.Underlying()
}
if s, is := t.(*types.Struct); is {
// Otherwise, it's a resource if it has an embedded resource field.
for i := 0; i < s.NumFields(); i++ {
fld := s.Field(i)
if fld.Anonymous() {
if named, ok := fld.Type().(*types.Named); ok {
if isres, isname := IsSpecialResource(named.Obj()); isres {
return isres, isname
}
}
}
}
}
return false, false
}
type SpecialType int
const (
NotSpecialType = iota
SpecialResourceType
SpecialNamedResourceType
SpecialAssetType
SpecialArchiveType
)
var (
idlArchiveType = reflect.TypeOf(idl.Archive{})
idlAssetType = reflect.TypeOf(idl.Asset{})
idlResourceType = reflect.TypeOf(idl.Resource{})
idlNamedResourceType = reflect.TypeOf(idl.NamedResource{})
)
func IsSpecial(obj *types.TypeName) (bool, SpecialType) {
if obj != nil && obj.Pkg().Path() == idlResourceType.PkgPath() {
switch obj.Name() {
case idlArchiveType.Name():
return true, SpecialArchiveType
case idlAssetType.Name():
return true, SpecialAssetType
case idlResourceType.Name():
return true, SpecialResourceType
case idlNamedResourceType.Name():
return true, SpecialNamedResourceType
}
}
return false, NotSpecialType
}
func IsSpecialResource(obj *types.TypeName) (bool, bool) {
spec, kind := IsSpecial(obj)
isres := (spec && kind == SpecialResourceType)
isnamed := (spec && kind == SpecialNamedResourceType)
return isres || isnamed, isnamed
}