// Code generated by protoc-gen-twirp v7.1.0, DO NOT EDIT.
// source: status.proto

/*
Package rpc is a generated twirp stub package.
This code was generated with github.com/twitchtv/twirp/protoc-gen-twirp v7.1.0.

It is generated from these files:
	status.proto
*/
package rpc

import (
	bytes "bytes"
	strings "strings"

	context "context"

	fmt "fmt"

	ioutil "io/ioutil"

	http "net/http"

	strconv "strconv"

	jsonpb "github.com/golang/protobuf/jsonpb"

	proto "github.com/golang/protobuf/proto"

	twirp "github.com/twitchtv/twirp"

	ctxsetters "github.com/twitchtv/twirp/ctxsetters"

	// Imports only used by utility functions:

	io "io"

	json "encoding/json"

	path "path"

	url "net/url"
)

// This is a compile-time assertion to ensure that this generated file
// is compatible with the twirp package used in your project.
// A compilation error at this line likely means your copy of the
// twirp package needs to be updated.
const _ = twirp.TwirpPackageIsVersion7

// =======================
// StatusService Interface
// =======================

// API (non-page, non-resource) endpoints for Status.
type StatusService interface {
	// Method to get updates to the lists of recent commits, their tasks, etc.
	GetIncrementalCommits(context.Context, *GetIncrementalCommitsRequest) (*GetIncrementalCommitsResponse, error)

	// Method to add a comment to a task, commit, or task spec.
	AddComment(context.Context, *AddCommentRequest) (*AddCommentResponse, error)

	// Method to delete a comment to a task, commit, or task spec.
	DeleteComment(context.Context, *DeleteCommentRequest) (*DeleteCommentResponse, error)

	// Method to get latest status of various autorollers.
	GetAutorollerStatuses(context.Context, *GetAutorollerStatusesRequest) (*GetAutorollerStatusesResponse, error)

	// Method to get latest bot usage / capacity metrics.
	GetBotUsage(context.Context, *GetBotUsageRequest) (*GetBotUsageResponse, error)
}

// =============================
// StatusService Protobuf Client
// =============================

type statusServiceProtobufClient struct {
	client      HTTPClient
	urls        [5]string
	interceptor twirp.Interceptor
	opts        twirp.ClientOptions
}

// NewStatusServiceProtobufClient creates a Protobuf client that implements the StatusService interface.
// It communicates using Protobuf and can be configured with a custom HTTPClient.
func NewStatusServiceProtobufClient(baseURL string, client HTTPClient, opts ...twirp.ClientOption) StatusService {
	if c, ok := client.(*http.Client); ok {
		client = withoutRedirects(c)
	}

	clientOpts := twirp.ClientOptions{}
	for _, o := range opts {
		o(&clientOpts)
	}

	// Build method URLs: <baseURL>[<prefix>]/<package>.<Service>/<Method>
	serviceURL := sanitizeBaseURL(baseURL)
	serviceURL += baseServicePath(clientOpts.PathPrefix(), "status", "StatusService")
	urls := [5]string{
		serviceURL + "GetIncrementalCommits",
		serviceURL + "AddComment",
		serviceURL + "DeleteComment",
		serviceURL + "GetAutorollerStatuses",
		serviceURL + "GetBotUsage",
	}

	return &statusServiceProtobufClient{
		client:      client,
		urls:        urls,
		interceptor: twirp.ChainInterceptors(clientOpts.Interceptors...),
		opts:        clientOpts,
	}
}

func (c *statusServiceProtobufClient) GetIncrementalCommits(ctx context.Context, in *GetIncrementalCommitsRequest) (*GetIncrementalCommitsResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "status")
	ctx = ctxsetters.WithServiceName(ctx, "StatusService")
	ctx = ctxsetters.WithMethodName(ctx, "GetIncrementalCommits")
	caller := c.callGetIncrementalCommits
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *GetIncrementalCommitsRequest) (*GetIncrementalCommitsResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*GetIncrementalCommitsRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*GetIncrementalCommitsRequest) when calling interceptor")
					}
					return c.callGetIncrementalCommits(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*GetIncrementalCommitsResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*GetIncrementalCommitsResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *statusServiceProtobufClient) callGetIncrementalCommits(ctx context.Context, in *GetIncrementalCommitsRequest) (*GetIncrementalCommitsResponse, error) {
	out := new(GetIncrementalCommitsResponse)
	ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[0], in, out)
	if err != nil {
		twerr, ok := err.(twirp.Error)
		if !ok {
			twerr = twirp.InternalErrorWith(err)
		}
		callClientError(ctx, c.opts.Hooks, twerr)
		return nil, err
	}

	callClientResponseReceived(ctx, c.opts.Hooks)

	return out, nil
}

func (c *statusServiceProtobufClient) AddComment(ctx context.Context, in *AddCommentRequest) (*AddCommentResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "status")
	ctx = ctxsetters.WithServiceName(ctx, "StatusService")
	ctx = ctxsetters.WithMethodName(ctx, "AddComment")
	caller := c.callAddComment
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *AddCommentRequest) (*AddCommentResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*AddCommentRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*AddCommentRequest) when calling interceptor")
					}
					return c.callAddComment(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*AddCommentResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*AddCommentResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *statusServiceProtobufClient) callAddComment(ctx context.Context, in *AddCommentRequest) (*AddCommentResponse, error) {
	out := new(AddCommentResponse)
	ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[1], in, out)
	if err != nil {
		twerr, ok := err.(twirp.Error)
		if !ok {
			twerr = twirp.InternalErrorWith(err)
		}
		callClientError(ctx, c.opts.Hooks, twerr)
		return nil, err
	}

	callClientResponseReceived(ctx, c.opts.Hooks)

	return out, nil
}

func (c *statusServiceProtobufClient) DeleteComment(ctx context.Context, in *DeleteCommentRequest) (*DeleteCommentResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "status")
	ctx = ctxsetters.WithServiceName(ctx, "StatusService")
	ctx = ctxsetters.WithMethodName(ctx, "DeleteComment")
	caller := c.callDeleteComment
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *DeleteCommentRequest) (*DeleteCommentResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*DeleteCommentRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*DeleteCommentRequest) when calling interceptor")
					}
					return c.callDeleteComment(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*DeleteCommentResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*DeleteCommentResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *statusServiceProtobufClient) callDeleteComment(ctx context.Context, in *DeleteCommentRequest) (*DeleteCommentResponse, error) {
	out := new(DeleteCommentResponse)
	ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[2], in, out)
	if err != nil {
		twerr, ok := err.(twirp.Error)
		if !ok {
			twerr = twirp.InternalErrorWith(err)
		}
		callClientError(ctx, c.opts.Hooks, twerr)
		return nil, err
	}

	callClientResponseReceived(ctx, c.opts.Hooks)

	return out, nil
}

func (c *statusServiceProtobufClient) GetAutorollerStatuses(ctx context.Context, in *GetAutorollerStatusesRequest) (*GetAutorollerStatusesResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "status")
	ctx = ctxsetters.WithServiceName(ctx, "StatusService")
	ctx = ctxsetters.WithMethodName(ctx, "GetAutorollerStatuses")
	caller := c.callGetAutorollerStatuses
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *GetAutorollerStatusesRequest) (*GetAutorollerStatusesResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*GetAutorollerStatusesRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*GetAutorollerStatusesRequest) when calling interceptor")
					}
					return c.callGetAutorollerStatuses(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*GetAutorollerStatusesResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*GetAutorollerStatusesResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *statusServiceProtobufClient) callGetAutorollerStatuses(ctx context.Context, in *GetAutorollerStatusesRequest) (*GetAutorollerStatusesResponse, error) {
	out := new(GetAutorollerStatusesResponse)
	ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[3], in, out)
	if err != nil {
		twerr, ok := err.(twirp.Error)
		if !ok {
			twerr = twirp.InternalErrorWith(err)
		}
		callClientError(ctx, c.opts.Hooks, twerr)
		return nil, err
	}

	callClientResponseReceived(ctx, c.opts.Hooks)

	return out, nil
}

func (c *statusServiceProtobufClient) GetBotUsage(ctx context.Context, in *GetBotUsageRequest) (*GetBotUsageResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "status")
	ctx = ctxsetters.WithServiceName(ctx, "StatusService")
	ctx = ctxsetters.WithMethodName(ctx, "GetBotUsage")
	caller := c.callGetBotUsage
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *GetBotUsageRequest) (*GetBotUsageResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*GetBotUsageRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*GetBotUsageRequest) when calling interceptor")
					}
					return c.callGetBotUsage(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*GetBotUsageResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*GetBotUsageResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *statusServiceProtobufClient) callGetBotUsage(ctx context.Context, in *GetBotUsageRequest) (*GetBotUsageResponse, error) {
	out := new(GetBotUsageResponse)
	ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[4], in, out)
	if err != nil {
		twerr, ok := err.(twirp.Error)
		if !ok {
			twerr = twirp.InternalErrorWith(err)
		}
		callClientError(ctx, c.opts.Hooks, twerr)
		return nil, err
	}

	callClientResponseReceived(ctx, c.opts.Hooks)

	return out, nil
}

// =========================
// StatusService JSON Client
// =========================

type statusServiceJSONClient struct {
	client      HTTPClient
	urls        [5]string
	interceptor twirp.Interceptor
	opts        twirp.ClientOptions
}

// NewStatusServiceJSONClient creates a JSON client that implements the StatusService interface.
// It communicates using JSON and can be configured with a custom HTTPClient.
func NewStatusServiceJSONClient(baseURL string, client HTTPClient, opts ...twirp.ClientOption) StatusService {
	if c, ok := client.(*http.Client); ok {
		client = withoutRedirects(c)
	}

	clientOpts := twirp.ClientOptions{}
	for _, o := range opts {
		o(&clientOpts)
	}

	// Build method URLs: <baseURL>[<prefix>]/<package>.<Service>/<Method>
	serviceURL := sanitizeBaseURL(baseURL)
	serviceURL += baseServicePath(clientOpts.PathPrefix(), "status", "StatusService")
	urls := [5]string{
		serviceURL + "GetIncrementalCommits",
		serviceURL + "AddComment",
		serviceURL + "DeleteComment",
		serviceURL + "GetAutorollerStatuses",
		serviceURL + "GetBotUsage",
	}

	return &statusServiceJSONClient{
		client:      client,
		urls:        urls,
		interceptor: twirp.ChainInterceptors(clientOpts.Interceptors...),
		opts:        clientOpts,
	}
}

