github.com/aavshr/aws-sdk-go@v1.41.3/private/model/api/eventstream_tmpl.go (about)

     1  //go:build codegen
     2  // +build codegen
     3  
     4  package api
     5  
     6  import (
     7  	"fmt"
     8  	"io"
     9  	"strings"
    10  	"text/template"
    11  )
    12  
    13  func renderEventStreamAPI(w io.Writer, op *Operation) error {
    14  	// Imports needed by the EventStream APIs.
    15  	op.API.AddImport("fmt")
    16  	op.API.AddImport("bytes")
    17  	op.API.AddImport("io")
    18  	op.API.AddImport("time")
    19  	op.API.AddSDKImport("aws")
    20  	op.API.AddSDKImport("aws/awserr")
    21  	op.API.AddSDKImport("aws/request")
    22  	op.API.AddSDKImport("private/protocol/eventstream")
    23  	op.API.AddSDKImport("private/protocol/eventstream/eventstreamapi")
    24  
    25  	w.Write([]byte(`
    26  var _ awserr.Error
    27  `))
    28  
    29  	return eventStreamAPITmpl.Execute(w, op)
    30  }
    31  
    32  // Template for an EventStream API Shape that will provide read/writing events
    33  // across the EventStream. This is a special shape that's only public members
    34  // are the Events channel and a Close and Err method.
    35  //
    36  // Executed in the context of a Shape.
    37  var eventStreamAPITmpl = template.Must(
    38  	template.New("eventStreamAPITmplDef").
    39  		Funcs(template.FuncMap{
    40  			"unexported": func(v string) string {
    41  				return strings.ToLower(string(v[0])) + v[1:]
    42  			},
    43  		}).
    44  		Parse(eventStreamAPITmplDef),
    45  )
    46  
    47  const eventStreamAPITmplDef = `
    48  {{- $esapi := $.EventStreamAPI }}
    49  {{- $outputStream := $esapi.OutputStream }}
    50  {{- $inputStream := $esapi.InputStream }}
    51  
    52  // {{ $esapi.Name }} provides the event stream handling for the {{ $.ExportedName }}.
    53  //
    54  // For testing and mocking the event stream this type should be initialized via
    55  // the New{{ $esapi.Name }} constructor function. Using the functional options
    56  // to pass in nested mock behavior.
    57  type {{ $esapi.Name }} struct {
    58  	{{- if $inputStream }}
    59  
    60  		// Writer is the EventStream writer for the {{ $inputStream.Name }}
    61  		// events. This value is automatically set by the SDK when the API call is made
    62  		// Use this member when unit testing your code with the SDK to mock out the
    63  		// EventStream Writer.
    64  		//
    65  		// Must not be nil.
    66  		Writer {{ $inputStream.StreamWriterAPIName }}
    67  
    68  		inputWriter io.WriteCloser
    69  		{{- if eq .API.Metadata.Protocol "json" }}
    70  			input {{ $.InputRef.GoType }}
    71  		{{- end }}
    72  	{{- end }}
    73  
    74  	{{- if $outputStream }}
    75  
    76  		// Reader is the EventStream reader for the {{ $outputStream.Name }}
    77  		// events. This value is automatically set by the SDK when the API call is made
    78  		// Use this member when unit testing your code with the SDK to mock out the
    79  		// EventStream Reader.
    80  		//
    81  		// Must not be nil.
    82  		Reader {{ $outputStream.StreamReaderAPIName }}
    83  
    84  		outputReader io.ReadCloser
    85  		{{- if eq .API.Metadata.Protocol "json" }}
    86  			output {{ $.OutputRef.GoType }}
    87  		{{- end }}
    88  	{{- end }}
    89  
    90  	{{- if $esapi.Legacy }}
    91  
    92  		// StreamCloser is the io.Closer for the EventStream connection. For HTTP
    93  		// EventStream this is the response Body. The stream will be closed when
    94  		// the Close method of the EventStream is called.
    95  		StreamCloser io.Closer
    96  	{{- end }}
    97  
    98  	done      chan struct{}
    99  	closeOnce sync.Once
   100  	err       *eventstreamapi.OnceError
   101  }
   102  
   103  // New{{ $esapi.Name }} initializes an {{ $esapi.Name }}.
   104  // This function should only be used for testing and mocking the {{ $esapi.Name }}
   105  // stream within your application.
   106  {{- if $inputStream }}
   107  //
   108  // The Writer member must be set before writing events to the stream.
   109  {{- end }}
   110  {{- if $outputStream }}
   111  //
   112  // The Reader member must be set before reading events from the stream.
   113  {{- end }}
   114  {{- if $esapi.Legacy }}
   115  //
   116  // The StreamCloser member should be set to the underlying io.Closer,
   117  // (e.g. http.Response.Body), that will be closed when the stream Close method
   118  // is called.
   119  {{- end }}
   120  //
   121  //   es := New{{ $esapi.Name }}(func(o *{{ $esapi.Name}}{
   122  {{- if $inputStream }}
   123  //       es.Writer = myMockStreamWriter
   124  {{- end }}
   125  {{- if $outputStream }}
   126  //       es.Reader = myMockStreamReader
   127  {{- end }}
   128  {{- if $esapi.Legacy }}
   129  //       es.StreamCloser = myMockStreamCloser
   130  {{- end }}
   131  //   })
   132  func New{{ $esapi.Name }}(opts ...func(*{{ $esapi.Name}})) *{{ $esapi.Name }} {
   133  	es := &{{ $esapi.Name }} {
   134  		done: make(chan struct{}),
   135  		err: eventstreamapi.NewOnceError(),
   136  	}
   137  
   138  	for _, fn := range opts {
   139  		fn(es)
   140  	}
   141  
   142  	return es
   143  }
   144  
   145  {{- if $esapi.Legacy }}
   146  
   147  	func (es *{{ $esapi.Name }}) setStreamCloser(r *request.Request) {
   148  		es.StreamCloser = r.HTTPResponse.Body
   149  	}
   150  {{- end }}
   151  
   152  func (es *{{ $esapi.Name }}) runOnStreamPartClose(r *request.Request) {
   153  	if es.done == nil {
   154  		return
   155  	}
   156  	go es.waitStreamPartClose()
   157  
   158  }
   159  
   160  func (es *{{ $esapi.Name }}) waitStreamPartClose() {
   161  	{{- if $inputStream }}
   162  		var inputErrCh <-chan struct{}
   163  		if v, ok := es.Writer.(interface{ErrorSet() <-chan struct{}}); ok {
   164  			inputErrCh = v.ErrorSet()
   165  		}
   166  	{{- end }}
   167  	{{- if $outputStream }}
   168  		var outputErrCh <-chan struct{}
   169  		if v, ok := es.Reader.(interface{ErrorSet() <-chan struct{}}); ok {
   170  			outputErrCh = v.ErrorSet()
   171  		}
   172  		var outputClosedCh <- chan struct{}
   173  		if v, ok := es.Reader.(interface{Closed() <-chan struct{}}); ok {
   174  			outputClosedCh = v.Closed()
   175  		}
   176  	{{- end }}
   177  
   178  	select {
   179  		case <-es.done:
   180  
   181  		{{- if $inputStream }}
   182  		case <-inputErrCh:
   183  			es.err.SetError(es.Writer.Err())
   184  			es.Close()
   185  		{{- end }}
   186  
   187  		{{- if $outputStream }}
   188  		case <-outputErrCh:
   189  			es.err.SetError(es.Reader.Err())
   190  			es.Close()
   191  		case <-outputClosedCh:
   192  			if err := es.Reader.Err(); err != nil {
   193  				es.err.SetError(es.Reader.Err())
   194  			}
   195  			es.Close()
   196  		{{- end }}
   197  	}
   198  }
   199  
   200  {{- if $inputStream }}
   201  
   202  	{{- if eq .API.Metadata.Protocol "json" }}
   203  
   204  		func {{ $esapi.StreamInputEventTypeGetterName }}(event {{ $inputStream.EventGroupName }}) (string, error) {
   205  			if _, ok := event.({{ $.InputRef.GoType }}); ok {
   206  				return "initial-request", nil
   207  			}
   208  			return {{ $inputStream.StreamEventTypeGetterName }}(event)
   209  		}
   210  	{{- end }}
   211  
   212  	func (es *{{ $esapi.Name }}) setupInputPipe(r *request.Request) {
   213  			inputReader, inputWriter := io.Pipe()
   214  			r.SetStreamingBody(inputReader)
   215  			es.inputWriter = inputWriter
   216  	}
   217  
   218  	// Closes the input-pipe writer
   219  	func (es *{{ $esapi.Name }}) closeInputPipe() error {
   220  		if es.inputWriter != nil {
   221  			return es.inputWriter.Close()
   222  		}
   223  		return nil
   224  	}	
   225  
   226  	// Send writes the event to the stream blocking until the event is written.
   227  	// Returns an error if the event was not written.
   228  	//
   229  	// These events are:
   230  	// {{ range $_, $event := $inputStream.Events }}
   231  	//     * {{ $event.Shape.ShapeName }}
   232  	{{- end }}
   233  	func (es *{{ $esapi.Name }}) Send(ctx aws.Context, event {{ $inputStream.EventGroupName }}) error {
   234  		return es.Writer.Send(ctx, event)
   235  	}
   236  
   237  	func (es *{{ $esapi.Name }}) runInputStream(r *request.Request) {
   238  		var opts []func(*eventstream.Encoder)
   239  		if r.Config.Logger != nil && r.Config.LogLevel.Matches(aws.LogDebugWithEventStreamBody) {
   240  			opts = append(opts, eventstream.EncodeWithLogger(r.Config.Logger))
   241  		}
   242  		var encoder eventstreamapi.Encoder = eventstream.NewEncoder(es.inputWriter, opts...)
   243  
   244  		var closer aws.MultiCloser
   245  		{{- if $.ShouldSignRequestBody }}
   246  			{{- $_ := $.API.AddSDKImport "aws/signer/v4" }}
   247  			sigSeed, err := v4.GetSignedRequestSignature(r.HTTPRequest)
   248  			if err != nil {
   249  				r.Error = awserr.New(request.ErrCodeSerialization,
   250  					"unable to get initial request's signature", err)
   251  				return
   252  			}
   253  			signer := eventstreamapi.NewSignEncoder(
   254  				v4.NewStreamSigner(r.ClientInfo.SigningRegion, r.ClientInfo.SigningName,
   255  					sigSeed, r.Config.Credentials),
   256  				encoder,
   257  			)
   258  			encoder = signer
   259  			closer = append(closer, signer)
   260  		{{- end }}
   261  		closer = append(closer, es.inputWriter)
   262  
   263  		eventWriter := eventstreamapi.NewEventWriter(encoder,
   264  			protocol.HandlerPayloadMarshal{
   265  				Marshalers: r.Handlers.BuildStream,
   266  			},
   267  			{{- if eq .API.Metadata.Protocol "json" }}
   268  				{{ $esapi.StreamInputEventTypeGetterName }},
   269  			{{- else }}
   270  				{{ $inputStream.StreamEventTypeGetterName }},
   271  			{{- end }}
   272  		)
   273  
   274  		es.Writer = &{{ $inputStream.StreamWriterImplName }}{
   275  			StreamWriter: eventstreamapi.NewStreamWriter(eventWriter, closer),
   276  		}
   277  	}
   278  
   279  	{{- if eq .API.Metadata.Protocol "json" }}
   280  		func (es *{{ $esapi.Name }}) sendInitialEvent(r *request.Request) {
   281  			if err := es.Send(es.input); err != nil {
   282  				r.Error = err
   283  			}
   284  		}
   285  	{{- end }}
   286  {{- end }}
   287  
   288  {{- if $outputStream }}
   289  	{{- if eq .API.Metadata.Protocol "json" }}
   290  
   291  		type {{ $esapi.StreamOutputUnmarshalerForEventName }} struct {
   292  			unmarshalerForEvent func(string) (eventstreamapi.Unmarshaler, error)
   293  			output {{ $.OutputRef.GoType }}
   294  		}
   295  		func (e {{ $esapi.StreamOutputUnmarshalerForEventName }}) UnmarshalerForEventName(eventType string) (eventstreamapi.Unmarshaler, error) {
   296  			if eventType == "initial-response" {
   297  				return e.output, nil
   298  			}
   299  			return e.unmarshalerForEvent(eventType)
   300  		}
   301  	{{- end }}
   302  
   303  	// Events returns a channel to read events from.
   304  	//
   305  	// These events are:
   306  	// {{ range $_, $event := $outputStream.Events }}
   307  	//     * {{ $event.Shape.ShapeName }}
   308  	{{- end }}
   309      //     * {{ $outputStream.StreamUnknownEventName }}
   310  	func (es *{{ $esapi.Name }}) Events() <-chan {{ $outputStream.EventGroupName }} {
   311  		return es.Reader.Events()
   312  	}
   313  
   314  	func (es *{{ $esapi.Name }}) runOutputStream(r *request.Request) {
   315  		var opts []func(*eventstream.Decoder)
   316  		if r.Config.Logger != nil && r.Config.LogLevel.Matches(aws.LogDebugWithEventStreamBody) {
   317  			opts = append(opts, eventstream.DecodeWithLogger(r.Config.Logger))
   318  		}
   319  
   320  		unmarshalerForEvent := {{ $outputStream.StreamUnmarshalerForEventName }}{
   321  			metadata: protocol.ResponseMetadata{
   322  				StatusCode: r.HTTPResponse.StatusCode,
   323  				RequestID: r.RequestID,
   324  			},
   325  		}.UnmarshalerForEventName
   326  		{{- if eq .API.Metadata.Protocol "json" }}
   327  			unmarshalerForEvent = {{ $esapi.StreamOutputUnmarshalerForEventName }}{
   328  				unmarshalerForEvent: unmarshalerForEvent,
   329  				output: es.output,
   330  			}.UnmarshalerForEventName
   331  		{{- end }}
   332  
   333  		decoder := eventstream.NewDecoder(r.HTTPResponse.Body, opts...)
   334  		eventReader := eventstreamapi.NewEventReader(decoder,
   335  			protocol.HandlerPayloadUnmarshal{
   336  				Unmarshalers: r.Handlers.UnmarshalStream,
   337  			},
   338  			unmarshalerForEvent,
   339  		)
   340  
   341  		es.outputReader = r.HTTPResponse.Body
   342  		es.Reader = {{ $outputStream.StreamReaderImplConstructorName }}(eventReader)
   343  	}
   344  
   345  	{{- if eq .API.Metadata.Protocol "json" }}
   346  		func (es *{{ $esapi.Name }}) recvInitialEvent(r *request.Request) {
   347  			// Wait for the initial response event, which must be the first
   348  			// event to be received from the API.
   349  			select {
   350  			case event, ok := <- es.Events():
   351  				if !ok {
   352  					return
   353  				}
   354  
   355  				v, ok := event.({{ $.OutputRef.GoType }})
   356  				if !ok || v == nil {
   357  					r.Error = awserr.New(
   358  						request.ErrCodeSerialization,
   359  						fmt.Sprintf("invalid event, %T, expect %T, %v",
   360  							event, ({{ $.OutputRef.GoType }})(nil), v),
   361  						nil,
   362  					)
   363  					return
   364  				}
   365  
   366  				*es.output = *v
   367  				es.output.{{ $.EventStreamAPI.OutputMemberName  }} = es
   368  			}
   369  		}
   370  	{{- end }}
   371  {{- end }}
   372  
   373  // Close closes the stream. This will also cause the stream to be closed.
   374  // Close must be called when done using the stream API. Not calling Close
   375  // may result in resource leaks.
   376  {{- if $inputStream }}
   377  //
   378  // Will close the underlying EventStream writer, and no more events can be
   379  // sent.
   380  {{- end }}
   381  {{- if $outputStream }}
   382  //
   383  // You can use the closing of the Reader's Events channel to terminate your
   384  // application's read from the API's stream.
   385  {{- end }}
   386  //
   387  func (es *{{ $esapi.Name }}) Close() (err error) {
   388  	es.closeOnce.Do(es.safeClose)
   389  	return es.Err()
   390  }
   391  
   392  func (es *{{ $esapi.Name }}) safeClose() {
   393  	if es.done != nil {
   394  		close(es.done)
   395  	}
   396  
   397  	{{- if $inputStream }}
   398  
   399  		t := time.NewTicker(time.Second)
   400  		defer t.Stop()
   401  		writeCloseDone := make(chan error)
   402  		go func() {
   403  			if err := es.Writer.Close(); err != nil {
   404  				es.err.SetError(err)
   405  			}
   406  			close(writeCloseDone)
   407  		}()
   408  		select {
   409  		case <-t.C:
   410  		case <-writeCloseDone:
   411  		}
   412  		if err := es.closeInputPipe(); err != nil {
   413  			es.err.SetError(err)
   414  		}
   415  	{{- end }}
   416  
   417  	{{- if $outputStream }}
   418  
   419  		es.Reader.Close()
   420  		if es.outputReader != nil {
   421  			es.outputReader.Close()
   422  		}
   423  	{{- end }}
   424  
   425  	{{- if $esapi.Legacy }}
   426  
   427  		es.StreamCloser.Close()
   428  	{{- end }}
   429  }
   430  
   431  // Err returns any error that occurred while reading or writing EventStream
   432  // Events from the service API's response. Returns nil if there were no errors.
   433  func (es *{{ $esapi.Name }}) Err() error {
   434  	if err := es.err.Err(); err != nil {
   435  		return err
   436  	}
   437  
   438  	{{- if $inputStream }}
   439  		if err := es.Writer.Err(); err != nil {
   440  			return err
   441  		}
   442  	{{- end }}
   443  
   444  	{{- if $outputStream }}
   445  		if err := es.Reader.Err(); err != nil {
   446  			return err
   447  		}
   448  	{{- end }}
   449  
   450  	return nil
   451  }
   452  `
   453  
   454  func renderEventStreamShape(w io.Writer, s *Shape) error {
   455  	// Imports needed by the EventStream APIs.
   456  	s.API.AddImport("fmt")
   457  	s.API.AddImport("bytes")
   458  	s.API.AddImport("io")
   459  	s.API.AddImport("sync")
   460  	s.API.AddSDKImport("aws")
   461  	s.API.AddSDKImport("aws/awserr")
   462  	s.API.AddSDKImport("private/protocol/eventstream")
   463  	s.API.AddSDKImport("private/protocol/eventstream/eventstreamapi")
   464  
   465  	return eventStreamShapeTmpl.Execute(w, s)
   466  }
   467  
   468  var eventStreamShapeTmpl = func() *template.Template {
   469  	t := template.Must(
   470  		template.New("eventStreamShapeTmplDef").
   471  			Parse(eventStreamShapeTmplDef),
   472  	)
   473  	template.Must(
   474  		t.AddParseTree(
   475  			"eventStreamShapeWriterTmpl", eventStreamShapeWriterTmpl.Tree),
   476  	)
   477  	template.Must(
   478  		t.AddParseTree(
   479  			"eventStreamShapeReaderTmpl", eventStreamShapeReaderTmpl.Tree),
   480  	)
   481  
   482  	return t
   483  }()
   484  
   485  const eventStreamShapeTmplDef = `
   486  {{- $eventStream := $.EventStream }}
   487  {{- $eventStreamEventGroup := printf "%sEvent" $eventStream.Name }}
   488  
   489  // {{ $eventStreamEventGroup }} groups together all EventStream
   490  // events writes for {{ $eventStream.Name }}.
   491  //
   492  // These events are:
   493  // {{ range $_, $event := $eventStream.Events }}
   494  //     * {{ $event.Shape.ShapeName }}
   495  {{- end }}
   496  type {{ $eventStreamEventGroup }} interface {
   497  	event{{ $eventStream.Name }}()
   498  	eventstreamapi.Marshaler
   499  	eventstreamapi.Unmarshaler
   500  }
   501  
   502  {{- if $.IsInputEventStream }}
   503  	{{- template "eventStreamShapeWriterTmpl" $ }}
   504  {{- end }}
   505  
   506  {{- if $.IsOutputEventStream }}
   507  	{{- template "eventStreamShapeReaderTmpl" $ }}
   508  {{- end }}
   509  `
   510  
   511  // EventStreamHeaderTypeMap provides the mapping of a EventStream Header's
   512  // Value type to the shape reference's member type.
   513  type EventStreamHeaderTypeMap struct {
   514  	Header string
   515  	Member string
   516  }
   517  
   518  // Returns if the event has any members which are not the event's blob payload,
   519  // nor a header.
   520  func eventHasNonBlobPayloadMembers(s *Shape) bool {
   521  	num := len(s.MemberRefs)
   522  	for _, ref := range s.MemberRefs {
   523  		if ref.IsEventHeader || (ref.IsEventPayload && (ref.Shape.Type == "blob" || ref.Shape.Type == "string")) {
   524  			num--
   525  		}
   526  	}
   527  	return num > 0
   528  }
   529  
   530  func setEventHeaderValueForType(s *Shape, memVar string) string {
   531  	switch s.Type {
   532  	case "blob":
   533  		return fmt.Sprintf("eventstream.BytesValue(%s)", memVar)
   534  	case "string":
   535  		return fmt.Sprintf("eventstream.StringValue(*%s)", memVar)
   536  	case "boolean":
   537  		return fmt.Sprintf("eventstream.BoolValue(*%s)", memVar)
   538  	case "byte":
   539  		return fmt.Sprintf("eventstream.Int8Value(int8(*%s))", memVar)
   540  	case "short":
   541  		return fmt.Sprintf("eventstream.Int16Value(int16(*%s))", memVar)
   542  	case "integer":
   543  		return fmt.Sprintf("eventstream.Int32Value(int32(*%s))", memVar)
   544  	case "long":
   545  		return fmt.Sprintf("eventstream.Int64Value(*%s)", memVar)
   546  	case "float":
   547  		return fmt.Sprintf("eventstream.Float32Value(float32(*%s))", memVar)
   548  	case "double":
   549  		return fmt.Sprintf("eventstream.Float64Value(*%s)", memVar)
   550  	case "timestamp":
   551  		return fmt.Sprintf("eventstream.TimestampValue(*%s)", memVar)
   552  	default:
   553  		panic(fmt.Sprintf("value type %s not supported for event headers, %s", s.Type, s.ShapeName))
   554  	}
   555  }
   556  
   557  func shapeMessageType(s *Shape) string {
   558  	if s.Exception {
   559  		return "eventstreamapi.ExceptionMessageType"
   560  	}
   561  	return "eventstreamapi.EventMessageType"
   562  }
   563  
   564  var eventStreamEventShapeTmplFuncs = template.FuncMap{
   565  	"EventStreamHeaderTypeMap": func(ref *ShapeRef) EventStreamHeaderTypeMap {
   566  		switch ref.Shape.Type {
   567  		case "boolean":
   568  			return EventStreamHeaderTypeMap{Header: "bool", Member: "bool"}
   569  		case "byte":
   570  			return EventStreamHeaderTypeMap{Header: "int8", Member: "int64"}
   571  		case "short":
   572  			return EventStreamHeaderTypeMap{Header: "int16", Member: "int64"}
   573  		case "integer":
   574  			return EventStreamHeaderTypeMap{Header: "int32", Member: "int64"}
   575  		case "long":
   576  			return EventStreamHeaderTypeMap{Header: "int64", Member: "int64"}
   577  		case "timestamp":
   578  			return EventStreamHeaderTypeMap{Header: "time.Time", Member: "time.Time"}
   579  		case "blob":
   580  			return EventStreamHeaderTypeMap{Header: "[]byte", Member: "[]byte"}
   581  		case "string":
   582  			return EventStreamHeaderTypeMap{Header: "string", Member: "string"}
   583  		case "uuid":
   584  			return EventStreamHeaderTypeMap{Header: "[]byte", Member: "[]byte"}
   585  		default:
   586  			panic("unsupported EventStream header type, " + ref.Shape.Type)
   587  		}
   588  	},
   589  	"EventHeaderValueForType":  setEventHeaderValueForType,
   590  	"ShapeMessageType":         shapeMessageType,
   591  	"HasNonBlobPayloadMembers": eventHasNonBlobPayloadMembers,
   592  }
   593  
   594  // Template for an EventStream Event shape. This is a normal API shape that is
   595  // decorated as an EventStream Event.
   596  //
   597  // Executed in the context of a Shape.
   598  var eventStreamEventShapeTmpl = template.Must(template.New("eventStreamEventShapeTmpl").
   599  	Funcs(eventStreamEventShapeTmplFuncs).Parse(`
   600  {{ range $_, $eventStream := $.EventFor }}
   601  	// The {{ $.ShapeName }} is and event in the {{ $eventStream.Name }} group of events.
   602  	func (s *{{ $.ShapeName }}) event{{ $eventStream.Name }}() {}
   603  {{ end }}
   604  
   605  // UnmarshalEvent unmarshals the EventStream Message into the {{ $.ShapeName }} value.
   606  // This method is only used internally within the SDK's EventStream handling.
   607  func (s *{{ $.ShapeName }}) UnmarshalEvent(
   608  	payloadUnmarshaler protocol.PayloadUnmarshaler,
   609  	msg eventstream.Message,
   610  ) error {
   611  	{{- range $memName, $memRef := $.MemberRefs }}
   612  		{{- if $memRef.IsEventHeader }}
   613  			if hv := msg.Headers.Get("{{ $memName }}"); hv != nil {
   614  				{{ $types := EventStreamHeaderTypeMap $memRef -}}
   615  				v := hv.Get().({{ $types.Header }})
   616  				{{- if ne $types.Header $types.Member }}
   617  					m := {{ $types.Member }}(v)
   618  					s.{{ $memName }} = {{ if $memRef.UseIndirection }}&{{ end }}m
   619  				{{- else }}
   620  					s.{{ $memName }} = {{ if $memRef.UseIndirection }}&{{ end }}v
   621  				{{- end }}
   622  			}
   623  		{{- else if (and ($memRef.IsEventPayload) (eq $memRef.Shape.Type "blob")) }}
   624  			s.{{ $memName }} = make([]byte, len(msg.Payload))
   625  			copy(s.{{ $memName }}, msg.Payload)
   626  		{{- else if (and ($memRef.IsEventPayload) (eq $memRef.Shape.Type "string")) }}
   627  			s.{{ $memName }} = aws.String(string(msg.Payload))
   628  		{{- end }}
   629  	{{- end }}
   630  	{{- if HasNonBlobPayloadMembers $ }}
   631  		if err := payloadUnmarshaler.UnmarshalPayload(
   632  			bytes.NewReader(msg.Payload), s,
   633  		); err != nil {
   634  			return err
   635  		}
   636  	{{- end }}
   637  	return nil
   638  }
   639  
   640  // MarshalEvent marshals the type into an stream event value. This method
   641  // should only used internally within the SDK's EventStream handling.
   642  func (s *{{ $.ShapeName}}) MarshalEvent(pm protocol.PayloadMarshaler) (msg eventstream.Message, err error) {
   643  	msg.Headers.Set(eventstreamapi.MessageTypeHeader, eventstream.StringValue({{ ShapeMessageType $ }}))
   644  
   645  	{{- range $memName, $memRef := $.MemberRefs }}
   646  		{{- if $memRef.IsEventHeader }}
   647  			{{ $memVar := printf "s.%s" $memName -}}
   648  			{{ $typedMem := EventHeaderValueForType $memRef.Shape $memVar -}}
   649  			msg.Headers.Set("{{ $memName }}", {{ $typedMem }})
   650  		{{- else if (and ($memRef.IsEventPayload) (eq $memRef.Shape.Type "blob")) }}
   651  			msg.Headers.Set(":content-type", eventstream.StringValue("application/octet-stream"))
   652  			msg.Payload = s.{{ $memName }}
   653  		{{- else if (and ($memRef.IsEventPayload) (eq $memRef.Shape.Type "string")) }}
   654  			msg.Payload = []byte(aws.StringValue(s.{{ $memName }}))
   655  		{{- end }}
   656  	{{- end }}
   657  	{{- if HasNonBlobPayloadMembers $ }}
   658  		var buf bytes.Buffer
   659  		if err = pm.MarshalPayload(&buf, s); err != nil {
   660  			return eventstream.Message{}, err
   661  		}
   662  		msg.Payload = buf.Bytes()
   663  	{{- end }}
   664  	return msg, err
   665  }
   666  `))