// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.

package restxmlservice

import (
	"bytes"
	"fmt"
	"io"
	"sync"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/aws/awsutil"
	"github.com/aws/aws-sdk-go/aws/client"
	"github.com/aws/aws-sdk-go/aws/request"
	"github.com/aws/aws-sdk-go/private/protocol"
	"github.com/aws/aws-sdk-go/private/protocol/eventstream"
	"github.com/aws/aws-sdk-go/private/protocol/eventstream/eventstreamapi"
	"github.com/aws/aws-sdk-go/private/protocol/rest"
	"github.com/aws/aws-sdk-go/private/protocol/restxml"
)

const opEmptyStream = "EmptyStream"

// EmptyStreamRequest generates a "aws/request.Request" representing the
// client's request for the EmptyStream operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See EmptyStream for more information on using the EmptyStream
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the EmptyStreamRequest method.
//    req, resp := client.EmptyStreamRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/RESTXMLService-0000-00-00/EmptyStream
func (c *RESTXMLService) EmptyStreamRequest(input *EmptyStreamInput) (req *request.Request, output *EmptyStreamOutput) {
	op := &request.Operation{
		Name:       opEmptyStream,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &EmptyStreamInput{}
	}

	output = &EmptyStreamOutput{}
	req = c.newRequest(op, input, output)

	es := NewEmptyStreamEventStream()
	output.eventStream = es

	req.Handlers.Send.Swap(client.LogHTTPResponseHandler.Name, client.LogHTTPResponseHeaderHandler)
	req.Handlers.Unmarshal.Swap(restxml.UnmarshalHandler.Name, rest.UnmarshalHandler)
	req.Handlers.Unmarshal.PushBack(es.runOutputStream)
	req.Handlers.Unmarshal.PushBack(es.runOnStreamPartClose)
	return
}

// EmptyStream API operation for REST XML Service.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for REST XML Service's
// API operation EmptyStream for usage and error information.
// See also, https://docs.aws.amazon.com/goto/WebAPI/RESTXMLService-0000-00-00/EmptyStream
func (c *RESTXMLService) EmptyStream(input *EmptyStreamInput) (*EmptyStreamOutput, error) {
	req, out := c.EmptyStreamRequest(input)
	return out, req.Send()
}

// EmptyStreamWithContext is the same as EmptyStream with the addition of
// the ability to pass a context and additional request options.
//
// See EmptyStream for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *RESTXMLService) EmptyStreamWithContext(ctx aws.Context, input *EmptyStreamInput, opts ...request.Option) (*EmptyStreamOutput, error) {
	req, out := c.EmptyStreamRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

var _ awserr.Error

// EmptyStreamEventStream provides the event stream handling for the EmptyStream.
//
// For testing and mocking the event stream this type should be initialized via
// the NewEmptyStreamEventStream constructor function. Using the functional options
// to pass in nested mock behavior.
type EmptyStreamEventStream struct {

	// Reader is the EventStream reader for the EmptyEventStream
	// 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 EmptyEventStreamReader

	outputReader io.ReadCloser

	done      chan struct{}
	closeOnce sync.Once
	err       *eventstreamapi.OnceError
}

// NewEmptyStreamEventStream initializes an EmptyStreamEventStream.
// This function should only be used for testing and mocking the EmptyStreamEventStream
// stream within your application.
//
// The Reader member must be set before reading events from the stream.
//
//   es := NewEmptyStreamEventStream(func(o *EmptyStreamEventStream{
//       es.Reader = myMockStreamReader
//   })
func NewEmptyStreamEventStream(opts ...func(*EmptyStreamEventStream)) *EmptyStreamEventStream {
	es := &EmptyStreamEventStream{
		done: make(chan struct{}),
		err:  eventstreamapi.NewOnceError(),
	}

	for _, fn := range opts {
		fn(es)
	}

	return es
}

func (es *EmptyStreamEventStream) runOnStreamPartClose(r *request.Request) {
	if es.done == nil {
		return
	}
	go es.waitStreamPartClose()

}

func (es *EmptyStreamEventStream) waitStreamPartClose() {
	var outputErrCh <-chan struct{}
	if v, ok := es.Reader.(interface{ ErrorSet() <-chan struct{} }); ok {
		outputErrCh = v.ErrorSet()
	}
	var outputClosedCh <-chan struct{}
	if v, ok := es.Reader.(interface{ Closed() <-chan struct{} }); ok {
		outputClosedCh = v.Closed()
	}

	select {
	case <-es.done:
	case <-outputErrCh:
		es.err.SetError(es.Reader.Err())
		es.Close()
	case <-outputClosedCh:
		if err := es.Reader.Err(); err != nil {
			es.err.SetError(es.Reader.Err())
		}
		es.Close()
	}
}

// Events returns a channel to read events from.
//
// These events are:
//
//     * EmptyEventStreamUnknownEvent
func (es *EmptyStreamEventStream) Events() <-chan EmptyEventStreamEvent {
	return es.Reader.Events()
}

func (es *EmptyStreamEventStream) runOutputStream(r *request.Request) {
	var opts []func(*eventstream.Decoder)
	if r.Config.Logger != nil && r.Config.LogLevel.Matches(aws.LogDebugWithEventStreamBody) {
		opts = append(opts, eventstream.DecodeWithLogger(r.Config.Logger))
	}

	unmarshalerForEvent := unmarshalerForEmptyEventStreamEvent{
		metadata: protocol.ResponseMetadata{
			StatusCode: r.HTTPResponse.StatusCode,
			RequestID:  r.RequestID,
		},
	}.UnmarshalerForEventName

	decoder := eventstream.NewDecoder(r.HTTPResponse.Body, opts...)
	eventReader := eventstreamapi.NewEventReader(decoder,
		protocol.HandlerPayloadUnmarshal{
			Unmarshalers: r.Handlers.UnmarshalStream,
		},
		unmarshalerForEvent,
	)

	es.outputReader = r.HTTPResponse.Body
	es.Reader = newReadEmptyEventStream(eventReader)
}