func (c *statusServiceJSONClient) GetIncrementalCommits(ctx context.Context, in *GetIncrementalCommitsRequest) (*GetIncrementalCommitsResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "status")
	ctx = ctxsetters.WithServiceName(ctx, "StatusService")
	ctx = ctxsetters.WithMethodName(ctx, "GetIncrementalCommits")
	caller := c.callGetIncrementalCommits
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *GetIncrementalCommitsRequest) (*GetIncrementalCommitsResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*GetIncrementalCommitsRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*GetIncrementalCommitsRequest) when calling interceptor")
					}
					return c.callGetIncrementalCommits(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*GetIncrementalCommitsResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*GetIncrementalCommitsResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *statusServiceJSONClient) callGetIncrementalCommits(ctx context.Context, in *GetIncrementalCommitsRequest) (*GetIncrementalCommitsResponse, error) {
	out := new(GetIncrementalCommitsResponse)
	ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[0], in, out)
	if err != nil {
		twerr, ok := err.(twirp.Error)
		if !ok {
			twerr = twirp.InternalErrorWith(err)
		}
		callClientError(ctx, c.opts.Hooks, twerr)
		return nil, err
	}

	callClientResponseReceived(ctx, c.opts.Hooks)

	return out, nil
}

func (c *statusServiceJSONClient) AddComment(ctx context.Context, in *AddCommentRequest) (*AddCommentResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "status")
	ctx = ctxsetters.WithServiceName(ctx, "StatusService")
	ctx = ctxsetters.WithMethodName(ctx, "AddComment")
	caller := c.callAddComment
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *AddCommentRequest) (*AddCommentResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*AddCommentRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*AddCommentRequest) when calling interceptor")
					}
					return c.callAddComment(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*AddCommentResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*AddCommentResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *statusServiceJSONClient) callAddComment(ctx context.Context, in *AddCommentRequest) (*AddCommentResponse, error) {
	out := new(AddCommentResponse)
	ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[1], in, out)
	if err != nil {
		twerr, ok := err.(twirp.Error)
		if !ok {
			twerr = twirp.InternalErrorWith(err)
		}
		callClientError(ctx, c.opts.Hooks, twerr)
		return nil, err
	}

	callClientResponseReceived(ctx, c.opts.Hooks)

	return out, nil
}

func (c *statusServiceJSONClient) DeleteComment(ctx context.Context, in *DeleteCommentRequest) (*DeleteCommentResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "status")
	ctx = ctxsetters.WithServiceName(ctx, "StatusService")
	ctx = ctxsetters.WithMethodName(ctx, "DeleteComment")
	caller := c.callDeleteComment
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *DeleteCommentRequest) (*DeleteCommentResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*DeleteCommentRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*DeleteCommentRequest) when calling interceptor")
					}
					return c.callDeleteComment(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*DeleteCommentResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*DeleteCommentResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *statusServiceJSONClient) callDeleteComment(ctx context.Context, in *DeleteCommentRequest) (*DeleteCommentResponse, error) {
	out := new(DeleteCommentResponse)
	ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[2], in, out)
	if err != nil {
		twerr, ok := err.(twirp.Error)
		if !ok {
			twerr = twirp.InternalErrorWith(err)
		}
		callClientError(ctx, c.opts.Hooks, twerr)
		return nil, err
	}

	callClientResponseReceived(ctx, c.opts.Hooks)

	return out, nil
}

func (c *statusServiceJSONClient) GetAutorollerStatuses(ctx context.Context, in *GetAutorollerStatusesRequest) (*GetAutorollerStatusesResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "status")
	ctx = ctxsetters.WithServiceName(ctx, "StatusService")
	ctx = ctxsetters.WithMethodName(ctx, "GetAutorollerStatuses")
	caller := c.callGetAutorollerStatuses
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *GetAutorollerStatusesRequest) (*GetAutorollerStatusesResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*GetAutorollerStatusesRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*GetAutorollerStatusesRequest) when calling interceptor")
					}
					return c.callGetAutorollerStatuses(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*GetAutorollerStatusesResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*GetAutorollerStatusesResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *statusServiceJSONClient) callGetAutorollerStatuses(ctx context.Context, in *GetAutorollerStatusesRequest) (*GetAutorollerStatusesResponse, error) {
	out := new(GetAutorollerStatusesResponse)
	ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[3], in, out)
	if err != nil {
		twerr, ok := err.(twirp.Error)
		if !ok {
			twerr = twirp.InternalErrorWith(err)
		}
		callClientError(ctx, c.opts.Hooks, twerr)
		return nil, err
	}

	callClientResponseReceived(ctx, c.opts.Hooks)

	return out, nil
}

func (c *statusServiceJSONClient) GetBotUsage(ctx context.Context, in *GetBotUsageRequest) (*GetBotUsageResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "status")
	ctx = ctxsetters.WithServiceName(ctx, "StatusService")
	ctx = ctxsetters.WithMethodName(ctx, "GetBotUsage")
	caller := c.callGetBotUsage
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *GetBotUsageRequest) (*GetBotUsageResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*GetBotUsageRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*GetBotUsageRequest) when calling interceptor")
					}
					return c.callGetBotUsage(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*GetBotUsageResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*GetBotUsageResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *statusServiceJSONClient) callGetBotUsage(ctx context.Context, in *GetBotUsageRequest) (*GetBotUsageResponse, error) {
	out := new(GetBotUsageResponse)
	ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[4], in, out)
	if err != nil {
		twerr, ok := err.(twirp.Error)
		if !ok {
			twerr = twirp.InternalErrorWith(err)
		}
		callClientError(ctx, c.opts.Hooks, twerr)
		return nil, err
	}

	callClientResponseReceived(ctx, c.opts.Hooks)

	return out, nil
}

// ============================
// StatusService Server Handler
// ============================

type statusServiceServer struct {
	StatusService
	interceptor      twirp.Interceptor
	hooks            *twirp.ServerHooks
	pathPrefix       string // prefix for routing
	jsonSkipDefaults bool   // do not include unpopulated fields (default values) in the response
}

// NewStatusServiceServer builds a TwirpServer that can be used as an http.Handler to handle
// HTTP requests that are routed to the right method in the provided svc implementation.
// The opts are twirp.ServerOption modifiers, for example twirp.WithServerHooks(hooks).
func NewStatusServiceServer(svc StatusService, opts ...interface{}) TwirpServer {
	serverOpts := twirp.ServerOptions{}
	for _, opt := range opts {
		switch o := opt.(type) {
		case twirp.ServerOption:
			o(&serverOpts)
		case *twirp.ServerHooks: // backwards compatibility, allow to specify hooks as an argument
			twirp.WithServerHooks(o)(&serverOpts)
		case nil: // backwards compatibility, allow nil value for the argument
			continue
		default:
			panic(fmt.Sprintf("Invalid option type %T on NewStatusServiceServer", o))
		}
	}

	return &statusServiceServer{
		StatusService:    svc,
		pathPrefix:       serverOpts.PathPrefix(),
		interceptor:      twirp.ChainInterceptors(serverOpts.Interceptors...),
		hooks:            serverOpts.Hooks,
		jsonSkipDefaults: serverOpts.JSONSkipDefaults,
	}
}

// writeError writes an HTTP response with a valid Twirp error format, and triggers hooks.
// If err is not a twirp.Error, it will get wrapped with twirp.InternalErrorWith(err)
func (s *statusServiceServer) writeError(ctx context.Context, resp http.ResponseWriter, err error) {
	writeError(ctx, resp, err, s.hooks)
}

// StatusServicePathPrefix is a convenience constant that could used to identify URL paths.
// Should be used with caution, it only matches routes generated by Twirp Go clients,
// that add a "/twirp" prefix by default, and use CamelCase service and method names.
// More info: https://twitchtv.github.io/twirp/docs/routing.html
const StatusServicePathPrefix = "/twirp/status.StatusService/"

func (s *statusServiceServer) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
	ctx := req.Context()
	ctx = ctxsetters.WithPackageName(ctx, "status")
	ctx = ctxsetters.WithServiceName(ctx, "StatusService")
	ctx = ctxsetters.WithResponseWriter(ctx, resp)

	var err error
	ctx, err = callRequestReceived(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}

	if req.Method != "POST" {
		msg := fmt.Sprintf("unsupported method %q (only POST is allowed)", req.Method)
		s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path))
		return
	}

	// Verify path format: [<prefix>]/<package>.<Service>/<Method>
	prefix, pkgService, method := parseTwirpPath(req.URL.Path)
	if pkgService != "status.StatusService" {
		msg := fmt.Sprintf("no handler for path %q", req.URL.Path)
		s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path))
		return
	}
	if prefix != s.pathPrefix {
		msg := fmt.Sprintf("invalid path prefix %q, expected %q, on path %q", prefix, s.pathPrefix, req.URL.Path)
		s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path))
		return
	}

	switch method {
	case "GetIncrementalCommits":
		s.serveGetIncrementalCommits(ctx, resp, req)
		return
	case "AddComment":
		s.serveAddComment(ctx, resp, req)
		return
	case "DeleteComment":
		s.serveDeleteComment(ctx, resp, req)
		return
	case "GetAutorollerStatuses":
		s.serveGetAutorollerStatuses(ctx, resp, req)
		return
	case "GetBotUsage":
		s.serveGetBotUsage(ctx, resp, req)
		return
	default:
		msg := fmt.Sprintf("no handler for path %q", req.URL.Path)
		s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path))
		return
	}
}

