// Code generated by protoc-gen-twirp v7.1.0, DO NOT EDIT.
// source: rpc.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:
	rpc.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

// ==============================
// TaskSchedulerService Interface
// ==============================

// TaskSchedulerService provides interactions with the Task Scheduler frontend.
type TaskSchedulerService interface {
	// TriggerJobs triggers the given jobs.
	TriggerJobs(context.Context, *TriggerJobsRequest) (*TriggerJobsResponse, error)

	// GetJob returns the given job.
	GetJob(context.Context, *GetJobRequest) (*GetJobResponse, error)

	// CancelJob cancels the given job.
	CancelJob(context.Context, *CancelJobRequest) (*CancelJobResponse, error)

	// SearchJobs searches the DB and returns jobs matching the given criteria.
	SearchJobs(context.Context, *SearchJobsRequest) (*SearchJobsResponse, error)

	// GetTask returns the given task.
	GetTask(context.Context, *GetTaskRequest) (*GetTaskResponse, error)

	// SearchTasks searches the DB and returns tasks matching the given
	// criteria.
	SearchTasks(context.Context, *SearchTasksRequest) (*SearchTasksResponse, error)

	// GetSkipTaskRules returns all active rules for skipping tasks.
	GetSkipTaskRules(context.Context, *GetSkipTaskRulesRequest) (*GetSkipTaskRulesResponse, error)

	// AddSkipTaskRule adds a rule for skipping tasks.
	AddSkipTaskRule(context.Context, *AddSkipTaskRuleRequest) (*AddSkipTaskRuleResponse, error)

	// DeleteSkipTaskRule deletes the given rule for skipping tasks.
	DeleteSkipTaskRule(context.Context, *DeleteSkipTaskRuleRequest) (*DeleteSkipTaskRuleResponse, error)
}

// ====================================
// TaskSchedulerService Protobuf Client
// ====================================

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

// NewTaskSchedulerServiceProtobufClient creates a Protobuf client that implements the TaskSchedulerService interface.
// It communicates using Protobuf and can be configured with a custom HTTPClient.
func NewTaskSchedulerServiceProtobufClient(baseURL string, client HTTPClient, opts ...twirp.ClientOption) TaskSchedulerService {
	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(), "task_scheduler.rpc", "TaskSchedulerService")
	urls := [9]string{
		serviceURL + "TriggerJobs",
		serviceURL + "GetJob",
		serviceURL + "CancelJob",
		serviceURL + "SearchJobs",
		serviceURL + "GetTask",
		serviceURL + "SearchTasks",
		serviceURL + "GetSkipTaskRules",
		serviceURL + "AddSkipTaskRule",
		serviceURL + "DeleteSkipTaskRule",
	}

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