// Close closes the stream. This will also cause the stream to be closed.
// Close must be called when done using the stream API. Not calling Close
// may result in resource leaks.
//
// You can use the closing of the Reader's Events channel to terminate your
// application's read from the API's stream.
//
func (es *EmptyStreamEventStream) Close() (err error) {
	es.closeOnce.Do(es.safeClose)
	return es.Err()
}

func (es *EmptyStreamEventStream) safeClose() {
	if es.done != nil {
		close(es.done)
	}

	es.Reader.Close()
	if es.outputReader != nil {
		es.outputReader.Close()
	}
}

// Err returns any error that occurred while reading or writing EventStream
// Events from the service API's response. Returns nil if there were no errors.
func (es *EmptyStreamEventStream) Err() error {
	if err := es.err.Err(); err != nil {
		return err
	}
	if err := es.Reader.Err(); err != nil {
		return err
	}

	return nil
}

const opGetEventStream = "GetEventStream"

// GetEventStreamRequest generates a "aws/request.Request" representing the
// client's request for the GetEventStream operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See GetEventStream for more information on using the GetEventStream
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the GetEventStreamRequest method.
//    req, resp := client.GetEventStreamRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/RESTXMLService-0000-00-00/GetEventStream
func (c *RESTXMLService) GetEventStreamRequest(input *GetEventStreamInput) (req *request.Request, output *GetEventStreamOutput) {
	op := &request.Operation{
		Name:       opGetEventStream,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &GetEventStreamInput{}
	}

	output = &GetEventStreamOutput{}
	req = c.newRequest(op, input, output)

	es := NewGetEventStreamEventStream()
	output.eventStream = es

	req.Handlers.Send.Swap(client.LogHTTPResponseHandler.Name, client.LogHTTPResponseHeaderHandler)
	req.Handlers.Unmarshal.Swap(restxml.UnmarshalHandler.Name, rest.UnmarshalHandler)
	req.Handlers.Unmarshal.PushBack(es.runOutputStream)
	req.Handlers.Unmarshal.PushBack(es.runOnStreamPartClose)
	return
}

// GetEventStream API operation for REST XML Service.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for REST XML Service's
// API operation GetEventStream for usage and error information.
// See also, https://docs.aws.amazon.com/goto/WebAPI/RESTXMLService-0000-00-00/GetEventStream
func (c *RESTXMLService) GetEventStream(input *GetEventStreamInput) (*GetEventStreamOutput, error) {
	req, out := c.GetEventStreamRequest(input)
	return out, req.Send()
}

// GetEventStreamWithContext is the same as GetEventStream with the addition of
// the ability to pass a context and additional request options.
//
// See GetEventStream for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *RESTXMLService) GetEventStreamWithContext(ctx aws.Context, input *GetEventStreamInput, opts ...request.Option) (*GetEventStreamOutput, error) {
	req, out := c.GetEventStreamRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

var _ awserr.Error

// GetEventStreamEventStream provides the event stream handling for the GetEventStream.
//
// For testing and mocking the event stream this type should be initialized via
// the NewGetEventStreamEventStream constructor function. Using the functional options
// to pass in nested mock behavior.
type GetEventStreamEventStream struct {

	// Reader is the EventStream reader for the EventStream
	// 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 EventStreamReader

	outputReader io.ReadCloser

	done      chan struct{}
	closeOnce sync.Once
	err       *eventstreamapi.OnceError
}

// NewGetEventStreamEventStream initializes an GetEventStreamEventStream.
// This function should only be used for testing and mocking the GetEventStreamEventStream
// stream within your application.
//
// The Reader member must be set before reading events from the stream.
//
//   es := NewGetEventStreamEventStream(func(o *GetEventStreamEventStream{
//       es.Reader = myMockStreamReader
//   })
func NewGetEventStreamEventStream(opts ...func(*GetEventStreamEventStream)) *GetEventStreamEventStream {
	es := &GetEventStreamEventStream{
		done: make(chan struct{}),
		err:  eventstreamapi.NewOnceError(),
	}

	for _, fn := range opts {
		fn(es)
	}

	return es
}

func (es *GetEventStreamEventStream) runOnStreamPartClose(r *request.Request) {
	if es.done == nil {
		return
	}
	go es.waitStreamPartClose()

}

func (es *GetEventStreamEventStream) waitStreamPartClose() {
	var outputErrCh <-chan struct{}
	if v, ok := es.Reader.(interface{ ErrorSet() <-chan struct{} }); ok {
		outputErrCh = v.ErrorSet()
	}
	var outputClosedCh <-chan struct{}
	if v, ok := es.Reader.(interface{ Closed() <-chan struct{} }); ok {
		outputClosedCh = v.Closed()
	}

	select {
	case <-es.done:
	case <-outputErrCh:
		es.err.SetError(es.Reader.Err())
		es.Close()
	case <-outputClosedCh:
		if err := es.Reader.Err(); err != nil {
			es.err.SetError(es.Reader.Err())
		}
		es.Close()
	}
}

// Events returns a channel to read events from.
//
// These events are:
//
//     * EmptyEvent
//     * ExplicitPayloadEvent
//     * HeaderOnlyEvent
//     * ImplicitPayloadEvent
//     * PayloadOnlyEvent
//     * PayloadOnlyBlobEvent
//     * PayloadOnlyStringEvent
//     * EventStreamUnknownEvent
func (es *GetEventStreamEventStream) Events() <-chan EventStreamEvent {
	return es.Reader.Events()
}

func (es *GetEventStreamEventStream) runOutputStream(r *request.Request) {
	var opts []func(*eventstream.Decoder)
	if r.Config.Logger != nil && r.Config.LogLevel.Matches(aws.LogDebugWithEventStreamBody) {
		opts = append(opts, eventstream.DecodeWithLogger(r.Config.Logger))
	}

	unmarshalerForEvent := unmarshalerForEventStreamEvent{
		metadata: protocol.ResponseMetadata{
			StatusCode: r.HTTPResponse.StatusCode,
			RequestID:  r.RequestID,
		},
	}.UnmarshalerForEventName

	decoder := eventstream.NewDecoder(r.HTTPResponse.Body, opts...)
	eventReader := eventstreamapi.NewEventReader(decoder,
		protocol.HandlerPayloadUnmarshal{
			Unmarshalers: r.Handlers.UnmarshalStream,
		},
		unmarshalerForEvent,
	)

	es.outputReader = r.HTTPResponse.Body
	es.Reader = newReadEventStream(eventReader)
}