func (s *statusServiceServer) serveGetIncrementalCommits(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	header := req.Header.Get("Content-Type")
	i := strings.Index(header, ";")
	if i == -1 {
		i = len(header)
	}
	switch strings.TrimSpace(strings.ToLower(header[:i])) {
	case "application/json":
		s.serveGetIncrementalCommitsJSON(ctx, resp, req)
	case "application/protobuf":
		s.serveGetIncrementalCommitsProtobuf(ctx, resp, req)
	default:
		msg := fmt.Sprintf("unexpected Content-Type: %q", req.Header.Get("Content-Type"))
		twerr := badRouteError(msg, req.Method, req.URL.Path)
		s.writeError(ctx, resp, twerr)
	}
}

func (s *statusServiceServer) serveGetIncrementalCommitsJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "GetIncrementalCommits")
	ctx, err = callRequestRouted(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}

	reqContent := new(GetIncrementalCommitsRequest)
	unmarshaler := jsonpb.Unmarshaler{AllowUnknownFields: true}
	if err = unmarshaler.Unmarshal(req.Body, reqContent); err != nil {
		s.writeError(ctx, resp, malformedRequestError("the json request could not be decoded"))
		return
	}

	handler := s.StatusService.GetIncrementalCommits
	if s.interceptor != nil {
		handler = func(ctx context.Context, req *GetIncrementalCommitsRequest) (*GetIncrementalCommitsResponse, error) {
			resp, err := s.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*GetIncrementalCommitsRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*GetIncrementalCommitsRequest) when calling interceptor")
					}
					return s.StatusService.GetIncrementalCommits(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*GetIncrementalCommitsResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*GetIncrementalCommitsResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}

	// Call service method
	var respContent *GetIncrementalCommitsResponse
	func() {
		defer ensurePanicResponses(ctx, resp, s.hooks)
		respContent, err = handler(ctx, reqContent)
	}()

	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}
	if respContent == nil {
		s.writeError(ctx, resp, twirp.InternalError("received a nil *GetIncrementalCommitsResponse and nil error while calling GetIncrementalCommits. nil responses are not supported"))
		return
	}

	ctx = callResponsePrepared(ctx, s.hooks)

	var buf bytes.Buffer
	marshaler := &jsonpb.Marshaler{OrigName: true, EmitDefaults: !s.jsonSkipDefaults}
	if err = marshaler.Marshal(&buf, respContent); err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to marshal json response"))
		return
	}

	ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
	respBytes := buf.Bytes()
	resp.Header().Set("Content-Type", "application/json")
	resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
	resp.WriteHeader(http.StatusOK)

	if n, err := resp.Write(respBytes); err != nil {
		msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error())
		twerr := twirp.NewError(twirp.Unknown, msg)
		ctx = callError(ctx, s.hooks, twerr)
	}
	callResponseSent(ctx, s.hooks)
}

func (s *statusServiceServer) serveGetIncrementalCommitsProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "GetIncrementalCommits")
	ctx, err = callRequestRouted(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}

	buf, err := ioutil.ReadAll(req.Body)
	if err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to read request body"))
		return
	}
	reqContent := new(GetIncrementalCommitsRequest)
	if err = proto.Unmarshal(buf, reqContent); err != nil {
		s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded"))
		return
	}

	handler := s.StatusService.GetIncrementalCommits
	if s.interceptor != nil {
		handler = func(ctx context.Context, req *GetIncrementalCommitsRequest) (*GetIncrementalCommitsResponse, error) {
			resp, err := s.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*GetIncrementalCommitsRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*GetIncrementalCommitsRequest) when calling interceptor")
					}
					return s.StatusService.GetIncrementalCommits(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*GetIncrementalCommitsResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*GetIncrementalCommitsResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}

	// Call service method
	var respContent *GetIncrementalCommitsResponse
	func() {
		defer ensurePanicResponses(ctx, resp, s.hooks)
		respContent, err = handler(ctx, reqContent)
	}()

	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}
	if respContent == nil {
		s.writeError(ctx, resp, twirp.InternalError("received a nil *GetIncrementalCommitsResponse and nil error while calling GetIncrementalCommits. nil responses are not supported"))
		return
	}

	ctx = callResponsePrepared(ctx, s.hooks)

	respBytes, err := proto.Marshal(respContent)
	if err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to marshal proto response"))
		return
	}

	ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
	resp.Header().Set("Content-Type", "application/protobuf")
	resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
	resp.WriteHeader(http.StatusOK)
	if n, err := resp.Write(respBytes); err != nil {
		msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error())
		twerr := twirp.NewError(twirp.Unknown, msg)
		ctx = callError(ctx, s.hooks, twerr)
	}
	callResponseSent(ctx, s.hooks)
}

func (s *statusServiceServer) serveAddComment(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	header := req.Header.Get("Content-Type")
	i := strings.Index(header, ";")
	if i == -1 {
		i = len(header)
	}
	switch strings.TrimSpace(strings.ToLower(header[:i])) {
	case "application/json":
		s.serveAddCommentJSON(ctx, resp, req)
	case "application/protobuf":
		s.serveAddCommentProtobuf(ctx, resp, req)
	default:
		msg := fmt.Sprintf("unexpected Content-Type: %q", req.Header.Get("Content-Type"))
		twerr := badRouteError(msg, req.Method, req.URL.Path)
		s.writeError(ctx, resp, twerr)
	}
}

func (s *statusServiceServer) serveAddCommentJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "AddComment")
	ctx, err = callRequestRouted(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}

	reqContent := new(AddCommentRequest)
	unmarshaler := jsonpb.Unmarshaler{AllowUnknownFields: true}
	if err = unmarshaler.Unmarshal(req.Body, reqContent); err != nil {
		s.writeError(ctx, resp, malformedRequestError("the json request could not be decoded"))
		return
	}

	handler := s.StatusService.AddComment
	if s.interceptor != nil {
		handler = func(ctx context.Context, req *AddCommentRequest) (*AddCommentResponse, error) {
			resp, err := s.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*AddCommentRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*AddCommentRequest) when calling interceptor")
					}
					return s.StatusService.AddComment(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*AddCommentResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*AddCommentResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}

	// Call service method
	var respContent *AddCommentResponse
	func() {
		defer ensurePanicResponses(ctx, resp, s.hooks)
		respContent, err = handler(ctx, reqContent)
	}()

	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}
	if respContent == nil {
		s.writeError(ctx, resp, twirp.InternalError("received a nil *AddCommentResponse and nil error while calling AddComment. nil responses are not supported"))
		return
	}

	ctx = callResponsePrepared(ctx, s.hooks)

	var buf bytes.Buffer
	marshaler := &jsonpb.Marshaler{OrigName: true, EmitDefaults: !s.jsonSkipDefaults}
	if err = marshaler.Marshal(&buf, respContent); err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to marshal json response"))
		return
	}

	ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
	respBytes := buf.Bytes()
	resp.Header().Set("Content-Type", "application/json")
	resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
	resp.WriteHeader(http.StatusOK)

	if n, err := resp.Write(respBytes); err != nil {
		msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error())
		twerr := twirp.NewError(twirp.Unknown, msg)
		ctx = callError(ctx, s.hooks, twerr)
	}
	callResponseSent(ctx, s.hooks)
}

func (s *statusServiceServer) serveAddCommentProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "AddComment")
	ctx, err = callRequestRouted(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}

	buf, err := ioutil.ReadAll(req.Body)
	if err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to read request body"))
		return
	}
	reqContent := new(AddCommentRequest)
	if err = proto.Unmarshal(buf, reqContent); err != nil {
		s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded"))
		return
	}

	handler := s.StatusService.AddComment
	if s.interceptor != nil {
		handler = func(ctx context.Context, req *AddCommentRequest) (*AddCommentResponse, error) {
			resp, err := s.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*AddCommentRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*AddCommentRequest) when calling interceptor")
					}
					return s.StatusService.AddComment(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*AddCommentResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*AddCommentResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}

	// Call service method
	var respContent *AddCommentResponse
	func() {
		defer ensurePanicResponses(ctx, resp, s.hooks)
		respContent, err = handler(ctx, reqContent)
	}()

	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}
	if respContent == nil {
		s.writeError(ctx, resp, twirp.InternalError("received a nil *AddCommentResponse and nil error while calling AddComment. nil responses are not supported"))
		return
	}

	ctx = callResponsePrepared(ctx, s.hooks)

	respBytes, err := proto.Marshal(respContent)
	if err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to marshal proto response"))
		return
	}

	ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
	resp.Header().Set("Content-Type", "application/protobuf")
	resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
	resp.WriteHeader(http.StatusOK)
	if n, err := resp.Write(respBytes); err != nil {
		msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error())
		twerr := twirp.NewError(twirp.Unknown, msg)
		ctx = callError(ctx, s.hooks, twerr)
	}
	callResponseSent(ctx, s.hooks)
}

func (s *statusServiceServer) serveDeleteComment(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	header := req.Header.Get("Content-Type")
	i := strings.Index(header, ";")
	if i == -1 {
		i = len(header)
	}
	switch strings.TrimSpace(strings.ToLower(header[:i])) {
	case "application/json":
		s.serveDeleteCommentJSON(ctx, resp, req)
	case "application/protobuf":
		s.serveDeleteCommentProtobuf(ctx, resp, req)
	default:
		msg := fmt.Sprintf("unexpected Content-Type: %q", req.Header.Get("Content-Type"))
		twerr := badRouteError(msg, req.Method, req.URL.Path)
		s.writeError(ctx, resp, twerr)
	}
}