func (c *taskSchedulerServiceProtobufClient) TriggerJobs(ctx context.Context, in *TriggerJobsRequest) (*TriggerJobsResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "task_scheduler.rpc")
	ctx = ctxsetters.WithServiceName(ctx, "TaskSchedulerService")
	ctx = ctxsetters.WithMethodName(ctx, "TriggerJobs")
	caller := c.callTriggerJobs
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *TriggerJobsRequest) (*TriggerJobsResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*TriggerJobsRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*TriggerJobsRequest) when calling interceptor")
					}
					return c.callTriggerJobs(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*TriggerJobsResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*TriggerJobsResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *taskSchedulerServiceProtobufClient) callTriggerJobs(ctx context.Context, in *TriggerJobsRequest) (*TriggerJobsResponse, error) {
	out := new(TriggerJobsResponse)
	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 *taskSchedulerServiceProtobufClient) GetJob(ctx context.Context, in *GetJobRequest) (*GetJobResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "task_scheduler.rpc")
	ctx = ctxsetters.WithServiceName(ctx, "TaskSchedulerService")
	ctx = ctxsetters.WithMethodName(ctx, "GetJob")
	caller := c.callGetJob
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *GetJobRequest) (*GetJobResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*GetJobRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*GetJobRequest) when calling interceptor")
					}
					return c.callGetJob(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*GetJobResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*GetJobResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *taskSchedulerServiceProtobufClient) callGetJob(ctx context.Context, in *GetJobRequest) (*GetJobResponse, error) {
	out := new(GetJobResponse)
	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 *taskSchedulerServiceProtobufClient) CancelJob(ctx context.Context, in *CancelJobRequest) (*CancelJobResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "task_scheduler.rpc")
	ctx = ctxsetters.WithServiceName(ctx, "TaskSchedulerService")
	ctx = ctxsetters.WithMethodName(ctx, "CancelJob")
	caller := c.callCancelJob
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *CancelJobRequest) (*CancelJobResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*CancelJobRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*CancelJobRequest) when calling interceptor")
					}
					return c.callCancelJob(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*CancelJobResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*CancelJobResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *taskSchedulerServiceProtobufClient) callCancelJob(ctx context.Context, in *CancelJobRequest) (*CancelJobResponse, error) {
	out := new(CancelJobResponse)
	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 *taskSchedulerServiceProtobufClient) SearchJobs(ctx context.Context, in *SearchJobsRequest) (*SearchJobsResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "task_scheduler.rpc")
	ctx = ctxsetters.WithServiceName(ctx, "TaskSchedulerService")
	ctx = ctxsetters.WithMethodName(ctx, "SearchJobs")
	caller := c.callSearchJobs
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *SearchJobsRequest) (*SearchJobsResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*SearchJobsRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*SearchJobsRequest) when calling interceptor")
					}
					return c.callSearchJobs(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*SearchJobsResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*SearchJobsResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *taskSchedulerServiceProtobufClient) callSearchJobs(ctx context.Context, in *SearchJobsRequest) (*SearchJobsResponse, error) {
	out := new(SearchJobsResponse)
	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 *taskSchedulerServiceProtobufClient) GetTask(ctx context.Context, in *GetTaskRequest) (*GetTaskResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "task_scheduler.rpc")
	ctx = ctxsetters.WithServiceName(ctx, "TaskSchedulerService")
	ctx = ctxsetters.WithMethodName(ctx, "GetTask")
	caller := c.callGetTask
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *GetTaskRequest) (*GetTaskResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*GetTaskRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*GetTaskRequest) when calling interceptor")
					}
					return c.callGetTask(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*GetTaskResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*GetTaskResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *taskSchedulerServiceProtobufClient) callGetTask(ctx context.Context, in *GetTaskRequest) (*GetTaskResponse, error) {
	out := new(GetTaskResponse)
	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
}