// Close closes the stream. This will also cause the stream to be closed.
// Close must be called when done using the stream API. Not calling Close
// may result in resource leaks.
//
// You can use the closing of the Reader's Events channel to terminate your
// application's read from the API's stream.
//
func (es *GetEventStreamEventStream) Close() (err error) {
	es.closeOnce.Do(es.safeClose)
	return es.Err()
}

func (es *GetEventStreamEventStream) safeClose() {
	if es.done != nil {
		close(es.done)
	}

	es.Reader.Close()
	if es.outputReader != nil {
		es.outputReader.Close()
	}
}

// Err returns any error that occurred while reading or writing EventStream
// Events from the service API's response. Returns nil if there were no errors.
func (es *GetEventStreamEventStream) Err() error {
	if err := es.err.Err(); err != nil {
		return err
	}
	if err := es.Reader.Err(); err != nil {
		return err
	}

	return nil
}

const opOtherOperation = "OtherOperation"

// OtherOperationRequest generates a "aws/request.Request" representing the
// client's request for the OtherOperation operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See OtherOperation for more information on using the OtherOperation
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the OtherOperationRequest method.
//    req, resp := client.OtherOperationRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/RESTXMLService-0000-00-00/OtherOperation
func (c *RESTXMLService) OtherOperationRequest(input *OtherOperationInput) (req *request.Request, output *OtherOperationOutput) {
	op := &request.Operation{
		Name:       opOtherOperation,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &OtherOperationInput{}
	}

	output = &OtherOperationOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(restxml.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// OtherOperation API operation for REST XML Service.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for REST XML Service's
// API operation OtherOperation for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeExceptionEvent2 "ExceptionEvent2"
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/RESTXMLService-0000-00-00/OtherOperation
func (c *RESTXMLService) OtherOperation(input *OtherOperationInput) (*OtherOperationOutput, error) {
	req, out := c.OtherOperationRequest(input)
	return out, req.Send()
}

// OtherOperationWithContext is the same as OtherOperation with the addition of
// the ability to pass a context and additional request options.
//
// See OtherOperation for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *RESTXMLService) OtherOperationWithContext(ctx aws.Context, input *OtherOperationInput, opts ...request.Option) (*OtherOperationOutput, error) {
	req, out := c.OtherOperationRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

type EmptyEvent struct {
	_ struct{} `locationName:"EmptyEvent" type:"structure"`
}

// String returns the string representation
func (s EmptyEvent) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s EmptyEvent) GoString() string {
	return s.String()
}

// The EmptyEvent is and event in the EventStream group of events.
func (s *EmptyEvent) eventEventStream() {}

// UnmarshalEvent unmarshals the EventStream Message into the EmptyEvent value.
// This method is only used internally within the SDK's EventStream handling.
func (s *EmptyEvent) UnmarshalEvent(
	payloadUnmarshaler protocol.PayloadUnmarshaler,
	msg eventstream.Message,
) error {
	return nil
}

// MarshalEvent marshals the type into an stream event value. This method
// should only used internally within the SDK's EventStream handling.
func (s *EmptyEvent) MarshalEvent(pm protocol.PayloadMarshaler) (msg eventstream.Message, err error) {
	msg.Headers.Set(eventstreamapi.MessageTypeHeader, eventstream.StringValue(eventstreamapi.EventMessageType))
	return msg, err
}

// EmptyEventStreamEvent groups together all EventStream
// events writes for EmptyEventStream.
//
// These events are:
//
type EmptyEventStreamEvent interface {
	eventEmptyEventStream()
	eventstreamapi.Marshaler
	eventstreamapi.Unmarshaler
}

// EmptyEventStreamReader provides the interface for reading to the stream. The
// default implementation for this interface will be EmptyEventStream.
//
// The reader's Close method must allow multiple concurrent calls.
//
// These events are:
//
//     * EmptyEventStreamUnknownEvent
type EmptyEventStreamReader interface {
	// Returns a channel of events as they are read from the event stream.
	Events() <-chan EmptyEventStreamEvent

	// Close will stop the reader reading events from the stream.
	Close() error

	// Returns any error that has occurred while reading from the event stream.
	Err() error
}

type readEmptyEventStream struct {
	eventReader *eventstreamapi.EventReader
	stream      chan EmptyEventStreamEvent
	err         *eventstreamapi.OnceError

	done      chan struct{}
	closeOnce sync.Once
}

func newReadEmptyEventStream(eventReader *eventstreamapi.EventReader) *readEmptyEventStream {
	r := &readEmptyEventStream{
		eventReader: eventReader,
		stream:      make(chan EmptyEventStreamEvent),
		done:        make(chan struct{}),
		err:         eventstreamapi.NewOnceError(),
	}
	go r.readEventStream()

	return r
}

// Close will close the underlying event stream reader.
func (r *readEmptyEventStream) Close() error {
	r.closeOnce.Do(r.safeClose)
	return r.Err()
}

func (r *readEmptyEventStream) ErrorSet() <-chan struct{} {
	return r.err.ErrorSet()
}

func (r *readEmptyEventStream) Closed() <-chan struct{} {
	return r.done
}

func (r *readEmptyEventStream) safeClose() {
	close(r.done)
}

func (r *readEmptyEventStream) Err() error {
	return r.err.Err()
}

func (r *readEmptyEventStream) Events() <-chan EmptyEventStreamEvent {
	return r.stream
}

func (r *readEmptyEventStream) readEventStream() {
	defer r.Close()
	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:
			}
			if _, ok := err.(*eventstreamapi.UnknownMessageTypeError); ok {
				continue
			}
			r.err.SetError(err)
			return
		}

		select {
		case r.stream <- event.(EmptyEventStreamEvent):
		case <-r.done:
			return
		}
	}
}