func (s *statusServiceServer) serveDeleteCommentJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "DeleteComment")
	ctx, err = callRequestRouted(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}

	reqContent := new(DeleteCommentRequest)
	unmarshaler := jsonpb.Unmarshaler{AllowUnknownFields: true}
	if err = unmarshaler.Unmarshal(req.Body, reqContent); err != nil {
		s.writeError(ctx, resp, malformedRequestError("the json request could not be decoded"))
		return
	}

	handler := s.StatusService.DeleteComment
	if s.interceptor != nil {
		handler = func(ctx context.Context, req *DeleteCommentRequest) (*DeleteCommentResponse, error) {
			resp, err := s.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*DeleteCommentRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*DeleteCommentRequest) when calling interceptor")
					}
					return s.StatusService.DeleteComment(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*DeleteCommentResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*DeleteCommentResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}

	// Call service method
	var respContent *DeleteCommentResponse
	func() {
		defer ensurePanicResponses(ctx, resp, s.hooks)
		respContent, err = handler(ctx, reqContent)
	}()

	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}
	if respContent == nil {
		s.writeError(ctx, resp, twirp.InternalError("received a nil *DeleteCommentResponse and nil error while calling DeleteComment. nil responses are not supported"))
		return
	}

	ctx = callResponsePrepared(ctx, s.hooks)

	var buf bytes.Buffer
	marshaler := &jsonpb.Marshaler{OrigName: true, EmitDefaults: !s.jsonSkipDefaults}
	if err = marshaler.Marshal(&buf, respContent); err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to marshal json response"))
		return
	}

	ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
	respBytes := buf.Bytes()
	resp.Header().Set("Content-Type", "application/json")
	resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
	resp.WriteHeader(http.StatusOK)

	if n, err := resp.Write(respBytes); err != nil {
		msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error())
		twerr := twirp.NewError(twirp.Unknown, msg)
		ctx = callError(ctx, s.hooks, twerr)
	}
	callResponseSent(ctx, s.hooks)
}

func (s *statusServiceServer) serveDeleteCommentProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "DeleteComment")
	ctx, err = callRequestRouted(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}

	buf, err := ioutil.ReadAll(req.Body)
	if err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to read request body"))
		return
	}
	reqContent := new(DeleteCommentRequest)
	if err = proto.Unmarshal(buf, reqContent); err != nil {
		s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded"))
		return
	}

	handler := s.StatusService.DeleteComment
	if s.interceptor != nil {
		handler = func(ctx context.Context, req *DeleteCommentRequest) (*DeleteCommentResponse, error) {
			resp, err := s.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*DeleteCommentRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*DeleteCommentRequest) when calling interceptor")
					}
					return s.StatusService.DeleteComment(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*DeleteCommentResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*DeleteCommentResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}

	// Call service method
	var respContent *DeleteCommentResponse
	func() {
		defer ensurePanicResponses(ctx, resp, s.hooks)
		respContent, err = handler(ctx, reqContent)
	}()

	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}
	if respContent == nil {
		s.writeError(ctx, resp, twirp.InternalError("received a nil *DeleteCommentResponse and nil error while calling DeleteComment. nil responses are not supported"))
		return
	}

	ctx = callResponsePrepared(ctx, s.hooks)

	respBytes, err := proto.Marshal(respContent)
	if err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to marshal proto response"))
		return
	}

	ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
	resp.Header().Set("Content-Type", "application/protobuf")
	resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
	resp.WriteHeader(http.StatusOK)
	if n, err := resp.Write(respBytes); err != nil {
		msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error())
		twerr := twirp.NewError(twirp.Unknown, msg)
		ctx = callError(ctx, s.hooks, twerr)
	}
	callResponseSent(ctx, s.hooks)
}

func (s *statusServiceServer) serveGetAutorollerStatuses(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	header := req.Header.Get("Content-Type")
	i := strings.Index(header, ";")
	if i == -1 {
		i = len(header)
	}
	switch strings.TrimSpace(strings.ToLower(header[:i])) {
	case "application/json":
		s.serveGetAutorollerStatusesJSON(ctx, resp, req)
	case "application/protobuf":
		s.serveGetAutorollerStatusesProtobuf(ctx, resp, req)
	default:
		msg := fmt.Sprintf("unexpected Content-Type: %q", req.Header.Get("Content-Type"))
		twerr := badRouteError(msg, req.Method, req.URL.Path)
		s.writeError(ctx, resp, twerr)
	}
}

func (s *statusServiceServer) serveGetAutorollerStatusesJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "GetAutorollerStatuses")
	ctx, err = callRequestRouted(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}

	reqContent := new(GetAutorollerStatusesRequest)
	unmarshaler := jsonpb.Unmarshaler{AllowUnknownFields: true}
	if err = unmarshaler.Unmarshal(req.Body, reqContent); err != nil {
		s.writeError(ctx, resp, malformedRequestError("the json request could not be decoded"))
		return
	}

	handler := s.StatusService.GetAutorollerStatuses
	if s.interceptor != nil {
		handler = func(ctx context.Context, req *GetAutorollerStatusesRequest) (*GetAutorollerStatusesResponse, error) {
			resp, err := s.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*GetAutorollerStatusesRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*GetAutorollerStatusesRequest) when calling interceptor")
					}
					return s.StatusService.GetAutorollerStatuses(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*GetAutorollerStatusesResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*GetAutorollerStatusesResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}

	// Call service method
	var respContent *GetAutorollerStatusesResponse
	func() {
		defer ensurePanicResponses(ctx, resp, s.hooks)
		respContent, err = handler(ctx, reqContent)
	}()

	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}
	if respContent == nil {
		s.writeError(ctx, resp, twirp.InternalError("received a nil *GetAutorollerStatusesResponse and nil error while calling GetAutorollerStatuses. nil responses are not supported"))
		return
	}

	ctx = callResponsePrepared(ctx, s.hooks)

	var buf bytes.Buffer
	marshaler := &jsonpb.Marshaler{OrigName: true, EmitDefaults: !s.jsonSkipDefaults}
	if err = marshaler.Marshal(&buf, respContent); err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to marshal json response"))
		return
	}

	ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
	respBytes := buf.Bytes()
	resp.Header().Set("Content-Type", "application/json")
	resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
	resp.WriteHeader(http.StatusOK)

	if n, err := resp.Write(respBytes); err != nil {
		msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error())
		twerr := twirp.NewError(twirp.Unknown, msg)
		ctx = callError(ctx, s.hooks, twerr)
	}
	callResponseSent(ctx, s.hooks)
}

func (s *statusServiceServer) serveGetAutorollerStatusesProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "GetAutorollerStatuses")
	ctx, err = callRequestRouted(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}

	buf, err := ioutil.ReadAll(req.Body)
	if err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to read request body"))
		return
	}
	reqContent := new(GetAutorollerStatusesRequest)
	if err = proto.Unmarshal(buf, reqContent); err != nil {
		s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded"))
		return
	}

	handler := s.StatusService.GetAutorollerStatuses
	if s.interceptor != nil {
		handler = func(ctx context.Context, req *GetAutorollerStatusesRequest) (*GetAutorollerStatusesResponse, error) {
			resp, err := s.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*GetAutorollerStatusesRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*GetAutorollerStatusesRequest) when calling interceptor")
					}
					return s.StatusService.GetAutorollerStatuses(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*GetAutorollerStatusesResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*GetAutorollerStatusesResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}

	// Call service method
	var respContent *GetAutorollerStatusesResponse
	func() {
		defer ensurePanicResponses(ctx, resp, s.hooks)
		respContent, err = handler(ctx, reqContent)
	}()

	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}
	if respContent == nil {
		s.writeError(ctx, resp, twirp.InternalError("received a nil *GetAutorollerStatusesResponse and nil error while calling GetAutorollerStatuses. nil responses are not supported"))
		return
	}

	ctx = callResponsePrepared(ctx, s.hooks)

	respBytes, err := proto.Marshal(respContent)
	if err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to marshal proto response"))
		return
	}

	ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
	resp.Header().Set("Content-Type", "application/protobuf")
	resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
	resp.WriteHeader(http.StatusOK)
	if n, err := resp.Write(respBytes); err != nil {
		msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error())
		twerr := twirp.NewError(twirp.Unknown, msg)
		ctx = callError(ctx, s.hooks, twerr)
	}
	callResponseSent(ctx, s.hooks)
}

func (s *statusServiceServer) serveGetBotUsage(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	header := req.Header.Get("Content-Type")
	i := strings.Index(header, ";")
	if i == -1 {
		i = len(header)
	}
	switch strings.TrimSpace(strings.ToLower(header[:i])) {
	case "application/json":
		s.serveGetBotUsageJSON(ctx, resp, req)
	case "application/protobuf":
		s.serveGetBotUsageProtobuf(ctx, resp, req)
	default:
		msg := fmt.Sprintf("unexpected Content-Type: %q", req.Header.Get("Content-Type"))
		twerr := badRouteError(msg, req.Method, req.URL.Path)
		s.writeError(ctx, resp, twerr)
	}
}

func (s *statusServiceServer) serveGetBotUsageJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "GetBotUsage")
	ctx, err = callRequestRouted(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}

	reqContent := new(GetBotUsageRequest)
	unmarshaler := jsonpb.Unmarshaler{AllowUnknownFields: true}
	if err = unmarshaler.Unmarshal(req.Body, reqContent); err != nil {
		s.writeError(ctx, resp, malformedRequestError("the json request could not be decoded"))
		return
	}

	handler := s.StatusService.GetBotUsage
	if s.interceptor != nil {
		handler = func(ctx context.Context, req *GetBotUsageRequest) (*GetBotUsageResponse, error) {
			resp, err := s.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*GetBotUsageRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*GetBotUsageRequest) when calling interceptor")
					}
					return s.StatusService.GetBotUsage(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*GetBotUsageResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*GetBotUsageResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}

	// Call service method
	var respContent *GetBotUsageResponse
	func() {
		defer ensurePanicResponses(ctx, resp, s.hooks)
		respContent, err = handler(ctx, reqContent)
	}()

	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}
	if respContent == nil {
		s.writeError(ctx, resp, twirp.InternalError("received a nil *GetBotUsageResponse and nil error while calling GetBotUsage. nil responses are not supported"))
		return
	}

	ctx = callResponsePrepared(ctx, s.hooks)

	var buf bytes.Buffer
	marshaler := &jsonpb.Marshaler{OrigName: true, EmitDefaults: !s.jsonSkipDefaults}
	if err = marshaler.Marshal(&buf, respContent); err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to marshal json response"))
		return
	}

	ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
	respBytes := buf.Bytes()
	resp.Header().Set("Content-Type", "application/json")
	resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
	resp.WriteHeader(http.StatusOK)

	if n, err := resp.Write(respBytes); err != nil {
		msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error())
		twerr := twirp.NewError(twirp.Unknown, msg)
		ctx = callError(ctx, s.hooks, twerr)
	}
	callResponseSent(ctx, s.hooks)
}