func (c *taskSchedulerServiceProtobufClient) SearchTasks(ctx context.Context, in *SearchTasksRequest) (*SearchTasksResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "task_scheduler.rpc")
	ctx = ctxsetters.WithServiceName(ctx, "TaskSchedulerService")
	ctx = ctxsetters.WithMethodName(ctx, "SearchTasks")
	caller := c.callSearchTasks
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *SearchTasksRequest) (*SearchTasksResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*SearchTasksRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*SearchTasksRequest) when calling interceptor")
					}
					return c.callSearchTasks(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*SearchTasksResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*SearchTasksResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *taskSchedulerServiceProtobufClient) callSearchTasks(ctx context.Context, in *SearchTasksRequest) (*SearchTasksResponse, error) {
	out := new(SearchTasksResponse)
	ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[5], 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 *taskSchedulerServiceProtobufClient) GetSkipTaskRules(ctx context.Context, in *GetSkipTaskRulesRequest) (*GetSkipTaskRulesResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "task_scheduler.rpc")
	ctx = ctxsetters.WithServiceName(ctx, "TaskSchedulerService")
	ctx = ctxsetters.WithMethodName(ctx, "GetSkipTaskRules")
	caller := c.callGetSkipTaskRules
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *GetSkipTaskRulesRequest) (*GetSkipTaskRulesResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*GetSkipTaskRulesRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*GetSkipTaskRulesRequest) when calling interceptor")
					}
					return c.callGetSkipTaskRules(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*GetSkipTaskRulesResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*GetSkipTaskRulesResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *taskSchedulerServiceProtobufClient) callGetSkipTaskRules(ctx context.Context, in *GetSkipTaskRulesRequest) (*GetSkipTaskRulesResponse, error) {
	out := new(GetSkipTaskRulesResponse)
	ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[6], 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 *taskSchedulerServiceProtobufClient) AddSkipTaskRule(ctx context.Context, in *AddSkipTaskRuleRequest) (*AddSkipTaskRuleResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "task_scheduler.rpc")
	ctx = ctxsetters.WithServiceName(ctx, "TaskSchedulerService")
	ctx = ctxsetters.WithMethodName(ctx, "AddSkipTaskRule")
	caller := c.callAddSkipTaskRule
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *AddSkipTaskRuleRequest) (*AddSkipTaskRuleResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*AddSkipTaskRuleRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*AddSkipTaskRuleRequest) when calling interceptor")
					}
					return c.callAddSkipTaskRule(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*AddSkipTaskRuleResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*AddSkipTaskRuleResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *taskSchedulerServiceProtobufClient) callAddSkipTaskRule(ctx context.Context, in *AddSkipTaskRuleRequest) (*AddSkipTaskRuleResponse, error) {
	out := new(AddSkipTaskRuleResponse)
	ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[7], 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 *taskSchedulerServiceProtobufClient) DeleteSkipTaskRule(ctx context.Context, in *DeleteSkipTaskRuleRequest) (*DeleteSkipTaskRuleResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "task_scheduler.rpc")
	ctx = ctxsetters.WithServiceName(ctx, "TaskSchedulerService")
	ctx = ctxsetters.WithMethodName(ctx, "DeleteSkipTaskRule")
	caller := c.callDeleteSkipTaskRule
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *DeleteSkipTaskRuleRequest) (*DeleteSkipTaskRuleResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*DeleteSkipTaskRuleRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*DeleteSkipTaskRuleRequest) when calling interceptor")
					}
					return c.callDeleteSkipTaskRule(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*DeleteSkipTaskRuleResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*DeleteSkipTaskRuleResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *taskSchedulerServiceProtobufClient) callDeleteSkipTaskRule(ctx context.Context, in *DeleteSkipTaskRuleRequest) (*DeleteSkipTaskRuleResponse, error) {
	out := new(DeleteSkipTaskRuleResponse)
	ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[8], 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
}

// ================================
// TaskSchedulerService JSON Client
// ================================

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

// NewTaskSchedulerServiceJSONClient creates a JSON client that implements the TaskSchedulerService interface.
// It communicates using JSON and can be configured with a custom HTTPClient.
func NewTaskSchedulerServiceJSONClient(baseURL string, client HTTPClient, opts ...twirp.ClientOption) TaskSchedulerService {
	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(), "task_scheduler.rpc", "TaskSchedulerService")
	urls := [9]string{
		serviceURL + "TriggerJobs",
		serviceURL + "GetJob",
		serviceURL + "CancelJob",
		serviceURL + "SearchJobs",
		serviceURL + "GetTask",
		serviceURL + "SearchTasks",
		serviceURL + "GetSkipTaskRules",
		serviceURL + "AddSkipTaskRule",
		serviceURL + "DeleteSkipTaskRule",
	}

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