type unmarshalerForEmptyEventStreamEvent struct {
	metadata protocol.ResponseMetadata
}

func (u unmarshalerForEmptyEventStreamEvent) UnmarshalerForEventName(eventType string) (eventstreamapi.Unmarshaler, error) {
	switch eventType {
	default:
		return &EmptyEventStreamUnknownEvent{Type: eventType}, nil
	}
}

// EmptyEventStreamUnknownEvent provides a failsafe event for the
// EmptyEventStream group of events when an unknown event is received.
type EmptyEventStreamUnknownEvent struct {
	Type    string
	Message eventstream.Message
}

// The EmptyEventStreamUnknownEvent is and event in the EmptyEventStream
// group of events.
func (s *EmptyEventStreamUnknownEvent) eventEmptyEventStream() {}

// MarshalEvent marshals the type into an stream event value. This method
// should only used internally within the SDK's EventStream handling.
func (e *EmptyEventStreamUnknownEvent) MarshalEvent(pm protocol.PayloadMarshaler) (
	msg eventstream.Message, err error,
) {
	return e.Message.Clone(), nil
}

// UnmarshalEvent unmarshals the EventStream Message into the EmptyEventStream value.
// This method is only used internally within the SDK's EventStream handling.
func (e *EmptyEventStreamUnknownEvent) UnmarshalEvent(
	payloadUnmarshaler protocol.PayloadUnmarshaler,
	msg eventstream.Message,
) error {
	e.Message = msg.Clone()
	return nil
}

type EmptyStreamInput struct {
	_ struct{} `locationName:"EmptyStreamRequest" type:"structure"`
}

// String returns the string representation
func (s EmptyStreamInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s EmptyStreamInput) GoString() string {
	return s.String()
}

type EmptyStreamOutput struct {
	_ struct{} `type:"structure"`

	eventStream *EmptyStreamEventStream
}

// String returns the string representation
func (s EmptyStreamOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s EmptyStreamOutput) GoString() string {
	return s.String()
}

// GetStream returns the type to interact with the event stream.
func (s *EmptyStreamOutput) GetStream() *EmptyStreamEventStream {
	return s.eventStream
}

// EventStreamEvent groups together all EventStream
// events writes for EventStream.
//
// These events are:
//
//     * EmptyEvent
//     * ExplicitPayloadEvent
//     * HeaderOnlyEvent
//     * ImplicitPayloadEvent
//     * PayloadOnlyEvent
//     * PayloadOnlyBlobEvent
//     * PayloadOnlyStringEvent
type EventStreamEvent interface {
	eventEventStream()
	eventstreamapi.Marshaler
	eventstreamapi.Unmarshaler
}

// EventStreamReader provides the interface for reading to the stream. The
// default implementation for this interface will be EventStream.
//
// The reader's Close method must allow multiple concurrent calls.
//
// These events are:
//
//     * EmptyEvent
//     * ExplicitPayloadEvent
//     * HeaderOnlyEvent
//     * ImplicitPayloadEvent
//     * PayloadOnlyEvent
//     * PayloadOnlyBlobEvent
//     * PayloadOnlyStringEvent
//     * EventStreamUnknownEvent
type EventStreamReader interface {
	// Returns a channel of events as they are read from the event stream.
	Events() <-chan EventStreamEvent

	// Close will stop the reader reading events from the stream.
	Close() error

	// Returns any error that has occurred while reading from the event stream.
	Err() error
}

type readEventStream struct {
	eventReader *eventstreamapi.EventReader
	stream      chan EventStreamEvent
	err         *eventstreamapi.OnceError

	done      chan struct{}
	closeOnce sync.Once
}

func newReadEventStream(eventReader *eventstreamapi.EventReader) *readEventStream {
	r := &readEventStream{
		eventReader: eventReader,
		stream:      make(chan EventStreamEvent),
		done:        make(chan struct{}),
		err:         eventstreamapi.NewOnceError(),
	}
	go r.readEventStream()

	return r
}

// Close will close the underlying event stream reader.
func (r *readEventStream) Close() error {
	r.closeOnce.Do(r.safeClose)
	return r.Err()
}

func (r *readEventStream) ErrorSet() <-chan struct{} {
	return r.err.ErrorSet()
}

func (r *readEventStream) Closed() <-chan struct{} {
	return r.done
}

func (r *readEventStream) safeClose() {
	close(r.done)
}

func (r *readEventStream) Err() error {
	return r.err.Err()
}

func (r *readEventStream) Events() <-chan EventStreamEvent {
	return r.stream
}

func (r *readEventStream) readEventStream() {
	defer r.Close()
	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:
			}
			if _, ok := err.(*eventstreamapi.UnknownMessageTypeError); ok {
				continue
			}
			r.err.SetError(err)
			return
		}

		select {
		case r.stream <- event.(EventStreamEvent):
		case <-r.done:
			return
		}
	}
}

type unmarshalerForEventStreamEvent struct {
	metadata protocol.ResponseMetadata
}

func (u unmarshalerForEventStreamEvent) UnmarshalerForEventName(eventType string) (eventstreamapi.Unmarshaler, error) {
	switch eventType {
	case "Empty":
		return &EmptyEvent{}, nil
	case "ExplicitPayload":
		return &ExplicitPayloadEvent{}, nil
	case "Headers":
		return &HeaderOnlyEvent{}, nil
	case "ImplicitPayload":
		return &ImplicitPayloadEvent{}, nil
	case "PayloadOnly":
		return &PayloadOnlyEvent{}, nil
	case "PayloadOnlyBlob":
		return &PayloadOnlyBlobEvent{}, nil
	case "PayloadOnlyString":
		return &PayloadOnlyStringEvent{}, nil
	case "Exception":
		return newErrorExceptionEvent(u.metadata).(eventstreamapi.Unmarshaler), nil
	case "Exception2":
		return newErrorExceptionEvent2(u.metadata).(eventstreamapi.Unmarshaler), nil
	default:
		return &EventStreamUnknownEvent{Type: eventType}, nil
	}
}