func (s *statusServiceServer) serveGetBotUsageProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "GetBotUsage")
	ctx, err = callRequestRouted(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}

	buf, err := ioutil.ReadAll(req.Body)
	if err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to read request body"))
		return
	}
	reqContent := new(GetBotUsageRequest)
	if err = proto.Unmarshal(buf, reqContent); err != nil {
		s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded"))
		return
	}

	handler := s.StatusService.GetBotUsage
	if s.interceptor != nil {
		handler = func(ctx context.Context, req *GetBotUsageRequest) (*GetBotUsageResponse, error) {
			resp, err := s.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*GetBotUsageRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*GetBotUsageRequest) when calling interceptor")
					}
					return s.StatusService.GetBotUsage(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*GetBotUsageResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*GetBotUsageResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}

	// Call service method
	var respContent *GetBotUsageResponse
	func() {
		defer ensurePanicResponses(ctx, resp, s.hooks)
		respContent, err = handler(ctx, reqContent)
	}()

	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}
	if respContent == nil {
		s.writeError(ctx, resp, twirp.InternalError("received a nil *GetBotUsageResponse and nil error while calling GetBotUsage. nil responses are not supported"))
		return
	}

	ctx = callResponsePrepared(ctx, s.hooks)

	respBytes, err := proto.Marshal(respContent)
	if err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to marshal proto response"))
		return
	}

	ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
	resp.Header().Set("Content-Type", "application/protobuf")
	resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
	resp.WriteHeader(http.StatusOK)
	if n, err := resp.Write(respBytes); err != nil {
		msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error())
		twerr := twirp.NewError(twirp.Unknown, msg)
		ctx = callError(ctx, s.hooks, twerr)
	}
	callResponseSent(ctx, s.hooks)
}

func (s *statusServiceServer) ServiceDescriptor() ([]byte, int) {
	return twirpFileDescriptor0, 0
}

func (s *statusServiceServer) ProtocGenTwirpVersion() string {
	return "v7.1.0"
}

// PathPrefix returns the base service path, in the form: "/<prefix>/<package>.<Service>/"
// that is everything in a Twirp route except for the <Method>. This can be used for routing,
// for example to identify the requests that are targeted to this service in a mux.
func (s *statusServiceServer) PathPrefix() string {
	return baseServicePath(s.pathPrefix, "status", "StatusService")
}

// =====
// Utils
// =====

// HTTPClient is the interface used by generated clients to send HTTP requests.
// It is fulfilled by *(net/http).Client, which is sufficient for most users.
// Users can provide their own implementation for special retry policies.
//
// HTTPClient implementations should not follow redirects. Redirects are
// automatically disabled if *(net/http).Client is passed to client
// constructors. See the withoutRedirects function in this file for more
// details.
type HTTPClient interface {
	Do(req *http.Request) (*http.Response, error)
}

// TwirpServer is the interface generated server structs will support: they're
// HTTP handlers with additional methods for accessing metadata about the
// service. Those accessors are a low-level API for building reflection tools.
// Most people can think of TwirpServers as just http.Handlers.
type TwirpServer interface {
	http.Handler

	// ServiceDescriptor returns gzipped bytes describing the .proto file that
	// this service was generated from. Once unzipped, the bytes can be
	// unmarshalled as a
	// github.com/golang/protobuf/protoc-gen-go/descriptor.FileDescriptorProto.
	//
	// The returned integer is the index of this particular service within that
	// FileDescriptorProto's 'Service' slice of ServiceDescriptorProtos. This is a
	// low-level field, expected to be used for reflection.
	ServiceDescriptor() ([]byte, int)

	// ProtocGenTwirpVersion is the semantic version string of the version of
	// twirp used to generate this file.
	ProtocGenTwirpVersion() string

	// PathPrefix returns the HTTP URL path prefix for all methods handled by this
	// service. This can be used with an HTTP mux to route Twirp requests.
	// The path prefix is in the form: "/<prefix>/<package>.<Service>/"
	// that is, everything in a Twirp route except for the <Method> at the end.
	PathPrefix() string
}

// WriteError writes an HTTP response with a valid Twirp error format (code, msg, meta).
// Useful outside of the Twirp server (e.g. http middleware), but does not trigger hooks.
// If err is not a twirp.Error, it will get wrapped with twirp.InternalErrorWith(err)
func WriteError(resp http.ResponseWriter, err error) {
	writeError(context.Background(), resp, err, nil)
}

// writeError writes Twirp errors in the response and triggers hooks.
func writeError(ctx context.Context, resp http.ResponseWriter, err error, hooks *twirp.ServerHooks) {
	// Non-twirp errors are wrapped as Internal (default)
	twerr, ok := err.(twirp.Error)
	if !ok {
		twerr = twirp.InternalErrorWith(err)
	}

	statusCode := twirp.ServerHTTPStatusFromErrorCode(twerr.Code())
	ctx = ctxsetters.WithStatusCode(ctx, statusCode)
	ctx = callError(ctx, hooks, twerr)

	respBody := marshalErrorToJSON(twerr)

	resp.Header().Set("Content-Type", "application/json") // Error responses are always JSON
	resp.Header().Set("Content-Length", strconv.Itoa(len(respBody)))
	resp.WriteHeader(statusCode) // set HTTP status code and send response

	_, writeErr := resp.Write(respBody)
	if writeErr != nil {
		// We have three options here. We could log the error, call the Error
		// hook, or just silently ignore the error.
		//
		// Logging is unacceptable because we don't have a user-controlled
		// logger; writing out to stderr without permission is too rude.
		//
		// Calling the Error hook would confuse users: it would mean the Error
		// hook got called twice for one request, which is likely to lead to
		// duplicated log messages and metrics, no matter how well we document
		// the behavior.
		//
		// Silently ignoring the error is our least-bad option. It's highly
		// likely that the connection is broken and the original 'err' says
		// so anyway.
		_ = writeErr
	}

	callResponseSent(ctx, hooks)
}

// sanitizeBaseURL parses the the baseURL, and adds the "http" scheme if needed.
// If the URL is unparsable, the baseURL is returned unchaged.
func sanitizeBaseURL(baseURL string) string {
	u, err := url.Parse(baseURL)
	if err != nil {
		return baseURL // invalid URL will fail later when making requests
	}
	if u.Scheme == "" {
		u.Scheme = "http"
	}
	return u.String()
}

// baseServicePath composes the path prefix for the service (without <Method>).
// e.g.: baseServicePath("/twirp", "my.pkg", "MyService")
//       returns => "/twirp/my.pkg.MyService/"
// e.g.: baseServicePath("", "", "MyService")
//       returns => "/MyService/"
func baseServicePath(prefix, pkg, service string) string {
	fullServiceName := service
	if pkg != "" {
		fullServiceName = pkg + "." + service
	}
	return path.Join("/", prefix, fullServiceName) + "/"
}

// parseTwirpPath extracts path components form a valid Twirp route.
// Expected format: "[<prefix>]/<package>.<Service>/<Method>"
// e.g.: prefix, pkgService, method := parseTwirpPath("/twirp/pkg.Svc/MakeHat")
func parseTwirpPath(path string) (string, string, string) {
	parts := strings.Split(path, "/")
	if len(parts) < 2 {
		return "", "", ""
	}
	method := parts[len(parts)-1]
	pkgService := parts[len(parts)-2]
	prefix := strings.Join(parts[0:len(parts)-2], "/")
	return prefix, pkgService, method
}

// getCustomHTTPReqHeaders retrieves a copy of any headers that are set in
// a context through the twirp.WithHTTPRequestHeaders function.
// If there are no headers set, or if they have the wrong type, nil is returned.
func getCustomHTTPReqHeaders(ctx context.Context) http.Header {
	header, ok := twirp.HTTPRequestHeaders(ctx)
	if !ok || header == nil {
		return nil
	}
	copied := make(http.Header)
	for k, vv := range header {
		if vv == nil {
			copied[k] = nil
			continue
		}
		copied[k] = make([]string, len(vv))
		copy(copied[k], vv)
	}
	return copied
}

// newRequest makes an http.Request from a client, adding common headers.
func newRequest(ctx context.Context, url string, reqBody io.Reader, contentType string) (*http.Request, error) {
	req, err := http.NewRequest("POST", url, reqBody)
	if err != nil {
		return nil, err
	}
	req = req.WithContext(ctx)
	if customHeader := getCustomHTTPReqHeaders(ctx); customHeader != nil {
		req.Header = customHeader
	}
	req.Header.Set("Accept", contentType)
	req.Header.Set("Content-Type", contentType)
	req.Header.Set("Twirp-Version", "v7.1.0")
	return req, nil
}

// JSON serialization for errors
type twerrJSON struct {
	Code string            `json:"code"`
	Msg  string            `json:"msg"`
	Meta map[string]string `json:"meta,omitempty"`
}

// marshalErrorToJSON returns JSON from a twirp.Error, that can be used as HTTP error response body.
// If serialization fails, it will use a descriptive Internal error instead.
func marshalErrorToJSON(twerr twirp.Error) []byte {
	// make sure that msg is not too large
	msg := twerr.Msg()
	if len(msg) > 1e6 {
		msg = msg[:1e6]
	}

	tj := twerrJSON{
		Code: string(twerr.Code()),
		Msg:  msg,
		Meta: twerr.MetaMap(),
	}

	buf, err := json.Marshal(&tj)
	if err != nil {
		buf = []byte("{\"type\": \"" + twirp.Internal + "\", \"msg\": \"There was an error but it could not be serialized into JSON\"}") // fallback
	}

	return buf
}