func (c *taskSchedulerServiceJSONClient) TriggerJobs(ctx context.Context, in *TriggerJobsRequest) (*TriggerJobsResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "task_scheduler.rpc")
	ctx = ctxsetters.WithServiceName(ctx, "TaskSchedulerService")
	ctx = ctxsetters.WithMethodName(ctx, "TriggerJobs")
	caller := c.callTriggerJobs
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *TriggerJobsRequest) (*TriggerJobsResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*TriggerJobsRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*TriggerJobsRequest) when calling interceptor")
					}
					return c.callTriggerJobs(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*TriggerJobsResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*TriggerJobsResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *taskSchedulerServiceJSONClient) callTriggerJobs(ctx context.Context, in *TriggerJobsRequest) (*TriggerJobsResponse, error) {
	out := new(TriggerJobsResponse)
	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 *taskSchedulerServiceJSONClient) GetJob(ctx context.Context, in *GetJobRequest) (*GetJobResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "task_scheduler.rpc")
	ctx = ctxsetters.WithServiceName(ctx, "TaskSchedulerService")
	ctx = ctxsetters.WithMethodName(ctx, "GetJob")
	caller := c.callGetJob
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *GetJobRequest) (*GetJobResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*GetJobRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*GetJobRequest) when calling interceptor")
					}
					return c.callGetJob(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*GetJobResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*GetJobResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *taskSchedulerServiceJSONClient) callGetJob(ctx context.Context, in *GetJobRequest) (*GetJobResponse, error) {
	out := new(GetJobResponse)
	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 *taskSchedulerServiceJSONClient) CancelJob(ctx context.Context, in *CancelJobRequest) (*CancelJobResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "task_scheduler.rpc")
	ctx = ctxsetters.WithServiceName(ctx, "TaskSchedulerService")
	ctx = ctxsetters.WithMethodName(ctx, "CancelJob")
	caller := c.callCancelJob
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *CancelJobRequest) (*CancelJobResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*CancelJobRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*CancelJobRequest) when calling interceptor")
					}
					return c.callCancelJob(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*CancelJobResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*CancelJobResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *taskSchedulerServiceJSONClient) callCancelJob(ctx context.Context, in *CancelJobRequest) (*CancelJobResponse, error) {
	out := new(CancelJobResponse)
	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 *taskSchedulerServiceJSONClient) SearchJobs(ctx context.Context, in *SearchJobsRequest) (*SearchJobsResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "task_scheduler.rpc")
	ctx = ctxsetters.WithServiceName(ctx, "TaskSchedulerService")
	ctx = ctxsetters.WithMethodName(ctx, "SearchJobs")
	caller := c.callSearchJobs
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *SearchJobsRequest) (*SearchJobsResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*SearchJobsRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*SearchJobsRequest) when calling interceptor")
					}
					return c.callSearchJobs(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*SearchJobsResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*SearchJobsResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *taskSchedulerServiceJSONClient) callSearchJobs(ctx context.Context, in *SearchJobsRequest) (*SearchJobsResponse, error) {
	out := new(SearchJobsResponse)
	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 *taskSchedulerServiceJSONClient) GetTask(ctx context.Context, in *GetTaskRequest) (*GetTaskResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "task_scheduler.rpc")
	ctx = ctxsetters.WithServiceName(ctx, "TaskSchedulerService")
	ctx = ctxsetters.WithMethodName(ctx, "GetTask")
	caller := c.callGetTask
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *GetTaskRequest) (*GetTaskResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*GetTaskRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*GetTaskRequest) when calling interceptor")
					}
					return c.callGetTask(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*GetTaskResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*GetTaskResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *taskSchedulerServiceJSONClient) callGetTask(ctx context.Context, in *GetTaskRequest) (*GetTaskResponse, error) {
	out := new(GetTaskResponse)
	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
}