// EventStreamUnknownEvent provides a failsafe event for the
// EventStream group of events when an unknown event is received.
type EventStreamUnknownEvent struct {
	Type    string
	Message eventstream.Message
}

// The EventStreamUnknownEvent is and event in the EventStream
// group of events.
func (s *EventStreamUnknownEvent) eventEventStream() {}

// MarshalEvent marshals the type into an stream event value. This method
// should only used internally within the SDK's EventStream handling.
func (e *EventStreamUnknownEvent) MarshalEvent(pm protocol.PayloadMarshaler) (
	msg eventstream.Message, err error,
) {
	return e.Message.Clone(), nil
}

// UnmarshalEvent unmarshals the EventStream Message into the EventStream value.
// This method is only used internally within the SDK's EventStream handling.
func (e *EventStreamUnknownEvent) UnmarshalEvent(
	payloadUnmarshaler protocol.PayloadUnmarshaler,
	msg eventstream.Message,
) error {
	e.Message = msg.Clone()
	return nil
}

type ExceptionEvent struct {
	_            struct{}                  `locationName:"ExceptionEvent" type:"structure"`
	RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"`

	IntVal *int64 `type:"integer"`

	Message_ *string `locationName:"message" type:"string"`
}

// String returns the string representation
func (s ExceptionEvent) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s ExceptionEvent) GoString() string {
	return s.String()
}

// The ExceptionEvent is and event in the EventStream group of events.
func (s *ExceptionEvent) eventEventStream() {}

// UnmarshalEvent unmarshals the EventStream Message into the ExceptionEvent value.
// This method is only used internally within the SDK's EventStream handling.
func (s *ExceptionEvent) UnmarshalEvent(
	payloadUnmarshaler protocol.PayloadUnmarshaler,
	msg eventstream.Message,
) error {
	if err := payloadUnmarshaler.UnmarshalPayload(
		bytes.NewReader(msg.Payload), s,
	); err != nil {
		return err
	}
	return nil
}

// MarshalEvent marshals the type into an stream event value. This method
// should only used internally within the SDK's EventStream handling.
func (s *ExceptionEvent) MarshalEvent(pm protocol.PayloadMarshaler) (msg eventstream.Message, err error) {
	msg.Headers.Set(eventstreamapi.MessageTypeHeader, eventstream.StringValue(eventstreamapi.ExceptionMessageType))
	var buf bytes.Buffer
	if err = pm.MarshalPayload(&buf, s); err != nil {
		return eventstream.Message{}, err
	}
	msg.Payload = buf.Bytes()
	return msg, err
}

func newErrorExceptionEvent(v protocol.ResponseMetadata) error {
	return &ExceptionEvent{
		RespMetadata: v,
	}
}

// Code returns the exception type name.
func (s *ExceptionEvent) Code() string {
	return "ExceptionEvent"
}

// Message returns the exception's message.
func (s *ExceptionEvent) Message() string {
	if s.Message_ != nil {
		return *s.Message_
	}
	return ""
}

// OrigErr always returns nil, satisfies awserr.Error interface.
func (s *ExceptionEvent) OrigErr() error {
	return nil
}

func (s *ExceptionEvent) Error() string {
	return fmt.Sprintf("%s: %s\n%s", s.Code(), s.Message(), s.String())
}

// Status code returns the HTTP status code for the request's response error.
func (s *ExceptionEvent) StatusCode() int {
	return s.RespMetadata.StatusCode
}

// RequestID returns the service's response RequestID for request.
func (s *ExceptionEvent) RequestID() string {
	return s.RespMetadata.RequestID
}

type ExceptionEvent2 struct {
	_            struct{}                  `locationName:"ExceptionEvent2" type:"structure"`
	RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"`

	Message_ *string `locationName:"Message" type:"string"`
}

// String returns the string representation
func (s ExceptionEvent2) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s ExceptionEvent2) GoString() string {
	return s.String()
}

// The ExceptionEvent2 is and event in the EventStream group of events.
func (s *ExceptionEvent2) eventEventStream() {}

// UnmarshalEvent unmarshals the EventStream Message into the ExceptionEvent2 value.
// This method is only used internally within the SDK's EventStream handling.
func (s *ExceptionEvent2) UnmarshalEvent(
	payloadUnmarshaler protocol.PayloadUnmarshaler,
	msg eventstream.Message,
) error {
	if err := payloadUnmarshaler.UnmarshalPayload(
		bytes.NewReader(msg.Payload), s,
	); err != nil {
		return err
	}
	return nil
}

// MarshalEvent marshals the type into an stream event value. This method
// should only used internally within the SDK's EventStream handling.
func (s *ExceptionEvent2) MarshalEvent(pm protocol.PayloadMarshaler) (msg eventstream.Message, err error) {
	msg.Headers.Set(eventstreamapi.MessageTypeHeader, eventstream.StringValue(eventstreamapi.ExceptionMessageType))
	var buf bytes.Buffer
	if err = pm.MarshalPayload(&buf, s); err != nil {
		return eventstream.Message{}, err
	}
	msg.Payload = buf.Bytes()
	return msg, err
}

func newErrorExceptionEvent2(v protocol.ResponseMetadata) error {
	return &ExceptionEvent2{
		RespMetadata: v,
	}
}

// Code returns the exception type name.
func (s *ExceptionEvent2) Code() string {
	return "ExceptionEvent2"
}

// Message returns the exception's message.
func (s *ExceptionEvent2) Message() string {
	if s.Message_ != nil {
		return *s.Message_
	}
	return ""
}

// OrigErr always returns nil, satisfies awserr.Error interface.
func (s *ExceptionEvent2) OrigErr() error {
	return nil
}

func (s *ExceptionEvent2) Error() string {
	return fmt.Sprintf("%s: %s", s.Code(), s.Message())
}

// Status code returns the HTTP status code for the request's response error.
func (s *ExceptionEvent2) StatusCode() int {
	return s.RespMetadata.StatusCode
}