// errorFromResponse builds a twirp.Error from a non-200 HTTP response.
// If the response has a valid serialized Twirp error, then it's returned.
// If not, the response status code is used to generate a similar twirp
// error. See twirpErrorFromIntermediary for more info on intermediary errors.
func errorFromResponse(resp *http.Response) twirp.Error {
	statusCode := resp.StatusCode
	statusText := http.StatusText(statusCode)

	if isHTTPRedirect(statusCode) {
		// Unexpected redirect: it must be an error from an intermediary.
		// Twirp clients don't follow redirects automatically, Twirp only handles
		// POST requests, redirects should only happen on GET and HEAD requests.
		location := resp.Header.Get("Location")
		msg := fmt.Sprintf("unexpected HTTP status code %d %q received, Location=%q", statusCode, statusText, location)
		return twirpErrorFromIntermediary(statusCode, msg, location)
	}

	respBodyBytes, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return wrapInternal(err, "failed to read server error response body")
	}

	var tj twerrJSON
	dec := json.NewDecoder(bytes.NewReader(respBodyBytes))
	dec.DisallowUnknownFields()
	if err := dec.Decode(&tj); err != nil || tj.Code == "" {
		// Invalid JSON response; it must be an error from an intermediary.
		msg := fmt.Sprintf("Error from intermediary with HTTP status code %d %q", statusCode, statusText)
		return twirpErrorFromIntermediary(statusCode, msg, string(respBodyBytes))
	}

	errorCode := twirp.ErrorCode(tj.Code)
	if !twirp.IsValidErrorCode(errorCode) {
		msg := "invalid type returned from server error response: " + tj.Code
		return twirp.InternalError(msg).WithMeta("body", string(respBodyBytes))
	}

	twerr := twirp.NewError(errorCode, tj.Msg)
	for k, v := range tj.Meta {
		twerr = twerr.WithMeta(k, v)
	}
	return twerr
}

// twirpErrorFromIntermediary maps HTTP errors from non-twirp sources to twirp errors.
// The mapping is similar to gRPC: https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md.
// Returned twirp Errors have some additional metadata for inspection.
func twirpErrorFromIntermediary(status int, msg string, bodyOrLocation string) twirp.Error {
	var code twirp.ErrorCode
	if isHTTPRedirect(status) { // 3xx
		code = twirp.Internal
	} else {
		switch status {
		case 400: // Bad Request
			code = twirp.Internal
		case 401: // Unauthorized
			code = twirp.Unauthenticated
		case 403: // Forbidden
			code = twirp.PermissionDenied
		case 404: // Not Found
			code = twirp.BadRoute
		case 429: // Too Many Requests
			code = twirp.ResourceExhausted
		case 502, 503, 504: // Bad Gateway, Service Unavailable, Gateway Timeout
			code = twirp.Unavailable
		default: // All other codes
			code = twirp.Unknown
		}
	}

	twerr := twirp.NewError(code, msg)
	twerr = twerr.WithMeta("http_error_from_intermediary", "true") // to easily know if this error was from intermediary
	twerr = twerr.WithMeta("status_code", strconv.Itoa(status))
	if isHTTPRedirect(status) {
		twerr = twerr.WithMeta("location", bodyOrLocation)
	} else {
		twerr = twerr.WithMeta("body", bodyOrLocation)
	}
	return twerr
}

func isHTTPRedirect(status int) bool {
	return status >= 300 && status <= 399
}

// wrapInternal wraps an error with a prefix as an Internal error.
// The original error cause is accessible by github.com/pkg/errors.Cause.
func wrapInternal(err error, prefix string) twirp.Error {
	return twirp.InternalErrorWith(&wrappedError{prefix: prefix, cause: err})
}

type wrappedError struct {
	prefix string
	cause  error
}

func (e *wrappedError) Error() string { return e.prefix + ": " + e.cause.Error() }
func (e *wrappedError) Unwrap() error { return e.cause } // for go1.13 + errors.Is/As
func (e *wrappedError) Cause() error  { return e.cause } // for github.com/pkg/errors

// ensurePanicResponses makes sure that rpc methods causing a panic still result in a Twirp Internal
// error response (status 500), and error hooks are properly called with the panic wrapped as an error.
// The panic is re-raised so it can be handled normally with middleware.
func ensurePanicResponses(ctx context.Context, resp http.ResponseWriter, hooks *twirp.ServerHooks) {
	if r := recover(); r != nil {
		// Wrap the panic as an error so it can be passed to error hooks.
		// The original error is accessible from error hooks, but not visible in the response.
		err := errFromPanic(r)
		twerr := &internalWithCause{msg: "Internal service panic", cause: err}
		// Actually write the error
		writeError(ctx, resp, twerr, hooks)
		// If possible, flush the error to the wire.
		f, ok := resp.(http.Flusher)
		if ok {
			f.Flush()
		}

		panic(r)
	}
}

// errFromPanic returns the typed error if the recovered panic is an error, otherwise formats as error.
func errFromPanic(p interface{}) error {
	if err, ok := p.(error); ok {
		return err
	}
	return fmt.Errorf("panic: %v", p)
}

// internalWithCause is a Twirp Internal error wrapping an original error cause,
// but the original error message is not exposed on Msg(). The original error
// can be checked with go1.13+ errors.Is/As, and also by (github.com/pkg/errors).Unwrap
type internalWithCause struct {
	msg   string
	cause error
}

func (e *internalWithCause) Unwrap() error                               { return e.cause } // for go1.13 + errors.Is/As
func (e *internalWithCause) Cause() error                                { return e.cause } // for github.com/pkg/errors
func (e *internalWithCause) Error() string                               { return e.msg + ": " + e.cause.Error() }
func (e *internalWithCause) Code() twirp.ErrorCode                       { return twirp.Internal }
func (e *internalWithCause) Msg() string                                 { return e.msg }
func (e *internalWithCause) Meta(key string) string                      { return "" }
func (e *internalWithCause) MetaMap() map[string]string                  { return nil }
func (e *internalWithCause) WithMeta(key string, val string) twirp.Error { return e }

// malformedRequestError is used when the twirp server cannot unmarshal a request
func malformedRequestError(msg string) twirp.Error {
	return twirp.NewError(twirp.Malformed, msg)
}

// badRouteError is used when the twirp server cannot route a request
func badRouteError(msg string, method, url string) twirp.Error {
	err := twirp.NewError(twirp.BadRoute, msg)
	err = err.WithMeta("twirp_invalid_route", method+" "+url)
	return err
}

// withoutRedirects makes sure that the POST request can not be redirected.
// The standard library will, by default, redirect requests (including POSTs) if it gets a 302 or
// 303 response, and also 301s in go1.8. It redirects by making a second request, changing the
// method to GET and removing the body. This produces very confusing error messages, so instead we
// set a redirect policy that always errors. This stops Go from executing the redirect.
//
// We have to be a little careful in case the user-provided http.Client has its own CheckRedirect
// policy - if so, we'll run through that policy first.
//
// Because this requires modifying the http.Client, we make a new copy of the client and return it.
func withoutRedirects(in *http.Client) *http.Client {
	copy := *in
	copy.CheckRedirect = func(req *http.Request, via []*http.Request) error {
		if in.CheckRedirect != nil {
			// Run the input's redirect if it exists, in case it has side effects, but ignore any error it
			// returns, since we want to use ErrUseLastResponse.
			err := in.CheckRedirect(req, via)
			_ = err // Silly, but this makes sure generated code passes errcheck -blank, which some people use.
		}
		return http.ErrUseLastResponse
	}
	return &copy
}

// doProtobufRequest makes a Protobuf request to the remote Twirp service.
func doProtobufRequest(ctx context.Context, client HTTPClient, hooks *twirp.ClientHooks, url string, in, out proto.Message) (_ context.Context, err error) {
	reqBodyBytes, err := proto.Marshal(in)
	if err != nil {
		return ctx, wrapInternal(err, "failed to marshal proto request")
	}
	reqBody := bytes.NewBuffer(reqBodyBytes)
	if err = ctx.Err(); err != nil {
		return ctx, wrapInternal(err, "aborted because context was done")
	}

	req, err := newRequest(ctx, url, reqBody, "application/protobuf")
	if err != nil {
		return ctx, wrapInternal(err, "could not build request")
	}
	ctx, err = callClientRequestPrepared(ctx, hooks, req)
	if err != nil {
		return ctx, err
	}

	req = req.WithContext(ctx)
	resp, err := client.Do(req)
	if err != nil {
		return ctx, wrapInternal(err, "failed to do request")
	}

	defer func() {
		cerr := resp.Body.Close()
		if err == nil && cerr != nil {
			err = wrapInternal(cerr, "failed to close response body")
		}
	}()

	if err = ctx.Err(); err != nil {
		return ctx, wrapInternal(err, "aborted because context was done")
	}

	if resp.StatusCode != 200 {
		return ctx, errorFromResponse(resp)
	}

	respBodyBytes, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return ctx, wrapInternal(err, "failed to read response body")
	}
	if err = ctx.Err(); err != nil {
		return ctx, wrapInternal(err, "aborted because context was done")
	}

	if err = proto.Unmarshal(respBodyBytes, out); err != nil {
		return ctx, wrapInternal(err, "failed to unmarshal proto response")
	}
	return ctx, nil
}

