func (p *Provider) Refresh(
	info *terraform.InstanceInfo,
	s *terraform.InstanceState) (*terraform.InstanceState, error) {
	r, ok := p.ResourcesMap[info.Type]
	if !ok {
		return nil, fmt.Errorf("unknown resource type: %s", info.Type)
	}
	return r.Refresh(s, p.meta)
}
Refresh implementation of terraform.ResourceProvider interface.
package schema
import (
	"context"
	"errors"
	"fmt"
	"sort"
	"sync"
	"github.com/hashicorp/go-multierror"
	"github.com/hashicorp/terraform/terraform"
)
type Provider struct {
	Schema map[string]*Schema
	ResourcesMap map[string]*Resource
	DataSourcesMap map[string]*Resource
	ConfigureFunc ConfigureFunc
	MetaReset func() error
	meta interface{}
	stopMu        sync.Mutex
	stopCtx       context.Context
	stopCtxCancel context.CancelFunc
	stopOnce      sync.Once
}
type ConfigureFunc func(*ResourceData) (interface{}, error)
func (p *Provider) InternalValidate() error {
	if p == nil {
		return errors.New("provider is nil")
	}
	var validationErrors error
	sm := schemaMap(p.Schema)
	if err := sm.InternalValidate(sm); err != nil {
		validationErrors = multierror.Append(validationErrors, err)
	}
	for k, r := range p.ResourcesMap {
		if err := r.InternalValidate(nil, true); err != nil {
			validationErrors = multierror.Append(validationErrors, fmt.Errorf("resource %s: %s", k, err))
		}
	}
	for k, r := range p.DataSourcesMap {
		if err := r.InternalValidate(nil, false); err != nil {
			validationErrors = multierror.Append(validationErrors, fmt.Errorf("data source %s: %s", k, err))
		}
	}
	return validationErrors
}
func (p *Provider) Meta() interface{} {
	return p.meta
}
func (p *Provider) SetMeta(v interface{}) {
	p.meta = v
}
func (p *Provider) Stopped() bool {
	ctx := p.StopContext()
	select {
	case <-ctx.Done():
		return true
	default:
		return false
	}
}
func (p *Provider) StopContext() context.Context {
	p.stopOnce.Do(p.stopInit)
	p.stopMu.Lock()
	defer p.stopMu.Unlock()
	return p.stopCtx
}
func (p *Provider) stopInit() {
	p.stopMu.Lock()
	defer p.stopMu.Unlock()
	p.stopCtx, p.stopCtxCancel = context.WithCancel(context.Background())
}
func (p *Provider) Stop() error {
	p.stopOnce.Do(p.stopInit)
	p.stopMu.Lock()
	defer p.stopMu.Unlock()
	p.stopCtxCancel()
	return nil
}
func (p *Provider) TestReset() error {
	p.stopInit()
	if p.MetaReset != nil {
		return p.MetaReset()
	}
	return nil
}
func (p *Provider) Input(
	input terraform.UIInput,
	c *terraform.ResourceConfig) (*terraform.ResourceConfig, error) {
	return schemaMap(p.Schema).Input(input, c)
}
func (p *Provider) Validate(c *terraform.ResourceConfig) ([]string, []error) {
	if err := p.InternalValidate(); err != nil {
		return nil, []error{fmt.Errorf(
			"Internal validation of the provider failed! This is always a bug\n"+
				"with the provider itself, and not a user issue. Please report\n"+
				"this bug:\n\n%s", err)}
	}
	return schemaMap(p.Schema).Validate(c)
}
func (p *Provider) ValidateResource(
	t string, c *terraform.ResourceConfig) ([]string, []error) {
	r, ok := p.ResourcesMap[t]
	if !ok {
		return nil, []error{fmt.Errorf(
			"Provider doesn't support resource: %s", t)}
	}
	return r.Validate(c)
}
func (p *Provider) Configure(c *terraform.ResourceConfig) error {
	if p.ConfigureFunc == nil {
		return nil
	}
	sm := schemaMap(p.Schema)
	diff, err := sm.Diff(nil, c)
	if err != nil {
		return err
	}
	data, err := sm.Data(nil, diff)
	if err != nil {
		return err
	}
	meta, err := p.ConfigureFunc(data)
	if err != nil {
		return err
	}
	p.meta = meta
	return nil
}
func (p *Provider) Apply(
	info *terraform.InstanceInfo,
	s *terraform.InstanceState,
	d *terraform.InstanceDiff) (*terraform.InstanceState, error) {
	r, ok := p.ResourcesMap[info.Type]
	if !ok {
		return nil, fmt.Errorf("unknown resource type: %s", info.Type)
	}
	return r.Apply(s, d, p.meta)
}
func (p *Provider) Diff(
	info *terraform.InstanceInfo,
	s *terraform.InstanceState,
	c *terraform.ResourceConfig) (*terraform.InstanceDiff, error) {
	r, ok := p.ResourcesMap[info.Type]
	if !ok {
		return nil, fmt.Errorf("unknown resource type: %s", info.Type)
	}
	return r.Diff(s, c)
}