func (c *taskSchedulerServiceJSONClient) SearchTasks(ctx context.Context, in *SearchTasksRequest) (*SearchTasksResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "task_scheduler.rpc")
	ctx = ctxsetters.WithServiceName(ctx, "TaskSchedulerService")
	ctx = ctxsetters.WithMethodName(ctx, "SearchTasks")
	caller := c.callSearchTasks
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *SearchTasksRequest) (*SearchTasksResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*SearchTasksRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*SearchTasksRequest) when calling interceptor")
					}
					return c.callSearchTasks(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*SearchTasksResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*SearchTasksResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *taskSchedulerServiceJSONClient) callSearchTasks(ctx context.Context, in *SearchTasksRequest) (*SearchTasksResponse, error) {
	out := new(SearchTasksResponse)
	ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[5], 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 *taskSchedulerServiceJSONClient) GetSkipTaskRules(ctx context.Context, in *GetSkipTaskRulesRequest) (*GetSkipTaskRulesResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "task_scheduler.rpc")
	ctx = ctxsetters.WithServiceName(ctx, "TaskSchedulerService")
	ctx = ctxsetters.WithMethodName(ctx, "GetSkipTaskRules")
	caller := c.callGetSkipTaskRules
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *GetSkipTaskRulesRequest) (*GetSkipTaskRulesResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*GetSkipTaskRulesRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*GetSkipTaskRulesRequest) when calling interceptor")
					}
					return c.callGetSkipTaskRules(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*GetSkipTaskRulesResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*GetSkipTaskRulesResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *taskSchedulerServiceJSONClient) callGetSkipTaskRules(ctx context.Context, in *GetSkipTaskRulesRequest) (*GetSkipTaskRulesResponse, error) {
	out := new(GetSkipTaskRulesResponse)
	ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[6], 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 *taskSchedulerServiceJSONClient) AddSkipTaskRule(ctx context.Context, in *AddSkipTaskRuleRequest) (*AddSkipTaskRuleResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "task_scheduler.rpc")
	ctx = ctxsetters.WithServiceName(ctx, "TaskSchedulerService")
	ctx = ctxsetters.WithMethodName(ctx, "AddSkipTaskRule")
	caller := c.callAddSkipTaskRule
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *AddSkipTaskRuleRequest) (*AddSkipTaskRuleResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*AddSkipTaskRuleRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*AddSkipTaskRuleRequest) when calling interceptor")
					}
					return c.callAddSkipTaskRule(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*AddSkipTaskRuleResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*AddSkipTaskRuleResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *taskSchedulerServiceJSONClient) callAddSkipTaskRule(ctx context.Context, in *AddSkipTaskRuleRequest) (*AddSkipTaskRuleResponse, error) {
	out := new(AddSkipTaskRuleResponse)
	ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[7], 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 *taskSchedulerServiceJSONClient) DeleteSkipTaskRule(ctx context.Context, in *DeleteSkipTaskRuleRequest) (*DeleteSkipTaskRuleResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "task_scheduler.rpc")
	ctx = ctxsetters.WithServiceName(ctx, "TaskSchedulerService")
	ctx = ctxsetters.WithMethodName(ctx, "DeleteSkipTaskRule")
	caller := c.callDeleteSkipTaskRule
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *DeleteSkipTaskRuleRequest) (*DeleteSkipTaskRuleResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*DeleteSkipTaskRuleRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*DeleteSkipTaskRuleRequest) when calling interceptor")
					}
					return c.callDeleteSkipTaskRule(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*DeleteSkipTaskRuleResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*DeleteSkipTaskRuleResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *taskSchedulerServiceJSONClient) callDeleteSkipTaskRule(ctx context.Context, in *DeleteSkipTaskRuleRequest) (*DeleteSkipTaskRuleResponse, error) {
	out := new(DeleteSkipTaskRuleResponse)
	ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[8], 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
}

// ===================================
// TaskSchedulerService Server Handler
// ===================================

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

// NewTaskSchedulerServiceServer 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 NewTaskSchedulerServiceServer(svc TaskSchedulerService, 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 NewTaskSchedulerServiceServer", o))
		}
	}

	return &taskSchedulerServiceServer{
		TaskSchedulerService: 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 *taskSchedulerServiceServer) writeError(ctx context.Context, resp http.ResponseWriter, err error) {
	writeError(ctx, resp, err, s.hooks)
}

// TaskSchedulerServicePathPrefix 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 TaskSchedulerServicePathPrefix = "/twirp/task_scheduler.rpc.TaskSchedulerService/"