// doJSONRequest makes a JSON request to the remote Twirp service.
func doJSONRequest(ctx context.Context, client HTTPClient, hooks *twirp.ClientHooks, url string, in, out proto.Message) (_ context.Context, err error) {
	reqBody := bytes.NewBuffer(nil)
	marshaler := &jsonpb.Marshaler{OrigName: true}
	if err = marshaler.Marshal(reqBody, in); err != nil {
		return ctx, wrapInternal(err, "failed to marshal json request")
	}
	if err = ctx.Err(); err != nil {
		return ctx, wrapInternal(err, "aborted because context was done")
	}

	req, err := newRequest(ctx, url, reqBody, "application/json")
	if err != nil {
		return ctx, wrapInternal(err, "could not build request")
	}
	ctx, err = callClientRequestPrepared(ctx, hooks, req)
	if err != nil {
		return ctx, err
	}

	req = req.WithContext(ctx)
	resp, err := client.Do(req)
	if err != nil {
		return ctx, wrapInternal(err, "failed to do request")
	}

	defer func() {
		cerr := resp.Body.Close()
		if err == nil && cerr != nil {
			err = wrapInternal(cerr, "failed to close response body")
		}
	}()

	if err = ctx.Err(); err != nil {
		return ctx, wrapInternal(err, "aborted because context was done")
	}

	if resp.StatusCode != 200 {
		return ctx, errorFromResponse(resp)
	}

	unmarshaler := jsonpb.Unmarshaler{AllowUnknownFields: true}
	if err = unmarshaler.Unmarshal(resp.Body, out); err != nil {
		return ctx, wrapInternal(err, "failed to unmarshal json response")
	}
	if err = ctx.Err(); err != nil {
		return ctx, wrapInternal(err, "aborted because context was done")
	}
	return ctx, nil
}

// Call twirp.ServerHooks.RequestReceived if the hook is available
func callRequestReceived(ctx context.Context, h *twirp.ServerHooks) (context.Context, error) {
	if h == nil || h.RequestReceived == nil {
		return ctx, nil
	}
	return h.RequestReceived(ctx)
}

// Call twirp.ServerHooks.RequestRouted if the hook is available
func callRequestRouted(ctx context.Context, h *twirp.ServerHooks) (context.Context, error) {
	if h == nil || h.RequestRouted == nil {
		return ctx, nil
	}
	return h.RequestRouted(ctx)
}

// Call twirp.ServerHooks.ResponsePrepared if the hook is available
func callResponsePrepared(ctx context.Context, h *twirp.ServerHooks) context.Context {
	if h == nil || h.ResponsePrepared == nil {
		return ctx
	}
	return h.ResponsePrepared(ctx)
}

// Call twirp.ServerHooks.ResponseSent if the hook is available
func callResponseSent(ctx context.Context, h *twirp.ServerHooks) {
	if h == nil || h.ResponseSent == nil {
		return
	}
	h.ResponseSent(ctx)
}

// Call twirp.ServerHooks.Error if the hook is available
func callError(ctx context.Context, h *twirp.ServerHooks, err twirp.Error) context.Context {
	if h == nil || h.Error == nil {
		return ctx
	}
	return h.Error(ctx, err)
}

func callClientResponseReceived(ctx context.Context, h *twirp.ClientHooks) {
	if h == nil || h.ResponseReceived == nil {
		return
	}
	h.ResponseReceived(ctx)
}

func callClientRequestPrepared(ctx context.Context, h *twirp.ClientHooks, req *http.Request) (context.Context, error) {
	if h == nil || h.RequestPrepared == nil {
		return ctx, nil
	}
	return h.RequestPrepared(ctx, req)
}

func callClientError(ctx context.Context, h *twirp.ClientHooks, err twirp.Error) {
	if h == nil || h.Error == nil {
		return
	}
	h.Error(ctx, err)
}

