package schema import ( "sync" "github.com/blang/semver" jsoniter "github.com/json-iterator/go" "github.com/pulumi/pulumi/sdk/v2/go/common/resource/plugin" "github.com/pulumi/pulumi/sdk/v2/go/common/tokens" ) type Loader interface { LoadPackage(pkg string, version *semver.Version) (*Package, error) } type pluginLoader struct { m sync.RWMutex host plugin.Host entries map[string]*Package } func NewPluginLoader(host plugin.Host) Loader { return &pluginLoader{ host: host, entries: map[string]*Package{}, } } func (l *pluginLoader) getPackage(key string) (*Package, bool) { l.m.RLock() defer l.m.RUnlock() p, ok := l.entries[key] return p, ok } func (l *pluginLoader) LoadPackage(pkg string, version *semver.Version) (*Package, error) { key := pkg + "@" if version != nil { key += version.String() } if p, ok := l.getPackage(key); ok { return p, nil } provider, err := l.host.Provider(tokens.Package(pkg), version) if err != nil { return nil, err } schemaFormatVersion := 0 schemaBytes, err := provider.GetSchema(schemaFormatVersion) if err != nil { return nil, err } var spec PackageSpec if err := jsoniter.Unmarshal(schemaBytes, &spec); err != nil { return nil, err } p, err := ImportSpec(spec, nil) if err != nil { return nil, err } l.m.Lock() defer l.m.Unlock() if p, ok := l.entries[pkg]; ok { return p, nil } l.entries[key] = p return p, nil }