// RequestID returns the service's response RequestID for request.
func (s *ExceptionEvent2) RequestID() string {
	return s.RespMetadata.RequestID
}

type ExplicitPayloadEvent struct {
	_ struct{} `locationName:"ExplicitPayloadEvent" type:"structure" payload:"NestedVal"`

	LongVal *int64 `location:"header" type:"long"`

	NestedVal *NestedShape `locationName:"NestedVal" type:"structure"`

	StringVal *string `location:"header" type:"string"`
}

// String returns the string representation
func (s ExplicitPayloadEvent) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s ExplicitPayloadEvent) GoString() string {
	return s.String()
}

// SetLongVal sets the LongVal field's value.
func (s *ExplicitPayloadEvent) SetLongVal(v int64) *ExplicitPayloadEvent {
	s.LongVal = &v
	return s
}

// SetNestedVal sets the NestedVal field's value.
func (s *ExplicitPayloadEvent) SetNestedVal(v *NestedShape) *ExplicitPayloadEvent {
	s.NestedVal = v
	return s
}

// SetStringVal sets the StringVal field's value.
func (s *ExplicitPayloadEvent) SetStringVal(v string) *ExplicitPayloadEvent {
	s.StringVal = &v
	return s
}

// The ExplicitPayloadEvent is and event in the EventStream group of events.
func (s *ExplicitPayloadEvent) eventEventStream() {}

// UnmarshalEvent unmarshals the EventStream Message into the ExplicitPayloadEvent value.
// This method is only used internally within the SDK's EventStream handling.
func (s *ExplicitPayloadEvent) UnmarshalEvent(
	payloadUnmarshaler protocol.PayloadUnmarshaler,
	msg eventstream.Message,
) error {
	if hv := msg.Headers.Get("LongVal"); hv != nil {
		v := hv.Get().(int64)
		s.LongVal = &v
	}
	if hv := msg.Headers.Get("StringVal"); hv != nil {
		v := hv.Get().(string)
		s.StringVal = &v
	}
	if err := payloadUnmarshaler.UnmarshalPayload(
		bytes.NewReader(msg.Payload), s,
	); err != nil {
		return err
	}
	return nil
}

// MarshalEvent marshals the type into an stream event value. This method
// should only used internally within the SDK's EventStream handling.
func (s *ExplicitPayloadEvent) MarshalEvent(pm protocol.PayloadMarshaler) (msg eventstream.Message, err error) {
	msg.Headers.Set(eventstreamapi.MessageTypeHeader, eventstream.StringValue(eventstreamapi.EventMessageType))
	msg.Headers.Set("LongVal", eventstream.Int64Value(*s.LongVal))
	msg.Headers.Set("StringVal", eventstream.StringValue(*s.StringVal))
	var buf bytes.Buffer
	if err = pm.MarshalPayload(&buf, s); err != nil {
		return eventstream.Message{}, err
	}
	msg.Payload = buf.Bytes()
	return msg, err
}

type GetEventStreamInput struct {
	_ struct{} `locationName:"GetEventStreamRequest" type:"structure"`

	InputVal *string `type:"string"`
}

// String returns the string representation
func (s GetEventStreamInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s GetEventStreamInput) GoString() string {
	return s.String()
}

// SetInputVal sets the InputVal field's value.
func (s *GetEventStreamInput) SetInputVal(v string) *GetEventStreamInput {
	s.InputVal = &v
	return s
}

type GetEventStreamOutput struct {
	_ struct{} `type:"structure"`

	eventStream *GetEventStreamEventStream

	IntVal *int64 `type:"integer"`

	StrVal *string `type:"string"`
}

// String returns the string representation
func (s GetEventStreamOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s GetEventStreamOutput) GoString() string {
	return s.String()
}

// SetIntVal sets the IntVal field's value.
func (s *GetEventStreamOutput) SetIntVal(v int64) *GetEventStreamOutput {
	s.IntVal = &v
	return s
}

// SetStrVal sets the StrVal field's value.
func (s *GetEventStreamOutput) SetStrVal(v string) *GetEventStreamOutput {
	s.StrVal = &v
	return s
}

// GetStream returns the type to interact with the event stream.
func (s *GetEventStreamOutput) GetStream() *GetEventStreamEventStream {
	return s.eventStream
}

type HeaderOnlyEvent struct {
	_ struct{} `locationName:"HeaderOnlyEvent" type:"structure"`

	// BlobVal is automatically base64 encoded/decoded by the SDK.
	BlobVal []byte `location:"header" type:"blob"`

	BoolVal *bool `location:"header" type:"boolean"`

	ByteVal *int64 `location:"header" type:"byte"`

	IntegerVal *int64 `location:"header" type:"integer"`

	LongVal *int64 `location:"header" type:"long"`

	ShortVal *int64 `location:"header" type:"short"`

	StringVal *string `location:"header" type:"string"`

	TimeVal *time.Time `location:"header" type:"timestamp"`
}

// String returns the string representation
func (s HeaderOnlyEvent) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s HeaderOnlyEvent) GoString() string {
	return s.String()
}

// SetBlobVal sets the BlobVal field's value.
func (s *HeaderOnlyEvent) SetBlobVal(v []byte) *HeaderOnlyEvent {
	s.BlobVal = v
	return s
}

// SetBoolVal sets the BoolVal field's value.
func (s *HeaderOnlyEvent) SetBoolVal(v bool) *HeaderOnlyEvent {
	s.BoolVal = &v
	return s
}

// SetByteVal sets the ByteVal field's value.
func (s *HeaderOnlyEvent) SetByteVal(v int64) *HeaderOnlyEvent {
	s.ByteVal = &v
	return s
}

// SetIntegerVal sets the IntegerVal field's value.
func (s *HeaderOnlyEvent) SetIntegerVal(v int64) *HeaderOnlyEvent {
	s.IntegerVal = &v
	return s
}

// SetLongVal sets the LongVal field's value.
func (s *HeaderOnlyEvent) SetLongVal(v int64) *HeaderOnlyEvent {
	s.LongVal = &v
	return s
}