var twirpFileDescriptor0 = []byte{
	// 1210 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0xcb, 0x6e, 0x1c, 0x45,
	0x17, 0x56, 0xf7, 0x8c, 0x67, 0xa6, 0xcf, 0xd8, 0x8e, 0x53, 0x7f, 0xf2, 0xa7, 0x33, 0xb9, 0x99,
	0x56, 0x22, 0x99, 0x8b, 0x66, 0x88, 0x61, 0x11, 0x21, 0x81, 0x88, 0x1d, 0x12, 0x22, 0x85, 0x10,
	0x95, 0x93, 0x0d, 0x9b, 0x56, 0x4d, 0x77, 0x79, 0xa6, 0x71, 0x77, 0x57, 0xbb, 0xaa, 0x7a, 0x90,
	0x17, 0xec, 0x79, 0x0c, 0xc4, 0x23, 0xb0, 0x00, 0x89, 0x2d, 0x62, 0xc7, 0x03, 0xf0, 0x38, 0xa8,
	0x6e, 0x3d, 0x97, 0x8c, 0x13, 0xcc, 0x82, 0x55, 0x57, 0x9d, 0xf3, 0xd5, 0xa9, 0x73, 0xbe, 0x73,
	0xa9, 0x86, 0x4d, 0x21, 0x89, 0xac, 0xc5, 0xb0, 0xe2, 0x4c, 0x32, 0xd4, 0x31, 0xbb, 0xc1, 0x9d,
	0x09, 0x63, 0x93, 0x9c, 0x8e, 0xb4, 0x74, 0x5c, 0x1f, 0x8f, 0x64, 0x56, 0x50, 0x21, 0x49, 0x51,
	0x19, 0x60, 0xf4, 0xab, 0x07, 0x37, 0x9f, 0x50, 0xf9, 0xb4, 0x4c, 0x38, 0x2d, 0x68, 0x29, 0x49,
	0x7e, 0xc8, 0x8a, 0x22, 0x93, 0x02, 0xd3, 0xd3, 0x9a, 0x0a, 0x89, 0x86, 0xd0, 0x3e, 0xe6, 0xac,
	0x08, 0xbd, 0x5d, 0x6f, 0xaf, 0xbf, 0x3f, 0x18, 0x1a, 0x83, 0x43, 0x67, 0x70, 0xf8, 0xd2, 0x19,
	0xc4, 0x1a, 0x87, 0xde, 0x03, 0x5f, 0xb2, 0xd0, 0x7f, 0x2b, 0xda, 0x97, 0x0c, 0x6d, 0x82, 0x57,
	0x86, 0xad, 0x5d, 0x6f, 0xaf, 0x85, 0xbd, 0x12, 0xed, 0x40, 0xab, 0x62, 0x69, 0xd8, 0xde, 0xf5,
	0xf6, 0x02, 0xac, 0x96, 0xe8, 0x06, 0x04, 0x9c, 0x56, 0x2c, 0xae, 0x88, 0x9c, 0x86, 0x1b, 0x5a,
	0xde, 0x53, 0x82, 0x17, 0x44, 0x4e, 0xa3, 0x1f, 0x3c, 0xb8, 0x75, 0x8e, 0xe7, 0xa2, 0x62, 0xa5,
	0xa0, 0xe8, 0x63, 0xe8, 0x15, 0x54, 0x92, 0x94, 0x48, 0x62, 0xdd, 0x0f, 0x87, 0x96, 0x25, 0x87,
	0xf9, 0xca, 0xea, 0x71, 0x83, 0x44, 0xf7, 0xa1, 0x53, 0x57, 0x29, 0x91, 0xd4, 0x06, 0x71, 0xdd,
	0x9d, 0x59, 0xb8, 0xe9, 0x95, 0x06, 0x60, 0x0b, 0x8c, 0xfe, 0xf0, 0xe0, 0xf2, 0x6b, 0x5a, 0xf4,
	0x01, 0x74, 0x13, 0xe3, 0x51, 0xe8, 0xed, 0xb6, 0xf6, 0xfa, 0xfb, 0xc8, 0x59, 0x7a, 0xc6, 0xca,
	0x89, 0x71, 0x16, 0x3b, 0x08, 0xba, 0x0f, 0x9b, 0x63, 0x4e, 0xca, 0x64, 0x1a, 0x4f, 0x29, 0x49,
	0x45, 0xe8, 0xeb, 0x23, 0xdb, 0xee, 0xc8, 0x81, 0xd6, 0xe1, 0xbe, 0xc1, 0x7c, 0xa9, 0x20, 0x28,
	0x82, 0x0d, 0x49, 0xc4, 0x89, 0x08, 0x5b, 0x1a, 0xbb, 0xe9, 0xb0, 0x2f, 0x89, 0x38, 0xc1, 0x46,
	0x85, 0xde, 0x87, 0x9e, 0xba, 0x81, 0x96, 0x52, 0x84, 0x6d, 0x0d, 0xbb, 0xe4, 0x60, 0x87, 0x46,
	0x8e, 0x1b, 0x40, 0xf4, 0x21, 0x74, 0xcc, 0x3d, 0x08, 0x41, 0xbb, 0x24, 0x05, 0xd5, 0xb4, 0x05,
	0x58, 0xaf, 0x95, 0x4c, 0xb9, 0xa6, 0x69, 0x09, 0xb0, 0x5e, 0x47, 0x3f, 0x79, 0xd0, 0x56, 0xd7,
	0xa1, 0x70, 0x39, 0xd8, 0x60, 0x1e, 0x98, 0x33, 0xe5, 0x2f, 0x98, 0xda, 0x06, 0x3f, 0x4b, 0x75,
	0xe6, 0x03, 0xec, 0x67, 0x29, 0x1a, 0x40, 0x8f, 0xd3, 0x59, 0x26, 0x32, 0x56, 0xda, 0xfc, 0x37,
	0x7b, 0xf4, 0x7f, 0xb0, 0xc5, 0x6c, 0x2b, 0xc0, 0xee, 0xd0, 0x1e, 0xec, 0x88, 0xef, 0x08, 0x2f,
	0xb2, 0x72, 0x12, 0xab, 0x58, 0xe3, 0x2c, 0x0d, 0x3b, 0x1a, 0xb1, 0xed, 0xe4, 0xca, 0xb3, 0xa7,
	0x69, 0xf4, 0x9b, 0x07, 0x30, 0xa7, 0x5c, 0xc7, 0x41, 0xc4, 0xd4, 0xc5, 0xa6, 0xd6, 0xea, 0x12,
	0x52, 0xcb, 0x29, 0xe3, 0xd6, 0x4d, 0xbb, 0x53, 0x61, 0x89, 0x7a, 0xfc, 0x2d, 0x4d, 0xa4, 0xf5,
	0xd6, 0x6d, 0x95, 0xa6, 0x22, 0xbc, 0xe1, 0x35, 0xc0, 0x6e, 0xab, 0xec, 0x8f, 0x59, 0x7a, 0x66,
	0xdd, 0xd5, 0x6b, 0xf4, 0x00, 0x82, 0xa6, 0xf3, 0xb4, 0x97, 0x6f, 0x6e, 0x8e, 0x39, 0x38, 0xfa,
	0xdd, 0x87, 0xae, 0xcd, 0x94, 0xa5, 0xcd, 0x6b, 0x68, 0x43, 0xd0, 0x56, 0xed, 0xe0, 0xa8, 0x55,
	0xeb, 0xe5, 0x9b, 0x5a, 0x17, 0xb8, 0x49, 0x59, 0xab, 0x05, 0xe5, 0x36, 0x01, 0x7a, 0xad, 0xa2,
	0x2c, 0xa8, 0x10, 0x64, 0x42, 0x6d, 0x38, 0x6e, 0xab, 0x34, 0x29, 0xcd, 0xa9, 0xa4, 0x86, 0xf5,
	0x1e, 0x76, 0x5b, 0x74, 0x0f, 0xb6, 0xb3, 0x49, 0xc9, 0x38, 0x8d, 0x8f, 0x49, 0x96, 0xd7, 0x9c,
	0x86, 0x5d, 0x0d, 0xd8, 0x32, 0xd2, 0xc7, 0x46, 0x88, 0xae, 0xc0, 0xc6, 0x71, 0x4e, 0x4e, 0xce,
	0xc2, 0x9e, 0xd6, 0x9a, 0x0d, 0xba, 0x0b, 0xdb, 0x3a, 0x99, 0xa2, 0xa2, 0x49, 0xac, 0xeb, 0x26,
	0xd0, 0xf7, 0x6e, 0x2a, 0xe9, 0x51, 0x45, 0x93, 0xe7, 0xaa, 0x7e, 0xae, 0x41, 0xd7, 0xa5, 0x1c,
	0x4c, 0xbe, 0xa4, 0x4e, 0xb5, 0xca, 0xa3, 0xa9, 0xbb, 0xb0, 0x6f, 0xe4, 0x66, 0x17, 0x7d, 0x0f,
	0x3b, 0xab, 0x2d, 0x8f, 0x6e, 0x01, 0x08, 0x49, 0xb8, 0x8c, 0xd9, 0x8c, 0x72, 0xcd, 0x6a, 0x0f,
	0x07, 0x5a, 0xf2, 0xf5, 0x8c, 0x72, 0x37, 0x8e, 0xfc, 0xf9, 0x38, 0xfa, 0xd7, 0xd4, 0x46, 0x7f,
	0x7a, 0x70, 0xf9, 0x61, 0x9a, 0xba, 0x8e, 0xb3, 0xa3, 0xd5, 0xa5, 0xcf, 0x5b, 0x48, 0xdf, 0x3c,
	0x00, 0x7f, 0x31, 0x00, 0x35, 0x0a, 0x1b, 0x5e, 0x6c, 0x29, 0xf6, 0x1c, 0x25, 0x8b, 0x74, 0xb4,
	0x97, 0xe8, 0x38, 0x3f, 0x7d, 0x0d, 0xfb, 0x9d, 0x45, 0xf6, 0xff, 0x59, 0xea, 0xa2, 0xe7, 0x80,
	0x16, 0xa3, 0xb1, 0xe3, 0x76, 0x89, 0x1e, 0xef, 0x22, 0xf4, 0xfc, 0xec, 0xc1, 0x95, 0x47, 0xba,
	0x7a, 0xfe, 0x73, 0x86, 0x96, 0x9c, 0xde, 0xb8, 0x88, 0xd3, 0xd7, 0xe0, 0xea, 0x8a, 0xcf, 0x86,
	0x87, 0xe8, 0xb6, 0x7e, 0x51, 0x1f, 0xd6, 0x92, 0x71, 0x96, 0xe7, 0x94, 0x1f, 0xe9, 0x79, 0x45,
	0xdd, 0x8b, 0x1a, 0x1d, 0xe9, 0x77, 0x6b, 0x9d, 0xde, 0x12, 0xb9, 0x0f, 0x5d, 0xa3, 0x71, 0x0f,
	0x47, 0xf3, 0x6c, 0xad, 0x1e, 0xc2, 0x0e, 0x18, 0xfd, 0xe5, 0xc1, 0xce, 0xaa, 0x76, 0xed, 0x14,
	0xdf, 0x83, 0x9d, 0xa4, 0xe6, 0x6a, 0x52, 0xc5, 0x0a, 0x1b, 0x73, 0x3a, 0xb3, 0x44, 0x6e, 0x5b,
	0x39, 0x66, 0x79, 0x8e, 0xe9, 0x0c, 0x45, 0xb0, 0x95, 0x13, 0xb1, 0x00, 0x33, 0xa4, 0xf6, 0x95,
	0xd0, 0x61, 0x10, 0xb4, 0x0b, 0x96, 0x52, 0x37, 0x33, 0xd4, 0x5a, 0xf5, 0x55, 0x59, 0x17, 0xba,
	0x82, 0x68, 0xaa, 0x39, 0xdd, 0xc0, 0x41, 0x59, 0x17, 0x8f, 0xb5, 0xc0, 0xa9, 0xc7, 0x74, 0x9a,
	0x95, 0x66, 0x76, 0x18, 0xf5, 0x81, 0x16, 0xa8, 0xb6, 0xab, 0x79, 0xae, 0xeb, 0x2e, 0xc0, 0x6a,
	0x19, 0x5d, 0x01, 0xf4, 0x84, 0xca, 0x03, 0x26, 0x5f, 0xa9, 0xca, 0x75, 0x2c, 0x7e, 0x0e, 0xff,
	0x5b, 0x92, 0x5a, 0xee, 0xde, 0x85, 0xde, 0x98, 0xc9, 0x58, 0xd0, 0xe6, 0xd5, 0x9d, 0x3f, 0xa1,
	0x4c, 0x1e, 0x51, 0x89, 0xbb, 0x63, 0xfd, 0x15, 0xd1, 0x8f, 0x3e, 0x74, 0x8c, 0x0c, 0x7d, 0x06,
	0x90, 0x66, 0x05, 0x2d, 0xd5, 0x83, 0xe3, 0xce, 0xdd, 0x5e, 0x3e, 0x37, 0x7c, 0xd4, 0x00, 0xbe,
	0x28, 0x25, 0x3f, 0xc3, 0x0b, 0x27, 0x54, 0xed, 0xa9, 0x5b, 0x13, 0x56, 0x97, 0xa6, 0x2c, 0x37,
	0xb0, 0x72, 0xe3, 0x50, 0xed, 0xd1, 0x75, 0xe8, 0x25, 0xa7, 0xb1, 0x7b, 0xa9, 0x95, 0xae, 0x9b,
	0x9c, 0xbe, 0xd4, 0xaf, 0xf3, 0x00, 0x82, 0x42, 0xc4, 0x15, 0xe5, 0x71, 0x72, 0xaa, 0x39, 0x6c,
	0xe1, 0x6e, 0x21, 0x5e, 0x50, 0x7e, 0x78, 0x8a, 0xee, 0x40, 0x5f, 0x32, 0x49, 0x72, 0x7b, 0xd2,
	0xf0, 0x08, 0x5a, 0x64, 0x0e, 0x47, 0xb0, 0xe5, 0x0e, 0x9b, 0x7e, 0xe8, 0x68, 0x03, 0x7d, 0x63,
	0x40, 0x8b, 0x06, 0x9f, 0xc2, 0xa5, 0x15, 0xbf, 0x15, 0xc1, 0x27, 0xf4, 0xcc, 0xd6, 0x84, 0x5a,
	0xaa, 0x59, 0x30, 0x23, 0x79, 0xed, 0x9e, 0x68, 0xb3, 0xf9, 0xc4, 0x7f, 0xe0, 0xed, 0xff, 0xd2,
	0x82, 0x2d, 0x53, 0x4b, 0x47, 0x94, 0xcf, 0xb2, 0x84, 0xa2, 0x14, 0xae, 0xae, 0xfd, 0xe9, 0x42,
	0x77, 0x1d, 0x5d, 0x6f, 0xfa, 0x9b, 0x1c, 0xdc, 0x7b, 0x0b, 0xca, 0x66, 0xf1, 0x10, 0x60, 0x3e,
	0x60, 0x50, 0xf3, 0x07, 0xf6, 0xda, 0x08, 0x1d, 0x0c, 0xd6, 0xa9, 0xac, 0x91, 0x67, 0xb0, 0xb5,
	0xd4, 0xa0, 0xe8, 0xa6, 0x03, 0xaf, 0x9b, 0x35, 0x83, 0x5b, 0xe7, 0x68, 0xad, 0x35, 0x13, 0xf8,
	0xeb, 0x5d, 0xbb, 0x14, 0xf8, 0xb9, 0x4d, 0xbf, 0x14, 0xf8, 0x1b, 0x5a, 0xff, 0x31, 0xf4, 0x17,
	0xaa, 0x1a, 0x0d, 0x16, 0x4e, 0xad, 0x34, 0xc0, 0xe0, 0xc6, 0x5a, 0x9d, 0xb1, 0x73, 0xf0, 0xce,
	0x37, 0x77, 0x26, 0x6c, 0x28, 0x4e, 0x32, 0x32, 0x64, 0x7c, 0x32, 0xca, 0xca, 0x63, 0x4e, 0x46,
	0x06, 0x3f, 0x9a, 0xb0, 0x11, 0xaf, 0x92, 0x71, 0x47, 0x8f, 0xb7, 0x8f, 0xfe, 0x0e, 0x00, 0x00,
	0xff, 0xff, 0x76, 0x57, 0x61, 0x3d, 0x39, 0x0c, 0x00, 0x00,
}
