func (s Service) Endpoints() map[string]Endpoint {
	es := make(map[string]Endpoint, len(s.p.Services[s.id].Endpoints))
	for id := range s.p.Services[s.id].Endpoints {
		es[id] = Endpoint{
			id:        id,
			serviceID: s.id,
			p:         s.p,
		}
	}
	return es
}
Endpoints returns a map of Endpoints indexed by their ID for all known
endpoints for a service.

A region is the AWS region the service exists in. Whereas a Endpoint is
an URL that can be resolved to a instance of a service.
package endpoints
import (
	"fmt"
	"regexp"
	"strings"
	"github.com/aws/aws-sdk-go/aws/awserr"
)
type Options struct {
	DisableSSL bool
	UseDualStack bool
	StrictMatching bool
	ResolveUnknownService bool
	STSRegionalEndpoint STSRegionalEndpoint
	S3UsEast1RegionalEndpoint S3UsEast1RegionalEndpoint
}
type STSRegionalEndpoint int
func (e STSRegionalEndpoint) String() string {
	switch e {
	case LegacySTSEndpoint:
		return "legacy"
	case RegionalSTSEndpoint:
		return "regional"
	case UnsetSTSEndpoint:
		return ""
	default:
		return "unknown"
	}
}
const (
	UnsetSTSEndpoint STSRegionalEndpoint = iota
	LegacySTSEndpoint
	RegionalSTSEndpoint
)
func GetSTSRegionalEndpoint(s string) (STSRegionalEndpoint, error) {
	switch {
	case strings.EqualFold(s, "legacy"):
		return LegacySTSEndpoint, nil
	case strings.EqualFold(s, "regional"):
		return RegionalSTSEndpoint, nil
	default:
		return UnsetSTSEndpoint, fmt.Errorf("unable to resolve the value of STSRegionalEndpoint for %v", s)
	}
}
type S3UsEast1RegionalEndpoint int
func (e S3UsEast1RegionalEndpoint) String() string {
	switch e {
	case LegacyS3UsEast1Endpoint:
		return "legacy"
	case RegionalS3UsEast1Endpoint:
		return "regional"
	case UnsetS3UsEast1Endpoint:
		return ""
	default:
		return "unknown"
	}
}
const (
	UnsetS3UsEast1Endpoint S3UsEast1RegionalEndpoint = iota
	LegacyS3UsEast1Endpoint
	RegionalS3UsEast1Endpoint
)
func GetS3UsEast1RegionalEndpoint(s string) (S3UsEast1RegionalEndpoint, error) {
	switch {
	case strings.EqualFold(s, "legacy"):
		return LegacyS3UsEast1Endpoint, nil
	case strings.EqualFold(s, "regional"):
		return RegionalS3UsEast1Endpoint, nil
	default:
		return UnsetS3UsEast1Endpoint,
			fmt.Errorf("unable to resolve the value of S3UsEast1RegionalEndpoint for %v", s)
	}
}
func (o *Options) Set(optFns ...func(*Options)) {
	for _, fn := range optFns {
		fn(o)
	}
}
func DisableSSLOption(o *Options) {
	o.DisableSSL = true
}
func UseDualStackOption(o *Options) {
	o.UseDualStack = true
}
func StrictMatchingOption(o *Options) {
	o.StrictMatching = true
}
func ResolveUnknownServiceOption(o *Options) {
	o.ResolveUnknownService = true
}
func STSRegionalEndpointOption(o *Options) {
	o.STSRegionalEndpoint = RegionalSTSEndpoint
}
type Resolver interface {
	EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error)
}
type ResolverFunc func(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error)
func (fn ResolverFunc) EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error) {
	return fn(service, region, opts...)
}
var schemeRE = regexp.MustCompile("^([^:]+)://")
func AddScheme(endpoint string, disableSSL bool) string {
	if !schemeRE.MatchString(endpoint) {
		scheme := "https"
		if disableSSL {
			scheme = "http"
		}
		endpoint = fmt.Sprintf("%s://%s", scheme, endpoint)
	}
	return endpoint
}
type EnumPartitions interface {
	Partitions() []Partition
}
func RegionsForService(ps []Partition, partitionID, serviceID string) (map[string]Region, bool) {
	for _, p := range ps {
		if p.ID() != partitionID {
			continue
		}
		if _, ok := p.p.Services[serviceID]; !ok {
			break
		}
		s := Service{
			id: serviceID,
			p:  p.p,
		}
		return s.Regions(), true
	}
	return map[string]Region{}, false
}
func PartitionForRegion(ps []Partition, regionID string) (Partition, bool) {
	for _, p := range ps {
		if _, ok := p.p.Regions[regionID]; ok || p.p.RegionRegex.MatchString(regionID) {
			return p, true
		}
	}
	return Partition{}, false
}
type Partition struct {
	id, dnsSuffix string
	p             *partition
}
func (p Partition) DNSSuffix() string { return p.dnsSuffix }
func (p Partition) ID() string { return p.id }
func (p Partition) EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error) {
	return p.p.EndpointFor(service, region, opts...)
}
func (p Partition) Regions() map[string]Region {
	rs := make(map[string]Region, len(p.p.Regions))
	for id, r := range p.p.Regions {
		rs[id] = Region{
			id:   id,
			desc: r.Description,
			p:    p.p,
		}
	}
	return rs
}
func (p Partition) Services() map[string]Service {
	ss := make(map[string]Service, len(p.p.Services))
	for id := range p.p.Services {
		ss[id] = Service{
			id: id,
			p:  p.p,
		}
	}
	return ss
}
type Region struct {
	id, desc string
	p        *partition
}
func (r Region) ID() string { return r.id }
func (r Region) Description() string { return r.desc }
func (r Region) ResolveEndpoint(service string, opts ...func(*Options)) (ResolvedEndpoint, error) {
	return r.p.EndpointFor(service, r.id, opts...)
}
func (r Region) Services() map[string]Service {
	ss := map[string]Service{}
	for id, s := range r.p.Services {
		if _, ok := s.Endpoints[r.id]; ok {
			ss[id] = Service{
				id: id,
				p:  r.p,
			}
		}
	}
	return ss
}
type Service struct {
	id string
	p  *partition
}
func (s Service) ID() string { return s.id }
func (s Service) ResolveEndpoint(region string, opts ...func(*Options)) (ResolvedEndpoint, error) {
	return s.p.EndpointFor(s.id, region, opts...)
}
func (s Service) Regions() map[string]Region {
	rs := map[string]Region{}
	for id := range s.p.Services[s.id].Endpoints {
		if r, ok := s.p.Regions[id]; ok {
			rs[id] = Region{
				id:   id,
				desc: r.Description,
				p:    s.p,
			}
		}
	}
	return rs
}