func (s *taskSchedulerServiceServer) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
	ctx := req.Context()
	ctx = ctxsetters.WithPackageName(ctx, "task_scheduler.rpc")
	ctx = ctxsetters.WithServiceName(ctx, "TaskSchedulerService")
	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 != "task_scheduler.rpc.TaskSchedulerService" {
		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 "TriggerJobs":
		s.serveTriggerJobs(ctx, resp, req)
		return
	case "GetJob":
		s.serveGetJob(ctx, resp, req)
		return
	case "CancelJob":
		s.serveCancelJob(ctx, resp, req)
		return
	case "SearchJobs":
		s.serveSearchJobs(ctx, resp, req)
		return
	case "GetTask":
		s.serveGetTask(ctx, resp, req)
		return
	case "SearchTasks":
		s.serveSearchTasks(ctx, resp, req)
		return
	case "GetSkipTaskRules":
		s.serveGetSkipTaskRules(ctx, resp, req)
		return
	case "AddSkipTaskRule":
		s.serveAddSkipTaskRule(ctx, resp, req)
		return
	case "DeleteSkipTaskRule":
		s.serveDeleteSkipTaskRule(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 *taskSchedulerServiceServer) serveTriggerJobs(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.serveTriggerJobsJSON(ctx, resp, req)
	case "application/protobuf":
		s.serveTriggerJobsProtobuf(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 *taskSchedulerServiceServer) serveTriggerJobsJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "TriggerJobs")
	ctx, err = callRequestRouted(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}

	reqContent := new(TriggerJobsRequest)
	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.TaskSchedulerService.TriggerJobs
	if s.interceptor != nil {
		handler = func(ctx context.Context, req *TriggerJobsRequest) (*TriggerJobsResponse, error) {
			resp, err := s.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*TriggerJobsRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*TriggerJobsRequest) when calling interceptor")
					}
					return s.TaskSchedulerService.TriggerJobs(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*TriggerJobsResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*TriggerJobsResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}

	// Call service method
	var respContent *TriggerJobsResponse
	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 *TriggerJobsResponse and nil error while calling TriggerJobs. 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 *taskSchedulerServiceServer) serveTriggerJobsProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "TriggerJobs")
	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(TriggerJobsRequest)
	if err = proto.Unmarshal(buf, reqContent); err != nil {
		s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded"))
		return
	}

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

	// Call service method
	var respContent *TriggerJobsResponse
	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 *TriggerJobsResponse and nil error while calling TriggerJobs. 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 *taskSchedulerServiceServer) serveGetJob(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.serveGetJobJSON(ctx, resp, req)
	case "application/protobuf":
		s.serveGetJobProtobuf(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 *taskSchedulerServiceServer) serveGetJobJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "GetJob")
	ctx, err = callRequestRouted(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}

	reqContent := new(GetJobRequest)
	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.TaskSchedulerService.GetJob
	if s.interceptor != nil {
		handler = func(ctx context.Context, req *GetJobRequest) (*GetJobResponse, error) {
			resp, err := s.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*GetJobRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*GetJobRequest) when calling interceptor")
					}
					return s.TaskSchedulerService.GetJob(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*GetJobResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*GetJobResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}

	// Call service method
	var respContent *GetJobResponse
	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 *GetJobResponse and nil error while calling GetJob. 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 *taskSchedulerServiceServer) serveGetJobProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "GetJob")
	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(GetJobRequest)
	if err = proto.Unmarshal(buf, reqContent); err != nil {
		s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded"))
		return
	}

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

	// Call service method
	var respContent *GetJobResponse
	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 *GetJobResponse and nil error while calling GetJob. 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 *taskSchedulerServiceServer) serveCancelJob(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.serveCancelJobJSON(ctx, resp, req)
	case "application/protobuf":
		s.serveCancelJobProtobuf(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 *taskSchedulerServiceServer) serveCancelJobJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "CancelJob")
	ctx, err = callRequestRouted(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}

	reqContent := new(CancelJobRequest)
	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.TaskSchedulerService.CancelJob
	if s.interceptor != nil {
		handler = func(ctx context.Context, req *CancelJobRequest) (*CancelJobResponse, error) {
			resp, err := s.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*CancelJobRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*CancelJobRequest) when calling interceptor")
					}
					return s.TaskSchedulerService.CancelJob(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*CancelJobResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*CancelJobResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}

	// Call service method
	var respContent *CancelJobResponse
	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 *CancelJobResponse and nil error while calling CancelJob. 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 *taskSchedulerServiceServer) serveCancelJobProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "CancelJob")
	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(CancelJobRequest)
	if err = proto.Unmarshal(buf, reqContent); err != nil {
		s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded"))
		return
	}

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

	// Call service method
	var respContent *CancelJobResponse
	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 *CancelJobResponse and nil error while calling CancelJob. 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 *taskSchedulerServiceServer) serveSearchJobs(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.serveSearchJobsJSON(ctx, resp, req)
	case "application/protobuf":
		s.serveSearchJobsProtobuf(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 *taskSchedulerServiceServer) serveSearchJobsJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "SearchJobs")
	ctx, err = callRequestRouted(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}

	reqContent := new(SearchJobsRequest)
	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.TaskSchedulerService.SearchJobs
	if s.interceptor != nil {
		handler = func(ctx context.Context, req *SearchJobsRequest) (*SearchJobsResponse, error) {
			resp, err := s.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*SearchJobsRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*SearchJobsRequest) when calling interceptor")
					}
					return s.TaskSchedulerService.SearchJobs(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*SearchJobsResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*SearchJobsResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}

	// Call service method
	var respContent *SearchJobsResponse
	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 *SearchJobsResponse and nil error while calling SearchJobs. 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 *taskSchedulerServiceServer) serveSearchJobsProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "SearchJobs")
	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(SearchJobsRequest)
	if err = proto.Unmarshal(buf, reqContent); err != nil {
		s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded"))
		return
	}

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

	// Call service method
	var respContent *SearchJobsResponse
	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 *SearchJobsResponse and nil error while calling SearchJobs. 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 *taskSchedulerServiceServer) serveGetTask(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.serveGetTaskJSON(ctx, resp, req)
	case "application/protobuf":
		s.serveGetTaskProtobuf(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 *taskSchedulerServiceServer) serveGetTaskJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "GetTask")
	ctx, err = callRequestRouted(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}

	reqContent := new(GetTaskRequest)
	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.TaskSchedulerService.GetTask
	if s.interceptor != nil {
		handler = func(ctx context.Context, req *GetTaskRequest) (*GetTaskResponse, error) {
			resp, err := s.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*GetTaskRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*GetTaskRequest) when calling interceptor")
					}
					return s.TaskSchedulerService.GetTask(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*GetTaskResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*GetTaskResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}

	// Call service method
	var respContent *GetTaskResponse
	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 *GetTaskResponse and nil error while calling GetTask. 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 *taskSchedulerServiceServer) serveGetTaskProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "GetTask")
	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(GetTaskRequest)
	if err = proto.Unmarshal(buf, reqContent); err != nil {
		s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded"))
		return
	}

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

	// Call service method
	var respContent *GetTaskResponse
	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 *GetTaskResponse and nil error while calling GetTask. 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 *taskSchedulerServiceServer) serveSearchTasks(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.serveSearchTasksJSON(ctx, resp, req)
	case "application/protobuf":
		s.serveSearchTasksProtobuf(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 *taskSchedulerServiceServer) serveSearchTasksJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "SearchTasks")
	ctx, err = callRequestRouted(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}

	reqContent := new(SearchTasksRequest)
	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.TaskSchedulerService.SearchTasks
	if s.interceptor != nil {
		handler = func(ctx context.Context, req *SearchTasksRequest) (*SearchTasksResponse, error) {
			resp, err := s.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*SearchTasksRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*SearchTasksRequest) when calling interceptor")
					}
					return s.TaskSchedulerService.SearchTasks(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*SearchTasksResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*SearchTasksResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}

	// Call service method
	var respContent *SearchTasksResponse
	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 *SearchTasksResponse and nil error while calling SearchTasks. 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 *taskSchedulerServiceServer) serveSearchTasksProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "SearchTasks")
	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(SearchTasksRequest)
	if err = proto.Unmarshal(buf, reqContent); err != nil {
		s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded"))
		return
	}

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

	// Call service method
	var respContent *SearchTasksResponse
	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 *SearchTasksResponse and nil error while calling SearchTasks. 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 *taskSchedulerServiceServer) serveGetSkipTaskRules(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.serveGetSkipTaskRulesJSON(ctx, resp, req)
	case "application/protobuf":
		s.serveGetSkipTaskRulesProtobuf(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 *taskSchedulerServiceServer) serveGetSkipTaskRulesJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "GetSkipTaskRules")
	ctx, err = callRequestRouted(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}

	reqContent := new(GetSkipTaskRulesRequest)
	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.TaskSchedulerService.GetSkipTaskRules
	if s.interceptor != nil {
		handler = func(ctx context.Context, req *GetSkipTaskRulesRequest) (*GetSkipTaskRulesResponse, error) {
			resp, err := s.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*GetSkipTaskRulesRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*GetSkipTaskRulesRequest) when calling interceptor")
					}
					return s.TaskSchedulerService.GetSkipTaskRules(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*GetSkipTaskRulesResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*GetSkipTaskRulesResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}

	// Call service method
	var respContent *GetSkipTaskRulesResponse
	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 *GetSkipTaskRulesResponse and nil error while calling GetSkipTaskRules. 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 *taskSchedulerServiceServer) serveGetSkipTaskRulesProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "GetSkipTaskRules")
	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(GetSkipTaskRulesRequest)
	if err = proto.Unmarshal(buf, reqContent); err != nil {
		s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded"))
		return
	}

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

	// Call service method
	var respContent *GetSkipTaskRulesResponse
	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 *GetSkipTaskRulesResponse and nil error while calling GetSkipTaskRules. 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 *taskSchedulerServiceServer) serveAddSkipTaskRule(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.serveAddSkipTaskRuleJSON(ctx, resp, req)
	case "application/protobuf":
		s.serveAddSkipTaskRuleProtobuf(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 *taskSchedulerServiceServer) serveAddSkipTaskRuleJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "AddSkipTaskRule")
	ctx, err = callRequestRouted(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}

	reqContent := new(AddSkipTaskRuleRequest)
	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.TaskSchedulerService.AddSkipTaskRule
	if s.interceptor != nil {
		handler = func(ctx context.Context, req *AddSkipTaskRuleRequest) (*AddSkipTaskRuleResponse, error) {
			resp, err := s.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*AddSkipTaskRuleRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*AddSkipTaskRuleRequest) when calling interceptor")
					}
					return s.TaskSchedulerService.AddSkipTaskRule(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*AddSkipTaskRuleResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*AddSkipTaskRuleResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}

	// Call service method
	var respContent *AddSkipTaskRuleResponse
	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 *AddSkipTaskRuleResponse and nil error while calling AddSkipTaskRule. 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 *taskSchedulerServiceServer) serveAddSkipTaskRuleProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "AddSkipTaskRule")
	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(AddSkipTaskRuleRequest)
	if err = proto.Unmarshal(buf, reqContent); err != nil {
		s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded"))
		return
	}

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

	// Call service method
	var respContent *AddSkipTaskRuleResponse
	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 *AddSkipTaskRuleResponse and nil error while calling AddSkipTaskRule. 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 *taskSchedulerServiceServer) serveDeleteSkipTaskRule(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.serveDeleteSkipTaskRuleJSON(ctx, resp, req)
	case "application/protobuf":
		s.serveDeleteSkipTaskRuleProtobuf(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 *taskSchedulerServiceServer) serveDeleteSkipTaskRuleJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "DeleteSkipTaskRule")
	ctx, err = callRequestRouted(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}

	reqContent := new(DeleteSkipTaskRuleRequest)
	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.TaskSchedulerService.DeleteSkipTaskRule
	if s.interceptor != nil {
		handler = func(ctx context.Context, req *DeleteSkipTaskRuleRequest) (*DeleteSkipTaskRuleResponse, error) {
			resp, err := s.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*DeleteSkipTaskRuleRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*DeleteSkipTaskRuleRequest) when calling interceptor")
					}
					return s.TaskSchedulerService.DeleteSkipTaskRule(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*DeleteSkipTaskRuleResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*DeleteSkipTaskRuleResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}

	// Call service method
	var respContent *DeleteSkipTaskRuleResponse
	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 *DeleteSkipTaskRuleResponse and nil error while calling DeleteSkipTaskRule. 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 *taskSchedulerServiceServer) serveDeleteSkipTaskRuleProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "DeleteSkipTaskRule")
	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(DeleteSkipTaskRuleRequest)
	if err = proto.Unmarshal(buf, reqContent); err != nil {
		s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded"))
		return
	}

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

	// Call service method
	var respContent *DeleteSkipTaskRuleResponse
	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 *DeleteSkipTaskRuleResponse and nil error while calling DeleteSkipTaskRule. 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 *taskSchedulerServiceServer) ServiceDescriptor() ([]byte, int) {
	return twirpFileDescriptor0, 0
}

func (s *taskSchedulerServiceServer) 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 *taskSchedulerServiceServer) PathPrefix() string {
	return baseServicePath(s.pathPrefix, "task_scheduler.rpc", "TaskSchedulerService")
}

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