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