// SetShortVal sets the ShortVal field's value.
func (s *HeaderOnlyEvent) SetShortVal(v int64) *HeaderOnlyEvent {
	s.ShortVal = &v
	return s
}

// SetStringVal sets the StringVal field's value.
func (s *HeaderOnlyEvent) SetStringVal(v string) *HeaderOnlyEvent {
	s.StringVal = &v
	return s
}

// SetTimeVal sets the TimeVal field's value.
func (s *HeaderOnlyEvent) SetTimeVal(v time.Time) *HeaderOnlyEvent {
	s.TimeVal = &v
	return s
}

// The HeaderOnlyEvent is and event in the EventStream group of events.
func (s *HeaderOnlyEvent) eventEventStream() {}

// UnmarshalEvent unmarshals the EventStream Message into the HeaderOnlyEvent value.
// This method is only used internally within the SDK's EventStream handling.
func (s *HeaderOnlyEvent) UnmarshalEvent(
	payloadUnmarshaler protocol.PayloadUnmarshaler,
	msg eventstream.Message,
) error {
	if hv := msg.Headers.Get("BlobVal"); hv != nil {
		v := hv.Get().([]byte)
		s.BlobVal = v
	}
	if hv := msg.Headers.Get("BoolVal"); hv != nil {
		v := hv.Get().(bool)
		s.BoolVal = &v
	}
	if hv := msg.Headers.Get("ByteVal"); hv != nil {
		v := hv.Get().(int8)
		m := int64(v)
		s.ByteVal = &m
	}
	if hv := msg.Headers.Get("IntegerVal"); hv != nil {
		v := hv.Get().(int32)
		m := int64(v)
		s.IntegerVal = &m
	}
	if hv := msg.Headers.Get("LongVal"); hv != nil {
		v := hv.Get().(int64)
		s.LongVal = &v
	}
	if hv := msg.Headers.Get("ShortVal"); hv != nil {
		v := hv.Get().(int16)
		m := int64(v)
		s.ShortVal = &m
	}
	if hv := msg.Headers.Get("StringVal"); hv != nil {
		v := hv.Get().(string)
		s.StringVal = &v
	}
	if hv := msg.Headers.Get("TimeVal"); hv != nil {
		v := hv.Get().(time.Time)
		s.TimeVal = &v
	}
	return nil
}

// MarshalEvent marshals the type into an stream event value. This method
// should only used internally within the SDK's EventStream handling.
func (s *HeaderOnlyEvent) MarshalEvent(pm protocol.PayloadMarshaler) (msg eventstream.Message, err error) {
	msg.Headers.Set(eventstreamapi.MessageTypeHeader, eventstream.StringValue(eventstreamapi.EventMessageType))
	msg.Headers.Set("BlobVal", eventstream.BytesValue(s.BlobVal))
	msg.Headers.Set("BoolVal", eventstream.BoolValue(*s.BoolVal))
	msg.Headers.Set("ByteVal", eventstream.Int8Value(int8(*s.ByteVal)))
	msg.Headers.Set("IntegerVal", eventstream.Int32Value(int32(*s.IntegerVal)))
	msg.Headers.Set("LongVal", eventstream.Int64Value(*s.LongVal))
	msg.Headers.Set("ShortVal", eventstream.Int16Value(int16(*s.ShortVal)))
	msg.Headers.Set("StringVal", eventstream.StringValue(*s.StringVal))
	msg.Headers.Set("TimeVal", eventstream.TimestampValue(*s.TimeVal))
	return msg, err
}

type ImplicitPayloadEvent struct {
	_ struct{} `locationName:"ImplicitPayloadEvent" type:"structure"`

	ByteVal *int64 `location:"header" type:"byte"`

	IntegerVal *int64 `type:"integer"`

	ShortVal *int64 `type:"short"`
}

// String returns the string representation
func (s ImplicitPayloadEvent) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s ImplicitPayloadEvent) GoString() string {
	return s.String()
}

// SetByteVal sets the ByteVal field's value.
func (s *ImplicitPayloadEvent) SetByteVal(v int64) *ImplicitPayloadEvent {
	s.ByteVal = &v
	return s
}

// SetIntegerVal sets the IntegerVal field's value.
func (s *ImplicitPayloadEvent) SetIntegerVal(v int64) *ImplicitPayloadEvent {
	s.IntegerVal = &v
	return s
}

// SetShortVal sets the ShortVal field's value.
func (s *ImplicitPayloadEvent) SetShortVal(v int64) *ImplicitPayloadEvent {
	s.ShortVal = &v
	return s
}

// The ImplicitPayloadEvent is and event in the EventStream group of events.
func (s *ImplicitPayloadEvent) eventEventStream() {}

// UnmarshalEvent unmarshals the EventStream Message into the ImplicitPayloadEvent value.
// This method is only used internally within the SDK's EventStream handling.
func (s *ImplicitPayloadEvent) UnmarshalEvent(
	payloadUnmarshaler protocol.PayloadUnmarshaler,
	msg eventstream.Message,
) error {
	if hv := msg.Headers.Get("ByteVal"); hv != nil {
		v := hv.Get().(int8)
		m := int64(v)
		s.ByteVal = &m
	}
	if err := payloadUnmarshaler.UnmarshalPayload(
		bytes.NewReader(msg.Payload), s,
	); err != nil {
		return err
	}
	return nil
}

// MarshalEvent marshals the type into an stream event value. This method
// should only used internally within the SDK's EventStream handling.
func (s *ImplicitPayloadEvent) MarshalEvent(pm protocol.PayloadMarshaler) (msg eventstream.Message, err error) {
	msg.Headers.Set(eventstreamapi.MessageTypeHeader, eventstream.StringValue(eventstreamapi.EventMessageType))
	msg.Headers.Set("ByteVal", eventstream.Int8Value(int8(*s.ByteVal)))
	var buf bytes.Buffer
	if err = pm.MarshalPayload(&buf, s); err != nil {
		return eventstream.Message{}, err
	}
	msg.Payload = buf.Bytes()
	return msg, err
}

