vendor: update all dependencies

This commit is contained in:
Nick Craig-Wood 2018-06-17 17:59:12 +01:00
parent 3f0789e2db
commit 08021c4636
2474 changed files with 435818 additions and 282709 deletions

View file

@ -10,6 +10,7 @@ import (
"io/ioutil"
"path"
"path/filepath"
"regexp"
"sort"
"strings"
"text/template"
@ -54,6 +55,8 @@ type API struct {
path string
BaseCrosslinkURL string
HasEventStream bool `json:"-"`
}
// A Metadata is the metadata about an API's definition.
@ -69,6 +72,7 @@ type Metadata struct {
Protocol string
UID string
EndpointsID string
ServiceID string
NoResolveEndpoint bool
}
@ -416,6 +420,28 @@ var tplServiceDoc = template.Must(template.New("service docs").Funcs(template.Fu
// https://docs.aws.amazon.com/sdk-for-go/api/service/{{ .PackageName }}/#New
`))
var serviceIDRegex = regexp.MustCompile("[^a-zA-Z0-9 ]+")
var prefixDigitRegex = regexp.MustCompile("^[0-9]+")
// ServiceID will return a unique identifier specific to a service.
func ServiceID(a *API) string {
if len(a.Metadata.ServiceID) > 0 {
return a.Metadata.ServiceID
}
name := a.Metadata.ServiceAbbreviation
if len(name) == 0 {
name = a.Metadata.ServiceFullName
}
name = strings.Replace(name, "Amazon", "", -1)
name = strings.Replace(name, "AWS", "", -1)
name = serviceIDRegex.ReplaceAllString(name, "")
name = prefixDigitRegex.ReplaceAllString(name, "")
name = strings.TrimSpace(name)
return name
}
// A tplService defines the template for the service generated code.
var tplService = template.Must(template.New("service").Funcs(template.FuncMap{
"ServiceNameValue": func(a *API) string {
@ -440,6 +466,14 @@ var tplService = template.Must(template.New("service").Funcs(template.FuncMap{
return "EndpointsID"
},
"ServiceIDVar": func(a *API) string {
if a.NoConstServiceNames {
return fmt.Sprintf("%q", ServiceID(a))
}
return "ServiceID"
},
"ServiceID": ServiceID,
}).Parse(`
// {{ .StructName }} provides the API operation methods for making requests to
// {{ .Metadata.ServiceFullName }}. See this package's package overview docs
@ -464,6 +498,7 @@ var initRequest func(*request.Request)
const (
ServiceName = "{{ .Metadata.EndpointPrefix }}" // Service endpoint prefix API calls made to.
EndpointsID = {{ EndpointsIDConstValue . }} // Service ID for Regions and Endpoints metadata.
ServiceID = "{{ ServiceID . }}" // ServiceID is a unique identifer of a specific service
)
{{- end }}
@ -504,6 +539,7 @@ func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio
cfg,
metadata.ClientInfo{
ServiceName: {{ ServiceNameValue . }},
ServiceID : {{ ServiceIDVar . }},
SigningName: signingName,
SigningRegion: signingRegion,
Endpoint: endpoint,
@ -528,6 +564,9 @@ func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio
svc.Handlers.Unmarshal.PushBackNamed({{ .ProtocolPackage }}.UnmarshalHandler)
svc.Handlers.UnmarshalMeta.PushBackNamed({{ .ProtocolPackage }}.UnmarshalMetaHandler)
svc.Handlers.UnmarshalError.PushBackNamed({{ .ProtocolPackage }}.UnmarshalErrorHandler)
{{ if .HasEventStream }}
svc.Handlers.UnmarshalStream.PushBackNamed({{ .ProtocolPackage }}.UnmarshalHandler)
{{ end }}
{{ if .UseInitMethods }}// Run custom client initialization if present
if initClient != nil {

View file

@ -2,27 +2,536 @@
package api
func (a *API) suppressEventStreams() {
import (
"bytes"
"fmt"
"io"
"text/template"
)
// EventStreamAPI provides details about the event stream async API and
// associated EventStream shapes.
type EventStreamAPI struct {
Name string
Operation *Operation
Shape *Shape
Inbound *EventStream
Outbound *EventStream
}
// EventStream represents a single eventstream group (input/output) and the
// modeled events that are known for the stream.
type EventStream struct {
Name string
Shape *Shape
Events []*Event
}
// Event is a single EventStream event that can be sent or received in an
// EventStream.
type Event struct {
Name string
Shape *Shape
For *EventStream
}
// ShapeDoc returns the docstring for the EventStream API.
func (esAPI *EventStreamAPI) ShapeDoc() string {
tmpl := template.Must(template.New("eventStreamShapeDoc").Parse(`
{{- $.Name }} provides handling of EventStreams for
the {{ $.Operation.ExportedName }} API.
{{- if $.Inbound }}
Use this type to receive {{ $.Inbound.Name }} events. The events
can be read from the Events channel member.
The events that can be received are:
{{ range $_, $event := $.Inbound.Events }}
* {{ $event.Shape.ShapeName }}
{{- end }}
{{- end }}
{{- if $.Outbound }}
Use this type to send {{ $.Outbound.Name }} events. The events
can be sent with the Send method.
The events that can be sent are:
{{ range $_, $event := $.Outbound.Events -}}
* {{ $event.Shape.ShapeName }}
{{- end }}
{{- end }}`))
var w bytes.Buffer
if err := tmpl.Execute(&w, esAPI); err != nil {
panic(fmt.Sprintf("failed to generate eventstream shape template for %v, %v", esAPI.Name, err))
}
return commentify(w.String())
}
func eventStreamAPIShapeRefDoc(refName string) string {
return commentify(fmt.Sprintf("Use %s to use the API's stream.", refName))
}
func (a *API) setupEventStreams() {
const eventStreamMemberName = "EventStream"
for name, op := range a.Operations {
outbound := hasEventStream(op.InputRef.Shape)
inbound := hasEventStream(op.OutputRef.Shape)
for _, op := range a.Operations {
outbound := setupEventStream(op.InputRef.Shape)
inbound := setupEventStream(op.OutputRef.Shape)
if !(outbound || inbound) {
if outbound == nil && inbound == nil {
continue
}
a.removeOperation(name)
if outbound != nil {
panic(fmt.Sprintf("Outbound stream support not implemented, %s, %s",
outbound.Name, outbound.Shape.ShapeName))
}
switch a.Metadata.Protocol {
case `rest-json`, `rest-xml`, `json`:
default:
panic(fmt.Sprintf("EventStream not supported for protocol %v",
a.Metadata.Protocol))
}
eventStreamAPI := &EventStreamAPI{
Name: op.ExportedName + eventStreamMemberName,
Operation: op,
Outbound: outbound,
Inbound: inbound,
}
streamShape := &Shape{
API: a,
ShapeName: eventStreamAPI.Name,
Documentation: eventStreamAPI.ShapeDoc(),
Type: "structure",
EventStreamAPI: eventStreamAPI,
}
streamShapeRef := &ShapeRef{
API: a,
ShapeName: streamShape.ShapeName,
Shape: streamShape,
Documentation: eventStreamAPIShapeRefDoc(eventStreamMemberName),
}
streamShape.refs = []*ShapeRef{streamShapeRef}
eventStreamAPI.Shape = streamShape
if _, ok := op.OutputRef.Shape.MemberRefs[eventStreamMemberName]; ok {
panic(fmt.Sprintf("shape ref already exists, %s.%s",
op.OutputRef.Shape.ShapeName, eventStreamMemberName))
}
op.OutputRef.Shape.MemberRefs[eventStreamMemberName] = streamShapeRef
op.OutputRef.Shape.EventStreamsMemberName = eventStreamMemberName
if _, ok := a.Shapes[streamShape.ShapeName]; ok {
panic("shape already exists, " + streamShape.ShapeName)
}
a.Shapes[streamShape.ShapeName] = streamShape
a.HasEventStream = true
}
}
func hasEventStream(topShape *Shape) bool {
for _, ref := range topShape.MemberRefs {
if ref.Shape.IsEventStream {
return true
func setupEventStream(topShape *Shape) *EventStream {
var eventStream *EventStream
for refName, ref := range topShape.MemberRefs {
if !ref.Shape.IsEventStream {
continue
}
if eventStream != nil {
panic(fmt.Sprintf("multiple shape ref eventstreams, %s, prev: %s",
refName, eventStream.Name))
}
eventStream = &EventStream{
Name: ref.Shape.ShapeName,
Shape: ref.Shape,
}
for _, eventRefName := range ref.Shape.MemberNames() {
eventRef := ref.Shape.MemberRefs[eventRefName]
if !eventRef.Shape.IsEvent {
panic(fmt.Sprintf("unexpected non-event member reference %s.%s",
ref.Shape.ShapeName, eventRefName))
}
updateEventPayloadRef(eventRef.Shape)
eventRef.Shape.EventFor = append(eventRef.Shape.EventFor, eventStream)
eventStream.Events = append(eventStream.Events, &Event{
Name: eventRefName,
Shape: eventRef.Shape,
For: eventStream,
})
}
// Remove the eventstream references as they will be added elsewhere.
ref.Shape.removeRef(ref)
delete(topShape.MemberRefs, refName)
delete(topShape.API.Shapes, ref.Shape.ShapeName)
}
return eventStream
}
func updateEventPayloadRef(parent *Shape) {
refName := parent.PayloadRefName()
if len(refName) == 0 {
return
}
payloadRef := parent.MemberRefs[refName]
if payloadRef.Shape.Type == "blob" {
return
}
if len(payloadRef.LocationName) != 0 {
return
}
payloadRef.LocationName = refName
}
func renderEventStreamAPIShape(w io.Writer, s *Shape) error {
// Imports needed by the EventStream APIs.
s.API.imports["bytes"] = true
s.API.imports["io"] = true
s.API.imports["sync"] = true
s.API.imports["sync/atomic"] = true
s.API.imports["github.com/aws/aws-sdk-go/private/protocol/eventstream"] = true
s.API.imports["github.com/aws/aws-sdk-go/private/protocol/eventstream/eventstreamapi"] = true
return eventStreamAPIShapeTmpl.Execute(w, s)
}
// EventStreamReaderInterfaceName returns the interface name for the
// EventStream's reader interface.
func EventStreamReaderInterfaceName(s *Shape) string {
return s.ShapeName + "Reader"
}
// Template for an EventStream API Shape that will provide read/writing events
// across the EventStream. This is a special shape that's only public members
// are the Events channel and a Close and Err method.
//
// Executed in the context of a Shape.
var eventStreamAPIShapeTmpl = func() *template.Template {
t := template.Must(
template.New("eventStreamAPIShapeTmpl").
Funcs(template.FuncMap{}).
Parse(eventStreamAPITmplDef),
)
template.Must(
t.AddParseTree(
"eventStreamAPIReaderTmpl", eventStreamAPIReaderTmpl.Tree),
)
return t
}()
const eventStreamAPITmplDef = `
{{ $.Documentation }}
type {{ $.ShapeName }} struct {
{{- if $.EventStreamAPI.Inbound }}
// Reader is the EventStream reader for the {{ $.EventStreamAPI.Inbound.Name }}
// events. This value is automatically set by the SDK when the API call is made
// Use this member when unit testing your code with the SDK to mock out the
// EventStream Reader.
//
// Must not be nil.
Reader {{ $.ShapeName }}Reader
{{ end -}}
{{- if $.EventStreamAPI.Outbound }}
// Writer is the EventStream reader for the {{ $.EventStreamAPI.Inbound.Name }}
// events. This value is automatically set by the SDK when the API call is made
// Use this member when unit testing your code with the SDK to mock out the
// EventStream Writer.
//
// Must not be nil.
Writer *{{ $.ShapeName }}Writer
{{ end -}}
// StreamCloser is the io.Closer for the EventStream connection. For HTTP
// EventStream this is the response Body. The stream will be closed when
// the Close method of the EventStream is called.
StreamCloser io.Closer
}
// Close closes the EventStream. This will also cause the Events channel to be
// closed. You can use the closing of the Events channel to terminate your
// application's read from the API's EventStream.
{{- if $.EventStreamAPI.Inbound }}
//
// Will close the underlying EventStream reader. For EventStream over HTTP
// connection this will also close the HTTP connection.
{{ end -}}
//
// Close must be called when done using the EventStream API. Not calling Close
// may result in resource leaks.
func (es *{{ $.ShapeName }}) Close() (err error) {
{{- if $.EventStreamAPI.Inbound }}
es.Reader.Close()
{{ end -}}
{{- if $.EventStreamAPI.Outbound }}
es.Writer.Close()
{{ end -}}
return es.Err()
}
// Err returns any error that occurred while reading EventStream Events from
// the service API's response. Returns nil if there were no errors.
func (es *{{ $.ShapeName }}) Err() error {
{{- if $.EventStreamAPI.Outbound }}
if err := es.Writer.Err(); err != nil {
return err
}
{{ end -}}
{{- if $.EventStreamAPI.Inbound }}
if err := es.Reader.Err(); err != nil {
return err
}
{{ end -}}
es.StreamCloser.Close()
return nil
}
{{ if $.EventStreamAPI.Inbound }}
// Events returns a channel to read EventStream Events from the
// {{ $.EventStreamAPI.Operation.ExportedName }} API.
//
// These events are:
// {{ range $_, $event := $.EventStreamAPI.Inbound.Events }}
// * {{ $event.Shape.ShapeName }}
{{- end }}
func (es *{{ $.ShapeName }}) Events() <-chan {{ $.EventStreamAPI.Inbound.Name }}Event {
return es.Reader.Events()
}
{{ template "eventStreamAPIReaderTmpl" $ }}
{{ end }}
{{ if $.EventStreamAPI.Outbound }}
// TODO writer helper method.
{{ end }}
`
var eventStreamAPIReaderTmpl = template.Must(template.New("eventStreamAPIReaderTmpl").
Funcs(template.FuncMap{}).
Parse(`
// {{ $.EventStreamAPI.Inbound.Name }}Event groups together all EventStream
// events read from the {{ $.EventStreamAPI.Operation.ExportedName }} API.
//
// These events are:
// {{ range $_, $event := $.EventStreamAPI.Inbound.Events }}
// * {{ $event.Shape.ShapeName }}
{{- end }}
type {{ $.EventStreamAPI.Inbound.Name }}Event interface {
event{{ $.EventStreamAPI.Name }}()
}
// {{ $.ShapeName }}Reader provides the interface for reading EventStream
// Events from the {{ $.EventStreamAPI.Operation.ExportedName }} API. The
// default implementation for this interface will be {{ $.ShapeName }}.
//
// The reader's Close method must allow multiple concurrent calls.
//
// These events are:
// {{ range $_, $event := $.EventStreamAPI.Inbound.Events }}
// * {{ $event.Shape.ShapeName }}
{{- end }}
type {{ $.ShapeName }}Reader interface {
// Returns a channel of events as they are read from the event stream.
Events() <-chan {{ $.EventStreamAPI.Inbound.Name }}Event
// Close will close the underlying event stream reader. For event stream over
// HTTP this will also close the HTTP connection.
Close() error
// Returns any error that has occured while reading from the event stream.
Err() error
}
type read{{ $.ShapeName }} struct {
eventReader *eventstreamapi.EventReader
stream chan {{ $.EventStreamAPI.Inbound.Name }}Event
errVal atomic.Value
done chan struct{}
closeOnce sync.Once
}
func newRead{{ $.ShapeName }}(
reader io.ReadCloser,
unmarshalers request.HandlerList,
logger aws.Logger,
logLevel aws.LogLevelType,
) *read{{ $.ShapeName }} {
r := &read{{ $.ShapeName }}{
stream: make(chan {{ $.EventStreamAPI.Inbound.Name }}Event),
done: make(chan struct{}),
}
r.eventReader = eventstreamapi.NewEventReader(
reader,
protocol.HandlerPayloadUnmarshal{
Unmarshalers: unmarshalers,
},
r.unmarshalerForEventType,
)
r.eventReader.UseLogger(logger, logLevel)
return r
}
// Close will close the underlying event stream reader. For EventStream over
// HTTP this will also close the HTTP connection.
func (r *read{{ $.ShapeName }}) Close() error {
r.closeOnce.Do(r.safeClose)
return r.Err()
}
func (r *read{{ $.ShapeName }}) safeClose() {
close(r.done)
err := r.eventReader.Close()
if err != nil {
r.errVal.Store(err)
}
}
func (r *read{{ $.ShapeName }}) Err() error {
if v := r.errVal.Load(); v != nil {
return v.(error)
}
return nil
}
func (r *read{{ $.ShapeName }}) Events() <-chan {{ $.EventStreamAPI.Inbound.Name }}Event {
return r.stream
}
func (r *read{{ $.ShapeName }}) readEventStream() {
defer close(r.stream)
for {
event, err := r.eventReader.ReadEvent()
if err != nil {
if err == io.EOF {
return
}
select {
case <-r.done:
// If closed already ignore the error
return
default:
}
r.errVal.Store(err)
return
}
select {
case r.stream <- event.({{ $.EventStreamAPI.Inbound.Name }}Event):
case <-r.done:
return
}
}
return false
}
func (r *read{{ $.ShapeName }}) unmarshalerForEventType(
eventType string,
) (eventstreamapi.Unmarshaler, error) {
switch eventType {
{{- range $_, $event := $.EventStreamAPI.Inbound.Events }}
case {{ printf "%q" $event.Name }}:
return &{{ $event.Shape.ShapeName }}{}, nil
{{ end -}}
default:
return nil, fmt.Errorf(
"unknown event type name, %s, for {{ $.ShapeName }}", eventType)
}
}
`))
// Template for the EventStream API Output shape that contains the EventStream
// member.
//
// Executed in the context of a Shape.
var eventStreamAPILoopMethodTmpl = template.Must(
template.New("eventStreamAPILoopMethodTmpl").Parse(`
func (s *{{ $.ShapeName }}) runEventStreamLoop(r *request.Request) {
if r.Error != nil {
return
}
{{- $esMemberRef := index $.MemberRefs $.EventStreamsMemberName }}
{{- if $esMemberRef.Shape.EventStreamAPI.Inbound }}
reader := newRead{{ $esMemberRef.ShapeName }}(
r.HTTPResponse.Body,
r.Handlers.UnmarshalStream,
r.Config.Logger,
r.Config.LogLevel.Value(),
)
go reader.readEventStream()
eventStream := &{{ $esMemberRef.ShapeName }} {
StreamCloser: r.HTTPResponse.Body,
Reader: reader,
}
{{ end -}}
s.{{ $.EventStreamsMemberName }} = eventStream
}
`))
// Template for an EventStream Event shape. This is a normal API shape that is
// decorated as an EventStream Event.
//
// Executed in the context of a Shape.
var eventStreamEventShapeTmpl = template.Must(template.New("eventStreamEventShapeTmpl").Parse(`
{{ range $_, $eventstream := $.EventFor }}
// The {{ $.ShapeName }} is and event in the {{ $eventstream.Name }} group of events.
func (s *{{ $.ShapeName }}) event{{ $eventstream.Name }}() {}
{{ end }}
// UnmarshalEvent unmarshals the EventStream Message into the {{ $.ShapeName }} value.
// This method is only used internally within the SDK's EventStream handling.
func (s *{{ $.ShapeName }}) UnmarshalEvent(
payloadUnmarshaler protocol.PayloadUnmarshaler,
msg eventstream.Message,
) error {
{{- range $fieldIdx, $fieldName := $.MemberNames }}
{{- $fieldRef := index $.MemberRefs $fieldName -}}
{{ if $fieldRef.IsEventHeader }}
// TODO handle event header, {{ $fieldName }}
{{- else if (and ($fieldRef.IsEventPayload) (eq $fieldRef.Shape.Type "blob")) }}
s.{{ $fieldName }} = make([]byte, len(msg.Payload))
copy(s.{{ $fieldName }}, msg.Payload)
{{- else }}
if err := payloadUnmarshaler.UnmarshalPayload(
bytes.NewReader(msg.Payload), s,
); err != nil {
return fmt.Errorf("failed to unmarshal payload, %v", err)
}
{{- end }}
{{- end }}
return nil
}
`))
var eventStreamTestTmpl = template.Must(template.New("eventStreamTestTmpl").Parse(`
`))

View file

@ -1,79 +0,0 @@
// +build go1.6,codegen
package api
import (
"testing"
)
func TestSuppressEventStream(t *testing.T) {
cases := []struct {
API *API
Ops []string
Shapes []string
}{
{
API: &API{
Operations: map[string]*Operation{
"abc": {
InputRef: ShapeRef{
ShapeName: "abcRequest",
},
OutputRef: ShapeRef{
ShapeName: "abcResponse",
},
},
"eventStreamOp": {
InputRef: ShapeRef{
ShapeName: "eventStreamOpRequest",
},
OutputRef: ShapeRef{
ShapeName: "eventStreamOpResponse",
},
},
},
Shapes: map[string]*Shape{
"abcRequest": {},
"abcResponse": {},
"eventStreamOpRequest": {},
"eventStreamOpResponse": {
MemberRefs: map[string]*ShapeRef{
"eventStreamShape": {
ShapeName: "eventStreamShape",
},
},
},
"eventStreamShape": {
IsEventStream: true,
},
},
},
Ops: []string{"Abc"},
Shapes: []string{"AbcInput", "AbcOutput"},
},
}
for _, c := range cases {
c.API.Setup()
if e, a := c.Ops, c.API.OperationNames(); !stringsEqual(e, a) {
t.Errorf("expect %v ops, got %v", e, a)
}
if e, a := c.Shapes, c.API.ShapeNames(); !stringsEqual(e, a) {
t.Errorf("expect %v ops, got %v", e, a)
}
}
}
func stringsEqual(a, b []string) bool {
if len(a) != len(b) {
return false
}
for i := 0; i < len(a); i++ {
if a[i] != b[i] {
return false
}
}
return true
}

View file

@ -47,7 +47,7 @@ func (a *API) Setup() {
a.renameCollidingFields()
a.updateTopLevelShapeReferences()
a.createInputOutputShapes()
a.suppressEventStreams()
a.setupEventStreams()
a.customizationPasses()
if !a.NoRemoveUnusedShapes {

View file

@ -44,6 +44,7 @@ func (o *Operation) HasOutput() bool {
return o.OutputRef.ShapeName != ""
}
// GetSigner returns the signer that should be used for a API request.
func (o *Operation) GetSigner() string {
if o.AuthType == "v4-unsigned-body" {
o.API.imports["github.com/aws/aws-sdk-go/aws/signer/v4"] = true
@ -66,7 +67,8 @@ func (o *Operation) GetSigner() string {
// tplOperation defines a template for rendering an API Operation
var tplOperation = template.Must(template.New("operation").Funcs(template.FuncMap{
"GetCrosslinkURL": GetCrosslinkURL,
"GetCrosslinkURL": GetCrosslinkURL,
"EnableStopOnSameToken": enableStopOnSameToken,
}).Parse(`
const op{{ .ExportedName }} = "{{ .Name }}"
@ -120,10 +122,16 @@ func (c *{{ .API.StructName }}) {{ .ExportedName }}Request(` +
}
output = &{{ .OutputRef.GoTypeElem }}{}
req = c.newRequest(op, input, output){{ if eq .OutputRef.Shape.Placeholder true }}
req.Handlers.Unmarshal.Remove({{ .API.ProtocolPackage }}.UnmarshalHandler)
req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler){{ end }}
req = c.newRequest(op, input, output)
{{ if eq .OutputRef.Shape.Placeholder true -}}
req.Handlers.Unmarshal.Remove({{ .API.ProtocolPackage }}.UnmarshalHandler)
req.Handlers.Unmarshal.PushBackNamed(protocol.UnmarshalDiscardBodyHandler)
{{ end -}}
{{ if ne .AuthType "" }}{{ .GetSigner }}{{ end -}}
{{ if .OutputRef.Shape.EventStreamsMemberName -}}
req.Handlers.Unmarshal.Swap({{ .API.ProtocolPackage }}.UnmarshalHandler.Name, rest.UnmarshalHandler)
req.Handlers.Unmarshal.PushBack(output.runEventStreamLoop)
{{ end -}}
return
}
@ -214,6 +222,8 @@ func (c *{{ .API.StructName }}) {{ .ExportedName }}PagesWithContext(` +
`fn func({{ .OutputRef.GoType }}, bool) bool, ` +
`opts ...request.Option) error {
p := request.Pagination {
{{ if EnableStopOnSameToken .API.PackageName -}}EndPageOnSameToken: true,
{{ end -}}
NewRequest: func() (*request.Request, error) {
var inCpy {{ .InputRef.GoType }}
if input != nil {
@ -239,6 +249,12 @@ func (c *{{ .API.StructName }}) {{ .ExportedName }}PagesWithContext(` +
// GoCode returns a string of rendered GoCode for this Operation
func (o *Operation) GoCode() string {
var buf bytes.Buffer
if len(o.OutputRef.Shape.EventStreamsMemberName) != 0 {
// TODO need better was of updating protocol unmarshalers
o.API.imports["github.com/aws/aws-sdk-go/private/protocol/rest"] = true
}
err := tplOperation.Execute(&buf, o)
if err != nil {
panic(err)

View file

@ -89,3 +89,12 @@ func (p *paginationDefinitions) setup() {
}
}
}
func enableStopOnSameToken(service string) bool {
switch service {
case "cloudwatchlogs":
return true
default:
return false
}
}

View file

@ -59,6 +59,7 @@ func (a *API) resolveReferences() {
for i := range o.ErrorRefs {
resolver.resolveReference(&o.ErrorRefs[i])
o.ErrorRefs[i].Shape.IsError = true
o.ErrorRefs[i].Shape.ErrorInfo.Type = o.ErrorRefs[i].Shape.ShapeName
}
}
}

View file

@ -12,6 +12,19 @@ import (
"text/template"
)
// ErrorInfo represents the error block of a shape's structure
type ErrorInfo struct {
Type string
Code string
HTTPStatusCode int
}
// A XMLInfo defines URL and prefix for Shapes when rendered as XML
type XMLInfo struct {
Prefix string
URI string
}
// A ShapeRef defines the usage of a shape within the API.
type ShapeRef struct {
API *API `json:"-"`
@ -35,18 +48,9 @@ type ShapeRef struct {
OrigShapeName string `json:"-"`
GenerateGetter bool
}
// ErrorInfo represents the error block of a shape's structure
type ErrorInfo struct {
Code string
HTTPStatusCode int
}
// A XMLInfo defines URL and prefix for Shapes when rendered as XML
type XMLInfo struct {
Prefix string
URI string
IsEventPayload bool `json:"eventpayload"`
IsEventHeader bool `json:"eventheader"`
}
// A Shape defines the definition of a shape type
@ -73,7 +77,12 @@ type Shape struct {
Min float64 // optional Minimum length (string, list) or value (number)
Max float64 // optional Maximum length (string, list) or value (number)
EventStreamsMemberName string `json:"-"`
EventStreamAPI *EventStreamAPI `json:"-"`
EventFor []*EventStream `json:"-"`
IsEventStream bool `json:"eventstream"`
IsEvent bool `json:"event"`
refs []*ShapeRef // References to this shape
resolvePkg string // use this package in the goType() if present
@ -101,7 +110,7 @@ func (s *Shape) ErrorCodeName() string {
// ErrorName will return the shape's name or error code if available based
// on the API's protocol. This is the error code string returned by the service.
func (s *Shape) ErrorName() string {
name := s.ShapeName
name := s.ErrorInfo.Type
switch s.API.Metadata.Protocol {
case "query", "ec2query", "rest-xml":
if len(s.ErrorInfo.Code) > 0 {
@ -112,6 +121,23 @@ func (s *Shape) ErrorName() string {
return name
}
// PayloadRefName returns the payload member of the shape if there is one
// modeled. If no payload is modeled, empty string will be returned.
func (s *Shape) PayloadRefName() string {
if name := s.Payload; len(name) != 0 {
// Root shape
return name
}
for name, ref := range s.MemberRefs {
if ref.IsEventPayload {
return name
}
}
return ""
}
// GoTags returns the struct tags for a shape.
func (s *Shape) GoTags(root, required bool) string {
ref := &ShapeRef{ShapeName: s.ShapeName, API: s.API, Shape: s}
@ -149,6 +175,8 @@ func (s *Shape) GoTypeWithPkgName() string {
return goType(s, true)
}
// GoTypeWithPkgNameElem returns the shapes type as a string with the "*"
// removed if there was one preset.
func (s *Shape) GoTypeWithPkgNameElem() string {
t := goType(s, true)
if strings.HasPrefix(t, "*") {
@ -157,7 +185,7 @@ func (s *Shape) GoTypeWithPkgNameElem() string {
return t
}
// GenAccessors returns if the shape's reference should have setters generated.
// UseIndirection returns if the shape's reference should use indirection or not.
func (s *ShapeRef) UseIndirection() bool {
switch s.Shape.Type {
case "map", "list", "blob", "structure", "jsonvalue":
@ -401,8 +429,8 @@ func (ref *ShapeRef) GoTags(toplevel bool, isRequired bool) string {
}
if toplevel {
if ref.Shape.Payload != "" {
tags = append(tags, ShapeTag{"payload", ref.Shape.Payload})
if name := ref.Shape.PayloadRefName(); len(name) > 0 {
tags = append(tags, ShapeTag{"payload", name})
}
}
@ -514,9 +542,29 @@ func (s *Shape) NestedShape() *Shape {
return nestedShape
}
var structShapeTmpl = template.Must(template.New("StructShape").Funcs(template.FuncMap{
"GetCrosslinkURL": GetCrosslinkURL,
}).Parse(`
var structShapeTmpl = func() *template.Template {
shapeTmpl := template.Must(
template.New("structShapeTmpl").
Funcs(template.FuncMap{
"GetCrosslinkURL": GetCrosslinkURL,
}).
Parse(structShapeTmplDef),
)
template.Must(
shapeTmpl.AddParseTree(
"eventStreamAPILoopMethodTmpl", eventStreamAPILoopMethodTmpl.Tree),
)
template.Must(
shapeTmpl.AddParseTree(
"eventStreamEventShapeTmpl", eventStreamEventShapeTmpl.Tree),
)
return shapeTmpl
}()
const structShapeTmplDef = `
{{ .Docstring }}
{{ $context := . -}}
type {{ .ShapeName }} struct {
@ -557,38 +605,43 @@ type {{ .ShapeName }} struct {
{{ end }}
{{ if not .API.NoGenStructFieldAccessors }}
{{ $builderShapeName := print .ShapeName -}}
{{ range $_, $name := $context.MemberNames -}}
{{ $elem := index $context.MemberRefs $name -}}
{{ $builderShapeName := print .ShapeName -}}
{{ range $_, $name := $context.MemberNames -}}
{{ $elem := index $context.MemberRefs $name -}}
// Set{{ $name }} sets the {{ $name }} field's value.
func (s *{{ $builderShapeName }}) Set{{ $name }}(v {{ $context.GoStructValueType $name $elem }}) *{{ $builderShapeName }} {
{{ if $elem.UseIndirection -}}
s.{{ $name }} = &v
{{ else -}}
s.{{ $name }} = v
{{ end -}}
return s
}
{{ if $elem.GenerateGetter -}}
func (s *{{ $builderShapeName }}) get{{ $name }}() (v {{ $context.GoStructValueType $name $elem }}) {
{{ if $elem.UseIndirection -}}
if s.{{ $name }} == nil {
return v
// Set{{ $name }} sets the {{ $name }} field's value.
func (s *{{ $builderShapeName }}) Set{{ $name }}(v {{ $context.GoStructValueType $name $elem }}) *{{ $builderShapeName }} {
{{ if $elem.UseIndirection -}}
s.{{ $name }} = &v
{{ else -}}
s.{{ $name }} = v
{{ end -}}
return s
}
return *s.{{ $name }}
{{ else -}}
return s.{{ $name }}
{{ end -}}
}
{{- end }}
{{ if $elem.GenerateGetter -}}
func (s *{{ $builderShapeName }}) get{{ $name }}() (v {{ $context.GoStructValueType $name $elem }}) {
{{ if $elem.UseIndirection -}}
if s.{{ $name }} == nil {
return v
}
return *s.{{ $name }}
{{ else -}}
return s.{{ $name }}
{{ end -}}
}
{{- end }}
{{ end }}
{{ end }}
{{ if $.EventStreamsMemberName }}
{{ template "eventStreamAPILoopMethodTmpl" $ }}
{{ end }}
`))
{{ if $.IsEvent }}
{{ template "eventStreamEventShapeTmpl" $ }}
{{ end }}
`
var enumShapeTmpl = template.Must(template.New("EnumShape").Parse(`
{{ .Docstring }}
@ -605,22 +658,38 @@ const (
// GoCode returns the rendered Go code for the Shape.
func (s *Shape) GoCode() string {
b := &bytes.Buffer{}
w := &bytes.Buffer{}
switch {
case s.EventStreamAPI != nil:
if err := renderEventStreamAPIShape(w, s); err != nil {
panic(
fmt.Sprintf(
"failed to generate eventstream API shape, %s, %v",
s.ShapeName, err),
)
}
case s.Type == "structure":
if err := structShapeTmpl.Execute(b, s); err != nil {
panic(fmt.Sprintf("Failed to generate struct shape %s, %v\n", s.ShapeName, err))
if err := structShapeTmpl.Execute(w, s); err != nil {
panic(
fmt.Sprintf(
"Failed to generate struct shape %s, %v",
s.ShapeName, err),
)
}
case s.IsEnum():
if err := enumShapeTmpl.Execute(b, s); err != nil {
panic(fmt.Sprintf("Failed to generate enum shape %s, %v\n", s.ShapeName, err))
if err := enumShapeTmpl.Execute(w, s); err != nil {
panic(
fmt.Sprintf(
"Failed to generate enum shape %s, %v",
s.ShapeName, err),
)
}
default:
panic(fmt.Sprintln("Cannot generate toplevel shape for", s.Type))
}
return b.String()
return w.String()
}
// IsEnum returns whether this shape is an enum list