type NestedShape struct {
	_ struct{} `type:"structure"`

	IntVal *int64 `type:"integer"`

	StrVal *string `type:"string"`
}

// String returns the string representation
func (s NestedShape) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s NestedShape) GoString() string {
	return s.String()
}

// SetIntVal sets the IntVal field's value.
func (s *NestedShape) SetIntVal(v int64) *NestedShape {
	s.IntVal = &v
	return s
}

// SetStrVal sets the StrVal field's value.
func (s *NestedShape) SetStrVal(v string) *NestedShape {
	s.StrVal = &v
	return s
}

type OtherOperationInput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s OtherOperationInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s OtherOperationInput) GoString() string {
	return s.String()
}

type OtherOperationOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s OtherOperationOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s OtherOperationOutput) GoString() string {
	return s.String()
}

type PayloadOnlyBlobEvent struct {
	_ struct{} `locationName:"PayloadOnlyBlobEvent" type:"structure" payload:"BlobPayload"`

	// BlobPayload is automatically base64 encoded/decoded by the SDK.
	BlobPayload []byte `type:"blob"`
}

// String returns the string representation
func (s PayloadOnlyBlobEvent) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s PayloadOnlyBlobEvent) GoString() string {
	return s.String()
}

// SetBlobPayload sets the BlobPayload field's value.
func (s *PayloadOnlyBlobEvent) SetBlobPayload(v []byte) *PayloadOnlyBlobEvent {
	s.BlobPayload = v
	return s
}

// The PayloadOnlyBlobEvent is and event in the EventStream group of events.
func (s *PayloadOnlyBlobEvent) eventEventStream() {}

// UnmarshalEvent unmarshals the EventStream Message into the PayloadOnlyBlobEvent value.
// This method is only used internally within the SDK's EventStream handling.
func (s *PayloadOnlyBlobEvent) UnmarshalEvent(
	payloadUnmarshaler protocol.PayloadUnmarshaler,
	msg eventstream.Message,
) error {
	s.BlobPayload = make([]byte, len(msg.Payload))
	copy(s.BlobPayload, msg.Payload)
	return nil
}

// MarshalEvent marshals the type into an stream event value. This method
// should only used internally within the SDK's EventStream handling.
func (s *PayloadOnlyBlobEvent) MarshalEvent(pm protocol.PayloadMarshaler) (msg eventstream.Message, err error) {
	msg.Headers.Set(eventstreamapi.MessageTypeHeader, eventstream.StringValue(eventstreamapi.EventMessageType))
	msg.Headers.Set(":content-type", eventstream.StringValue("application/octet-stream"))
	msg.Payload = s.BlobPayload
	return msg, err
}

type PayloadOnlyEvent struct {
	_ struct{} `locationName:"PayloadOnlyEvent" type:"structure" payload:"NestedVal"`

	NestedVal *NestedShape `locationName:"NestedVal" type:"structure"`
}

// String returns the string representation
func (s PayloadOnlyEvent) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s PayloadOnlyEvent) GoString() string {
	return s.String()
}

// SetNestedVal sets the NestedVal field's value.
func (s *PayloadOnlyEvent) SetNestedVal(v *NestedShape) *PayloadOnlyEvent {
	s.NestedVal = v
	return s
}

// The PayloadOnlyEvent is and event in the EventStream group of events.
func (s *PayloadOnlyEvent) eventEventStream() {}

// UnmarshalEvent unmarshals the EventStream Message into the PayloadOnlyEvent value.
// This method is only used internally within the SDK's EventStream handling.
func (s *PayloadOnlyEvent) UnmarshalEvent(
	payloadUnmarshaler protocol.PayloadUnmarshaler,
	msg eventstream.Message,
) error {
	if err := payloadUnmarshaler.UnmarshalPayload(
		bytes.NewReader(msg.Payload), s,
	); err != nil {
		return err
	}
	return nil
}

// MarshalEvent marshals the type into an stream event value. This method
// should only used internally within the SDK's EventStream handling.
func (s *PayloadOnlyEvent) MarshalEvent(pm protocol.PayloadMarshaler) (msg eventstream.Message, err error) {
	msg.Headers.Set(eventstreamapi.MessageTypeHeader, eventstream.StringValue(eventstreamapi.EventMessageType))
	var buf bytes.Buffer
	if err = pm.MarshalPayload(&buf, s); err != nil {
		return eventstream.Message{}, err
	}
	msg.Payload = buf.Bytes()
	return msg, err
}

type PayloadOnlyStringEvent struct {
	_ struct{} `locationName:"PayloadOnlyStringEvent" type:"structure" payload:"StringPayload"`

	StringPayload *string `locationName:"StringPayload" type:"string"`
}

// String returns the string representation
func (s PayloadOnlyStringEvent) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s PayloadOnlyStringEvent) GoString() string {
	return s.String()
}

// SetStringPayload sets the StringPayload field's value.
func (s *PayloadOnlyStringEvent) SetStringPayload(v string) *PayloadOnlyStringEvent {
	s.StringPayload = &v
	return s
}

// The PayloadOnlyStringEvent is and event in the EventStream group of events.
func (s *PayloadOnlyStringEvent) eventEventStream() {}

// UnmarshalEvent unmarshals the EventStream Message into the PayloadOnlyStringEvent value.
// This method is only used internally within the SDK's EventStream handling.
func (s *PayloadOnlyStringEvent) UnmarshalEvent(
	payloadUnmarshaler protocol.PayloadUnmarshaler,
	msg eventstream.Message,
) error {
	s.StringPayload = aws.String(string(msg.Payload))
	return nil
}

// MarshalEvent marshals the type into an stream event value. This method
// should only used internally within the SDK's EventStream handling.
func (s *PayloadOnlyStringEvent) MarshalEvent(pm protocol.PayloadMarshaler) (msg eventstream.Message, err error) {
	msg.Headers.Set(eventstreamapi.MessageTypeHeader, eventstream.StringValue(eventstreamapi.EventMessageType))
	msg.Payload = []byte(aws.StringValue(s.StringPayload))
	return msg, err
}
