From 3e4a40bcd517481fe241cdb18249dc8ae88eefd1 Mon Sep 17 00:00:00 2001 From: Erik Seliger Date: Sun, 28 Jan 2024 06:35:42 +0100 Subject: [PATCH] gitserver: Migrate Blame to rpc call (#59851) This PR migrates the first more sophisticated call to a gRPC equivalent. I had to generate quite a bunch of mocks and convert some things to interfaces to properly test this, so the diff looks scary but it's mostly generated code. Positive: Found a few bugs in the new gitcli backend by implementing these tests :) ## Test plan Added a ton of tests, tried blame manually. --- cmd/frontend/graphqlbackend/hunk.go | 3 +- cmd/frontend/internal/httpapi/stream_blame.go | 8 +- .../internal/httpapi/stream_blame_test.go | 37 +- cmd/gitserver/internal/BUILD.bazel | 9 + cmd/gitserver/internal/batchlog.go | 2 +- cmd/gitserver/internal/cleanup.go | 2 +- cmd/gitserver/internal/clone.go | 8 +- cmd/gitserver/internal/git/gitcli/BUILD.bazel | 3 + .../gitserver/internal/git/gitcli/blame.go | 98 +- .../internal/git/gitcli/blame_test.go | 451 +++ .../internal/git/gitcli/clibackend.go | 21 +- cmd/gitserver/internal/git/gitcli/exec.go | 21 +- cmd/gitserver/internal/git/iface.go | 21 + cmd/gitserver/internal/git/mock.go | 389 +++ .../integration_tests/archivereader_test.go | 2 +- .../internal/integration_tests/clone_test.go | 4 +- .../resolverevisions_test.go | 2 +- .../internal/integration_tests/test_utils.go | 2 +- cmd/gitserver/internal/mocks_test.go | 1312 ++++++++ cmd/gitserver/internal/p4exec.go | 15 +- cmd/gitserver/internal/p4exec_test.go | 2 +- cmd/gitserver/internal/patch.go | 2 +- cmd/gitserver/internal/repo_info_test.go | 2 +- cmd/gitserver/internal/search.go | 2 +- cmd/gitserver/internal/server.go | 24 +- cmd/gitserver/internal/server_grpc.go | 249 +- cmd/gitserver/internal/server_grpc_test.go | 176 + cmd/gitserver/internal/server_test.go | 16 +- cmd/gitserver/internal/statesyncer.go | 2 +- cmd/gitserver/shared/shared.go | 5 +- internal/gitserver/BUILD.bazel | 4 +- internal/gitserver/addrs.go | 28 +- internal/gitserver/addrs_test.go | 2 +- internal/gitserver/client.go | 49 +- internal/gitserver/commands.go | 143 +- internal/gitserver/commands_test.go | 318 +- internal/gitserver/gitdomain/BUILD.bazel | 1 + internal/gitserver/gitdomain/common.go | 55 + internal/gitserver/gitdomain/common_test.go | 17 + internal/gitserver/grpc_test.go | 4 +- internal/gitserver/mock.go | 1879 +++++++++++ internal/gitserver/retry.go | 5 + internal/gitserver/v1/gitserver.pb.go | 2929 ++++++++++------- internal/gitserver/v1/gitserver.proto | 55 + internal/gitserver/v1/gitserver_grpc.pb.go | 82 + mockgen.temp.yaml | 3 + mockgen.test.yaml | 6 + 47 files changed, 6714 insertions(+), 1756 deletions(-) rename internal/gitserver/stream_hunks.go => cmd/gitserver/internal/git/gitcli/blame.go (69%) create mode 100644 cmd/gitserver/internal/git/gitcli/blame_test.go create mode 100644 cmd/gitserver/internal/mocks_test.go create mode 100644 cmd/gitserver/internal/server_grpc_test.go diff --git a/cmd/frontend/graphqlbackend/hunk.go b/cmd/frontend/graphqlbackend/hunk.go index 1ffb19b8e9e..536396551f2 100644 --- a/cmd/frontend/graphqlbackend/hunk.go +++ b/cmd/frontend/graphqlbackend/hunk.go @@ -5,12 +5,13 @@ import ( "github.com/sourcegraph/sourcegraph/internal/database" "github.com/sourcegraph/sourcegraph/internal/gitserver" + "github.com/sourcegraph/sourcegraph/internal/gitserver/gitdomain" ) type hunkResolver struct { db database.DB repo *RepositoryResolver - hunk *gitserver.Hunk + hunk *gitdomain.Hunk } func (r *hunkResolver) Author() signatureResolver { diff --git a/cmd/frontend/internal/httpapi/stream_blame.go b/cmd/frontend/internal/httpapi/stream_blame.go index 20f8d625fbd..ca4da212b51 100644 --- a/cmd/frontend/internal/httpapi/stream_blame.go +++ b/cmd/frontend/internal/httpapi/stream_blame.go @@ -62,6 +62,10 @@ func handleStreamBlame(logger log.Logger, db database.DB, gitserverClient gitser }) if err != nil { tr.SetError(err) + if errcode.IsUnauthorized(err) { + http.Error(w, err.Error(), http.StatusForbidden) + return + } http.Error(w, err.Error(), http.StatusInternalServerError) return } @@ -167,8 +171,8 @@ func handleStreamBlame(logger log.Logger, db database.DB, gitserverClient gitser type BlameHunkResponse struct { api.CommitID `json:"commitID"` - StartLine int `json:"startLine"` // 1-indexed start line number - EndLine int `json:"endLine"` // 1-indexed end line number + StartLine uint32 `json:"startLine"` // 1-indexed start line number + EndLine uint32 `json:"endLine"` // 1-indexed end line number Author gitdomain.Signature `json:"author"` Message string `json:"message"` Filename string `json:"filename"` diff --git a/cmd/frontend/internal/httpapi/stream_blame_test.go b/cmd/frontend/internal/httpapi/stream_blame_test.go index 3a16bcb7c4a..10545b37ee1 100644 --- a/cmd/frontend/internal/httpapi/stream_blame_test.go +++ b/cmd/frontend/internal/httpapi/stream_blame_test.go @@ -2,6 +2,7 @@ package httpapi import ( "context" + "io" "net/http" "net/http/httptest" "testing" @@ -23,8 +24,34 @@ import ( "github.com/sourcegraph/sourcegraph/lib/errors" ) -func setupMockGSClient(t *testing.T, wantRev api.CommitID, returnErr error, hunks []*gitserver.Hunk) gitserver.Client { - hunkReader := gitserver.NewMockHunkReader(hunks, returnErr) +type mockHunkReader struct { + hunks []*gitdomain.Hunk + err error +} + +func newMockHunkReader(hunks []*gitdomain.Hunk, err error) gitserver.HunkReader { + return &mockHunkReader{ + hunks: hunks, + err: err, + } +} + +func (mh *mockHunkReader) Read() (*gitdomain.Hunk, error) { + if mh.err != nil { + return nil, mh.err + } + if len(mh.hunks) > 0 { + next := mh.hunks[0] + mh.hunks = mh.hunks[1:] + return next, nil + } + return nil, io.EOF +} + +func (mh *mockHunkReader) Close() error { return nil } + +func setupMockGSClient(t *testing.T, wantRev api.CommitID, returnErr error, hunks []*gitdomain.Hunk) gitserver.Client { + hunkReader := newMockHunkReader(hunks, returnErr) gsClient := gitserver.NewMockClient() gsClient.GetCommitFunc.SetDefaultHook( func(_ context.Context, @@ -54,7 +81,7 @@ func setupMockGSClient(t *testing.T, wantRev api.CommitID, returnErr error, hunk func TestStreamBlame(t *testing.T) { logger, _ := logtest.Captured(t) - hunks := []*gitserver.Hunk{ + hunks := []*gitdomain.Hunk{ { StartLine: 1, EndLine: 2, @@ -195,7 +222,7 @@ func TestStreamBlame(t *testing.T) { "Repo": "github.com/bob/foo", "path": "foo.c", }) - gsClient := setupMockGSClient(t, "efgh", nil, []*gitserver.Hunk{ + gsClient := setupMockGSClient(t, "efgh", nil, []*gitdomain.Hunk{ { StartLine: 1, EndLine: 2, @@ -244,7 +271,7 @@ func TestStreamBlame(t *testing.T) { "Repo": "foo", "path": "foo.c", }) - gsClient := setupMockGSClient(t, "efgh", nil, []*gitserver.Hunk{ + gsClient := setupMockGSClient(t, "efgh", nil, []*gitdomain.Hunk{ { StartLine: 1, EndLine: 2, diff --git a/cmd/gitserver/internal/BUILD.bazel b/cmd/gitserver/internal/BUILD.bazel index 17054e6fdc5..1f8bb630846 100644 --- a/cmd/gitserver/internal/BUILD.bazel +++ b/cmd/gitserver/internal/BUILD.bazel @@ -39,6 +39,7 @@ go_library( "//cmd/gitserver/internal/vcssyncer", "//internal/actor", "//internal/api", + "//internal/authz", "//internal/conf", "//internal/database", "//internal/database/dbutil", @@ -71,6 +72,7 @@ go_library( "//internal/wrexec", "//lib/errors", "//lib/gitservice", + "//lib/pointers", "@com_github_mxk_go_flowrate//flowrate", "@com_github_prometheus_client_golang//prometheus", "@com_github_prometheus_client_golang//prometheus/promauto", @@ -92,8 +94,10 @@ go_test( "cleanup_test.go", "list_gitolite_test.go", "main_test.go", + "mocks_test.go", "p4exec_test.go", "repo_info_test.go", + "server_grpc_test.go", "server_test.go", ], embed = [":internal"], @@ -114,12 +118,14 @@ go_test( "//cmd/gitserver/internal/vcssyncer", "//internal/actor", "//internal/api", + "//internal/authz", "//internal/conf", "//internal/database", "//internal/database/dbmocks", "//internal/database/dbtest", "//internal/extsvc/gitolite", "//internal/gitserver", + "//internal/gitserver/gitdomain", "//internal/gitserver/protocol", "//internal/gitserver/v1:gitserver", "//internal/grpc", @@ -127,12 +133,14 @@ go_test( "//internal/limiter", "//internal/observation", "//internal/ratelimit", + "//internal/trace", "//internal/types", "//internal/vcs", "//internal/wrexec", "//lib/errors", "//lib/pointers", "//schema", + "@com_github_derision_test_go_mockgen//testutil/assert", "@com_github_google_go_cmp//cmp", "@com_github_google_go_cmp//cmp/cmpopts", "@com_github_sourcegraph_log//:log", @@ -141,6 +149,7 @@ go_test( "@com_github_stretchr_testify//require", "@org_golang_google_grpc//codes", "@org_golang_google_grpc//status", + "@org_golang_google_protobuf//types/known/timestamppb", "@org_golang_x_sync//semaphore", "@org_golang_x_time//rate", ], diff --git a/cmd/gitserver/internal/batchlog.go b/cmd/gitserver/internal/batchlog.go index d8ee3a5f89b..dfe05b4fc8c 100644 --- a/cmd/gitserver/internal/batchlog.go +++ b/cmd/gitserver/internal/batchlog.go @@ -16,7 +16,7 @@ import ( // Note: The BatchLog endpoint has been deprecated. This file shall be removed after // the 5.3 release has been cut. -func (s *Server) batchGitLogInstrumentedHandler(ctx context.Context, req *proto.BatchLogRequest) (resp *proto.BatchLogResponse, err error) { +func (s *Server) BatchGitLogInstrumentedHandler(ctx context.Context, req *proto.BatchLogRequest) (resp *proto.BatchLogResponse, err error) { // Perform requests in each repository in the input batch. We perform these commands // concurrently, but only allow for so many commands to be in-flight at a time so that // we don't overwhelm a shard with either a large request or too many concurrent batch diff --git a/cmd/gitserver/internal/cleanup.go b/cmd/gitserver/internal/cleanup.go index 99809046676..16491c6d31e 100644 --- a/cmd/gitserver/internal/cleanup.go +++ b/cmd/gitserver/internal/cleanup.go @@ -288,7 +288,7 @@ func cleanupRepos( // Record the number of repos that should not belong on this instance and // remove up to SRC_WRONG_SHARD_DELETE_LIMIT in a single Janitor run. name := gitserverfs.RepoNameFromDir(reposDir, dir) - addr := addrForRepo(ctx, name, gitServerAddrs) + addr := gitServerAddrs.AddrForRepo(ctx, name) if hostnameMatch(shardID, addr) { return false, nil diff --git a/cmd/gitserver/internal/clone.go b/cmd/gitserver/internal/clone.go index 1aa2f3145ff..474e48b8eda 100644 --- a/cmd/gitserver/internal/clone.go +++ b/cmd/gitserver/internal/clone.go @@ -11,20 +11,20 @@ import ( "github.com/sourcegraph/sourcegraph/internal/gitserver/protocol" ) -// maybeStartClone checks if a given repository is cloned on disk. If not, it starts +// MaybeStartClone checks if a given repository is cloned on disk. If not, it starts // cloning the repository in the background and returns a NotFound error, if no current // clone operation is running for that repo yet. If it is already cloning, a NotFound // error with CloneInProgress: true is returned. // Note: If disableAutoGitUpdates is set in the site config, no operation is taken and // a NotFound error is returned. -func (s *Server) maybeStartClone(ctx context.Context, logger log.Logger, repo api.RepoName) (notFound *protocol.NotFoundPayload, cloned bool) { +func (s *Server) MaybeStartClone(ctx context.Context, repo api.RepoName) (notFound *protocol.NotFoundPayload, cloned bool) { dir := gitserverfs.RepoDirFromName(s.ReposDir, repo) if repoCloned(dir) { return nil, true } if conf.Get().DisableAutoGitUpdates { - logger.Debug("not cloning on demand as DisableAutoGitUpdates is set") + s.Logger.Debug("not cloning on demand as DisableAutoGitUpdates is set") return &protocol.NotFoundPayload{}, false } @@ -38,7 +38,7 @@ func (s *Server) maybeStartClone(ctx context.Context, logger log.Logger, repo ap cloneProgress, err := s.CloneRepo(ctx, repo, CloneOptions{}) if err != nil { - logger.Debug("error starting repo clone", log.String("repo", string(repo)), log.Error(err)) + s.Logger.Debug("error starting repo clone", log.String("repo", string(repo)), log.Error(err)) return &protocol.NotFoundPayload{CloneInProgress: false}, false } diff --git a/cmd/gitserver/internal/git/gitcli/BUILD.bazel b/cmd/gitserver/internal/git/gitcli/BUILD.bazel index 165d21e3255..42e032f120a 100644 --- a/cmd/gitserver/internal/git/gitcli/BUILD.bazel +++ b/cmd/gitserver/internal/git/gitcli/BUILD.bazel @@ -4,6 +4,7 @@ load("//dev:go_defs.bzl", "go_test") go_library( name = "gitcli", srcs = [ + "blame.go", "clibackend.go", "config.go", "exec.go", @@ -35,6 +36,7 @@ go_library( go_test( name = "gitcli_test", srcs = [ + "blame_test.go", "config_test.go", "exec_test.go", "mergebase_test.go", @@ -43,6 +45,7 @@ go_test( embed = [":gitcli"], deps = [ "//cmd/gitserver/internal/common", + "//cmd/gitserver/internal/git", "//internal/api", "//internal/gitserver", "//internal/gitserver/gitdomain", diff --git a/internal/gitserver/stream_hunks.go b/cmd/gitserver/internal/git/gitcli/blame.go similarity index 69% rename from internal/gitserver/stream_hunks.go rename to cmd/gitserver/internal/git/gitcli/blame.go index 60164b012cc..747d5dc60b1 100644 --- a/internal/gitserver/stream_hunks.go +++ b/cmd/gitserver/internal/git/gitcli/blame.go @@ -1,42 +1,84 @@ -package gitserver +package gitcli import ( "bufio" + "context" + "fmt" "io" + "path/filepath" "strconv" "strings" "time" + "github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/git" "github.com/sourcegraph/sourcegraph/internal/api" + "github.com/sourcegraph/sourcegraph/internal/gitserver/gitdomain" "github.com/sourcegraph/sourcegraph/lib/errors" ) +func (g *gitCLIBackend) Blame(ctx context.Context, path string, opt git.BlameOptions) (git.BlameHunkReader, error) { + if err := checkSpecArgSafety(string(opt.NewestCommit)); err != nil { + return nil, err + } + + cmd, cancel, err := g.gitCommand(ctx, buildBlameArgs(path, opt)...) + if err != nil { + cancel() + return nil, err + } + + r, err := g.runGitCommand(ctx, cmd) + if err != nil { + cancel() + return nil, err + } + + return newBlameHunkReader(r, cancel), nil +} + +func buildBlameArgs(path string, opt git.BlameOptions) []string { + args := []string{"blame", "--porcelain", "--incremental"} + if opt.IgnoreWhitespace { + args = append(args, "-w") + } + if opt.StartLine != 0 || opt.EndLine != 0 { + args = append(args, fmt.Sprintf("-L%d,%d", opt.StartLine, opt.EndLine)) + } + if opt.NewestCommit != "" { + args = append(args, string(opt.NewestCommit)) + } + args = append(args, "--", filepath.ToSlash(path)) + return args +} + // blameHunkReader enables to read hunks from an io.Reader. type blameHunkReader struct { - rc io.ReadCloser - sc *bufio.Scanner + rc io.ReadCloser + sc *bufio.Scanner + onClose func() - cur *Hunk + cur *gitdomain.Hunk // commits stores previously seen commits, so new hunks // whose annotations are abbreviated by git can still be // filled by the correct data even if the hunk entry doesn't // repeat them. - commits map[api.CommitID]*Hunk + commits map[api.CommitID]*gitdomain.Hunk } -func newBlameHunkReader(rc io.ReadCloser) HunkReader { +func newBlameHunkReader(rc io.ReadCloser, onClose func()) git.BlameHunkReader { return &blameHunkReader{ rc: rc, sc: bufio.NewScanner(rc), - commits: make(map[api.CommitID]*Hunk), + commits: make(map[api.CommitID]*gitdomain.Hunk), + onClose: onClose, } } // Read returns a slice of hunks, along with a done boolean indicating if there // is more to read. After the last hunk has been returned, Read() will return // an io.EOF error on success. -func (br *blameHunkReader) Read() (_ *Hunk, err error) { +func (br *blameHunkReader) Read() (_ *gitdomain.Hunk, err error) { for { // Do we have more to read? if !br.sc.Scan() { @@ -101,12 +143,14 @@ func (br *blameHunkReader) Read() (_ *Hunk, err error) { } func (br *blameHunkReader) Close() error { - return br.rc.Close() + err := br.rc.Close() + br.onClose() + return err } // parseEntry turns a `67b7b725a7ff913da520b997d71c840230351e30 10 20 1` line from // git blame into a hunk. -func parseEntry(rev string, content string) (*Hunk, error) { +func parseEntry(rev string, content string) (*gitdomain.Hunk, error) { fields := strings.Split(content, " ") if len(fields) != 3 { return nil, errors.Errorf("Expected at least 4 parts to hunkHeader, but got: '%s %s'", rev, content) @@ -121,16 +165,16 @@ func parseEntry(rev string, content string) (*Hunk, error) { return nil, err } - return &Hunk{ + return &gitdomain.Hunk{ CommitID: api.CommitID(rev), - StartLine: resultLine, - EndLine: resultLine + numLines, + StartLine: uint32(resultLine), + EndLine: uint32(resultLine + numLines), }, nil } // parseExtra updates a hunk with data parsed from the other annotations such as `author ...`, // `summary ...`. -func parseExtra(hunk *Hunk, annotation string, content string) (ok bool, err error) { +func parseExtra(hunk *gitdomain.Hunk, annotation string, content string) (ok bool, err error) { ok = true switch annotation { case "author": @@ -172,29 +216,3 @@ func splitLine(line string) (annotation string, content string) { } return line, "" } - -type mockHunkReader struct { - hunks []*Hunk - err error -} - -func NewMockHunkReader(hunks []*Hunk, err error) HunkReader { - return &mockHunkReader{ - hunks: hunks, - err: err, - } -} - -func (mh *mockHunkReader) Read() (*Hunk, error) { - if mh.err != nil { - return nil, mh.err - } - if len(mh.hunks) > 0 { - next := mh.hunks[0] - mh.hunks = mh.hunks[1:] - return next, nil - } - return nil, io.EOF -} - -func (mh *mockHunkReader) Close() error { return nil } diff --git a/cmd/gitserver/internal/git/gitcli/blame_test.go b/cmd/gitserver/internal/git/gitcli/blame_test.go new file mode 100644 index 00000000000..8dd394850b9 --- /dev/null +++ b/cmd/gitserver/internal/git/gitcli/blame_test.go @@ -0,0 +1,451 @@ +package gitcli + +import ( + "context" + "io" + "os" + "path/filepath" + "sort" + "strings" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" + + "github.com/sourcegraph/log/logtest" + + "github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/common" + "github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/git" + "github.com/sourcegraph/sourcegraph/internal/api" + "github.com/sourcegraph/sourcegraph/internal/gitserver" + "github.com/sourcegraph/sourcegraph/internal/gitserver/gitdomain" + "github.com/sourcegraph/sourcegraph/internal/wrexec" + "github.com/sourcegraph/sourcegraph/lib/errors" +) + +func TestGitCLIBackend_Blame(t *testing.T) { + rcf := wrexec.NewNoOpRecordingCommandFactory() + reposDir := t.TempDir() + + // Make a new bare repo on disk. + p := filepath.Join(reposDir, "repo") + require.NoError(t, os.MkdirAll(p, os.ModePerm)) + dir := common.GitDir(filepath.Join(p, ".git")) + + // Prepare repo state: + cmds := []string{ + "echo 'hello\nworld\nfrom\nblame\n' > foo.txt", + "git add foo.txt", + "git commit -m foo --author='Foo Author '", + // Add a second commit with a different author. + "echo 'hello\nworld\nfrom\nthe best blame\n' > foo.txt", + "git add foo.txt", + "git commit -m bar --author='Bar Author '", + + // Promote the repo to a bare repo. + "git config --bool core.bare true", + } + for _, cmd := range append([]string{"git init --initial-branch=master ."}, cmds...) { + out, err := gitserver.CreateGitCommand(p, "bash", "-c", cmd).CombinedOutput() + if err != nil { + t.Fatalf("Failed to run git command %v. Output was:\n\n%s", cmd, out) + } + } + + backend := NewBackend(logtest.Scoped(t), rcf, dir, "repo") + + ctx := context.Background() + + t.Run("bad input", func(t *testing.T) { + // Bad commit triggers error. + _, err := backend.Blame(ctx, "foo.txt", git.BlameOptions{NewestCommit: "-very badarg"}) + require.Error(t, err) + }) + + t.Run("stream hunks", func(t *testing.T) { + // Verify that the blame output is correct and that the hunk reader correctly + // terminates. + hr, err := backend.Blame(ctx, "foo.txt", git.BlameOptions{}) + require.NoError(t, err) + + h, err := hr.Read() + require.NoError(t, err) + + require.Equal(t, &gitdomain.Hunk{ + StartLine: 4, + EndLine: 5, + CommitID: "53e63d6dd6e61a58369bbc637b0ead2ee58d993c", + Author: gitdomain.Signature{ + Name: "Bar Author", + Email: "bar@sourcegraph.com", + Date: h.Author.Date, // Hard to compare. + }, + Message: "bar", + Filename: "foo.txt", + }, h) + + h, err = hr.Read() + require.NoError(t, err) + + require.Equal(t, &gitdomain.Hunk{ + StartLine: 1, + EndLine: 4, + CommitID: "51f8be07ed2090b76e77b096c9d0737fc8ac70f4", + Author: gitdomain.Signature{ + Name: "Foo Author", + Email: "foo@sourcegraph.com", + Date: h.Author.Date, // Hard to compare. + }, + Message: "foo", + Filename: "foo.txt", + }, h) + + h, err = hr.Read() + require.NoError(t, err) + + require.Equal(t, &gitdomain.Hunk{ + StartLine: 5, + EndLine: 6, + CommitID: "51f8be07ed2090b76e77b096c9d0737fc8ac70f4", + Author: gitdomain.Signature{ + Name: "Foo Author", + Email: "foo@sourcegraph.com", + Date: h.Author.Date, // Hard to compare. + }, + Message: "foo", + Filename: "foo.txt", + }, h) + + _, err = hr.Read() + require.Equal(t, io.EOF, err) + + require.NoError(t, hr.Close()) + }) + + // Verify that if the context is canceled, the hunk reader returns an error. + t.Run("context cancelation", func(t *testing.T) { + ctx, cancel := context.WithCancel(ctx) + t.Cleanup(cancel) + + hr, err := backend.Blame(ctx, "foo.txt", git.BlameOptions{}) + require.NoError(t, err) + + cancel() + + _, err = hr.Read() + require.Error(t, err) + require.True(t, errors.Is(err, context.Canceled), "unexpected error: %v", err) + + require.NoError(t, hr.Close()) + }) +} + +func TestBuildBlameArgs(t *testing.T) { + path := "foo.txt" + + t.Run("default options", func(t *testing.T) { + want := []string{"blame", "--porcelain", "--incremental", "--", "foo.txt"} + opt := git.BlameOptions{} + got := buildBlameArgs(path, opt) + if !equalSlice(got, want) { + t.Errorf("unexpected args:\ngot: %v\nwant: %v", got, want) + } + }) + + t.Run("with ignore whitespace", func(t *testing.T) { + want := []string{"blame", "--porcelain", "--incremental", "-w", "--", "foo.txt"} + opt := git.BlameOptions{IgnoreWhitespace: true} + got := buildBlameArgs(path, opt) + if !equalSlice(got, want) { + t.Errorf("unexpected args:\ngot: %v\nwant: %v", got, want) + } + }) + + t.Run("with line range", func(t *testing.T) { + want := []string{"blame", "--porcelain", "--incremental", "-L5,10", "--", "foo.txt"} + opt := git.BlameOptions{StartLine: 5, EndLine: 10} + got := buildBlameArgs(path, opt) + if !equalSlice(got, want) { + t.Errorf("unexpected args:\ngot: %v\nwant: %v", got, want) + } + }) + + t.Run("with commit", func(t *testing.T) { + want := []string{"blame", "--porcelain", "--incremental", "abc123", "--", "foo.txt"} + opt := git.BlameOptions{NewestCommit: api.CommitID("abc123")} + got := buildBlameArgs(path, opt) + if !equalSlice(got, want) { + t.Errorf("unexpected args:\ngot: %v\nwant: %v", got, want) + } + }) +} + +func equalSlice(a, b []string) bool { + if len(a) != len(b) { + return false + } + for i := range a { + if a[i] != b[i] { + return false + } + } + return true +} + +// testGitBlameOutputIncremental is produced by running +// +// git blame -w --porcelain release.sh +// +// `sourcegraph/src-cli` +var testGitBlameOutputIncremental = `8a75c6f8b4cbe2a2f3c8be0f2c50bc766499f498 15 15 1 +author Adam Harvey +author-mail +author-time 1660860583 +author-tz -0700 +committer GitHub +committer-mail +committer-time 1660860583 +committer-tz +0000 +summary release.sh: allow -rc.X suffixes (#829) +previous e6e03e850770dd0ba745f0fa4b23127e9d72ad30 release.sh +filename release.sh +fbb98e0b7ff0752798463d9f49d922858a4188f6 5 5 10 +author Adam Harvey +author-mail +author-time 1602630694 +author-tz -0700 +committer GitHub +committer-mail +committer-time 1602630694 +committer-tz -0700 +summary release: add a prompt about DEVELOPMENT.md (#349) +previous 18f59760f4260518c29f0f07056245ed5d1d0f08 release.sh +filename release.sh +67b7b725a7ff913da520b997d71c840230351e30 10 20 1 +author Thorsten Ball +author-mail +author-time 1600334460 +author-tz +0200 +committer Thorsten Ball +committer-mail +committer-time 1600334460 +committer-tz +0200 +summary Fix goreleaser GitHub action setup and release script +previous 6e931cc9745502184ce32d48b01f9a8706a4dfe8 release.sh +filename release.sh +67b7b725a7ff913da520b997d71c840230351e30 12 22 2 +previous 6e931cc9745502184ce32d48b01f9a8706a4dfe8 release.sh +filename release.sh +3f61310114082d6179c23f75950b88d1842fe2de 1 1 4 +author Thorsten Ball +author-mail +author-time 1592827635 +author-tz +0200 +committer GitHub +committer-mail +committer-time 1592827635 +committer-tz +0200 +summary Check that $VERSION is in MAJOR.MINOR.PATCH format in release.sh (#227) +previous ec809e79094cbcd05825446ee14c6d072466a0b7 release.sh +filename release.sh +3f61310114082d6179c23f75950b88d1842fe2de 6 16 4 +previous ec809e79094cbcd05825446ee14c6d072466a0b7 release.sh +filename release.sh +3f61310114082d6179c23f75950b88d1842fe2de 10 21 1 +previous ec809e79094cbcd05825446ee14c6d072466a0b7 release.sh +filename release.sh +` + +// This test-data includes the boundary keyword, which is not present in the previous one. +var testGitBlameOutputIncremental2 = `bbca6551549492486ca1b0f8dee45553dd6aa6d7 16 16 1 +author French Ben +author-mail +author-time 1517407262 +author-tz +0100 +committer French Ben +committer-mail +committer-time 1517407262 +committer-tz +0100 +summary Update error output to be clean +previous b7773ae218740a7be65057fc60b366a49b538a44 format.go +filename format.go +bbca6551549492486ca1b0f8dee45553dd6aa6d7 25 25 2 +previous b7773ae218740a7be65057fc60b366a49b538a44 format.go +filename format.go +2c87fda17de1def6ea288141b8e7600b888e535b 15 15 1 +author David Tolnay +author-mail +author-time 1478451741 +author-tz -0800 +committer David Tolnay +committer-mail +committer-time 1478451741 +committer-tz -0800 +summary Singular message for a single error +previous 8c5f0ad9360406a3807ce7de6bc73269a91a6e51 format.go +filename format.go +2c87fda17de1def6ea288141b8e7600b888e535b 17 17 2 +previous 8c5f0ad9360406a3807ce7de6bc73269a91a6e51 format.go +filename format.go +31fee45604949934710ada68f0b307c4726fb4e8 1 1 14 +author Mitchell Hashimoto +author-mail +author-time 1418673320 +author-tz -0800 +committer Mitchell Hashimoto +committer-mail +committer-time 1418673320 +committer-tz -0800 +summary Initial commit +boundary +filename format.go +31fee45604949934710ada68f0b307c4726fb4e8 15 19 6 +filename format.go +31fee45604949934710ada68f0b307c4726fb4e8 23 27 1 +filename format.go +` + +var testGitBlameOutputHunks = []*gitdomain.Hunk{ + { + StartLine: 1, EndLine: 5, StartByte: 0, EndByte: 41, + CommitID: "3f61310114082d6179c23f75950b88d1842fe2de", + Author: gitdomain.Signature{ + Name: "Thorsten Ball", + Email: "mrnugget@gmail.com", + Date: mustParseTime(time.RFC3339, "2020-06-22T12:07:15Z"), + }, + Message: "Check that $VERSION is in MAJOR.MINOR.PATCH format in release.sh (#227)", + Filename: "release.sh", + }, + { + StartLine: 5, EndLine: 15, StartByte: 41, EndByte: 249, + CommitID: "fbb98e0b7ff0752798463d9f49d922858a4188f6", + Author: gitdomain.Signature{ + Name: "Adam Harvey", + Email: "aharvey@sourcegraph.com", + Date: mustParseTime(time.RFC3339, "2020-10-13T23:11:34Z"), + }, + Message: "release: add a prompt about DEVELOPMENT.md (#349)", + Filename: "release.sh", + }, + { + StartLine: 15, EndLine: 16, StartByte: 249, EndByte: 328, + CommitID: "8a75c6f8b4cbe2a2f3c8be0f2c50bc766499f498", + Author: gitdomain.Signature{ + Name: "Adam Harvey", + Email: "adam@adamharvey.name", + Date: mustParseTime(time.RFC3339, "2022-08-18T22:09:43Z"), + }, + Message: "release.sh: allow -rc.X suffixes (#829)", + Filename: "release.sh", + }, + { + StartLine: 16, EndLine: 20, StartByte: 328, EndByte: 394, + CommitID: "3f61310114082d6179c23f75950b88d1842fe2de", + Author: gitdomain.Signature{ + Name: "Thorsten Ball", + Email: "mrnugget@gmail.com", + Date: mustParseTime(time.RFC3339, "2020-06-22T12:07:15Z"), + }, + Message: "Check that $VERSION is in MAJOR.MINOR.PATCH format in release.sh (#227)", + Filename: "release.sh", + }, + { + StartLine: 20, EndLine: 21, StartByte: 394, EndByte: 504, + CommitID: "67b7b725a7ff913da520b997d71c840230351e30", + Author: gitdomain.Signature{ + Name: "Thorsten Ball", + Email: "mrnugget@gmail.com", + Date: mustParseTime(time.RFC3339, "2020-09-17T09:21:00Z"), + }, + Message: "Fix goreleaser GitHub action setup and release script", + Filename: "release.sh", + }, + { + StartLine: 21, EndLine: 22, StartByte: 504, EndByte: 553, + CommitID: "3f61310114082d6179c23f75950b88d1842fe2de", + Author: gitdomain.Signature{ + Name: "Thorsten Ball", + Email: "mrnugget@gmail.com", + Date: mustParseTime(time.RFC3339, "2020-06-22T12:07:15Z"), + }, + Message: "Check that $VERSION is in MAJOR.MINOR.PATCH format in release.sh (#227)", + Filename: "release.sh", + }, + { + StartLine: 22, EndLine: 24, StartByte: 553, EndByte: 695, + CommitID: "67b7b725a7ff913da520b997d71c840230351e30", + Author: gitdomain.Signature{ + Name: "Thorsten Ball", + Email: "mrnugget@gmail.com", + Date: mustParseTime(time.RFC3339, "2020-09-17T09:21:00Z"), + }, + Message: "Fix goreleaser GitHub action setup and release script", + Filename: "release.sh", + }, +} + +func TestBlameHunkReader(t *testing.T) { + t.Run("OK matching hunks", func(t *testing.T) { + rc := io.NopCloser(strings.NewReader(testGitBlameOutputIncremental)) + reader := newBlameHunkReader(rc, func() {}) + defer reader.Close() + + hunks := []*gitdomain.Hunk{} + for { + hunk, err := reader.Read() + if errors.Is(err, io.EOF) { + break + } else if err != nil { + t.Fatalf("blameHunkReader.Read failed: %s", err) + } + hunks = append(hunks, hunk) + } + + sortFn := func(x []*gitdomain.Hunk) func(i, j int) bool { + return func(i, j int) bool { + return x[i].Author.Date.After(x[j].Author.Date) + } + } + + // We're not giving back bytes, as the output of --incremental only gives back annotations. + expectedHunks := make([]*gitdomain.Hunk, 0, len(testGitBlameOutputHunks)) + for _, h := range testGitBlameOutputHunks { + dup := *h + dup.EndByte = 0 + dup.StartByte = 0 + expectedHunks = append(expectedHunks, &dup) + } + + // Sort expected hunks by the most recent first, as --incremental does. + sort.SliceStable(expectedHunks, sortFn(expectedHunks)) + + if d := cmp.Diff(expectedHunks, hunks); d != "" { + t.Fatalf("unexpected hunks (-want, +got):\n%s", d) + } + }) + + t.Run("OK parsing hunks", func(t *testing.T) { + rc := io.NopCloser(strings.NewReader(testGitBlameOutputIncremental2)) + reader := newBlameHunkReader(rc, func() {}) + defer reader.Close() + + for { + _, err := reader.Read() + if errors.Is(err, io.EOF) { + break + } else if err != nil { + t.Fatalf("blameHunkReader.Read failed: %s", err) + } + } + }) +} + +func mustParseTime(layout, value string) time.Time { + tm, err := time.Parse(layout, value) + if err != nil { + panic(err.Error()) + } + return tm +} diff --git a/cmd/gitserver/internal/git/gitcli/clibackend.go b/cmd/gitserver/internal/git/gitcli/clibackend.go index fa8f837e38e..b5005aa1c0f 100644 --- a/cmd/gitserver/internal/git/gitcli/clibackend.go +++ b/cmd/gitserver/internal/git/gitcli/clibackend.go @@ -41,7 +41,11 @@ type gitCLIBackend struct { repoName api.RepoName } -func commandFailedError(err error, cmd wrexec.Cmder, stderr []byte) error { +func commandFailedError(ctx context.Context, err error, cmd wrexec.Cmder, stderr []byte) error { + if ctx.Err() != nil { + return ctx.Err() + } + exitStatus := executil.UnsetExitStatus if cmd.Unwrap().ProcessState != nil { // is nil if process failed to start exitStatus = cmd.Unwrap().ProcessState.Sys().(syscall.WaitStatus).ExitStatus() @@ -84,7 +88,7 @@ func (g *gitCLIBackend) gitCommand(ctx context.Context, args ...string) (wrexec. return nil, cancel, ErrBadGitCommand } - cmd := exec.Command("git", args...) + cmd := exec.CommandContext(ctx, "git", args...) g.dir.Set(cmd) return g.rcf.WrapWithRepoName(ctx, g.logger, g.repoName, cmd), cancel, nil @@ -92,6 +96,7 @@ func (g *gitCLIBackend) gitCommand(ctx context.Context, args ...string) (wrexec. const maxStderrCapture = 1024 +// make sure to pass the same context in here as was passed to gitCommand. func (g *gitCLIBackend) runGitCommand(ctx context.Context, cmd wrexec.Cmder) (io.ReadCloser, error) { // Set up a limited buffer to capture stderr for error reporting. stderrBuf := bytes.NewBuffer(make([]byte, 0, maxStderrCapture)) @@ -127,6 +132,7 @@ type cmdReader struct { logger log.Logger git git.GitBackend repoName api.RepoName + closed bool } func (rc *cmdReader) Read(p []byte) (n int, err error) { @@ -134,12 +140,13 @@ func (rc *cmdReader) Read(p []byte) (n int, err error) { writtenN, writeErr := rc.buf.Write(p[:n]) if err == io.EOF { rc.ReadCloser.Close() + rc.closed = true if err := rc.cmd.Wait(); err != nil { if checkMaybeCorruptRepo(rc.ctx, rc.logger, rc.git, rc.repoName, rc.stderr.String()) { return n, common.ErrRepoCorrupted{Reason: rc.stderr.String()} } - return n, commandFailedError(err, rc.cmd, rc.stderr.Bytes()) + return n, commandFailedError(rc.ctx, err, rc.cmd, rc.stderr.Bytes()) } } if err == nil && writeErr != nil { @@ -148,6 +155,14 @@ func (rc *cmdReader) Read(p []byte) (n int, err error) { return n, err } +func (rc *cmdReader) Close() error { + if rc.closed { + return nil + } + + return rc.ReadCloser.Close() +} + // limitWriter is a io.Writer that writes to an W but discards after N bytes. type limitWriter struct { W io.Writer // underling writer diff --git a/cmd/gitserver/internal/git/gitcli/exec.go b/cmd/gitserver/internal/git/gitcli/exec.go index 84eac75badb..4076a11bd05 100644 --- a/cmd/gitserver/internal/git/gitcli/exec.go +++ b/cmd/gitserver/internal/git/gitcli/exec.go @@ -17,12 +17,29 @@ import ( func (g *gitCLIBackend) Exec(ctx context.Context, args ...string) (io.ReadCloser, error) { cmd, cancel, err := g.gitCommand(ctx, args...) - defer cancel() if err != nil { + cancel() return nil, err } - return g.runGitCommand(ctx, cmd) + r, err := g.runGitCommand(ctx, cmd) + if err != nil { + cancel() + return nil, err + } + + return &cancelingCloser{ReadCloser: r, cancel: cancel}, nil +} + +type cancelingCloser struct { + io.ReadCloser + cancel context.CancelFunc +} + +func (c *cancelingCloser) Close() error { + err := c.ReadCloser.Close() + c.cancel() + return err } var ( diff --git a/cmd/gitserver/internal/git/iface.go b/cmd/gitserver/internal/git/iface.go index 3508385d246..ce835b28f3e 100644 --- a/cmd/gitserver/internal/git/iface.go +++ b/cmd/gitserver/internal/git/iface.go @@ -22,6 +22,10 @@ type GitBackend interface { // Returns an empty string and no error if no common merge-base was found. MergeBase(ctx context.Context, baseRevspec, headRevspec string) (api.CommitID, error) + // Blame returns a reader for the blame info of the given path. + // BlameHunkReader must always be closed. + Blame(ctx context.Context, path string, opt BlameOptions) (BlameHunkReader, error) + // Exec is a temporary helper to run arbitrary git commands from the exec endpoint. // No new usages of it should be introduced and once the migration is done we will // remove this method. @@ -39,3 +43,20 @@ type GitConfigBackend interface { // no error is returned. Unset(ctx context.Context, key string) error } + +// BlameOptions are options for git blame. +type BlameOptions struct { + NewestCommit api.CommitID + IgnoreWhitespace bool + // 1-indexed start line (or 0 for beginning of file) + StartLine int + // 1-indexed end line (or 0 for end of file) + EndLine int +} + +// BlameHunkReader is a reader for git blame hunks. +type BlameHunkReader interface { + // Consume the next hunk. io.EOF is returned at the end of the stream. + Read() (*gitdomain.Hunk, error) + Close() error +} diff --git a/cmd/gitserver/internal/git/mock.go b/cmd/gitserver/internal/git/mock.go index a090ad47264..4576d3c90d8 100644 --- a/cmd/gitserver/internal/git/mock.go +++ b/cmd/gitserver/internal/git/mock.go @@ -15,11 +15,277 @@ import ( gitdomain "github.com/sourcegraph/sourcegraph/internal/gitserver/gitdomain" ) +// MockBlameHunkReader is a mock implementation of the BlameHunkReader +// interface (from the package +// github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/git) used for +// unit testing. +type MockBlameHunkReader struct { + // CloseFunc is an instance of a mock function object controlling the + // behavior of the method Close. + CloseFunc *BlameHunkReaderCloseFunc + // ReadFunc is an instance of a mock function object controlling the + // behavior of the method Read. + ReadFunc *BlameHunkReaderReadFunc +} + +// NewMockBlameHunkReader creates a new mock of the BlameHunkReader +// interface. All methods return zero values for all results, unless +// overwritten. +func NewMockBlameHunkReader() *MockBlameHunkReader { + return &MockBlameHunkReader{ + CloseFunc: &BlameHunkReaderCloseFunc{ + defaultHook: func() (r0 error) { + return + }, + }, + ReadFunc: &BlameHunkReaderReadFunc{ + defaultHook: func() (r0 *gitdomain.Hunk, r1 error) { + return + }, + }, + } +} + +// NewStrictMockBlameHunkReader creates a new mock of the BlameHunkReader +// interface. All methods panic on invocation, unless overwritten. +func NewStrictMockBlameHunkReader() *MockBlameHunkReader { + return &MockBlameHunkReader{ + CloseFunc: &BlameHunkReaderCloseFunc{ + defaultHook: func() error { + panic("unexpected invocation of MockBlameHunkReader.Close") + }, + }, + ReadFunc: &BlameHunkReaderReadFunc{ + defaultHook: func() (*gitdomain.Hunk, error) { + panic("unexpected invocation of MockBlameHunkReader.Read") + }, + }, + } +} + +// NewMockBlameHunkReaderFrom creates a new mock of the MockBlameHunkReader +// interface. All methods delegate to the given implementation, unless +// overwritten. +func NewMockBlameHunkReaderFrom(i BlameHunkReader) *MockBlameHunkReader { + return &MockBlameHunkReader{ + CloseFunc: &BlameHunkReaderCloseFunc{ + defaultHook: i.Close, + }, + ReadFunc: &BlameHunkReaderReadFunc{ + defaultHook: i.Read, + }, + } +} + +// BlameHunkReaderCloseFunc describes the behavior when the Close method of +// the parent MockBlameHunkReader instance is invoked. +type BlameHunkReaderCloseFunc struct { + defaultHook func() error + hooks []func() error + history []BlameHunkReaderCloseFuncCall + mutex sync.Mutex +} + +// Close delegates to the next hook function in the queue and stores the +// parameter and result values of this invocation. +func (m *MockBlameHunkReader) Close() error { + r0 := m.CloseFunc.nextHook()() + m.CloseFunc.appendCall(BlameHunkReaderCloseFuncCall{r0}) + return r0 +} + +// SetDefaultHook sets function that is called when the Close method of the +// parent MockBlameHunkReader instance is invoked and the hook queue is +// empty. +func (f *BlameHunkReaderCloseFunc) SetDefaultHook(hook func() error) { + f.defaultHook = hook +} + +// PushHook adds a function to the end of hook queue. Each invocation of the +// Close method of the parent MockBlameHunkReader instance invokes the hook +// at the front of the queue and discards it. After the queue is empty, the +// default hook function is invoked for any future action. +func (f *BlameHunkReaderCloseFunc) PushHook(hook func() error) { + f.mutex.Lock() + f.hooks = append(f.hooks, hook) + f.mutex.Unlock() +} + +// SetDefaultReturn calls SetDefaultHook with a function that returns the +// given values. +func (f *BlameHunkReaderCloseFunc) SetDefaultReturn(r0 error) { + f.SetDefaultHook(func() error { + return r0 + }) +} + +// PushReturn calls PushHook with a function that returns the given values. +func (f *BlameHunkReaderCloseFunc) PushReturn(r0 error) { + f.PushHook(func() error { + return r0 + }) +} + +func (f *BlameHunkReaderCloseFunc) nextHook() func() error { + f.mutex.Lock() + defer f.mutex.Unlock() + + if len(f.hooks) == 0 { + return f.defaultHook + } + + hook := f.hooks[0] + f.hooks = f.hooks[1:] + return hook +} + +func (f *BlameHunkReaderCloseFunc) appendCall(r0 BlameHunkReaderCloseFuncCall) { + f.mutex.Lock() + f.history = append(f.history, r0) + f.mutex.Unlock() +} + +// History returns a sequence of BlameHunkReaderCloseFuncCall objects +// describing the invocations of this function. +func (f *BlameHunkReaderCloseFunc) History() []BlameHunkReaderCloseFuncCall { + f.mutex.Lock() + history := make([]BlameHunkReaderCloseFuncCall, len(f.history)) + copy(history, f.history) + f.mutex.Unlock() + + return history +} + +// BlameHunkReaderCloseFuncCall is an object that describes an invocation of +// method Close on an instance of MockBlameHunkReader. +type BlameHunkReaderCloseFuncCall struct { + // Result0 is the value of the 1st result returned from this method + // invocation. + Result0 error +} + +// Args returns an interface slice containing the arguments of this +// invocation. +func (c BlameHunkReaderCloseFuncCall) Args() []interface{} { + return []interface{}{} +} + +// Results returns an interface slice containing the results of this +// invocation. +func (c BlameHunkReaderCloseFuncCall) Results() []interface{} { + return []interface{}{c.Result0} +} + +// BlameHunkReaderReadFunc describes the behavior when the Read method of +// the parent MockBlameHunkReader instance is invoked. +type BlameHunkReaderReadFunc struct { + defaultHook func() (*gitdomain.Hunk, error) + hooks []func() (*gitdomain.Hunk, error) + history []BlameHunkReaderReadFuncCall + mutex sync.Mutex +} + +// Read delegates to the next hook function in the queue and stores the +// parameter and result values of this invocation. +func (m *MockBlameHunkReader) Read() (*gitdomain.Hunk, error) { + r0, r1 := m.ReadFunc.nextHook()() + m.ReadFunc.appendCall(BlameHunkReaderReadFuncCall{r0, r1}) + return r0, r1 +} + +// SetDefaultHook sets function that is called when the Read method of the +// parent MockBlameHunkReader instance is invoked and the hook queue is +// empty. +func (f *BlameHunkReaderReadFunc) SetDefaultHook(hook func() (*gitdomain.Hunk, error)) { + f.defaultHook = hook +} + +// PushHook adds a function to the end of hook queue. Each invocation of the +// Read method of the parent MockBlameHunkReader instance invokes the hook +// at the front of the queue and discards it. After the queue is empty, the +// default hook function is invoked for any future action. +func (f *BlameHunkReaderReadFunc) PushHook(hook func() (*gitdomain.Hunk, error)) { + f.mutex.Lock() + f.hooks = append(f.hooks, hook) + f.mutex.Unlock() +} + +// SetDefaultReturn calls SetDefaultHook with a function that returns the +// given values. +func (f *BlameHunkReaderReadFunc) SetDefaultReturn(r0 *gitdomain.Hunk, r1 error) { + f.SetDefaultHook(func() (*gitdomain.Hunk, error) { + return r0, r1 + }) +} + +// PushReturn calls PushHook with a function that returns the given values. +func (f *BlameHunkReaderReadFunc) PushReturn(r0 *gitdomain.Hunk, r1 error) { + f.PushHook(func() (*gitdomain.Hunk, error) { + return r0, r1 + }) +} + +func (f *BlameHunkReaderReadFunc) nextHook() func() (*gitdomain.Hunk, error) { + f.mutex.Lock() + defer f.mutex.Unlock() + + if len(f.hooks) == 0 { + return f.defaultHook + } + + hook := f.hooks[0] + f.hooks = f.hooks[1:] + return hook +} + +func (f *BlameHunkReaderReadFunc) appendCall(r0 BlameHunkReaderReadFuncCall) { + f.mutex.Lock() + f.history = append(f.history, r0) + f.mutex.Unlock() +} + +// History returns a sequence of BlameHunkReaderReadFuncCall objects +// describing the invocations of this function. +func (f *BlameHunkReaderReadFunc) History() []BlameHunkReaderReadFuncCall { + f.mutex.Lock() + history := make([]BlameHunkReaderReadFuncCall, len(f.history)) + copy(history, f.history) + f.mutex.Unlock() + + return history +} + +// BlameHunkReaderReadFuncCall is an object that describes an invocation of +// method Read on an instance of MockBlameHunkReader. +type BlameHunkReaderReadFuncCall struct { + // Result0 is the value of the 1st result returned from this method + // invocation. + Result0 *gitdomain.Hunk + // Result1 is the value of the 2nd result returned from this method + // invocation. + Result1 error +} + +// Args returns an interface slice containing the arguments of this +// invocation. +func (c BlameHunkReaderReadFuncCall) Args() []interface{} { + return []interface{}{} +} + +// Results returns an interface slice containing the results of this +// invocation. +func (c BlameHunkReaderReadFuncCall) Results() []interface{} { + return []interface{}{c.Result0, c.Result1} +} + // MockGitBackend is a mock implementation of the GitBackend interface (from // the package // github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/git) used for // unit testing. type MockGitBackend struct { + // BlameFunc is an instance of a mock function object controlling the + // behavior of the method Blame. + BlameFunc *GitBackendBlameFunc // ConfigFunc is an instance of a mock function object controlling the // behavior of the method Config. ConfigFunc *GitBackendConfigFunc @@ -38,6 +304,11 @@ type MockGitBackend struct { // methods return zero values for all results, unless overwritten. func NewMockGitBackend() *MockGitBackend { return &MockGitBackend{ + BlameFunc: &GitBackendBlameFunc{ + defaultHook: func(context.Context, string, BlameOptions) (r0 BlameHunkReader, r1 error) { + return + }, + }, ConfigFunc: &GitBackendConfigFunc{ defaultHook: func() (r0 GitConfigBackend) { return @@ -65,6 +336,11 @@ func NewMockGitBackend() *MockGitBackend { // All methods panic on invocation, unless overwritten. func NewStrictMockGitBackend() *MockGitBackend { return &MockGitBackend{ + BlameFunc: &GitBackendBlameFunc{ + defaultHook: func(context.Context, string, BlameOptions) (BlameHunkReader, error) { + panic("unexpected invocation of MockGitBackend.Blame") + }, + }, ConfigFunc: &GitBackendConfigFunc{ defaultHook: func() GitConfigBackend { panic("unexpected invocation of MockGitBackend.Config") @@ -92,6 +368,9 @@ func NewStrictMockGitBackend() *MockGitBackend { // All methods delegate to the given implementation, unless overwritten. func NewMockGitBackendFrom(i GitBackend) *MockGitBackend { return &MockGitBackend{ + BlameFunc: &GitBackendBlameFunc{ + defaultHook: i.Blame, + }, ConfigFunc: &GitBackendConfigFunc{ defaultHook: i.Config, }, @@ -107,6 +386,116 @@ func NewMockGitBackendFrom(i GitBackend) *MockGitBackend { } } +// GitBackendBlameFunc describes the behavior when the Blame method of the +// parent MockGitBackend instance is invoked. +type GitBackendBlameFunc struct { + defaultHook func(context.Context, string, BlameOptions) (BlameHunkReader, error) + hooks []func(context.Context, string, BlameOptions) (BlameHunkReader, error) + history []GitBackendBlameFuncCall + mutex sync.Mutex +} + +// Blame delegates to the next hook function in the queue and stores the +// parameter and result values of this invocation. +func (m *MockGitBackend) Blame(v0 context.Context, v1 string, v2 BlameOptions) (BlameHunkReader, error) { + r0, r1 := m.BlameFunc.nextHook()(v0, v1, v2) + m.BlameFunc.appendCall(GitBackendBlameFuncCall{v0, v1, v2, r0, r1}) + return r0, r1 +} + +// SetDefaultHook sets function that is called when the Blame method of the +// parent MockGitBackend instance is invoked and the hook queue is empty. +func (f *GitBackendBlameFunc) SetDefaultHook(hook func(context.Context, string, BlameOptions) (BlameHunkReader, error)) { + f.defaultHook = hook +} + +// PushHook adds a function to the end of hook queue. Each invocation of the +// Blame method of the parent MockGitBackend instance invokes the hook at +// the front of the queue and discards it. After the queue is empty, the +// default hook function is invoked for any future action. +func (f *GitBackendBlameFunc) PushHook(hook func(context.Context, string, BlameOptions) (BlameHunkReader, error)) { + f.mutex.Lock() + f.hooks = append(f.hooks, hook) + f.mutex.Unlock() +} + +// SetDefaultReturn calls SetDefaultHook with a function that returns the +// given values. +func (f *GitBackendBlameFunc) SetDefaultReturn(r0 BlameHunkReader, r1 error) { + f.SetDefaultHook(func(context.Context, string, BlameOptions) (BlameHunkReader, error) { + return r0, r1 + }) +} + +// PushReturn calls PushHook with a function that returns the given values. +func (f *GitBackendBlameFunc) PushReturn(r0 BlameHunkReader, r1 error) { + f.PushHook(func(context.Context, string, BlameOptions) (BlameHunkReader, error) { + return r0, r1 + }) +} + +func (f *GitBackendBlameFunc) nextHook() func(context.Context, string, BlameOptions) (BlameHunkReader, error) { + f.mutex.Lock() + defer f.mutex.Unlock() + + if len(f.hooks) == 0 { + return f.defaultHook + } + + hook := f.hooks[0] + f.hooks = f.hooks[1:] + return hook +} + +func (f *GitBackendBlameFunc) appendCall(r0 GitBackendBlameFuncCall) { + f.mutex.Lock() + f.history = append(f.history, r0) + f.mutex.Unlock() +} + +// History returns a sequence of GitBackendBlameFuncCall objects describing +// the invocations of this function. +func (f *GitBackendBlameFunc) History() []GitBackendBlameFuncCall { + f.mutex.Lock() + history := make([]GitBackendBlameFuncCall, len(f.history)) + copy(history, f.history) + f.mutex.Unlock() + + return history +} + +// GitBackendBlameFuncCall is an object that describes an invocation of +// method Blame on an instance of MockGitBackend. +type GitBackendBlameFuncCall struct { + // Arg0 is the value of the 1st argument passed to this method + // invocation. + Arg0 context.Context + // Arg1 is the value of the 2nd argument passed to this method + // invocation. + Arg1 string + // Arg2 is the value of the 3rd argument passed to this method + // invocation. + Arg2 BlameOptions + // Result0 is the value of the 1st result returned from this method + // invocation. + Result0 BlameHunkReader + // Result1 is the value of the 2nd result returned from this method + // invocation. + Result1 error +} + +// Args returns an interface slice containing the arguments of this +// invocation. +func (c GitBackendBlameFuncCall) Args() []interface{} { + return []interface{}{c.Arg0, c.Arg1, c.Arg2} +} + +// Results returns an interface slice containing the results of this +// invocation. +func (c GitBackendBlameFuncCall) Results() []interface{} { + return []interface{}{c.Result0, c.Result1} +} + // GitBackendConfigFunc describes the behavior when the Config method of the // parent MockGitBackend instance is invoked. type GitBackendConfigFunc struct { diff --git a/cmd/gitserver/internal/integration_tests/archivereader_test.go b/cmd/gitserver/internal/integration_tests/archivereader_test.go index 01c73354076..ba9b01cb104 100644 --- a/cmd/gitserver/internal/integration_tests/archivereader_test.go +++ b/cmd/gitserver/internal/integration_tests/archivereader_test.go @@ -119,7 +119,7 @@ func TestClient_ArchiveReader(t *testing.T) { grpcServer := defaults.NewServer(logtest.Scoped(t)) - proto.RegisterGitserverServiceServer(grpcServer, &server.GRPCServer{Server: s}) + proto.RegisterGitserverServiceServer(grpcServer, server.NewGRPCServer(s)) handler := internalgrpc.MultiplexHandlers(grpcServer, s.Handler()) srv := httptest.NewServer(handler) defer srv.Close() diff --git a/cmd/gitserver/internal/integration_tests/clone_test.go b/cmd/gitserver/internal/integration_tests/clone_test.go index ed8174b01ab..54729435a0a 100644 --- a/cmd/gitserver/internal/integration_tests/clone_test.go +++ b/cmd/gitserver/internal/integration_tests/clone_test.go @@ -74,7 +74,7 @@ func TestClone(t *testing.T) { } grpcServer := defaults.NewServer(logtest.Scoped(t)) - proto.RegisterGitserverServiceServer(grpcServer, &server.GRPCServer{Server: &s}) + proto.RegisterGitserverServiceServer(grpcServer, server.NewGRPCServer(&s)) handler := internalgrpc.MultiplexHandlers(grpcServer, s.Handler()) srv := httptest.NewServer(handler) @@ -170,7 +170,7 @@ func TestClone_Fail(t *testing.T) { } grpcServer := defaults.NewServer(logtest.Scoped(t)) - proto.RegisterGitserverServiceServer(grpcServer, &server.GRPCServer{Server: &s}) + proto.RegisterGitserverServiceServer(grpcServer, server.NewGRPCServer(&s)) handler := internalgrpc.MultiplexHandlers(grpcServer, s.Handler()) srv := httptest.NewServer(handler) diff --git a/cmd/gitserver/internal/integration_tests/resolverevisions_test.go b/cmd/gitserver/internal/integration_tests/resolverevisions_test.go index 6022e7b9ee3..a17b706f75b 100644 --- a/cmd/gitserver/internal/integration_tests/resolverevisions_test.go +++ b/cmd/gitserver/internal/integration_tests/resolverevisions_test.go @@ -89,7 +89,7 @@ func TestClient_ResolveRevisions(t *testing.T) { } grpcServer := defaults.NewServer(logtest.Scoped(t)) - proto.RegisterGitserverServiceServer(grpcServer, &server.GRPCServer{Server: &s}) + proto.RegisterGitserverServiceServer(grpcServer, server.NewGRPCServer(&s)) handler := internalgrpc.MultiplexHandlers(grpcServer, s.Handler()) srv := httptest.NewServer(handler) diff --git a/cmd/gitserver/internal/integration_tests/test_utils.go b/cmd/gitserver/internal/integration_tests/test_utils.go index 479d53f183f..4ca896543e2 100644 --- a/cmd/gitserver/internal/integration_tests/test_utils.go +++ b/cmd/gitserver/internal/integration_tests/test_utils.go @@ -97,7 +97,7 @@ func InitGitserver() { } grpcServer := defaults.NewServer(logger) - proto.RegisterGitserverServiceServer(grpcServer, &server.GRPCServer{Server: &s}) + proto.RegisterGitserverServiceServer(grpcServer, server.NewGRPCServer(&s)) handler := internalgrpc.MultiplexHandlers(grpcServer, s.Handler()) srv := &http.Server{ diff --git a/cmd/gitserver/internal/mocks_test.go b/cmd/gitserver/internal/mocks_test.go new file mode 100644 index 00000000000..6e50cd807af --- /dev/null +++ b/cmd/gitserver/internal/mocks_test.go @@ -0,0 +1,1312 @@ +// Code generated by go-mockgen 1.3.7; DO NOT EDIT. +// +// This file was generated by running `sg generate` (or `go-mockgen`) at the root of +// this repository. To add additional mocks to this or another package, add a new entry +// to the mockgen.yaml file in the root of this repository. + +package internal + +import ( + "context" + "io" + "sync" + + log "github.com/sourcegraph/log" + api "github.com/sourcegraph/sourcegraph/internal/api" + protocol "github.com/sourcegraph/sourcegraph/internal/gitserver/protocol" + v1 "github.com/sourcegraph/sourcegraph/internal/gitserver/v1" + trace "github.com/sourcegraph/sourcegraph/internal/trace" +) + +// MockService is a mock implementation of the service interface (from the +// package github.com/sourcegraph/sourcegraph/cmd/gitserver/internal) used +// for unit testing. +type MockService struct { + // BatchGitLogInstrumentedHandlerFunc is an instance of a mock function + // object controlling the behavior of the method + // BatchGitLogInstrumentedHandler. + BatchGitLogInstrumentedHandlerFunc *ServiceBatchGitLogInstrumentedHandlerFunc + // CloneRepoFunc is an instance of a mock function object controlling + // the behavior of the method CloneRepo. + CloneRepoFunc *ServiceCloneRepoFunc + // CreateCommitFromPatchFunc is an instance of a mock function object + // controlling the behavior of the method CreateCommitFromPatch. + CreateCommitFromPatchFunc *ServiceCreateCommitFromPatchFunc + // ExecFunc is an instance of a mock function object controlling the + // behavior of the method Exec. + ExecFunc *ServiceExecFunc + // IsRepoCloneableFunc is an instance of a mock function object + // controlling the behavior of the method IsRepoCloneable. + IsRepoCloneableFunc *ServiceIsRepoCloneableFunc + // LogIfCorruptFunc is an instance of a mock function object controlling + // the behavior of the method LogIfCorrupt. + LogIfCorruptFunc *ServiceLogIfCorruptFunc + // MaybeStartCloneFunc is an instance of a mock function object + // controlling the behavior of the method MaybeStartClone. + MaybeStartCloneFunc *ServiceMaybeStartCloneFunc + // P4ExecFunc is an instance of a mock function object controlling the + // behavior of the method P4Exec. + P4ExecFunc *ServiceP4ExecFunc + // RepoUpdateFunc is an instance of a mock function object controlling + // the behavior of the method RepoUpdate. + RepoUpdateFunc *ServiceRepoUpdateFunc + // SearchWithObservabilityFunc is an instance of a mock function object + // controlling the behavior of the method SearchWithObservability. + SearchWithObservabilityFunc *ServiceSearchWithObservabilityFunc +} + +// NewMockService creates a new mock of the service interface. All methods +// return zero values for all results, unless overwritten. +func NewMockService() *MockService { + return &MockService{ + BatchGitLogInstrumentedHandlerFunc: &ServiceBatchGitLogInstrumentedHandlerFunc{ + defaultHook: func(context.Context, *v1.BatchLogRequest) (r0 *v1.BatchLogResponse, r1 error) { + return + }, + }, + CloneRepoFunc: &ServiceCloneRepoFunc{ + defaultHook: func(context.Context, api.RepoName, CloneOptions) (r0 string, r1 error) { + return + }, + }, + CreateCommitFromPatchFunc: &ServiceCreateCommitFromPatchFunc{ + defaultHook: func(context.Context, protocol.CreateCommitFromPatchRequest) (r0 int, r1 protocol.CreateCommitFromPatchResponse) { + return + }, + }, + ExecFunc: &ServiceExecFunc{ + defaultHook: func(context.Context, *protocol.ExecRequest, io.Writer) (r0 execStatus, r1 error) { + return + }, + }, + IsRepoCloneableFunc: &ServiceIsRepoCloneableFunc{ + defaultHook: func(context.Context, api.RepoName) (r0 protocol.IsRepoCloneableResponse, r1 error) { + return + }, + }, + LogIfCorruptFunc: &ServiceLogIfCorruptFunc{ + defaultHook: func(context.Context, api.RepoName, error) { + return + }, + }, + MaybeStartCloneFunc: &ServiceMaybeStartCloneFunc{ + defaultHook: func(context.Context, api.RepoName) (r0 *protocol.NotFoundPayload, r1 bool) { + return + }, + }, + P4ExecFunc: &ServiceP4ExecFunc{ + defaultHook: func(context.Context, log.Logger, *p4ExecRequest, io.Writer) (r0 execStatus) { + return + }, + }, + RepoUpdateFunc: &ServiceRepoUpdateFunc{ + defaultHook: func(*protocol.RepoUpdateRequest) (r0 protocol.RepoUpdateResponse) { + return + }, + }, + SearchWithObservabilityFunc: &ServiceSearchWithObservabilityFunc{ + defaultHook: func(context.Context, trace.Trace, *protocol.SearchRequest, func(*protocol.CommitMatch) error) (r0 bool, r1 error) { + return + }, + }, + } +} + +// NewStrictMockService creates a new mock of the service interface. All +// methods panic on invocation, unless overwritten. +func NewStrictMockService() *MockService { + return &MockService{ + BatchGitLogInstrumentedHandlerFunc: &ServiceBatchGitLogInstrumentedHandlerFunc{ + defaultHook: func(context.Context, *v1.BatchLogRequest) (*v1.BatchLogResponse, error) { + panic("unexpected invocation of MockService.BatchGitLogInstrumentedHandler") + }, + }, + CloneRepoFunc: &ServiceCloneRepoFunc{ + defaultHook: func(context.Context, api.RepoName, CloneOptions) (string, error) { + panic("unexpected invocation of MockService.CloneRepo") + }, + }, + CreateCommitFromPatchFunc: &ServiceCreateCommitFromPatchFunc{ + defaultHook: func(context.Context, protocol.CreateCommitFromPatchRequest) (int, protocol.CreateCommitFromPatchResponse) { + panic("unexpected invocation of MockService.CreateCommitFromPatch") + }, + }, + ExecFunc: &ServiceExecFunc{ + defaultHook: func(context.Context, *protocol.ExecRequest, io.Writer) (execStatus, error) { + panic("unexpected invocation of MockService.Exec") + }, + }, + IsRepoCloneableFunc: &ServiceIsRepoCloneableFunc{ + defaultHook: func(context.Context, api.RepoName) (protocol.IsRepoCloneableResponse, error) { + panic("unexpected invocation of MockService.IsRepoCloneable") + }, + }, + LogIfCorruptFunc: &ServiceLogIfCorruptFunc{ + defaultHook: func(context.Context, api.RepoName, error) { + panic("unexpected invocation of MockService.LogIfCorrupt") + }, + }, + MaybeStartCloneFunc: &ServiceMaybeStartCloneFunc{ + defaultHook: func(context.Context, api.RepoName) (*protocol.NotFoundPayload, bool) { + panic("unexpected invocation of MockService.MaybeStartClone") + }, + }, + P4ExecFunc: &ServiceP4ExecFunc{ + defaultHook: func(context.Context, log.Logger, *p4ExecRequest, io.Writer) execStatus { + panic("unexpected invocation of MockService.P4Exec") + }, + }, + RepoUpdateFunc: &ServiceRepoUpdateFunc{ + defaultHook: func(*protocol.RepoUpdateRequest) protocol.RepoUpdateResponse { + panic("unexpected invocation of MockService.RepoUpdate") + }, + }, + SearchWithObservabilityFunc: &ServiceSearchWithObservabilityFunc{ + defaultHook: func(context.Context, trace.Trace, *protocol.SearchRequest, func(*protocol.CommitMatch) error) (bool, error) { + panic("unexpected invocation of MockService.SearchWithObservability") + }, + }, + } +} + +// surrogateMockService is a copy of the service interface (from the package +// github.com/sourcegraph/sourcegraph/cmd/gitserver/internal). It is +// redefined here as it is unexported in the source package. +type surrogateMockService interface { + BatchGitLogInstrumentedHandler(context.Context, *v1.BatchLogRequest) (*v1.BatchLogResponse, error) + CloneRepo(context.Context, api.RepoName, CloneOptions) (string, error) + CreateCommitFromPatch(context.Context, protocol.CreateCommitFromPatchRequest) (int, protocol.CreateCommitFromPatchResponse) + Exec(context.Context, *protocol.ExecRequest, io.Writer) (execStatus, error) + IsRepoCloneable(context.Context, api.RepoName) (protocol.IsRepoCloneableResponse, error) + LogIfCorrupt(context.Context, api.RepoName, error) + MaybeStartClone(context.Context, api.RepoName) (*protocol.NotFoundPayload, bool) + P4Exec(context.Context, log.Logger, *p4ExecRequest, io.Writer) execStatus + RepoUpdate(*protocol.RepoUpdateRequest) protocol.RepoUpdateResponse + SearchWithObservability(context.Context, trace.Trace, *protocol.SearchRequest, func(*protocol.CommitMatch) error) (bool, error) +} + +// NewMockServiceFrom creates a new mock of the MockService interface. All +// methods delegate to the given implementation, unless overwritten. +func NewMockServiceFrom(i surrogateMockService) *MockService { + return &MockService{ + BatchGitLogInstrumentedHandlerFunc: &ServiceBatchGitLogInstrumentedHandlerFunc{ + defaultHook: i.BatchGitLogInstrumentedHandler, + }, + CloneRepoFunc: &ServiceCloneRepoFunc{ + defaultHook: i.CloneRepo, + }, + CreateCommitFromPatchFunc: &ServiceCreateCommitFromPatchFunc{ + defaultHook: i.CreateCommitFromPatch, + }, + ExecFunc: &ServiceExecFunc{ + defaultHook: i.Exec, + }, + IsRepoCloneableFunc: &ServiceIsRepoCloneableFunc{ + defaultHook: i.IsRepoCloneable, + }, + LogIfCorruptFunc: &ServiceLogIfCorruptFunc{ + defaultHook: i.LogIfCorrupt, + }, + MaybeStartCloneFunc: &ServiceMaybeStartCloneFunc{ + defaultHook: i.MaybeStartClone, + }, + P4ExecFunc: &ServiceP4ExecFunc{ + defaultHook: i.P4Exec, + }, + RepoUpdateFunc: &ServiceRepoUpdateFunc{ + defaultHook: i.RepoUpdate, + }, + SearchWithObservabilityFunc: &ServiceSearchWithObservabilityFunc{ + defaultHook: i.SearchWithObservability, + }, + } +} + +// ServiceBatchGitLogInstrumentedHandlerFunc describes the behavior when the +// BatchGitLogInstrumentedHandler method of the parent MockService instance +// is invoked. +type ServiceBatchGitLogInstrumentedHandlerFunc struct { + defaultHook func(context.Context, *v1.BatchLogRequest) (*v1.BatchLogResponse, error) + hooks []func(context.Context, *v1.BatchLogRequest) (*v1.BatchLogResponse, error) + history []ServiceBatchGitLogInstrumentedHandlerFuncCall + mutex sync.Mutex +} + +// BatchGitLogInstrumentedHandler delegates to the next hook function in the +// queue and stores the parameter and result values of this invocation. +func (m *MockService) BatchGitLogInstrumentedHandler(v0 context.Context, v1 *v1.BatchLogRequest) (*v1.BatchLogResponse, error) { + r0, r1 := m.BatchGitLogInstrumentedHandlerFunc.nextHook()(v0, v1) + m.BatchGitLogInstrumentedHandlerFunc.appendCall(ServiceBatchGitLogInstrumentedHandlerFuncCall{v0, v1, r0, r1}) + return r0, r1 +} + +// SetDefaultHook sets function that is called when the +// BatchGitLogInstrumentedHandler method of the parent MockService instance +// is invoked and the hook queue is empty. +func (f *ServiceBatchGitLogInstrumentedHandlerFunc) SetDefaultHook(hook func(context.Context, *v1.BatchLogRequest) (*v1.BatchLogResponse, error)) { + f.defaultHook = hook +} + +// PushHook adds a function to the end of hook queue. Each invocation of the +// BatchGitLogInstrumentedHandler method of the parent MockService instance +// invokes the hook at the front of the queue and discards it. After the +// queue is empty, the default hook function is invoked for any future +// action. +func (f *ServiceBatchGitLogInstrumentedHandlerFunc) PushHook(hook func(context.Context, *v1.BatchLogRequest) (*v1.BatchLogResponse, error)) { + f.mutex.Lock() + f.hooks = append(f.hooks, hook) + f.mutex.Unlock() +} + +// SetDefaultReturn calls SetDefaultHook with a function that returns the +// given values. +func (f *ServiceBatchGitLogInstrumentedHandlerFunc) SetDefaultReturn(r0 *v1.BatchLogResponse, r1 error) { + f.SetDefaultHook(func(context.Context, *v1.BatchLogRequest) (*v1.BatchLogResponse, error) { + return r0, r1 + }) +} + +// PushReturn calls PushHook with a function that returns the given values. +func (f *ServiceBatchGitLogInstrumentedHandlerFunc) PushReturn(r0 *v1.BatchLogResponse, r1 error) { + f.PushHook(func(context.Context, *v1.BatchLogRequest) (*v1.BatchLogResponse, error) { + return r0, r1 + }) +} + +func (f *ServiceBatchGitLogInstrumentedHandlerFunc) nextHook() func(context.Context, *v1.BatchLogRequest) (*v1.BatchLogResponse, error) { + f.mutex.Lock() + defer f.mutex.Unlock() + + if len(f.hooks) == 0 { + return f.defaultHook + } + + hook := f.hooks[0] + f.hooks = f.hooks[1:] + return hook +} + +func (f *ServiceBatchGitLogInstrumentedHandlerFunc) appendCall(r0 ServiceBatchGitLogInstrumentedHandlerFuncCall) { + f.mutex.Lock() + f.history = append(f.history, r0) + f.mutex.Unlock() +} + +// History returns a sequence of +// ServiceBatchGitLogInstrumentedHandlerFuncCall objects describing the +// invocations of this function. +func (f *ServiceBatchGitLogInstrumentedHandlerFunc) History() []ServiceBatchGitLogInstrumentedHandlerFuncCall { + f.mutex.Lock() + history := make([]ServiceBatchGitLogInstrumentedHandlerFuncCall, len(f.history)) + copy(history, f.history) + f.mutex.Unlock() + + return history +} + +// ServiceBatchGitLogInstrumentedHandlerFuncCall is an object that describes +// an invocation of method BatchGitLogInstrumentedHandler on an instance of +// MockService. +type ServiceBatchGitLogInstrumentedHandlerFuncCall struct { + // Arg0 is the value of the 1st argument passed to this method + // invocation. + Arg0 context.Context + // Arg1 is the value of the 2nd argument passed to this method + // invocation. + Arg1 *v1.BatchLogRequest + // Result0 is the value of the 1st result returned from this method + // invocation. + Result0 *v1.BatchLogResponse + // Result1 is the value of the 2nd result returned from this method + // invocation. + Result1 error +} + +// Args returns an interface slice containing the arguments of this +// invocation. +func (c ServiceBatchGitLogInstrumentedHandlerFuncCall) Args() []interface{} { + return []interface{}{c.Arg0, c.Arg1} +} + +// Results returns an interface slice containing the results of this +// invocation. +func (c ServiceBatchGitLogInstrumentedHandlerFuncCall) Results() []interface{} { + return []interface{}{c.Result0, c.Result1} +} + +// ServiceCloneRepoFunc describes the behavior when the CloneRepo method of +// the parent MockService instance is invoked. +type ServiceCloneRepoFunc struct { + defaultHook func(context.Context, api.RepoName, CloneOptions) (string, error) + hooks []func(context.Context, api.RepoName, CloneOptions) (string, error) + history []ServiceCloneRepoFuncCall + mutex sync.Mutex +} + +// CloneRepo delegates to the next hook function in the queue and stores the +// parameter and result values of this invocation. +func (m *MockService) CloneRepo(v0 context.Context, v1 api.RepoName, v2 CloneOptions) (string, error) { + r0, r1 := m.CloneRepoFunc.nextHook()(v0, v1, v2) + m.CloneRepoFunc.appendCall(ServiceCloneRepoFuncCall{v0, v1, v2, r0, r1}) + return r0, r1 +} + +// SetDefaultHook sets function that is called when the CloneRepo method of +// the parent MockService instance is invoked and the hook queue is empty. +func (f *ServiceCloneRepoFunc) SetDefaultHook(hook func(context.Context, api.RepoName, CloneOptions) (string, error)) { + f.defaultHook = hook +} + +// PushHook adds a function to the end of hook queue. Each invocation of the +// CloneRepo method of the parent MockService instance invokes the hook at +// the front of the queue and discards it. After the queue is empty, the +// default hook function is invoked for any future action. +func (f *ServiceCloneRepoFunc) PushHook(hook func(context.Context, api.RepoName, CloneOptions) (string, error)) { + f.mutex.Lock() + f.hooks = append(f.hooks, hook) + f.mutex.Unlock() +} + +// SetDefaultReturn calls SetDefaultHook with a function that returns the +// given values. +func (f *ServiceCloneRepoFunc) SetDefaultReturn(r0 string, r1 error) { + f.SetDefaultHook(func(context.Context, api.RepoName, CloneOptions) (string, error) { + return r0, r1 + }) +} + +// PushReturn calls PushHook with a function that returns the given values. +func (f *ServiceCloneRepoFunc) PushReturn(r0 string, r1 error) { + f.PushHook(func(context.Context, api.RepoName, CloneOptions) (string, error) { + return r0, r1 + }) +} + +func (f *ServiceCloneRepoFunc) nextHook() func(context.Context, api.RepoName, CloneOptions) (string, error) { + f.mutex.Lock() + defer f.mutex.Unlock() + + if len(f.hooks) == 0 { + return f.defaultHook + } + + hook := f.hooks[0] + f.hooks = f.hooks[1:] + return hook +} + +func (f *ServiceCloneRepoFunc) appendCall(r0 ServiceCloneRepoFuncCall) { + f.mutex.Lock() + f.history = append(f.history, r0) + f.mutex.Unlock() +} + +// History returns a sequence of ServiceCloneRepoFuncCall objects describing +// the invocations of this function. +func (f *ServiceCloneRepoFunc) History() []ServiceCloneRepoFuncCall { + f.mutex.Lock() + history := make([]ServiceCloneRepoFuncCall, len(f.history)) + copy(history, f.history) + f.mutex.Unlock() + + return history +} + +// ServiceCloneRepoFuncCall is an object that describes an invocation of +// method CloneRepo on an instance of MockService. +type ServiceCloneRepoFuncCall struct { + // Arg0 is the value of the 1st argument passed to this method + // invocation. + Arg0 context.Context + // Arg1 is the value of the 2nd argument passed to this method + // invocation. + Arg1 api.RepoName + // Arg2 is the value of the 3rd argument passed to this method + // invocation. + Arg2 CloneOptions + // Result0 is the value of the 1st result returned from this method + // invocation. + Result0 string + // Result1 is the value of the 2nd result returned from this method + // invocation. + Result1 error +} + +// Args returns an interface slice containing the arguments of this +// invocation. +func (c ServiceCloneRepoFuncCall) Args() []interface{} { + return []interface{}{c.Arg0, c.Arg1, c.Arg2} +} + +// Results returns an interface slice containing the results of this +// invocation. +func (c ServiceCloneRepoFuncCall) Results() []interface{} { + return []interface{}{c.Result0, c.Result1} +} + +// ServiceCreateCommitFromPatchFunc describes the behavior when the +// CreateCommitFromPatch method of the parent MockService instance is +// invoked. +type ServiceCreateCommitFromPatchFunc struct { + defaultHook func(context.Context, protocol.CreateCommitFromPatchRequest) (int, protocol.CreateCommitFromPatchResponse) + hooks []func(context.Context, protocol.CreateCommitFromPatchRequest) (int, protocol.CreateCommitFromPatchResponse) + history []ServiceCreateCommitFromPatchFuncCall + mutex sync.Mutex +} + +// CreateCommitFromPatch delegates to the next hook function in the queue +// and stores the parameter and result values of this invocation. +func (m *MockService) CreateCommitFromPatch(v0 context.Context, v1 protocol.CreateCommitFromPatchRequest) (int, protocol.CreateCommitFromPatchResponse) { + r0, r1 := m.CreateCommitFromPatchFunc.nextHook()(v0, v1) + m.CreateCommitFromPatchFunc.appendCall(ServiceCreateCommitFromPatchFuncCall{v0, v1, r0, r1}) + return r0, r1 +} + +// SetDefaultHook sets function that is called when the +// CreateCommitFromPatch method of the parent MockService instance is +// invoked and the hook queue is empty. +func (f *ServiceCreateCommitFromPatchFunc) SetDefaultHook(hook func(context.Context, protocol.CreateCommitFromPatchRequest) (int, protocol.CreateCommitFromPatchResponse)) { + f.defaultHook = hook +} + +// PushHook adds a function to the end of hook queue. Each invocation of the +// CreateCommitFromPatch method of the parent MockService instance invokes +// the hook at the front of the queue and discards it. After the queue is +// empty, the default hook function is invoked for any future action. +func (f *ServiceCreateCommitFromPatchFunc) PushHook(hook func(context.Context, protocol.CreateCommitFromPatchRequest) (int, protocol.CreateCommitFromPatchResponse)) { + f.mutex.Lock() + f.hooks = append(f.hooks, hook) + f.mutex.Unlock() +} + +// SetDefaultReturn calls SetDefaultHook with a function that returns the +// given values. +func (f *ServiceCreateCommitFromPatchFunc) SetDefaultReturn(r0 int, r1 protocol.CreateCommitFromPatchResponse) { + f.SetDefaultHook(func(context.Context, protocol.CreateCommitFromPatchRequest) (int, protocol.CreateCommitFromPatchResponse) { + return r0, r1 + }) +} + +// PushReturn calls PushHook with a function that returns the given values. +func (f *ServiceCreateCommitFromPatchFunc) PushReturn(r0 int, r1 protocol.CreateCommitFromPatchResponse) { + f.PushHook(func(context.Context, protocol.CreateCommitFromPatchRequest) (int, protocol.CreateCommitFromPatchResponse) { + return r0, r1 + }) +} + +func (f *ServiceCreateCommitFromPatchFunc) nextHook() func(context.Context, protocol.CreateCommitFromPatchRequest) (int, protocol.CreateCommitFromPatchResponse) { + f.mutex.Lock() + defer f.mutex.Unlock() + + if len(f.hooks) == 0 { + return f.defaultHook + } + + hook := f.hooks[0] + f.hooks = f.hooks[1:] + return hook +} + +func (f *ServiceCreateCommitFromPatchFunc) appendCall(r0 ServiceCreateCommitFromPatchFuncCall) { + f.mutex.Lock() + f.history = append(f.history, r0) + f.mutex.Unlock() +} + +// History returns a sequence of ServiceCreateCommitFromPatchFuncCall +// objects describing the invocations of this function. +func (f *ServiceCreateCommitFromPatchFunc) History() []ServiceCreateCommitFromPatchFuncCall { + f.mutex.Lock() + history := make([]ServiceCreateCommitFromPatchFuncCall, len(f.history)) + copy(history, f.history) + f.mutex.Unlock() + + return history +} + +// ServiceCreateCommitFromPatchFuncCall is an object that describes an +// invocation of method CreateCommitFromPatch on an instance of MockService. +type ServiceCreateCommitFromPatchFuncCall struct { + // Arg0 is the value of the 1st argument passed to this method + // invocation. + Arg0 context.Context + // Arg1 is the value of the 2nd argument passed to this method + // invocation. + Arg1 protocol.CreateCommitFromPatchRequest + // Result0 is the value of the 1st result returned from this method + // invocation. + Result0 int + // Result1 is the value of the 2nd result returned from this method + // invocation. + Result1 protocol.CreateCommitFromPatchResponse +} + +// Args returns an interface slice containing the arguments of this +// invocation. +func (c ServiceCreateCommitFromPatchFuncCall) Args() []interface{} { + return []interface{}{c.Arg0, c.Arg1} +} + +// Results returns an interface slice containing the results of this +// invocation. +func (c ServiceCreateCommitFromPatchFuncCall) Results() []interface{} { + return []interface{}{c.Result0, c.Result1} +} + +// ServiceExecFunc describes the behavior when the Exec method of the parent +// MockService instance is invoked. +type ServiceExecFunc struct { + defaultHook func(context.Context, *protocol.ExecRequest, io.Writer) (execStatus, error) + hooks []func(context.Context, *protocol.ExecRequest, io.Writer) (execStatus, error) + history []ServiceExecFuncCall + mutex sync.Mutex +} + +// Exec delegates to the next hook function in the queue and stores the +// parameter and result values of this invocation. +func (m *MockService) Exec(v0 context.Context, v1 *protocol.ExecRequest, v2 io.Writer) (execStatus, error) { + r0, r1 := m.ExecFunc.nextHook()(v0, v1, v2) + m.ExecFunc.appendCall(ServiceExecFuncCall{v0, v1, v2, r0, r1}) + return r0, r1 +} + +// SetDefaultHook sets function that is called when the Exec method of the +// parent MockService instance is invoked and the hook queue is empty. +func (f *ServiceExecFunc) SetDefaultHook(hook func(context.Context, *protocol.ExecRequest, io.Writer) (execStatus, error)) { + f.defaultHook = hook +} + +// PushHook adds a function to the end of hook queue. Each invocation of the +// Exec method of the parent MockService instance invokes the hook at the +// front of the queue and discards it. After the queue is empty, the default +// hook function is invoked for any future action. +func (f *ServiceExecFunc) PushHook(hook func(context.Context, *protocol.ExecRequest, io.Writer) (execStatus, error)) { + f.mutex.Lock() + f.hooks = append(f.hooks, hook) + f.mutex.Unlock() +} + +// SetDefaultReturn calls SetDefaultHook with a function that returns the +// given values. +func (f *ServiceExecFunc) SetDefaultReturn(r0 execStatus, r1 error) { + f.SetDefaultHook(func(context.Context, *protocol.ExecRequest, io.Writer) (execStatus, error) { + return r0, r1 + }) +} + +// PushReturn calls PushHook with a function that returns the given values. +func (f *ServiceExecFunc) PushReturn(r0 execStatus, r1 error) { + f.PushHook(func(context.Context, *protocol.ExecRequest, io.Writer) (execStatus, error) { + return r0, r1 + }) +} + +func (f *ServiceExecFunc) nextHook() func(context.Context, *protocol.ExecRequest, io.Writer) (execStatus, error) { + f.mutex.Lock() + defer f.mutex.Unlock() + + if len(f.hooks) == 0 { + return f.defaultHook + } + + hook := f.hooks[0] + f.hooks = f.hooks[1:] + return hook +} + +func (f *ServiceExecFunc) appendCall(r0 ServiceExecFuncCall) { + f.mutex.Lock() + f.history = append(f.history, r0) + f.mutex.Unlock() +} + +// History returns a sequence of ServiceExecFuncCall objects describing the +// invocations of this function. +func (f *ServiceExecFunc) History() []ServiceExecFuncCall { + f.mutex.Lock() + history := make([]ServiceExecFuncCall, len(f.history)) + copy(history, f.history) + f.mutex.Unlock() + + return history +} + +// ServiceExecFuncCall is an object that describes an invocation of method +// Exec on an instance of MockService. +type ServiceExecFuncCall struct { + // Arg0 is the value of the 1st argument passed to this method + // invocation. + Arg0 context.Context + // Arg1 is the value of the 2nd argument passed to this method + // invocation. + Arg1 *protocol.ExecRequest + // Arg2 is the value of the 3rd argument passed to this method + // invocation. + Arg2 io.Writer + // Result0 is the value of the 1st result returned from this method + // invocation. + Result0 execStatus + // Result1 is the value of the 2nd result returned from this method + // invocation. + Result1 error +} + +// Args returns an interface slice containing the arguments of this +// invocation. +func (c ServiceExecFuncCall) Args() []interface{} { + return []interface{}{c.Arg0, c.Arg1, c.Arg2} +} + +// Results returns an interface slice containing the results of this +// invocation. +func (c ServiceExecFuncCall) Results() []interface{} { + return []interface{}{c.Result0, c.Result1} +} + +// ServiceIsRepoCloneableFunc describes the behavior when the +// IsRepoCloneable method of the parent MockService instance is invoked. +type ServiceIsRepoCloneableFunc struct { + defaultHook func(context.Context, api.RepoName) (protocol.IsRepoCloneableResponse, error) + hooks []func(context.Context, api.RepoName) (protocol.IsRepoCloneableResponse, error) + history []ServiceIsRepoCloneableFuncCall + mutex sync.Mutex +} + +// IsRepoCloneable delegates to the next hook function in the queue and +// stores the parameter and result values of this invocation. +func (m *MockService) IsRepoCloneable(v0 context.Context, v1 api.RepoName) (protocol.IsRepoCloneableResponse, error) { + r0, r1 := m.IsRepoCloneableFunc.nextHook()(v0, v1) + m.IsRepoCloneableFunc.appendCall(ServiceIsRepoCloneableFuncCall{v0, v1, r0, r1}) + return r0, r1 +} + +// SetDefaultHook sets function that is called when the IsRepoCloneable +// method of the parent MockService instance is invoked and the hook queue +// is empty. +func (f *ServiceIsRepoCloneableFunc) SetDefaultHook(hook func(context.Context, api.RepoName) (protocol.IsRepoCloneableResponse, error)) { + f.defaultHook = hook +} + +// PushHook adds a function to the end of hook queue. Each invocation of the +// IsRepoCloneable method of the parent MockService instance invokes the +// hook at the front of the queue and discards it. After the queue is empty, +// the default hook function is invoked for any future action. +func (f *ServiceIsRepoCloneableFunc) PushHook(hook func(context.Context, api.RepoName) (protocol.IsRepoCloneableResponse, error)) { + f.mutex.Lock() + f.hooks = append(f.hooks, hook) + f.mutex.Unlock() +} + +// SetDefaultReturn calls SetDefaultHook with a function that returns the +// given values. +func (f *ServiceIsRepoCloneableFunc) SetDefaultReturn(r0 protocol.IsRepoCloneableResponse, r1 error) { + f.SetDefaultHook(func(context.Context, api.RepoName) (protocol.IsRepoCloneableResponse, error) { + return r0, r1 + }) +} + +// PushReturn calls PushHook with a function that returns the given values. +func (f *ServiceIsRepoCloneableFunc) PushReturn(r0 protocol.IsRepoCloneableResponse, r1 error) { + f.PushHook(func(context.Context, api.RepoName) (protocol.IsRepoCloneableResponse, error) { + return r0, r1 + }) +} + +func (f *ServiceIsRepoCloneableFunc) nextHook() func(context.Context, api.RepoName) (protocol.IsRepoCloneableResponse, error) { + f.mutex.Lock() + defer f.mutex.Unlock() + + if len(f.hooks) == 0 { + return f.defaultHook + } + + hook := f.hooks[0] + f.hooks = f.hooks[1:] + return hook +} + +func (f *ServiceIsRepoCloneableFunc) appendCall(r0 ServiceIsRepoCloneableFuncCall) { + f.mutex.Lock() + f.history = append(f.history, r0) + f.mutex.Unlock() +} + +// History returns a sequence of ServiceIsRepoCloneableFuncCall objects +// describing the invocations of this function. +func (f *ServiceIsRepoCloneableFunc) History() []ServiceIsRepoCloneableFuncCall { + f.mutex.Lock() + history := make([]ServiceIsRepoCloneableFuncCall, len(f.history)) + copy(history, f.history) + f.mutex.Unlock() + + return history +} + +// ServiceIsRepoCloneableFuncCall is an object that describes an invocation +// of method IsRepoCloneable on an instance of MockService. +type ServiceIsRepoCloneableFuncCall struct { + // Arg0 is the value of the 1st argument passed to this method + // invocation. + Arg0 context.Context + // Arg1 is the value of the 2nd argument passed to this method + // invocation. + Arg1 api.RepoName + // Result0 is the value of the 1st result returned from this method + // invocation. + Result0 protocol.IsRepoCloneableResponse + // Result1 is the value of the 2nd result returned from this method + // invocation. + Result1 error +} + +// Args returns an interface slice containing the arguments of this +// invocation. +func (c ServiceIsRepoCloneableFuncCall) Args() []interface{} { + return []interface{}{c.Arg0, c.Arg1} +} + +// Results returns an interface slice containing the results of this +// invocation. +func (c ServiceIsRepoCloneableFuncCall) Results() []interface{} { + return []interface{}{c.Result0, c.Result1} +} + +// ServiceLogIfCorruptFunc describes the behavior when the LogIfCorrupt +// method of the parent MockService instance is invoked. +type ServiceLogIfCorruptFunc struct { + defaultHook func(context.Context, api.RepoName, error) + hooks []func(context.Context, api.RepoName, error) + history []ServiceLogIfCorruptFuncCall + mutex sync.Mutex +} + +// LogIfCorrupt delegates to the next hook function in the queue and stores +// the parameter and result values of this invocation. +func (m *MockService) LogIfCorrupt(v0 context.Context, v1 api.RepoName, v2 error) { + m.LogIfCorruptFunc.nextHook()(v0, v1, v2) + m.LogIfCorruptFunc.appendCall(ServiceLogIfCorruptFuncCall{v0, v1, v2}) + return +} + +// SetDefaultHook sets function that is called when the LogIfCorrupt method +// of the parent MockService instance is invoked and the hook queue is +// empty. +func (f *ServiceLogIfCorruptFunc) SetDefaultHook(hook func(context.Context, api.RepoName, error)) { + f.defaultHook = hook +} + +// PushHook adds a function to the end of hook queue. Each invocation of the +// LogIfCorrupt method of the parent MockService instance invokes the hook +// at the front of the queue and discards it. After the queue is empty, the +// default hook function is invoked for any future action. +func (f *ServiceLogIfCorruptFunc) PushHook(hook func(context.Context, api.RepoName, error)) { + f.mutex.Lock() + f.hooks = append(f.hooks, hook) + f.mutex.Unlock() +} + +// SetDefaultReturn calls SetDefaultHook with a function that returns the +// given values. +func (f *ServiceLogIfCorruptFunc) SetDefaultReturn() { + f.SetDefaultHook(func(context.Context, api.RepoName, error) { + return + }) +} + +// PushReturn calls PushHook with a function that returns the given values. +func (f *ServiceLogIfCorruptFunc) PushReturn() { + f.PushHook(func(context.Context, api.RepoName, error) { + return + }) +} + +func (f *ServiceLogIfCorruptFunc) nextHook() func(context.Context, api.RepoName, error) { + f.mutex.Lock() + defer f.mutex.Unlock() + + if len(f.hooks) == 0 { + return f.defaultHook + } + + hook := f.hooks[0] + f.hooks = f.hooks[1:] + return hook +} + +func (f *ServiceLogIfCorruptFunc) appendCall(r0 ServiceLogIfCorruptFuncCall) { + f.mutex.Lock() + f.history = append(f.history, r0) + f.mutex.Unlock() +} + +// History returns a sequence of ServiceLogIfCorruptFuncCall objects +// describing the invocations of this function. +func (f *ServiceLogIfCorruptFunc) History() []ServiceLogIfCorruptFuncCall { + f.mutex.Lock() + history := make([]ServiceLogIfCorruptFuncCall, len(f.history)) + copy(history, f.history) + f.mutex.Unlock() + + return history +} + +// ServiceLogIfCorruptFuncCall is an object that describes an invocation of +// method LogIfCorrupt on an instance of MockService. +type ServiceLogIfCorruptFuncCall struct { + // Arg0 is the value of the 1st argument passed to this method + // invocation. + Arg0 context.Context + // Arg1 is the value of the 2nd argument passed to this method + // invocation. + Arg1 api.RepoName + // Arg2 is the value of the 3rd argument passed to this method + // invocation. + Arg2 error +} + +// Args returns an interface slice containing the arguments of this +// invocation. +func (c ServiceLogIfCorruptFuncCall) Args() []interface{} { + return []interface{}{c.Arg0, c.Arg1, c.Arg2} +} + +// Results returns an interface slice containing the results of this +// invocation. +func (c ServiceLogIfCorruptFuncCall) Results() []interface{} { + return []interface{}{} +} + +// ServiceMaybeStartCloneFunc describes the behavior when the +// MaybeStartClone method of the parent MockService instance is invoked. +type ServiceMaybeStartCloneFunc struct { + defaultHook func(context.Context, api.RepoName) (*protocol.NotFoundPayload, bool) + hooks []func(context.Context, api.RepoName) (*protocol.NotFoundPayload, bool) + history []ServiceMaybeStartCloneFuncCall + mutex sync.Mutex +} + +// MaybeStartClone delegates to the next hook function in the queue and +// stores the parameter and result values of this invocation. +func (m *MockService) MaybeStartClone(v0 context.Context, v1 api.RepoName) (*protocol.NotFoundPayload, bool) { + r0, r1 := m.MaybeStartCloneFunc.nextHook()(v0, v1) + m.MaybeStartCloneFunc.appendCall(ServiceMaybeStartCloneFuncCall{v0, v1, r0, r1}) + return r0, r1 +} + +// SetDefaultHook sets function that is called when the MaybeStartClone +// method of the parent MockService instance is invoked and the hook queue +// is empty. +func (f *ServiceMaybeStartCloneFunc) SetDefaultHook(hook func(context.Context, api.RepoName) (*protocol.NotFoundPayload, bool)) { + f.defaultHook = hook +} + +// PushHook adds a function to the end of hook queue. Each invocation of the +// MaybeStartClone method of the parent MockService instance invokes the +// hook at the front of the queue and discards it. After the queue is empty, +// the default hook function is invoked for any future action. +func (f *ServiceMaybeStartCloneFunc) PushHook(hook func(context.Context, api.RepoName) (*protocol.NotFoundPayload, bool)) { + f.mutex.Lock() + f.hooks = append(f.hooks, hook) + f.mutex.Unlock() +} + +// SetDefaultReturn calls SetDefaultHook with a function that returns the +// given values. +func (f *ServiceMaybeStartCloneFunc) SetDefaultReturn(r0 *protocol.NotFoundPayload, r1 bool) { + f.SetDefaultHook(func(context.Context, api.RepoName) (*protocol.NotFoundPayload, bool) { + return r0, r1 + }) +} + +// PushReturn calls PushHook with a function that returns the given values. +func (f *ServiceMaybeStartCloneFunc) PushReturn(r0 *protocol.NotFoundPayload, r1 bool) { + f.PushHook(func(context.Context, api.RepoName) (*protocol.NotFoundPayload, bool) { + return r0, r1 + }) +} + +func (f *ServiceMaybeStartCloneFunc) nextHook() func(context.Context, api.RepoName) (*protocol.NotFoundPayload, bool) { + f.mutex.Lock() + defer f.mutex.Unlock() + + if len(f.hooks) == 0 { + return f.defaultHook + } + + hook := f.hooks[0] + f.hooks = f.hooks[1:] + return hook +} + +func (f *ServiceMaybeStartCloneFunc) appendCall(r0 ServiceMaybeStartCloneFuncCall) { + f.mutex.Lock() + f.history = append(f.history, r0) + f.mutex.Unlock() +} + +// History returns a sequence of ServiceMaybeStartCloneFuncCall objects +// describing the invocations of this function. +func (f *ServiceMaybeStartCloneFunc) History() []ServiceMaybeStartCloneFuncCall { + f.mutex.Lock() + history := make([]ServiceMaybeStartCloneFuncCall, len(f.history)) + copy(history, f.history) + f.mutex.Unlock() + + return history +} + +// ServiceMaybeStartCloneFuncCall is an object that describes an invocation +// of method MaybeStartClone on an instance of MockService. +type ServiceMaybeStartCloneFuncCall struct { + // Arg0 is the value of the 1st argument passed to this method + // invocation. + Arg0 context.Context + // Arg1 is the value of the 2nd argument passed to this method + // invocation. + Arg1 api.RepoName + // Result0 is the value of the 1st result returned from this method + // invocation. + Result0 *protocol.NotFoundPayload + // Result1 is the value of the 2nd result returned from this method + // invocation. + Result1 bool +} + +// Args returns an interface slice containing the arguments of this +// invocation. +func (c ServiceMaybeStartCloneFuncCall) Args() []interface{} { + return []interface{}{c.Arg0, c.Arg1} +} + +// Results returns an interface slice containing the results of this +// invocation. +func (c ServiceMaybeStartCloneFuncCall) Results() []interface{} { + return []interface{}{c.Result0, c.Result1} +} + +// ServiceP4ExecFunc describes the behavior when the P4Exec method of the +// parent MockService instance is invoked. +type ServiceP4ExecFunc struct { + defaultHook func(context.Context, log.Logger, *p4ExecRequest, io.Writer) execStatus + hooks []func(context.Context, log.Logger, *p4ExecRequest, io.Writer) execStatus + history []ServiceP4ExecFuncCall + mutex sync.Mutex +} + +// P4Exec delegates to the next hook function in the queue and stores the +// parameter and result values of this invocation. +func (m *MockService) P4Exec(v0 context.Context, v1 log.Logger, v2 *p4ExecRequest, v3 io.Writer) execStatus { + r0 := m.P4ExecFunc.nextHook()(v0, v1, v2, v3) + m.P4ExecFunc.appendCall(ServiceP4ExecFuncCall{v0, v1, v2, v3, r0}) + return r0 +} + +// SetDefaultHook sets function that is called when the P4Exec method of the +// parent MockService instance is invoked and the hook queue is empty. +func (f *ServiceP4ExecFunc) SetDefaultHook(hook func(context.Context, log.Logger, *p4ExecRequest, io.Writer) execStatus) { + f.defaultHook = hook +} + +// PushHook adds a function to the end of hook queue. Each invocation of the +// P4Exec method of the parent MockService instance invokes the hook at the +// front of the queue and discards it. After the queue is empty, the default +// hook function is invoked for any future action. +func (f *ServiceP4ExecFunc) PushHook(hook func(context.Context, log.Logger, *p4ExecRequest, io.Writer) execStatus) { + f.mutex.Lock() + f.hooks = append(f.hooks, hook) + f.mutex.Unlock() +} + +// SetDefaultReturn calls SetDefaultHook with a function that returns the +// given values. +func (f *ServiceP4ExecFunc) SetDefaultReturn(r0 execStatus) { + f.SetDefaultHook(func(context.Context, log.Logger, *p4ExecRequest, io.Writer) execStatus { + return r0 + }) +} + +// PushReturn calls PushHook with a function that returns the given values. +func (f *ServiceP4ExecFunc) PushReturn(r0 execStatus) { + f.PushHook(func(context.Context, log.Logger, *p4ExecRequest, io.Writer) execStatus { + return r0 + }) +} + +func (f *ServiceP4ExecFunc) nextHook() func(context.Context, log.Logger, *p4ExecRequest, io.Writer) execStatus { + f.mutex.Lock() + defer f.mutex.Unlock() + + if len(f.hooks) == 0 { + return f.defaultHook + } + + hook := f.hooks[0] + f.hooks = f.hooks[1:] + return hook +} + +func (f *ServiceP4ExecFunc) appendCall(r0 ServiceP4ExecFuncCall) { + f.mutex.Lock() + f.history = append(f.history, r0) + f.mutex.Unlock() +} + +// History returns a sequence of ServiceP4ExecFuncCall objects describing +// the invocations of this function. +func (f *ServiceP4ExecFunc) History() []ServiceP4ExecFuncCall { + f.mutex.Lock() + history := make([]ServiceP4ExecFuncCall, len(f.history)) + copy(history, f.history) + f.mutex.Unlock() + + return history +} + +// ServiceP4ExecFuncCall is an object that describes an invocation of method +// P4Exec on an instance of MockService. +type ServiceP4ExecFuncCall struct { + // Arg0 is the value of the 1st argument passed to this method + // invocation. + Arg0 context.Context + // Arg1 is the value of the 2nd argument passed to this method + // invocation. + Arg1 log.Logger + // Arg2 is the value of the 3rd argument passed to this method + // invocation. + Arg2 *p4ExecRequest + // Arg3 is the value of the 4th argument passed to this method + // invocation. + Arg3 io.Writer + // Result0 is the value of the 1st result returned from this method + // invocation. + Result0 execStatus +} + +// Args returns an interface slice containing the arguments of this +// invocation. +func (c ServiceP4ExecFuncCall) Args() []interface{} { + return []interface{}{c.Arg0, c.Arg1, c.Arg2, c.Arg3} +} + +// Results returns an interface slice containing the results of this +// invocation. +func (c ServiceP4ExecFuncCall) Results() []interface{} { + return []interface{}{c.Result0} +} + +// ServiceRepoUpdateFunc describes the behavior when the RepoUpdate method +// of the parent MockService instance is invoked. +type ServiceRepoUpdateFunc struct { + defaultHook func(*protocol.RepoUpdateRequest) protocol.RepoUpdateResponse + hooks []func(*protocol.RepoUpdateRequest) protocol.RepoUpdateResponse + history []ServiceRepoUpdateFuncCall + mutex sync.Mutex +} + +// RepoUpdate delegates to the next hook function in the queue and stores +// the parameter and result values of this invocation. +func (m *MockService) RepoUpdate(v0 *protocol.RepoUpdateRequest) protocol.RepoUpdateResponse { + r0 := m.RepoUpdateFunc.nextHook()(v0) + m.RepoUpdateFunc.appendCall(ServiceRepoUpdateFuncCall{v0, r0}) + return r0 +} + +// SetDefaultHook sets function that is called when the RepoUpdate method of +// the parent MockService instance is invoked and the hook queue is empty. +func (f *ServiceRepoUpdateFunc) SetDefaultHook(hook func(*protocol.RepoUpdateRequest) protocol.RepoUpdateResponse) { + f.defaultHook = hook +} + +// PushHook adds a function to the end of hook queue. Each invocation of the +// RepoUpdate method of the parent MockService instance invokes the hook at +// the front of the queue and discards it. After the queue is empty, the +// default hook function is invoked for any future action. +func (f *ServiceRepoUpdateFunc) PushHook(hook func(*protocol.RepoUpdateRequest) protocol.RepoUpdateResponse) { + f.mutex.Lock() + f.hooks = append(f.hooks, hook) + f.mutex.Unlock() +} + +// SetDefaultReturn calls SetDefaultHook with a function that returns the +// given values. +func (f *ServiceRepoUpdateFunc) SetDefaultReturn(r0 protocol.RepoUpdateResponse) { + f.SetDefaultHook(func(*protocol.RepoUpdateRequest) protocol.RepoUpdateResponse { + return r0 + }) +} + +// PushReturn calls PushHook with a function that returns the given values. +func (f *ServiceRepoUpdateFunc) PushReturn(r0 protocol.RepoUpdateResponse) { + f.PushHook(func(*protocol.RepoUpdateRequest) protocol.RepoUpdateResponse { + return r0 + }) +} + +func (f *ServiceRepoUpdateFunc) nextHook() func(*protocol.RepoUpdateRequest) protocol.RepoUpdateResponse { + f.mutex.Lock() + defer f.mutex.Unlock() + + if len(f.hooks) == 0 { + return f.defaultHook + } + + hook := f.hooks[0] + f.hooks = f.hooks[1:] + return hook +} + +func (f *ServiceRepoUpdateFunc) appendCall(r0 ServiceRepoUpdateFuncCall) { + f.mutex.Lock() + f.history = append(f.history, r0) + f.mutex.Unlock() +} + +// History returns a sequence of ServiceRepoUpdateFuncCall objects +// describing the invocations of this function. +func (f *ServiceRepoUpdateFunc) History() []ServiceRepoUpdateFuncCall { + f.mutex.Lock() + history := make([]ServiceRepoUpdateFuncCall, len(f.history)) + copy(history, f.history) + f.mutex.Unlock() + + return history +} + +// ServiceRepoUpdateFuncCall is an object that describes an invocation of +// method RepoUpdate on an instance of MockService. +type ServiceRepoUpdateFuncCall struct { + // Arg0 is the value of the 1st argument passed to this method + // invocation. + Arg0 *protocol.RepoUpdateRequest + // Result0 is the value of the 1st result returned from this method + // invocation. + Result0 protocol.RepoUpdateResponse +} + +// Args returns an interface slice containing the arguments of this +// invocation. +func (c ServiceRepoUpdateFuncCall) Args() []interface{} { + return []interface{}{c.Arg0} +} + +// Results returns an interface slice containing the results of this +// invocation. +func (c ServiceRepoUpdateFuncCall) Results() []interface{} { + return []interface{}{c.Result0} +} + +// ServiceSearchWithObservabilityFunc describes the behavior when the +// SearchWithObservability method of the parent MockService instance is +// invoked. +type ServiceSearchWithObservabilityFunc struct { + defaultHook func(context.Context, trace.Trace, *protocol.SearchRequest, func(*protocol.CommitMatch) error) (bool, error) + hooks []func(context.Context, trace.Trace, *protocol.SearchRequest, func(*protocol.CommitMatch) error) (bool, error) + history []ServiceSearchWithObservabilityFuncCall + mutex sync.Mutex +} + +// SearchWithObservability delegates to the next hook function in the queue +// and stores the parameter and result values of this invocation. +func (m *MockService) SearchWithObservability(v0 context.Context, v1 trace.Trace, v2 *protocol.SearchRequest, v3 func(*protocol.CommitMatch) error) (bool, error) { + r0, r1 := m.SearchWithObservabilityFunc.nextHook()(v0, v1, v2, v3) + m.SearchWithObservabilityFunc.appendCall(ServiceSearchWithObservabilityFuncCall{v0, v1, v2, v3, r0, r1}) + return r0, r1 +} + +// SetDefaultHook sets function that is called when the +// SearchWithObservability method of the parent MockService instance is +// invoked and the hook queue is empty. +func (f *ServiceSearchWithObservabilityFunc) SetDefaultHook(hook func(context.Context, trace.Trace, *protocol.SearchRequest, func(*protocol.CommitMatch) error) (bool, error)) { + f.defaultHook = hook +} + +// PushHook adds a function to the end of hook queue. Each invocation of the +// SearchWithObservability method of the parent MockService instance invokes +// the hook at the front of the queue and discards it. After the queue is +// empty, the default hook function is invoked for any future action. +func (f *ServiceSearchWithObservabilityFunc) PushHook(hook func(context.Context, trace.Trace, *protocol.SearchRequest, func(*protocol.CommitMatch) error) (bool, error)) { + f.mutex.Lock() + f.hooks = append(f.hooks, hook) + f.mutex.Unlock() +} + +// SetDefaultReturn calls SetDefaultHook with a function that returns the +// given values. +func (f *ServiceSearchWithObservabilityFunc) SetDefaultReturn(r0 bool, r1 error) { + f.SetDefaultHook(func(context.Context, trace.Trace, *protocol.SearchRequest, func(*protocol.CommitMatch) error) (bool, error) { + return r0, r1 + }) +} + +// PushReturn calls PushHook with a function that returns the given values. +func (f *ServiceSearchWithObservabilityFunc) PushReturn(r0 bool, r1 error) { + f.PushHook(func(context.Context, trace.Trace, *protocol.SearchRequest, func(*protocol.CommitMatch) error) (bool, error) { + return r0, r1 + }) +} + +func (f *ServiceSearchWithObservabilityFunc) nextHook() func(context.Context, trace.Trace, *protocol.SearchRequest, func(*protocol.CommitMatch) error) (bool, error) { + f.mutex.Lock() + defer f.mutex.Unlock() + + if len(f.hooks) == 0 { + return f.defaultHook + } + + hook := f.hooks[0] + f.hooks = f.hooks[1:] + return hook +} + +func (f *ServiceSearchWithObservabilityFunc) appendCall(r0 ServiceSearchWithObservabilityFuncCall) { + f.mutex.Lock() + f.history = append(f.history, r0) + f.mutex.Unlock() +} + +// History returns a sequence of ServiceSearchWithObservabilityFuncCall +// objects describing the invocations of this function. +func (f *ServiceSearchWithObservabilityFunc) History() []ServiceSearchWithObservabilityFuncCall { + f.mutex.Lock() + history := make([]ServiceSearchWithObservabilityFuncCall, len(f.history)) + copy(history, f.history) + f.mutex.Unlock() + + return history +} + +// ServiceSearchWithObservabilityFuncCall is an object that describes an +// invocation of method SearchWithObservability on an instance of +// MockService. +type ServiceSearchWithObservabilityFuncCall struct { + // Arg0 is the value of the 1st argument passed to this method + // invocation. + Arg0 context.Context + // Arg1 is the value of the 2nd argument passed to this method + // invocation. + Arg1 trace.Trace + // Arg2 is the value of the 3rd argument passed to this method + // invocation. + Arg2 *protocol.SearchRequest + // Arg3 is the value of the 4th argument passed to this method + // invocation. + Arg3 func(*protocol.CommitMatch) error + // Result0 is the value of the 1st result returned from this method + // invocation. + Result0 bool + // Result1 is the value of the 2nd result returned from this method + // invocation. + Result1 error +} + +// Args returns an interface slice containing the arguments of this +// invocation. +func (c ServiceSearchWithObservabilityFuncCall) Args() []interface{} { + return []interface{}{c.Arg0, c.Arg1, c.Arg2, c.Arg3} +} + +// Results returns an interface slice containing the results of this +// invocation. +func (c ServiceSearchWithObservabilityFuncCall) Results() []interface{} { + return []interface{}{c.Result0, c.Result1} +} diff --git a/cmd/gitserver/internal/p4exec.go b/cmd/gitserver/internal/p4exec.go index 96fc722762a..b1d557a7349 100644 --- a/cmd/gitserver/internal/p4exec.go +++ b/cmd/gitserver/internal/p4exec.go @@ -28,7 +28,7 @@ import ( "github.com/sourcegraph/sourcegraph/internal/trace" ) -func (gs *GRPCServer) P4Exec(req *proto.P4ExecRequest, ss proto.GitserverService_P4ExecServer) error { +func (gs *grpcServer) P4Exec(req *proto.P4ExecRequest, ss proto.GitserverService_P4ExecServer) error { arguments := byteSlicesToStrings(req.GetArgs()) //nolint:staticcheck if len(arguments) < 1 { @@ -50,7 +50,7 @@ func (gs *GRPCServer) P4Exec(req *proto.P4ExecRequest, ss proto.GitserverService return status.Error(codes.InvalidArgument, fmt.Sprintf("subcommand %q is not allowed", subCommand)) } - p4home, err := gitserverfs.MakeP4HomeDir(gs.Server.ReposDir) + p4home, err := gitserverfs.MakeP4HomeDir(gs.reposDir) if err != nil { return status.Error(codes.Internal, err.Error()) } @@ -84,11 +84,11 @@ func (gs *GRPCServer) P4Exec(req *proto.P4ExecRequest, ss proto.GitserverService var r p4ExecRequest r.FromProto(req) - return gs.doP4Exec(ss.Context(), gs.Server.Logger, &r, "unknown-grpc-client", w) + return gs.doP4Exec(ss.Context(), &r, w) } -func (gs *GRPCServer) doP4Exec(ctx context.Context, logger log.Logger, req *p4ExecRequest, userAgent string, w io.Writer) error { - execStatus := gs.Server.p4Exec(ctx, logger, req, userAgent, w) +func (gs *grpcServer) doP4Exec(ctx context.Context, req *p4ExecRequest, w io.Writer) error { + execStatus := gs.svc.P4Exec(ctx, gs.logger, req, w) if execStatus.ExitStatus != 0 || execStatus.Err != nil { if ctxErr := ctx.Err(); ctxErr != nil { @@ -105,7 +105,7 @@ func (gs *GRPCServer) doP4Exec(ctx context.Context, logger log.Logger, req *p4Ex Stderr: execStatus.Stderr, }) if err != nil { - gs.Server.Logger.Error("failed to marshal status", log.Error(err)) + gs.logger.Error("failed to marshal status", log.Error(err)) return err } return s.Err() @@ -114,7 +114,7 @@ func (gs *GRPCServer) doP4Exec(ctx context.Context, logger log.Logger, req *p4Ex return nil } -func (s *Server) p4Exec(ctx context.Context, logger log.Logger, req *p4ExecRequest, userAgent string, w io.Writer) execStatus { +func (s *Server) P4Exec(ctx context.Context, logger log.Logger, req *p4ExecRequest, w io.Writer) execStatus { start := time.Now() var cmdStart time.Time // set once we have ensured commit exitStatus := executil.UnsetExitStatus @@ -163,7 +163,6 @@ func (s *Server) p4Exec(ctx context.Context, logger log.Logger, req *p4ExecReque ev.AddField("cmd", cmd) ev.AddField("args", args) ev.AddField("actor", act.UIDString()) - ev.AddField("client", userAgent) ev.AddField("duration_ms", duration.Milliseconds()) ev.AddField("stdout_size", stdoutN) ev.AddField("stderr_size", stderrN) diff --git a/cmd/gitserver/internal/p4exec_test.go b/cmd/gitserver/internal/p4exec_test.go index b4cf581fafd..7b62f167fe1 100644 --- a/cmd/gitserver/internal/p4exec_test.go +++ b/cmd/gitserver/internal/p4exec_test.go @@ -63,7 +63,7 @@ func TestServer_handleP4Exec(t *testing.T) { } server := defaults.NewServer(logger) - proto.RegisterGitserverServiceServer(server, &GRPCServer{Server: s}) + proto.RegisterGitserverServiceServer(server, NewGRPCServer(s)) handler = grpc.MultiplexHandlers(server, s.Handler()) srv := httptest.NewServer(handler) diff --git a/cmd/gitserver/internal/patch.go b/cmd/gitserver/internal/patch.go index 4a9044b5ee9..fef03999719 100644 --- a/cmd/gitserver/internal/patch.go +++ b/cmd/gitserver/internal/patch.go @@ -35,7 +35,7 @@ import ( var patchID uint64 -func (s *Server) createCommitFromPatch(ctx context.Context, req protocol.CreateCommitFromPatchRequest) (int, protocol.CreateCommitFromPatchResponse) { +func (s *Server) CreateCommitFromPatch(ctx context.Context, req protocol.CreateCommitFromPatchRequest) (int, protocol.CreateCommitFromPatchResponse) { logger := s.Logger.Scoped("createCommitFromPatch"). With( log.String("repo", string(req.Repo)), diff --git a/cmd/gitserver/internal/repo_info_test.go b/cmd/gitserver/internal/repo_info_test.go index 86e84e45845..a898deed303 100644 --- a/cmd/gitserver/internal/repo_info_test.go +++ b/cmd/gitserver/internal/repo_info_test.go @@ -62,7 +62,7 @@ func testDeleteRepo(t *testing.T, deletedInDB bool) { _ = s.Handler() // This will perform an initial clone - s.repoUpdate(&protocol.RepoUpdateRequest{ + s.RepoUpdate(&protocol.RepoUpdateRequest{ Repo: repoName, }) diff --git a/cmd/gitserver/internal/search.go b/cmd/gitserver/internal/search.go index 3d0dd145813..f6b8e42d3d6 100644 --- a/cmd/gitserver/internal/search.go +++ b/cmd/gitserver/internal/search.go @@ -21,7 +21,7 @@ import ( "github.com/sourcegraph/sourcegraph/internal/trace" ) -func (s *Server) searchWithObservability(ctx context.Context, tr trace.Trace, args *protocol.SearchRequest, onMatch func(*protocol.CommitMatch) error) (limitHit bool, err error) { +func (s *Server) SearchWithObservability(ctx context.Context, tr trace.Trace, args *protocol.SearchRequest, onMatch func(*protocol.CommitMatch) error) (limitHit bool, err error) { searchStart := time.Now() searchRunning.Inc() diff --git a/cmd/gitserver/internal/server.go b/cmd/gitserver/internal/server.go index 9319cd036e9..c6ee9979c00 100644 --- a/cmd/gitserver/internal/server.go +++ b/cmd/gitserver/internal/server.go @@ -43,7 +43,6 @@ import ( "github.com/sourcegraph/sourcegraph/internal/env" "github.com/sourcegraph/sourcegraph/internal/featureflag" "github.com/sourcegraph/sourcegraph/internal/fileutil" - "github.com/sourcegraph/sourcegraph/internal/gitserver" "github.com/sourcegraph/sourcegraph/internal/gitserver/gitdomain" "github.com/sourcegraph/sourcegraph/internal/gitserver/protocol" "github.com/sourcegraph/sourcegraph/internal/goroutine" @@ -269,10 +268,6 @@ func (s *Server) Handler() http.Handler { return mux } -func addrForRepo(ctx context.Context, repoName api.RepoName, gitServerAddrs gitserver.GitserverAddresses) string { - return gitServerAddrs.AddrForRepo(ctx, filepath.Base(os.Args[0]), repoName) -} - // NewClonePipeline creates a new pipeline that clones repos asynchronously. It // creates a producer-consumer pipeline that handles clone requests asychronously. func (s *Server) NewClonePipeline(logger log.Logger, cloneQueue *common.Queue[*cloneJob]) goroutine.BackgroundRoutine { @@ -444,7 +439,7 @@ func (s *Server) acquireCloneableLimiter(ctx context.Context) (context.Context, return s.cloneableLimiter.Acquire(ctx) } -func (s *Server) isRepoCloneable(ctx context.Context, repo api.RepoName) (protocol.IsRepoCloneableResponse, error) { +func (s *Server) IsRepoCloneable(ctx context.Context, repo api.RepoName) (protocol.IsRepoCloneableResponse, error) { // We use an internal actor here as the repo may be private. It is safe since all // we return is a bool indicating whether the repo is cloneable or not. Perhaps // the only things that could leak here is whether a private repo exists although @@ -471,7 +466,7 @@ func (s *Server) isRepoCloneable(ctx context.Context, repo api.RepoName) (protoc return resp, nil } -func (s *Server) repoUpdate(req *protocol.RepoUpdateRequest) protocol.RepoUpdateResponse { +func (s *Server) RepoUpdate(req *protocol.RepoUpdateRequest) protocol.RepoUpdateResponse { logger := s.Logger.Scoped("handleRepoUpdate") var resp protocol.RepoUpdateResponse req.Repo = protocol.NormalizeRepo(req.Repo) @@ -544,10 +539,10 @@ type execStatus struct { } // TODO: eseliger -// exec runs a git command. After the first write to w, it must not return an error. +// Exec runs a git command. After the first write to w, it must not return an error. // TODO(@camdencheek): once gRPC is the only consumer of this, do everything with errors // because gRPC can handle trailing errors on a stream. -func (s *Server) exec(ctx context.Context, logger log.Logger, req *protocol.ExecRequest, userAgent string, w io.Writer) (execStatus, error) { +func (s *Server) Exec(ctx context.Context, req *protocol.ExecRequest, w io.Writer) (execStatus, error) { repoName := protocol.NormalizeRepo(req.Repo) dir := gitserverfs.RepoDirFromName(s.ReposDir, repoName) backend := s.GetBackendFunc(dir, repoName) @@ -579,7 +574,7 @@ func (s *Server) exec(ctx context.Context, logger log.Logger, req *protocol.Exec attribute.String("args", args), attribute.String("ensure_revision", req.EnsureRevision), ) - logger = logger.WithTrace(trace.Context(ctx)) + logger := s.Logger.WithTrace(trace.Context(ctx)) execRunning.WithLabelValues(cmd).Inc() defer func() { @@ -614,7 +609,6 @@ func (s *Server) exec(ctx context.Context, logger log.Logger, req *protocol.Exec ev.AddField("actor", act.UIDString()) ev.AddField("ensure_revision", req.EnsureRevision) ev.AddField("ensure_revision_status", ensureRevisionStatus) - ev.AddField("client", userAgent) ev.AddField("duration_ms", duration.Milliseconds()) ev.AddField("exit_status", exitStatus) ev.AddField("status", status) @@ -648,7 +642,7 @@ func (s *Server) exec(ctx context.Context, logger log.Logger, req *protocol.Exec }() } - if notFoundPayload, cloned := s.maybeStartClone(ctx, logger, repoName); !cloned { + if notFoundPayload, cloned := s.MaybeStartClone(ctx, repoName); !cloned { if notFoundPayload.CloneInProgress { status = "clone-in-progress" } else { @@ -691,7 +685,7 @@ func (s *Server) exec(ctx context.Context, logger log.Logger, req *protocol.Exec _, execErr = io.Copy(w, stdout) if execErr != nil { - s.logIfCorrupt(ctx, repoName, execErr) + s.LogIfCorrupt(ctx, repoName, execErr) commandFailedErr := &gitcli.CommandFailedError{} if errors.As(execErr, &commandFailedErr) { exitStatus = commandFailedErr.ExitStatus @@ -741,7 +735,7 @@ func (s *Server) setLastErrorNonFatal(ctx context.Context, name api.RepoName, er } } -func (s *Server) logIfCorrupt(ctx context.Context, repo api.RepoName, err error) { +func (s *Server) LogIfCorrupt(ctx context.Context, repo api.RepoName, err error) { var corruptErr common.ErrRepoCorrupted if errors.As(err, &corruptErr) { if err := s.DB.GitserverRepos().LogCorruption(ctx, repo, corruptErr.Reason, s.Hostname); err != nil { @@ -1274,7 +1268,7 @@ func (s *Server) doRepoUpdate(ctx context.Context, repo api.RepoName, revspec st // The repo update might have failed due to the repo being corrupt var corruptErr common.ErrRepoCorrupted if errors.As(err, &corruptErr) { - s.logIfCorrupt(ctx, repo, corruptErr) + s.LogIfCorrupt(ctx, repo, corruptErr) } } s.setLastErrorNonFatal(s.ctx, repo, err) diff --git a/cmd/gitserver/internal/server_grpc.go b/cmd/gitserver/internal/server_grpc.go index a564e3cc256..2c79147c4a6 100644 --- a/cmd/gitserver/internal/server_grpc.go +++ b/cmd/gitserver/internal/server_grpc.go @@ -15,8 +15,11 @@ import ( "github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/git/gitcli" "github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/gitserverfs" "github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/perforce" + "github.com/sourcegraph/sourcegraph/internal/actor" "github.com/sourcegraph/sourcegraph/internal/api" + "github.com/sourcegraph/sourcegraph/internal/authz" "github.com/sourcegraph/sourcegraph/internal/conf" + "github.com/sourcegraph/sourcegraph/internal/database" "github.com/sourcegraph/sourcegraph/internal/gitserver" "github.com/sourcegraph/sourcegraph/internal/gitserver/gitdomain" "github.com/sourcegraph/sourcegraph/internal/gitserver/protocol" @@ -24,16 +27,53 @@ import ( "github.com/sourcegraph/sourcegraph/internal/grpc/streamio" "github.com/sourcegraph/sourcegraph/internal/trace" "github.com/sourcegraph/sourcegraph/lib/errors" + "github.com/sourcegraph/sourcegraph/lib/pointers" ) -type GRPCServer struct { - Server *Server +type service interface { + CreateCommitFromPatch(ctx context.Context, req protocol.CreateCommitFromPatchRequest) (int, protocol.CreateCommitFromPatchResponse) + LogIfCorrupt(context.Context, api.RepoName, error) + Exec(ctx context.Context, req *protocol.ExecRequest, w io.Writer) (execStatus, error) + MaybeStartClone(ctx context.Context, repo api.RepoName) (notFound *protocol.NotFoundPayload, cloned bool) + IsRepoCloneable(ctx context.Context, repo api.RepoName) (protocol.IsRepoCloneableResponse, error) + RepoUpdate(req *protocol.RepoUpdateRequest) protocol.RepoUpdateResponse + CloneRepo(ctx context.Context, repo api.RepoName, opts CloneOptions) (cloneProgress string, err error) + SearchWithObservability(ctx context.Context, tr trace.Trace, args *protocol.SearchRequest, onMatch func(*protocol.CommitMatch) error) (limitHit bool, err error) + + BatchGitLogInstrumentedHandler(ctx context.Context, req *proto.BatchLogRequest) (resp *proto.BatchLogResponse, err error) + P4Exec(ctx context.Context, logger log.Logger, req *p4ExecRequest, w io.Writer) execStatus +} + +func NewGRPCServer(server *Server) proto.GitserverServiceServer { + return &grpcServer{ + logger: server.Logger, + reposDir: server.ReposDir, + db: server.DB, + hostname: server.Hostname, + subRepoChecker: authz.DefaultSubRepoPermsChecker, + locker: server.Locker, + getBackendFunc: server.GetBackendFunc, + svc: server, + } +} + +type grpcServer struct { + logger log.Logger + reposDir string + db database.DB + hostname string + subRepoChecker authz.SubRepoPermissionChecker + locker RepositoryLocker + getBackendFunc Backender + + svc service + proto.UnimplementedGitserverServiceServer } -var _ proto.GitserverServiceServer = &GRPCServer{} +var _ proto.GitserverServiceServer = &grpcServer{} -func (gs *GRPCServer) BatchLog(ctx context.Context, req *proto.BatchLogRequest) (*proto.BatchLogResponse, error) { +func (gs *grpcServer) BatchLog(ctx context.Context, req *proto.BatchLogRequest) (*proto.BatchLogResponse, error) { // Validate request parameters if len(req.GetRepoCommits()) == 0 { //nolint:staticcheck return &proto.BatchLogResponse{}, nil @@ -43,7 +83,7 @@ func (gs *GRPCServer) BatchLog(ctx context.Context, req *proto.BatchLogRequest) } // Handle unexpected error conditions - resp, err := gs.Server.batchGitLogInstrumentedHandler(ctx, req) + resp, err := gs.svc.BatchGitLogInstrumentedHandler(ctx, req) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } @@ -51,7 +91,7 @@ func (gs *GRPCServer) BatchLog(ctx context.Context, req *proto.BatchLogRequest) return resp, nil } -func (gs *GRPCServer) CreateCommitFromPatchBinary(s proto.GitserverService_CreateCommitFromPatchBinaryServer) error { +func (gs *grpcServer) CreateCommitFromPatchBinary(s proto.GitserverService_CreateCommitFromPatchBinaryServer) error { var ( metadata *proto.CreateCommitFromPatchBinaryRequest_Metadata patch []byte @@ -89,7 +129,7 @@ func (gs *GRPCServer) CreateCommitFromPatchBinary(s proto.GitserverService_Creat var r protocol.CreateCommitFromPatchRequest r.FromProto(metadata, patch) - _, resp := gs.Server.createCommitFromPatch(s.Context(), r) + _, resp := gs.svc.CreateCommitFromPatch(s.Context(), r) res, err := resp.ToProto() if err != nil { return err.ToStatus().Err() @@ -98,11 +138,11 @@ func (gs *GRPCServer) CreateCommitFromPatchBinary(s proto.GitserverService_Creat return s.SendAndClose(res) } -func (gs *GRPCServer) DiskInfo(_ context.Context, _ *proto.DiskInfoRequest) (*proto.DiskInfoResponse, error) { - return getDiskInfo(gs.Server.ReposDir) +func (gs *grpcServer) DiskInfo(_ context.Context, _ *proto.DiskInfoRequest) (*proto.DiskInfoResponse, error) { + return getDiskInfo(gs.reposDir) } -func (gs *GRPCServer) Exec(req *proto.ExecRequest, ss proto.GitserverService_ExecServer) error { +func (gs *grpcServer) Exec(req *proto.ExecRequest, ss proto.GitserverService_ExecServer) error { internalReq := protocol.ExecRequest{ Repo: api.RepoName(req.GetRepo()), Args: byteSlicesToStrings(req.GetArgs()), @@ -131,11 +171,10 @@ func (gs *GRPCServer) Exec(req *proto.ExecRequest, ss proto.GitserverService_Exe log.Strings("args", args), ) - // TODO(mucles): set user agent from all grpc clients - return gs.doExec(ss.Context(), gs.Server.Logger, &internalReq, "unknown-grpc-client", w) + return gs.doExec(ss.Context(), &internalReq, w) } -func (gs *GRPCServer) Archive(req *proto.ArchiveRequest, ss proto.GitserverService_ArchiveServer) error { +func (gs *grpcServer) Archive(req *proto.ArchiveRequest, ss proto.GitserverService_ArchiveServer) error { // Log which which actor is accessing the repo. accesslog.Record(ss.Context(), req.GetRepo(), log.String("treeish", req.GetTreeish()), @@ -181,15 +220,14 @@ func (gs *GRPCServer) Archive(req *proto.ArchiveRequest, ss proto.GitserverServi ctx, cancel := context.WithTimeout(ss.Context(), conf.GitLongCommandTimeout()) defer cancel() - // TODO(mucles): set user agent from all grpc clients - return gs.doExec(ctx, gs.Server.Logger, execReq, "unknown-grpc-client", w) + return gs.doExec(ctx, execReq, w) } // doExec executes the given git command and streams the output to the given writer. // // Note: This function wraps the underlying exec implementation and returns grpc specific error handling. -func (gs *GRPCServer) doExec(ctx context.Context, logger log.Logger, req *protocol.ExecRequest, userAgent string, w io.Writer) error { - execStatus, err := gs.Server.exec(ctx, logger, req, userAgent, w) +func (gs *grpcServer) doExec(ctx context.Context, req *protocol.ExecRequest, w io.Writer) error { + execStatus, err := gs.svc.Exec(ctx, req, w) if err != nil { if v := (&NotFoundError{}); errors.As(err, &v) { s, err := status.New(codes.NotFound, "repo not found").WithDetails(&proto.NotFoundPayload{ @@ -198,7 +236,7 @@ func (gs *GRPCServer) doExec(ctx context.Context, logger log.Logger, req *protoc CloneProgress: v.Payload.CloneProgress, }) if err != nil { - gs.Server.Logger.Error("failed to marshal status", log.Error(err)) + gs.logger.Error("failed to marshal status", log.Error(err)) return err } return s.Err() @@ -230,7 +268,7 @@ func (gs *GRPCServer) doExec(ctx context.Context, logger log.Logger, req *protoc Stderr: execStatus.Stderr, }) if err != nil { - gs.Server.Logger.Error("failed to marshal status", log.Error(err)) + gs.logger.Error("failed to marshal status", log.Error(err)) return err } return s.Err() @@ -240,19 +278,19 @@ func (gs *GRPCServer) doExec(ctx context.Context, logger log.Logger, req *protoc } -func (gs *GRPCServer) GetObject(ctx context.Context, req *proto.GetObjectRequest) (*proto.GetObjectResponse, error) { +func (gs *grpcServer) GetObject(ctx context.Context, req *proto.GetObjectRequest) (*proto.GetObjectResponse, error) { repoName := api.RepoName(req.GetRepo()) - repoDir := gitserverfs.RepoDirFromName(gs.Server.ReposDir, repoName) + repoDir := gitserverfs.RepoDirFromName(gs.reposDir, repoName) // Log which actor is accessing the repo. accesslog.Record(ctx, string(repoName), log.String("objectname", req.GetObjectName())) - backend := gs.Server.GetBackendFunc(repoDir, repoName) + backend := gs.getBackendFunc(repoDir, repoName) obj, err := backend.GetObject(ctx, req.GetObjectName()) if err != nil { - gs.Server.logIfCorrupt(ctx, repoName, err) - gs.Server.Logger.Error("getting object", log.Error(err)) + gs.svc.LogIfCorrupt(ctx, repoName, err) + gs.logger.Error("getting object", log.Error(err)) return nil, err } @@ -263,7 +301,7 @@ func (gs *GRPCServer) GetObject(ctx context.Context, req *proto.GetObjectRequest return resp.ToProto(), nil } -func (gs *GRPCServer) ListGitolite(ctx context.Context, req *proto.ListGitoliteRequest) (*proto.ListGitoliteResponse, error) { +func (gs *grpcServer) ListGitolite(ctx context.Context, req *proto.ListGitoliteRequest) (*proto.ListGitoliteResponse, error) { host := req.GetGitoliteHost() repos, err := defaultGitolite.listRepos(ctx, host) if err != nil { @@ -281,7 +319,7 @@ func (gs *GRPCServer) ListGitolite(ctx context.Context, req *proto.ListGitoliteR }, nil } -func (gs *GRPCServer) Search(req *proto.SearchRequest, ss proto.GitserverService_SearchServer) error { +func (gs *grpcServer) Search(req *proto.SearchRequest, ss proto.GitserverService_SearchServer) error { args, err := protocol.SearchRequestFromProto(req) if err != nil { return status.Error(codes.InvalidArgument, err.Error()) @@ -296,7 +334,7 @@ func (gs *GRPCServer) Search(req *proto.SearchRequest, ss proto.GitserverService tr, ctx := trace.New(ss.Context(), "search") defer tr.End() - limitHit, err := gs.Server.searchWithObservability(ctx, tr, args, onMatch) + limitHit, err := gs.svc.SearchWithObservability(ctx, tr, args, onMatch) if err != nil { if notExistError := new(gitdomain.RepoNotExistError); errors.As(err, ¬ExistError) { st, _ := status.New(codes.NotFound, err.Error()).WithDetails(&proto.NotFoundPayload{ @@ -315,10 +353,10 @@ func (gs *GRPCServer) Search(req *proto.SearchRequest, ss proto.GitserverService }) } -func (gs *GRPCServer) RepoClone(ctx context.Context, in *proto.RepoCloneRequest) (*proto.RepoCloneResponse, error) { +func (gs *grpcServer) RepoClone(ctx context.Context, in *proto.RepoCloneRequest) (*proto.RepoCloneResponse, error) { repo := protocol.NormalizeRepo(api.RepoName(in.GetRepo())) - if _, err := gs.Server.CloneRepo(ctx, repo, CloneOptions{Block: false}); err != nil { + if _, err := gs.svc.CloneRepo(ctx, repo, CloneOptions{Block: false}); err != nil { return &proto.RepoCloneResponse{Error: err.Error()}, nil } @@ -326,7 +364,7 @@ func (gs *GRPCServer) RepoClone(ctx context.Context, in *proto.RepoCloneRequest) return &proto.RepoCloneResponse{Error: ""}, nil } -func (gs *GRPCServer) RepoCloneProgress(_ context.Context, req *proto.RepoCloneProgressRequest) (*proto.RepoCloneProgressResponse, error) { +func (gs *grpcServer) RepoCloneProgress(_ context.Context, req *proto.RepoCloneProgressRequest) (*proto.RepoCloneProgressResponse, error) { repositories := req.GetRepos() resp := protocol.RepoCloneProgressResponse{ @@ -334,39 +372,39 @@ func (gs *GRPCServer) RepoCloneProgress(_ context.Context, req *proto.RepoCloneP } for _, repo := range repositories { repoName := api.RepoName(repo) - result := repoCloneProgress(gs.Server.ReposDir, gs.Server.Locker, repoName) + result := repoCloneProgress(gs.reposDir, gs.locker, repoName) resp.Results[repoName] = result } return resp.ToProto(), nil } -func (gs *GRPCServer) RepoDelete(ctx context.Context, req *proto.RepoDeleteRequest) (*proto.RepoDeleteResponse, error) { +func (gs *grpcServer) RepoDelete(ctx context.Context, req *proto.RepoDeleteRequest) (*proto.RepoDeleteResponse, error) { repo := req.GetRepo() - if err := deleteRepo(ctx, gs.Server.Logger, gs.Server.DB, gs.Server.Hostname, gs.Server.ReposDir, api.RepoName(repo)); err != nil { - gs.Server.Logger.Error("failed to delete repository", log.String("repo", repo), log.Error(err)) + if err := deleteRepo(ctx, gs.logger, gs.db, gs.hostname, gs.reposDir, api.RepoName(repo)); err != nil { + gs.logger.Error("failed to delete repository", log.String("repo", repo), log.Error(err)) return &proto.RepoDeleteResponse{}, status.Errorf(codes.Internal, "failed to delete repository %s: %s", repo, err) } - gs.Server.Logger.Info("deleted repository", log.String("repo", repo)) + gs.logger.Info("deleted repository", log.String("repo", repo)) return &proto.RepoDeleteResponse{}, nil } -func (gs *GRPCServer) RepoUpdate(_ context.Context, req *proto.RepoUpdateRequest) (*proto.RepoUpdateResponse, error) { +func (gs *grpcServer) RepoUpdate(_ context.Context, req *proto.RepoUpdateRequest) (*proto.RepoUpdateResponse, error) { var in protocol.RepoUpdateRequest in.FromProto(req) - grpcResp := gs.Server.repoUpdate(&in) + grpcResp := gs.svc.RepoUpdate(&in) return grpcResp.ToProto(), nil } -func (gs *GRPCServer) IsRepoCloneable(ctx context.Context, req *proto.IsRepoCloneableRequest) (*proto.IsRepoCloneableResponse, error) { +func (gs *grpcServer) IsRepoCloneable(ctx context.Context, req *proto.IsRepoCloneableRequest) (*proto.IsRepoCloneableResponse, error) { repo := api.RepoName(req.GetRepo()) if req.Repo == "" { return nil, status.Error(codes.InvalidArgument, "no Repo given") } - resp, err := gs.Server.isRepoCloneable(ctx, repo) + resp, err := gs.svc.IsRepoCloneable(ctx, repo) if err != nil { return nil, err } @@ -374,12 +412,12 @@ func (gs *GRPCServer) IsRepoCloneable(ctx context.Context, req *proto.IsRepoClon return resp.ToProto(), nil } -func (gs *GRPCServer) IsPerforcePathCloneable(ctx context.Context, req *proto.IsPerforcePathCloneableRequest) (*proto.IsPerforcePathCloneableResponse, error) { +func (gs *grpcServer) IsPerforcePathCloneable(ctx context.Context, req *proto.IsPerforcePathCloneableRequest) (*proto.IsPerforcePathCloneableResponse, error) { if req.DepotPath == "" { return nil, status.Error(codes.InvalidArgument, "no DepotPath given") } - p4home, err := gitserverfs.MakeP4HomeDir(gs.Server.ReposDir) + p4home, err := gitserverfs.MakeP4HomeDir(gs.reposDir) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } @@ -393,8 +431,8 @@ func (gs *GRPCServer) IsPerforcePathCloneable(ctx context.Context, req *proto.Is return &proto.IsPerforcePathCloneableResponse{}, nil } -func (gs *GRPCServer) CheckPerforceCredentials(ctx context.Context, req *proto.CheckPerforceCredentialsRequest) (*proto.CheckPerforceCredentialsResponse, error) { - p4home, err := gitserverfs.MakeP4HomeDir(gs.Server.ReposDir) +func (gs *grpcServer) CheckPerforceCredentials(ctx context.Context, req *proto.CheckPerforceCredentialsRequest) (*proto.CheckPerforceCredentialsResponse, error) { + p4home, err := gitserverfs.MakeP4HomeDir(gs.reposDir) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } @@ -412,8 +450,8 @@ func (gs *GRPCServer) CheckPerforceCredentials(ctx context.Context, req *proto.C return &proto.CheckPerforceCredentialsResponse{}, nil } -func (gs *GRPCServer) PerforceUsers(ctx context.Context, req *proto.PerforceUsersRequest) (*proto.PerforceUsersResponse, error) { - p4home, err := gitserverfs.MakeP4HomeDir(gs.Server.ReposDir) +func (gs *grpcServer) PerforceUsers(ctx context.Context, req *proto.PerforceUsersRequest) (*proto.PerforceUsersResponse, error) { + p4home, err := gitserverfs.MakeP4HomeDir(gs.reposDir) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } @@ -451,8 +489,8 @@ func (gs *GRPCServer) PerforceUsers(ctx context.Context, req *proto.PerforceUser return resp, nil } -func (gs *GRPCServer) PerforceProtectsForUser(ctx context.Context, req *proto.PerforceProtectsForUserRequest) (*proto.PerforceProtectsForUserResponse, error) { - p4home, err := gitserverfs.MakeP4HomeDir(gs.Server.ReposDir) +func (gs *grpcServer) PerforceProtectsForUser(ctx context.Context, req *proto.PerforceProtectsForUserRequest) (*proto.PerforceProtectsForUserResponse, error) { + p4home, err := gitserverfs.MakeP4HomeDir(gs.reposDir) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } @@ -489,8 +527,8 @@ func (gs *GRPCServer) PerforceProtectsForUser(ctx context.Context, req *proto.Pe }, nil } -func (gs *GRPCServer) PerforceProtectsForDepot(ctx context.Context, req *proto.PerforceProtectsForDepotRequest) (*proto.PerforceProtectsForDepotResponse, error) { - p4home, err := gitserverfs.MakeP4HomeDir(gs.Server.ReposDir) +func (gs *grpcServer) PerforceProtectsForDepot(ctx context.Context, req *proto.PerforceProtectsForDepotRequest) (*proto.PerforceProtectsForDepotResponse, error) { + p4home, err := gitserverfs.MakeP4HomeDir(gs.reposDir) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } @@ -527,8 +565,8 @@ func (gs *GRPCServer) PerforceProtectsForDepot(ctx context.Context, req *proto.P }, nil } -func (gs *GRPCServer) PerforceGroupMembers(ctx context.Context, req *proto.PerforceGroupMembersRequest) (*proto.PerforceGroupMembersResponse, error) { - p4home, err := gitserverfs.MakeP4HomeDir(gs.Server.ReposDir) +func (gs *grpcServer) PerforceGroupMembers(ctx context.Context, req *proto.PerforceGroupMembersRequest) (*proto.PerforceGroupMembersResponse, error) { + p4home, err := gitserverfs.MakeP4HomeDir(gs.reposDir) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } @@ -560,8 +598,8 @@ func (gs *GRPCServer) PerforceGroupMembers(ctx context.Context, req *proto.Perfo }, nil } -func (gs *GRPCServer) IsPerforceSuperUser(ctx context.Context, req *proto.IsPerforceSuperUserRequest) (*proto.IsPerforceSuperUserResponse, error) { - p4home, err := gitserverfs.MakeP4HomeDir(gs.Server.ReposDir) +func (gs *grpcServer) IsPerforceSuperUser(ctx context.Context, req *proto.IsPerforceSuperUserRequest) (*proto.IsPerforceSuperUserResponse, error) { + p4home, err := gitserverfs.MakeP4HomeDir(gs.reposDir) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } @@ -592,8 +630,8 @@ func (gs *GRPCServer) IsPerforceSuperUser(ctx context.Context, req *proto.IsPerf return &proto.IsPerforceSuperUserResponse{}, nil } -func (gs *GRPCServer) PerforceGetChangelist(ctx context.Context, req *proto.PerforceGetChangelistRequest) (*proto.PerforceGetChangelistResponse, error) { - p4home, err := gitserverfs.MakeP4HomeDir(gs.Server.ReposDir) +func (gs *grpcServer) PerforceGetChangelist(ctx context.Context, req *proto.PerforceGetChangelistRequest) (*proto.PerforceGetChangelistResponse, error) { + p4home, err := gitserverfs.MakeP4HomeDir(gs.reposDir) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } @@ -633,7 +671,7 @@ func byteSlicesToStrings(in [][]byte) []string { return res } -func (gs *GRPCServer) MergeBase(ctx context.Context, req *proto.MergeBaseRequest) (*proto.MergeBaseResponse, error) { +func (gs *grpcServer) MergeBase(ctx context.Context, req *proto.MergeBaseRequest) (*proto.MergeBaseResponse, error) { accesslog.Record( ctx, req.GetRepoName(), @@ -654,11 +692,11 @@ func (gs *GRPCServer) MergeBase(ctx context.Context, req *proto.MergeBaseRequest } repoName := api.RepoName(req.GetRepoName()) - repoDir := gitserverfs.RepoDirFromName(gs.Server.ReposDir, repoName) + repoDir := gitserverfs.RepoDirFromName(gs.reposDir, repoName) // Ensure that the repo is cloned and if not start a background clone, then // return a well-known NotFound payload error. - if notFoundPayload, cloned := gs.Server.maybeStartClone(ctx, gs.Server.Logger, repoName); !cloned { + if notFoundPayload, cloned := gs.svc.MaybeStartClone(ctx, repoName); !cloned { s, err := status.New(codes.NotFound, "repo not cloned").WithDetails(&proto.NotFoundPayload{ CloneInProgress: notFoundPayload.CloneInProgress, CloneProgress: notFoundPayload.CloneProgress, @@ -671,13 +709,13 @@ func (gs *GRPCServer) MergeBase(ctx context.Context, req *proto.MergeBaseRequest } // TODO: This should be included in requests where we do ensure the revision exists. - // gs.Server.ensureRevision(ctx, repoName, "THE REVISION", repoDir) + // gs.server.ensureRevision(ctx, repoName, "THE REVISION", repoDir) - backend := gs.Server.GetBackendFunc(repoDir, repoName) + backend := gs.getBackendFunc(repoDir, repoName) sha, err := backend.MergeBase(ctx, string(req.GetBase()), string(req.GetHead())) if err != nil { - gs.Server.logIfCorrupt(ctx, repoName, err) + gs.svc.LogIfCorrupt(ctx, repoName, err) // TODO: Better error checking. return nil, err } @@ -686,3 +724,92 @@ func (gs *GRPCServer) MergeBase(ctx context.Context, req *proto.MergeBaseRequest MergeBaseCommitSha: string(sha), }, nil } + +func (gs *grpcServer) Blame(req *proto.BlameRequest, ss proto.GitserverService_BlameServer) error { + ctx := ss.Context() + + accesslog.Record( + ctx, + req.GetRepoName(), + log.String("path", req.GetPath()), + log.String("commit", req.GetCommit()), + ) + + if req.GetRepoName() == "" { + return status.New(codes.InvalidArgument, "repo must be specified").Err() + } + + if len(req.GetPath()) == 0 { + return status.New(codes.InvalidArgument, "path must be specified").Err() + } + + repoName := api.RepoName(req.GetRepoName()) + repoDir := gitserverfs.RepoDirFromName(gs.reposDir, repoName) + + // Ensure that the repo is cloned and if not start a background clone, then + // return a well-known NotFound payload error. + if notFoundPayload, cloned := gs.svc.MaybeStartClone(ctx, repoName); !cloned { + s, err := status.New(codes.NotFound, "repo not cloned").WithDetails(&proto.NotFoundPayload{ + CloneInProgress: notFoundPayload.CloneInProgress, + CloneProgress: notFoundPayload.CloneProgress, + Repo: req.GetRepoName(), + }) + if err != nil { + return err + } + return s.Err() + } + + // First, verify that the actor has access to the given path. + hasAccess, err := authz.FilterActorPath(ctx, gs.subRepoChecker, actor.FromContext(ctx), repoName, req.GetPath()) + if err != nil { + return err + } + if !hasAccess { + up := &proto.UnauthorizedPayload{ + RepoName: req.GetRepoName(), + Path: pointers.Ptr(req.GetPath()), + } + if c := req.GetCommit(); c != "" { + up.Commit = &c + } + s, marshalErr := status.New(codes.PermissionDenied, "no access to path").WithDetails(up) + if marshalErr != nil { + gs.logger.Error("failed to marshal error", log.Error(marshalErr)) + return err + } + return s.Err() + } + + backend := gs.getBackendFunc(repoDir, repoName) + + r, err := backend.Blame(ctx, req.GetPath(), git.BlameOptions{ + NewestCommit: api.CommitID(req.GetCommit()), + IgnoreWhitespace: req.GetIgnoreWhitespace(), + StartLine: int(req.GetStartLine()), + EndLine: int(req.GetEndLine()), + }) + if err != nil { + gs.svc.LogIfCorrupt(ctx, repoName, err) + // TODO: Better error checking. + return err + } + defer r.Close() + + for { + h, err := r.Read() + if err != nil { + // Check if we're done yet. + if err == io.EOF { + return nil + } + gs.svc.LogIfCorrupt(ctx, repoName, err) + return err + } + if err := ss.Send(&proto.BlameResponse{ + Hunk: h.ToProto(), + }); err != nil { + return err + } + } +} diff --git a/cmd/gitserver/internal/server_grpc_test.go b/cmd/gitserver/internal/server_grpc_test.go new file mode 100644 index 00000000000..b1046a6fc43 --- /dev/null +++ b/cmd/gitserver/internal/server_grpc_test.go @@ -0,0 +1,176 @@ +package internal + +import ( + "context" + "io" + "net/http" + "net/http/httptest" + "net/url" + "testing" + "time" + + mockassert "github.com/derision-test/go-mockgen/testutil/assert" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/types/known/timestamppb" + + "github.com/sourcegraph/log/logtest" + + "github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/common" + "github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/git" + "github.com/sourcegraph/sourcegraph/internal/actor" + "github.com/sourcegraph/sourcegraph/internal/api" + "github.com/sourcegraph/sourcegraph/internal/authz" + "github.com/sourcegraph/sourcegraph/internal/gitserver" + "github.com/sourcegraph/sourcegraph/internal/gitserver/gitdomain" + "github.com/sourcegraph/sourcegraph/internal/gitserver/protocol" + proto "github.com/sourcegraph/sourcegraph/internal/gitserver/v1" + v1 "github.com/sourcegraph/sourcegraph/internal/gitserver/v1" + internalgrpc "github.com/sourcegraph/sourcegraph/internal/grpc" + "github.com/sourcegraph/sourcegraph/internal/grpc/defaults" +) + +func TestGRPCServer_Blame(t *testing.T) { + mockSS := gitserver.NewMockGitserverService_BlameServer() + // Add an actor to the context. + a := actor.FromUser(1) + mockSS.ContextFunc.SetDefaultReturn(actor.WithActor(context.Background(), a)) + t.Run("argument validation", func(t *testing.T) { + gs := &grpcServer{} + err := gs.Blame(&v1.BlameRequest{RepoName: "", Path: "thepath"}, mockSS) + require.ErrorContains(t, err, "repo must be specified") + assertGRPCStatusCode(t, err, codes.InvalidArgument) + err = gs.Blame(&v1.BlameRequest{RepoName: "therepo", Path: ""}, mockSS) + require.ErrorContains(t, err, "path must be specified") + assertGRPCStatusCode(t, err, codes.InvalidArgument) + }) + t.Run("checks for uncloned repo", func(t *testing.T) { + svc := NewMockService() + svc.MaybeStartCloneFunc.SetDefaultReturn(&protocol.NotFoundPayload{CloneInProgress: true, CloneProgress: "cloning"}, false) + gs := &grpcServer{svc: svc} + err := gs.Blame(&v1.BlameRequest{RepoName: "therepo", Path: "thepath"}, mockSS) + require.Error(t, err) + assertGRPCStatusCode(t, err, codes.NotFound) + require.Contains(t, err.Error(), "repo not cloned") + mockassert.Called(t, svc.MaybeStartCloneFunc) + }) + t.Run("checks for subrepo perms access to given path", func(t *testing.T) { + srp := authz.NewMockSubRepoPermissionChecker() + svc := NewMockService() + // Repo is cloned, proceed! + svc.MaybeStartCloneFunc.SetDefaultReturn(nil, true) + gs := &grpcServer{ + subRepoChecker: srp, + svc: svc, + getBackendFunc: func(common.GitDir, api.RepoName) git.GitBackend { + b := git.NewMockGitBackend() + hr := git.NewMockBlameHunkReader() + hr.ReadFunc.SetDefaultReturn(nil, io.EOF) + b.BlameFunc.SetDefaultReturn(hr, nil) + return b + }, + } + + t.Run("subrepo perms are not enabled", func(t *testing.T) { + srp.EnabledFunc.SetDefaultReturn(false) + err := gs.Blame(&v1.BlameRequest{RepoName: "therepo", Path: "thepath"}, mockSS) + assert.NoError(t, err) + mockassert.Called(t, srp.EnabledFunc) + }) + + t.Run("subrepo perms are enabled, permission granted", func(t *testing.T) { + srp.EnabledFunc.SetDefaultReturn(true) + srp.PermissionsFunc.SetDefaultReturn(authz.Read, nil) + err := gs.Blame(&v1.BlameRequest{RepoName: "therepo", Path: "thepath"}, mockSS) + assert.NoError(t, err) + mockassert.Called(t, srp.EnabledFunc) + mockassert.Called(t, srp.PermissionsFunc) + }) + + t.Run("subrepo perms are enabled, permission denied", func(t *testing.T) { + srp.EnabledFunc.SetDefaultReturn(true) + srp.PermissionsFunc.SetDefaultReturn(authz.None, nil) + err := gs.Blame(&v1.BlameRequest{RepoName: "therepo", Path: "thepath"}, mockSS) + require.Error(t, err) + mockassert.Called(t, srp.EnabledFunc) + mockassert.Called(t, srp.PermissionsFunc) + assertGRPCStatusCode(t, err, codes.PermissionDenied) + }) + }) + t.Run("e2e", func(t *testing.T) { + srp := authz.NewMockSubRepoPermissionChecker() + // Skip subrepo perms checks. + srp.EnabledFunc.SetDefaultReturn(false) + svc := NewMockService() + // Repo is cloned, proceed! + svc.MaybeStartCloneFunc.SetDefaultReturn(nil, true) + b := git.NewMockGitBackend() + hr := git.NewMockBlameHunkReader() + hr.ReadFunc.PushReturn(&gitdomain.Hunk{CommitID: "deadbeef"}, nil) + hr.ReadFunc.PushReturn(nil, io.EOF) + b.BlameFunc.SetDefaultReturn(hr, nil) + gs := &grpcServer{ + subRepoChecker: srp, + svc: svc, + getBackendFunc: func(common.GitDir, api.RepoName) git.GitBackend { + return b + }, + } + + cli := spawnServer(t, gs) + r, err := cli.Blame(context.Background(), &v1.BlameRequest{ + RepoName: "therepo", + Path: "thepath", + }) + require.NoError(t, err) + for { + msg, err := r.Recv() + if err != nil { + if err == io.EOF { + return + } + require.NoError(t, err) + } + if diff := cmp.Diff(&proto.BlameResponse{ + Hunk: &proto.BlameHunk{ + Commit: "deadbeef", + Author: &v1.BlameAuthor{ + Date: timestamppb.New(time.Time{}), + }, + }, + }, msg, cmpopts.IgnoreUnexported(proto.BlameResponse{}, proto.BlameHunk{}, proto.BlameAuthor{}, timestamppb.Timestamp{})); diff != "" { + t.Fatalf("unexpected response (-want +got):\n%s", diff) + } + } + }) +} + +func assertGRPCStatusCode(t *testing.T, err error, want codes.Code) { + t.Helper() + s, ok := status.FromError(err) + require.True(t, ok, "expected status.FromError to succeed") + require.Equal(t, want, s.Code()) +} + +func spawnServer(t *testing.T, server *grpcServer) proto.GitserverServiceClient { + t.Helper() + grpcServer := defaults.NewServer(logtest.Scoped(t)) + proto.RegisterGitserverServiceServer(grpcServer, server) + handler := internalgrpc.MultiplexHandlers(grpcServer, http.NotFoundHandler()) + srv := httptest.NewServer(handler) + t.Cleanup(func() { + srv.Close() + }) + + u, err := url.Parse(srv.URL) + require.NoError(t, err) + + cc, err := defaults.Dial(u.Host, logtest.Scoped(t)) + require.NoError(t, err) + + return proto.NewGitserverServiceClient(cc) +} diff --git a/cmd/gitserver/internal/server_test.go b/cmd/gitserver/internal/server_test.go index cddd413bf0e..4235e07f013 100644 --- a/cmd/gitserver/internal/server_test.go +++ b/cmd/gitserver/internal/server_test.go @@ -192,7 +192,7 @@ func TestExecRequest(t *testing.T) { // Initialize side-effects. _ = s.Handler() - gs := &GRPCServer{Server: s} + gs := NewGRPCServer(s) origRepoCloned := repoCloned repoCloned = func(dir common.GitDir) bool { @@ -569,7 +569,7 @@ func TestHandleRepoUpdate(t *testing.T) { s.GetRemoteURLFunc = func(ctx context.Context, name api.RepoName) (string, error) { return "https://invalid.example.com/", nil } - s.repoUpdate(&protocol.RepoUpdateRequest{ + s.RepoUpdate(&protocol.RepoUpdateRequest{ Repo: repoName, }) @@ -600,7 +600,7 @@ func TestHandleRepoUpdate(t *testing.T) { // This will perform an initial clone s.GetRemoteURLFunc = oldRemoveURLFunc - s.repoUpdate(&protocol.RepoUpdateRequest{ + s.RepoUpdate(&protocol.RepoUpdateRequest{ Repo: repoName, }) @@ -629,7 +629,7 @@ func TestHandleRepoUpdate(t *testing.T) { t.Cleanup(func() { doBackgroundRepoUpdateMock = nil }) // This will trigger an update since the repo is already cloned - s.repoUpdate(&protocol.RepoUpdateRequest{ + s.RepoUpdate(&protocol.RepoUpdateRequest{ Repo: repoName, }) @@ -654,7 +654,7 @@ func TestHandleRepoUpdate(t *testing.T) { doBackgroundRepoUpdateMock = nil // This will trigger an update since the repo is already cloned - s.repoUpdate(&protocol.RepoUpdateRequest{ + s.RepoUpdate(&protocol.RepoUpdateRequest{ Repo: repoName, }) @@ -1045,7 +1045,7 @@ func TestHandleBatchLog(t *testing.T) { // Initialize side-effects. _ = server.Handler() - gs := &GRPCServer{Server: server} + gs := NewGRPCServer(server) res, err := gs.BatchLog(context.Background(), test.Request) @@ -1101,7 +1101,7 @@ func TestLogIfCorrupt(t *testing.T) { stdErr := "error: packfile .git/objects/pack/pack-e26c1fc0add58b7649a95f3e901e30f29395e174.pack does not match index" - s.logIfCorrupt(ctx, repoName, common.ErrRepoCorrupted{ + s.LogIfCorrupt(ctx, repoName, common.ErrRepoCorrupted{ Reason: stdErr, }) @@ -1127,7 +1127,7 @@ func TestLogIfCorrupt(t *testing.T) { db.Repos().Delete(ctx, dbRepo.ID) }) - s.logIfCorrupt(ctx, repoName, errors.New("Brought to you by Horsegraph")) + s.LogIfCorrupt(ctx, repoName, errors.New("Brought to you by Horsegraph")) fromDB, err := s.DB.GitserverRepos().GetByName(ctx, repoName) assert.NoError(t, err) diff --git a/cmd/gitserver/internal/statesyncer.go b/cmd/gitserver/internal/statesyncer.go index 56c35963814..b0107ec59cf 100644 --- a/cmd/gitserver/internal/statesyncer.go +++ b/cmd/gitserver/internal/statesyncer.go @@ -195,7 +195,7 @@ func syncRepoState( repo.Name = api.UndeletedRepoName(repo.Name) // Ensure we're only dealing with repos we are responsible for. - addr := addrForRepo(ctx, repo.Name, gitServerAddrs) + addr := gitServerAddrs.AddrForRepo(ctx, repo.Name) if !hostnameMatch(shardID, addr) { repoSyncStateCounter.WithLabelValues("other_shard").Inc() continue diff --git a/cmd/gitserver/shared/shared.go b/cmd/gitserver/shared/shared.go index caddae3fc6c..7334190fbe1 100644 --- a/cmd/gitserver/shared/shared.go +++ b/cmd/gitserver/shared/shared.go @@ -242,6 +242,7 @@ func makeGRPCServer(logger log.Logger, s *server.Server) *grpc.Server { proto.GitserverService_P4Exec_FullMethodName: logger.Scoped("p4exec.accesslog"), proto.GitserverService_GetObject_FullMethodName: logger.Scoped("get-object.accesslog"), proto.GitserverService_MergeBase_FullMethodName: logger.Scoped("merge-base.accesslog"), + proto.GitserverService_Blame_FullMethodName: logger.Scoped("blame.accesslog"), } { streamInterceptor := accesslog.StreamServerInterceptor(scopedLogger, configurationWatcher) unaryInterceptor := accesslog.UnaryServerInterceptor(scopedLogger, configurationWatcher) @@ -253,9 +254,7 @@ func makeGRPCServer(logger log.Logger, s *server.Server) *grpc.Server { } grpcServer := defaults.NewServer(logger, additionalServerOptions...) - proto.RegisterGitserverServiceServer(grpcServer, &server.GRPCServer{ - Server: s, - }) + proto.RegisterGitserverServiceServer(grpcServer, server.NewGRPCServer(s)) return grpcServer } diff --git a/internal/gitserver/BUILD.bazel b/internal/gitserver/BUILD.bazel index 9ed2c30d5a2..88a6020f5d0 100644 --- a/internal/gitserver/BUILD.bazel +++ b/internal/gitserver/BUILD.bazel @@ -13,7 +13,6 @@ go_library( "observability.go", "retry.go", "stream_client.go", - "stream_hunks.go", "test_utils.go", ], importpath = "github.com/sourcegraph/sourcegraph/internal/gitserver", @@ -39,6 +38,7 @@ go_library( "//internal/search/streaming/http", "//internal/trace", "//lib/errors", + "//lib/pointers", "@com_github_go_git_go_git_v5//plumbing/format/config", "@com_github_golang_groupcache//lru", "@com_github_prometheus_client_golang//prometheus", @@ -91,5 +91,7 @@ go_test( "@com_github_stretchr_testify//assert", "@com_github_stretchr_testify//require", "@org_golang_google_grpc//:go_default_library", + "@org_golang_google_grpc//codes", + "@org_golang_google_grpc//status", ], ) diff --git a/internal/gitserver/addrs.go b/internal/gitserver/addrs.go index d349aba17aa..44a3fba95c5 100644 --- a/internal/gitserver/addrs.go +++ b/internal/gitserver/addrs.go @@ -26,10 +26,10 @@ import ( ) var ( - addrForRepoInvoked = promauto.NewCounterVec(prometheus.CounterOpts{ + addrForRepoInvoked = promauto.NewCounter(prometheus.CounterOpts{ Name: "src_gitserver_addr_for_repo_invoked", Help: "Number of times gitserver.AddrForRepo was invoked", - }, []string{"user_agent"}) + }) ) // NewGitserverAddresses fetches the current set of gitserver addresses @@ -104,8 +104,8 @@ type testGitserverConns struct { } // AddrForRepo returns the gitserver address to use for the given repo name. -func (c *testGitserverConns) AddrForRepo(ctx context.Context, userAgent string, repo api.RepoName) string { - return c.conns.AddrForRepo(ctx, userAgent, repo) +func (c *testGitserverConns) AddrForRepo(ctx context.Context, repo api.RepoName) string { + return c.conns.AddrForRepo(ctx, repo) } // Addresses returns the current list of gitserver addresses. @@ -123,8 +123,8 @@ func (c *testGitserverConns) GetAddressWithClient(addr string) AddressWithClient } // ClientForRepo returns a client or host for the given repo name. -func (c *testGitserverConns) ClientForRepo(ctx context.Context, userAgent string, repo api.RepoName) (proto.GitserverServiceClient, error) { - conn, err := c.conns.ConnForRepo(ctx, userAgent, repo) +func (c *testGitserverConns) ClientForRepo(ctx context.Context, repo api.RepoName) (proto.GitserverServiceClient, error) { + conn, err := c.conns.ConnForRepo(ctx, repo) if err != nil { return nil, err } @@ -163,8 +163,8 @@ type GitserverAddresses struct { } // AddrForRepo returns the gitserver address to use for the given repo name. -func (g *GitserverAddresses) AddrForRepo(ctx context.Context, userAgent string, repoName api.RepoName) string { - addrForRepoInvoked.WithLabelValues(userAgent).Inc() +func (g *GitserverAddresses) AddrForRepo(ctx context.Context, repoName api.RepoName) string { + addrForRepoInvoked.Inc() // Normalizing the name in case the caller didn't. name := string(protocol.NormalizeRepo(repoName)) @@ -190,8 +190,8 @@ type GitserverConns struct { grpcConns map[string]connAndErr } -func (g *GitserverConns) ConnForRepo(ctx context.Context, userAgent string, repo api.RepoName) (*grpc.ClientConn, error) { - addr := g.AddrForRepo(ctx, userAgent, repo) +func (g *GitserverConns) ConnForRepo(ctx context.Context, repo api.RepoName) (*grpc.ClientConn, error) { + addr := g.AddrForRepo(ctx, repo) ce, ok := g.grpcConns[addr] if !ok { return nil, errors.Newf("no gRPC connection found for address %q", addr) @@ -224,12 +224,12 @@ type atomicGitServerConns struct { watchOnce sync.Once } -func (a *atomicGitServerConns) AddrForRepo(ctx context.Context, userAgent string, repo api.RepoName) string { - return a.get().AddrForRepo(ctx, userAgent, repo) +func (a *atomicGitServerConns) AddrForRepo(ctx context.Context, repo api.RepoName) string { + return a.get().AddrForRepo(ctx, repo) } -func (a *atomicGitServerConns) ClientForRepo(ctx context.Context, userAgent string, repo api.RepoName) (proto.GitserverServiceClient, error) { - conn, err := a.get().ConnForRepo(ctx, userAgent, repo) +func (a *atomicGitServerConns) ClientForRepo(ctx context.Context, repo api.RepoName) (proto.GitserverServiceClient, error) { + conn, err := a.get().ConnForRepo(ctx, repo) if err != nil { return nil, err } diff --git a/internal/gitserver/addrs_test.go b/internal/gitserver/addrs_test.go index 83c7272b7d3..62660155bba 100644 --- a/internal/gitserver/addrs_test.go +++ b/internal/gitserver/addrs_test.go @@ -46,7 +46,7 @@ func TestAddrForRepo(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - got := ga.AddrForRepo(ctx, "gitserver", tc.repo) + got := ga.AddrForRepo(ctx, tc.repo) if got != tc.want { t.Fatalf("Want %q, got %q", tc.want, got) } diff --git a/internal/gitserver/client.go b/internal/gitserver/client.go index 3d7c0b1fcf3..728e511a805 100644 --- a/internal/gitserver/client.go +++ b/internal/gitserver/client.go @@ -7,7 +7,6 @@ import ( "io" "io/fs" "os" - "path/filepath" "strings" "testing" "time" @@ -61,9 +60,9 @@ var _ Client = &clientImplementor{} // It allows for mocking out the client source in tests. type ClientSource interface { // ClientForRepo returns a Client for the given repo. - ClientForRepo(ctx context.Context, userAgent string, repo api.RepoName) (proto.GitserverServiceClient, error) + ClientForRepo(ctx context.Context, repo api.RepoName) (proto.GitserverServiceClient, error) // AddrForRepo returns the address of the gitserver for the given repo. - AddrForRepo(ctx context.Context, userAgent string, repo api.RepoName) string + AddrForRepo(ctx context.Context, repo api.RepoName) string // Address the current list of gitserver addresses. Addresses() []AddressWithClient // GetAddressWithClient returns the address and client for a gitserver instance. @@ -76,12 +75,8 @@ type ClientSource interface { func NewClient(scope string) Client { logger := sglog.Scoped("GitserverClient") return &clientImplementor{ - logger: logger, - scope: scope, - // Use the binary name for userAgent. This should effectively identify - // which service is making the request (excluding requests proxied via the - // frontend internal API) - userAgent: filepath.Base(os.Args[0]), + logger: logger, + scope: scope, operations: getOperations(), clientSource: conns, subRepoPermsChecker: authz.DefaultSubRepoPermsChecker, @@ -93,12 +88,8 @@ func NewTestClient(t testing.TB) TestClient { logger := logtest.Scoped(t) return &clientImplementor{ - logger: logger, - scope: fmt.Sprintf("gitserver.test.%s", t.Name()), - // Use the binary name for userAgent. This should effectively identify - // which service is making the request (excluding requests proxied via the - // frontend internal API) - userAgent: filepath.Base(os.Args[0]), + logger: logger, + scope: fmt.Sprintf("gitserver.test.%s", t.Name()), operations: newOperations(observation.ContextWithLogger(logger, &observation.TestContext)), clientSource: NewTestClientSource(t, nil), subRepoPermsChecker: authz.DefaultSubRepoPermsChecker, @@ -194,10 +185,6 @@ func NewMockClientWithExecReader(checker authz.SubRepoPermissionChecker, execRea // clientImplementor is a gitserver client. type clientImplementor struct { - // userAgent is a string identifying who the client is. It will be logged in - // the telemetry in gitserver. - userAgent string - // the current scope of the client. scope string @@ -219,7 +206,6 @@ func (c *clientImplementor) Scoped(scope string) Client { return &clientImplementor{ logger: c.logger, scope: appendScope(c.scope, scope), - userAgent: c.userAgent, operations: c.operations, clientSource: c.clientSource, } @@ -233,10 +219,27 @@ func appendScope(existing, new string) string { } type HunkReader interface { - Read() (*Hunk, error) + Read() (*gitdomain.Hunk, error) Close() error } +// BlameOptions configures a blame. +type BlameOptions struct { + NewestCommit api.CommitID `json:",omitempty" url:",omitempty"` + IgnoreWhitespace bool `json:",omitempty" url:",omitempty"` + StartLine int `json:",omitempty" url:",omitempty"` // 1-indexed start line (or 0 for beginning of file) + EndLine int `json:",omitempty" url:",omitempty"` // 1-indexed end line (or 0 for end of file) +} + +func (o *BlameOptions) Attrs() []attribute.KeyValue { + return []attribute.KeyValue{ + attribute.String("newestCommit", string(o.NewestCommit)), + attribute.Int("startLine", o.StartLine), + attribute.Int("endLine", o.EndLine), + attribute.Bool("ignoreWhitespace", o.IgnoreWhitespace), + } +} + type CommitLog struct { AuthorEmail string AuthorName string @@ -530,11 +533,11 @@ func (c *clientImplementor) getDiskInfo(ctx context.Context, addr AddressWithCli } func (c *clientImplementor) AddrForRepo(ctx context.Context, repo api.RepoName) string { - return c.clientSource.AddrForRepo(ctx, c.userAgent, repo) + return c.clientSource.AddrForRepo(ctx, repo) } func (c *clientImplementor) ClientForRepo(ctx context.Context, repo api.RepoName) (proto.GitserverServiceClient, error) { - return c.clientSource.ClientForRepo(ctx, c.userAgent, repo) + return c.clientSource.ClientForRepo(ctx, repo) } // ArchiveOptions contains options for the Archive func. diff --git a/internal/gitserver/commands.go b/internal/gitserver/commands.go index 00ae0210901..17215ea75a5 100644 --- a/internal/gitserver/commands.go +++ b/internal/gitserver/commands.go @@ -23,6 +23,8 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" "go.opentelemetry.io/otel/attribute" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" "github.com/sourcegraph/go-diff/diff" @@ -40,6 +42,7 @@ import ( "github.com/sourcegraph/sourcegraph/internal/observation" "github.com/sourcegraph/sourcegraph/internal/trace" "github.com/sourcegraph/sourcegraph/lib/errors" + "github.com/sourcegraph/sourcegraph/lib/pointers" ) type DiffOptions struct { @@ -787,35 +790,6 @@ func (c *clientImplementor) LogReverseEach(ctx context.Context, repo string, com return errors.Wrap(gitdomain.ParseLogReverseEach(stdout, onLogEntry), "ParseLogReverseEach") } -// BlameOptions configures a blame. -type BlameOptions struct { - NewestCommit api.CommitID `json:",omitempty" url:",omitempty"` - IgnoreWhitespace bool `json:",omitempty" url:",omitempty"` - StartLine int `json:",omitempty" url:",omitempty"` // 1-indexed start line (or 0 for beginning of file) - EndLine int `json:",omitempty" url:",omitempty"` // 1-indexed end line (or 0 for end of file) -} - -func (o *BlameOptions) Attrs() []attribute.KeyValue { - return []attribute.KeyValue{ - attribute.String("newestCommit", string(o.NewestCommit)), - attribute.Int("startLine", o.StartLine), - attribute.Int("endLine", o.EndLine), - attribute.Bool("ignoreWhitespace", o.IgnoreWhitespace), - } -} - -// A Hunk is a contiguous portion of a file associated with a commit. -type Hunk struct { - StartLine int // 1-indexed start line number - EndLine int // 1-indexed end line number - StartByte int // 0-indexed start byte position (inclusive) - EndByte int // 0-indexed end byte position (exclusive) - api.CommitID - Author gitdomain.Signature - Message string - Filename string -} - // StreamBlameFile returns Git blame information about a file. func (c *clientImplementor) StreamBlameFile(ctx context.Context, repo api.RepoName, path string, opt *BlameOptions) (_ HunkReader, err error) { ctx, _, endObservation := c.operations.streamBlameFile.With(ctx, &err, observation.Args{ @@ -825,9 +799,58 @@ func (c *clientImplementor) StreamBlameFile(ctx context.Context, repo api.RepoNa attribute.String("path", path), }, opt.Attrs()...), }) - defer endObservation(1, observation.Args{}) - return streamBlameFileCmd(ctx, c.subRepoPermsChecker, repo, path, opt, c.gitserverGitCommandFunc(repo)) + client, err := c.clientSource.ClientForRepo(ctx, repo) + if err != nil { + endObservation(1, observation.Args{}) + return nil, err + } + + req := &proto.BlameRequest{ + RepoName: string(repo), + Path: path, + IgnoreWhitespace: opt.IgnoreWhitespace, + } + if opt.NewestCommit != "" { + req.Commit = pointers.Ptr(string(opt.NewestCommit)) + } + if opt.StartLine != 0 { + req.StartLine = pointers.Ptr(uint32(opt.StartLine)) + } + if opt.EndLine != 0 { + req.EndLine = pointers.Ptr(uint32(opt.EndLine)) + } + + ctx, cancel := context.WithCancel(ctx) + cli, err := client.Blame(ctx, req) + if err != nil { + cancel() + endObservation(1, observation.Args{}) + return nil, err + } + + // We start by reading the first hunk to early-exit on potential errors, + // ie. permission denied errors or invalid git command. + firstHunkResp, err := cli.Recv() + if err != nil { + cancel() + endObservation(1, observation.Args{}) + + if s, ok := status.FromError(err); ok { + if s.Code() == codes.PermissionDenied { + return nil, errUnauthorizedStreamBlame{Repo: repo} + } + } + + return nil, err + } + + return &grpcBlameHunkReader{ + firstHunk: firstHunkResp.GetHunk(), + c: cli, + cancel: cancel, + endObservation: func() { endObservation(1, observation.Args{}) }, + }, nil } type errUnauthorizedStreamBlame struct { @@ -842,48 +865,32 @@ func (e errUnauthorizedStreamBlame) Error() string { return fmt.Sprintf("not authorized (name=%s)", e.Repo) } -func streamBlameFileCmd(ctx context.Context, checker authz.SubRepoPermissionChecker, repo api.RepoName, path string, opt *BlameOptions, command gitCommandFunc) (HunkReader, error) { - a := actor.FromContext(ctx) - hasAccess, err := authz.FilterActorPath(ctx, checker, a, repo, path) +type grpcBlameHunkReader struct { + firstHunk *proto.BlameHunk + firstHunkRead bool + c proto.GitserverService_BlameClient + cancel context.CancelFunc + endObservation func() +} + +func (r *grpcBlameHunkReader) Read() (_ *gitdomain.Hunk, err error) { + if !r.firstHunkRead { + r.firstHunkRead = true + return gitdomain.HunkFromBlameProto(r.firstHunk), nil + } + p, err := r.c.Recv() if err != nil { return nil, err } - if !hasAccess { - return nil, errUnauthorizedStreamBlame{Repo: repo} - } - if opt == nil { - opt = &BlameOptions{} - } - if err := checkSpecArgSafety(string(opt.NewestCommit)); err != nil { - return nil, err - } - - args := []string{"blame", "--porcelain", "--incremental"} - if opt.IgnoreWhitespace { - args = append(args, "-w") - } - if opt.StartLine != 0 || opt.EndLine != 0 { - args = append(args, fmt.Sprintf("-L%d,%d", opt.StartLine, opt.EndLine)) - } - args = append(args, string(opt.NewestCommit), "--", filepath.ToSlash(path)) - - rc, err := command(args).StdoutReader(ctx) - if err != nil { - return nil, errors.WithMessage(err, fmt.Sprintf("git command %v failed", args)) - } - - return newBlameHunkReader(rc), nil + return gitdomain.HunkFromBlameProto(p.GetHunk()), nil } -func (c *clientImplementor) gitserverGitCommandFunc(repo api.RepoName) gitCommandFunc { - return func(args []string) GitCommand { - return c.gitCommand(repo, args...) - } +func (r *grpcBlameHunkReader) Close() error { + r.cancel() + r.endObservation() + return nil } -// gitCommandFunc is a func that creates a new executable Git command. -type gitCommandFunc func(args []string) GitCommand - // ResolveRevisionOptions configure how we resolve revisions. // The zero value should contain appropriate default values. type ResolveRevisionOptions struct { @@ -1238,7 +1245,7 @@ func (c *clientImplementor) MergeBase(ctx context.Context, repo api.RepoName, ba }) defer endObservation(1, observation.Args{}) - client, err := c.clientSource.ClientForRepo(ctx, c.userAgent, repo) + client, err := c.clientSource.ClientForRepo(ctx, repo) if err != nil { return "", err } @@ -2282,7 +2289,7 @@ func (c *clientImplementor) ArchiveReader( return nil, err } - client, err := c.clientSource.ClientForRepo(ctx, c.userAgent, repo) + client, err := c.clientSource.ClientForRepo(ctx, repo) if err != nil { return nil, err } diff --git a/internal/gitserver/commands_test.go b/internal/gitserver/commands_test.go index f11d532108f..f9a11734437 100644 --- a/internal/gitserver/commands_test.go +++ b/internal/gitserver/commands_test.go @@ -16,6 +16,9 @@ import ( "time" "github.com/stretchr/testify/assert" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" "github.com/google/go-cmp/cmp" godiff "github.com/sourcegraph/go-diff/diff" @@ -26,6 +29,7 @@ import ( "github.com/sourcegraph/sourcegraph/internal/authz" "github.com/sourcegraph/sourcegraph/internal/errcode" "github.com/sourcegraph/sourcegraph/internal/gitserver/gitdomain" + proto "github.com/sourcegraph/sourcegraph/internal/gitserver/v1" "github.com/sourcegraph/sourcegraph/internal/types" "github.com/sourcegraph/sourcegraph/lib/errors" ) @@ -2426,278 +2430,58 @@ func usePermissionsForFilePermissionsFunc(m *authz.MockSubRepoPermissionChecker) }) } -// testGitBlameOutputIncremental is produced by running -// -// git blame -w --porcelain release.sh -// -// `sourcegraph/src-cli` -var testGitBlameOutputIncremental = `8a75c6f8b4cbe2a2f3c8be0f2c50bc766499f498 15 15 1 -author Adam Harvey -author-mail -author-time 1660860583 -author-tz -0700 -committer GitHub -committer-mail -committer-time 1660860583 -committer-tz +0000 -summary release.sh: allow -rc.X suffixes (#829) -previous e6e03e850770dd0ba745f0fa4b23127e9d72ad30 release.sh -filename release.sh -fbb98e0b7ff0752798463d9f49d922858a4188f6 5 5 10 -author Adam Harvey -author-mail -author-time 1602630694 -author-tz -0700 -committer GitHub -committer-mail -committer-time 1602630694 -committer-tz -0700 -summary release: add a prompt about DEVELOPMENT.md (#349) -previous 18f59760f4260518c29f0f07056245ed5d1d0f08 release.sh -filename release.sh -67b7b725a7ff913da520b997d71c840230351e30 10 20 1 -author Thorsten Ball -author-mail -author-time 1600334460 -author-tz +0200 -committer Thorsten Ball -committer-mail -committer-time 1600334460 -committer-tz +0200 -summary Fix goreleaser GitHub action setup and release script -previous 6e931cc9745502184ce32d48b01f9a8706a4dfe8 release.sh -filename release.sh -67b7b725a7ff913da520b997d71c840230351e30 12 22 2 -previous 6e931cc9745502184ce32d48b01f9a8706a4dfe8 release.sh -filename release.sh -3f61310114082d6179c23f75950b88d1842fe2de 1 1 4 -author Thorsten Ball -author-mail -author-time 1592827635 -author-tz +0200 -committer GitHub -committer-mail -committer-time 1592827635 -committer-tz +0200 -summary Check that $VERSION is in MAJOR.MINOR.PATCH format in release.sh (#227) -previous ec809e79094cbcd05825446ee14c6d072466a0b7 release.sh -filename release.sh -3f61310114082d6179c23f75950b88d1842fe2de 6 16 4 -previous ec809e79094cbcd05825446ee14c6d072466a0b7 release.sh -filename release.sh -3f61310114082d6179c23f75950b88d1842fe2de 10 21 1 -previous ec809e79094cbcd05825446ee14c6d072466a0b7 release.sh -filename release.sh -` - -// This test-data includes the boundary keyword, which is not present in the previous one. -var testGitBlameOutputIncremental2 = `bbca6551549492486ca1b0f8dee45553dd6aa6d7 16 16 1 -author French Ben -author-mail -author-time 1517407262 -author-tz +0100 -committer French Ben -committer-mail -committer-time 1517407262 -committer-tz +0100 -summary Update error output to be clean -previous b7773ae218740a7be65057fc60b366a49b538a44 format.go -filename format.go -bbca6551549492486ca1b0f8dee45553dd6aa6d7 25 25 2 -previous b7773ae218740a7be65057fc60b366a49b538a44 format.go -filename format.go -2c87fda17de1def6ea288141b8e7600b888e535b 15 15 1 -author David Tolnay -author-mail -author-time 1478451741 -author-tz -0800 -committer David Tolnay -committer-mail -committer-time 1478451741 -committer-tz -0800 -summary Singular message for a single error -previous 8c5f0ad9360406a3807ce7de6bc73269a91a6e51 format.go -filename format.go -2c87fda17de1def6ea288141b8e7600b888e535b 17 17 2 -previous 8c5f0ad9360406a3807ce7de6bc73269a91a6e51 format.go -filename format.go -31fee45604949934710ada68f0b307c4726fb4e8 1 1 14 -author Mitchell Hashimoto -author-mail -author-time 1418673320 -author-tz -0800 -committer Mitchell Hashimoto -committer-mail -committer-time 1418673320 -committer-tz -0800 -summary Initial commit -boundary -filename format.go -31fee45604949934710ada68f0b307c4726fb4e8 15 19 6 -filename format.go -31fee45604949934710ada68f0b307c4726fb4e8 23 27 1 -filename format.go -` - -var testGitBlameOutputHunks = []*Hunk{ - { - StartLine: 1, EndLine: 5, StartByte: 0, EndByte: 41, - CommitID: "3f61310114082d6179c23f75950b88d1842fe2de", - Author: gitdomain.Signature{ - Name: "Thorsten Ball", - Email: "mrnugget@gmail.com", - Date: MustParseTime(time.RFC3339, "2020-06-22T12:07:15Z"), - }, - Message: "Check that $VERSION is in MAJOR.MINOR.PATCH format in release.sh (#227)", - Filename: "release.sh", - }, - { - StartLine: 5, EndLine: 15, StartByte: 41, EndByte: 249, - CommitID: "fbb98e0b7ff0752798463d9f49d922858a4188f6", - Author: gitdomain.Signature{ - Name: "Adam Harvey", - Email: "aharvey@sourcegraph.com", - Date: MustParseTime(time.RFC3339, "2020-10-13T23:11:34Z"), - }, - Message: "release: add a prompt about DEVELOPMENT.md (#349)", - Filename: "release.sh", - }, - { - StartLine: 15, EndLine: 16, StartByte: 249, EndByte: 328, - CommitID: "8a75c6f8b4cbe2a2f3c8be0f2c50bc766499f498", - Author: gitdomain.Signature{ - Name: "Adam Harvey", - Email: "adam@adamharvey.name", - Date: MustParseTime(time.RFC3339, "2022-08-18T22:09:43Z"), - }, - Message: "release.sh: allow -rc.X suffixes (#829)", - Filename: "release.sh", - }, - { - StartLine: 16, EndLine: 20, StartByte: 328, EndByte: 394, - CommitID: "3f61310114082d6179c23f75950b88d1842fe2de", - Author: gitdomain.Signature{ - Name: "Thorsten Ball", - Email: "mrnugget@gmail.com", - Date: MustParseTime(time.RFC3339, "2020-06-22T12:07:15Z"), - }, - Message: "Check that $VERSION is in MAJOR.MINOR.PATCH format in release.sh (#227)", - Filename: "release.sh", - }, - { - StartLine: 20, EndLine: 21, StartByte: 394, EndByte: 504, - CommitID: "67b7b725a7ff913da520b997d71c840230351e30", - Author: gitdomain.Signature{ - Name: "Thorsten Ball", - Email: "mrnugget@gmail.com", - Date: MustParseTime(time.RFC3339, "2020-09-17T09:21:00Z"), - }, - Message: "Fix goreleaser GitHub action setup and release script", - Filename: "release.sh", - }, - { - StartLine: 21, EndLine: 22, StartByte: 504, EndByte: 553, - CommitID: "3f61310114082d6179c23f75950b88d1842fe2de", - Author: gitdomain.Signature{ - Name: "Thorsten Ball", - Email: "mrnugget@gmail.com", - Date: MustParseTime(time.RFC3339, "2020-06-22T12:07:15Z"), - }, - Message: "Check that $VERSION is in MAJOR.MINOR.PATCH format in release.sh (#227)", - Filename: "release.sh", - }, - { - StartLine: 22, EndLine: 24, StartByte: 553, EndByte: 695, - CommitID: "67b7b725a7ff913da520b997d71c840230351e30", - Author: gitdomain.Signature{ - Name: "Thorsten Ball", - Email: "mrnugget@gmail.com", - Date: MustParseTime(time.RFC3339, "2020-09-17T09:21:00Z"), - }, - Message: "Fix goreleaser GitHub action setup and release script", - Filename: "release.sh", - }, -} - -func TestStreamBlameFile(t *testing.T) { - t.Run("NOK unauthorized", func(t *testing.T) { - ctx := actor.WithActor(context.Background(), &actor.Actor{ - UID: 1, +func TestClient_StreamBlameFile(t *testing.T) { + t.Run("firstChunk memoization", func(t *testing.T) { + source := NewTestClientSource(t, []string{"gitserver"}, func(o *TestClientSourceOptions) { + o.ClientFunc = func(cc *grpc.ClientConn) proto.GitserverServiceClient { + c := NewMockGitserverServiceClient() + bc := NewMockGitserverService_BlameClient() + bc.RecvFunc.PushReturn(&proto.BlameResponse{Hunk: &proto.BlameHunk{Commit: "deadbeef"}}, nil) + bc.RecvFunc.PushReturn(&proto.BlameResponse{Hunk: &proto.BlameHunk{Commit: "deadbeef2"}}, nil) + bc.RecvFunc.PushReturn(nil, io.EOF) + c.BlameFunc.SetDefaultReturn(bc, nil) + return c + } }) - checker := authz.NewMockSubRepoPermissionChecker() - checker.EnabledFunc.SetDefaultHook(func() bool { - return true - }) - // User doesn't have access to this file - checker.PermissionsFunc.SetDefaultHook(func(ctx context.Context, i int32, content authz.RepoContent) (authz.Perms, error) { - return authz.None, nil - }) - hr, err := streamBlameFileCmd(ctx, checker, "foobar", "README.md", nil, func(_ []string) GitCommand { return nil }) - if hr != nil { - t.Fatalf("expected nil HunkReader") - } - if err == nil { - t.Fatalf("expected an error to be returned") - } - if !errcode.IsUnauthorized(err) { - t.Fatalf("expected err to be an authorization error, got %v", err) - } + + c := NewTestClient(t).WithClientSource(source) + + hr, err := c.StreamBlameFile(context.Background(), "repo", "file", &BlameOptions{}) + require.NoError(t, err) + + // This chunk comes from the memoized first message. + h, err := hr.Read() + require.NoError(t, err) + require.Equal(t, h.CommitID, api.CommitID("deadbeef")) + + // This chunk is returned from Recv inside the hunk reader. + h, err = hr.Read() + require.NoError(t, err) + require.Equal(t, h.CommitID, api.CommitID("deadbeef2")) + + // Done. + _, err = hr.Read() + require.Error(t, err) + require.Equal(t, io.EOF, err) + + require.NoError(t, hr.Close()) }) -} - -func TestBlameHunkReader(t *testing.T) { - t.Run("OK matching hunks", func(t *testing.T) { - rc := io.NopCloser(strings.NewReader(testGitBlameOutputIncremental)) - reader := newBlameHunkReader(rc) - defer reader.Close() - - hunks := []*Hunk{} - for { - hunk, err := reader.Read() - if errors.Is(err, io.EOF) { - break - } else if err != nil { - t.Fatalf("blameHunkReader.Read failed: %s", err) + t.Run("permission errors are returned early", func(t *testing.T) { + source := NewTestClientSource(t, []string{"gitserver"}, func(o *TestClientSourceOptions) { + o.ClientFunc = func(cc *grpc.ClientConn) proto.GitserverServiceClient { + c := NewMockGitserverServiceClient() + bc := NewMockGitserverService_BlameClient() + bc.RecvFunc.PushReturn(nil, status.New(codes.PermissionDenied, "bad actor").Err()) + c.BlameFunc.SetDefaultReturn(bc, nil) + return c } - hunks = append(hunks, hunk) - } + }) - sortFn := func(x []*Hunk) func(i, j int) bool { - return func(i, j int) bool { - return x[i].Author.Date.After(x[j].Author.Date) - } - } + c := NewTestClient(t).WithClientSource(source) - // We're not giving back bytes, as the output of --incremental only gives back annotations. - expectedHunks := make([]*Hunk, 0, len(testGitBlameOutputHunks)) - for _, h := range testGitBlameOutputHunks { - dup := *h - dup.EndByte = 0 - dup.StartByte = 0 - expectedHunks = append(expectedHunks, &dup) - } - - // Sort expected hunks by the most recent first, as --incremental does. - sort.SliceStable(expectedHunks, sortFn(expectedHunks)) - - if d := cmp.Diff(expectedHunks, hunks); d != "" { - t.Fatalf("unexpected hunks (-want, +got):\n%s", d) - } - }) - - t.Run("OK parsing hunks", func(t *testing.T) { - rc := io.NopCloser(strings.NewReader(testGitBlameOutputIncremental2)) - reader := newBlameHunkReader(rc) - defer reader.Close() - - for { - _, err := reader.Read() - if errors.Is(err, io.EOF) { - break - } else if err != nil { - t.Fatalf("blameHunkReader.Read failed: %s", err) - } - } + _, err := c.StreamBlameFile(context.Background(), "repo", "file", &BlameOptions{}) + require.Error(t, err) + require.True(t, errcode.IsUnauthorized(err)) }) } diff --git a/internal/gitserver/gitdomain/BUILD.bazel b/internal/gitserver/gitdomain/BUILD.bazel index 8e594685091..e8c28fbd6f5 100644 --- a/internal/gitserver/gitdomain/BUILD.bazel +++ b/internal/gitserver/gitdomain/BUILD.bazel @@ -17,6 +17,7 @@ go_library( "//internal/lazyregexp", "//lib/errors", "@com_github_gobwas_glob//:glob", + "@org_golang_google_protobuf//types/known/timestamppb", ], ) diff --git a/internal/gitserver/gitdomain/common.go b/internal/gitserver/gitdomain/common.go index d2117065d0e..54e63d33df1 100644 --- a/internal/gitserver/gitdomain/common.go +++ b/internal/gitserver/gitdomain/common.go @@ -8,6 +8,7 @@ import ( "time" "github.com/gobwas/glob" + "google.golang.org/protobuf/types/known/timestamppb" proto "github.com/sourcegraph/sourcegraph/internal/gitserver/v1" @@ -181,6 +182,60 @@ func (m Message) Body() string { return strings.TrimSpace(message[i:]) } +// A Hunk is a contiguous portion of a file associated with a commit. +type Hunk struct { + StartLine uint32 // 1-indexed start line number + EndLine uint32 // 1-indexed end line number + StartByte uint32 // 0-indexed start byte position (inclusive) + EndByte uint32 // 0-indexed end byte position (exclusive) + CommitID api.CommitID + Author Signature + Message string + Filename string +} + +func HunkFromBlameProto(h *proto.BlameHunk) *Hunk { + if h == nil { + return nil + } + + return &Hunk{ + StartLine: h.GetStartLine(), + EndLine: h.GetEndLine(), + StartByte: h.GetStartByte(), + EndByte: h.GetEndByte(), + CommitID: api.CommitID(h.GetCommit()), + Message: h.GetMessage(), + Filename: h.GetFilename(), + Author: Signature{ + Name: h.GetAuthor().GetName(), + Email: h.GetAuthor().GetEmail(), + Date: h.GetAuthor().GetDate().AsTime(), + }, + } +} + +func (h *Hunk) ToProto() *proto.BlameHunk { + if h == nil { + return nil + } + + return &proto.BlameHunk{ + StartLine: uint32(h.StartLine), + EndLine: uint32(h.EndLine), + StartByte: uint32(h.StartByte), + EndByte: uint32(h.EndByte), + Commit: string(h.CommitID), + Message: h.Message, + Filename: h.Filename, + Author: &proto.BlameAuthor{ + Name: h.Author.Name, + Email: h.Author.Email, + Date: timestamppb.New(h.Author.Date), + }, + } +} + // Signature represents a commit signature type Signature struct { Name string `json:"Name,omitempty"` diff --git a/internal/gitserver/gitdomain/common_test.go b/internal/gitserver/gitdomain/common_test.go index 3576c8c9318..23cdd111292 100644 --- a/internal/gitserver/gitdomain/common_test.go +++ b/internal/gitserver/gitdomain/common_test.go @@ -109,3 +109,20 @@ func TestIsAbsoluteRevision(t *testing.T) { } } } + +// TODO: Fails because a time.Time is embedded in the Hunk type. +// func TestRoundTripBlameHunk(t *testing.T) { +// diff := "" + +// err := quick.Check(func(original *Hunk) bool { +// converted := HunkFromBlameProto(original.ToProto()) +// if diff = cmp.Diff(original, converted); diff != "" { +// return false +// } + +// return true +// }, nil) +// if err != nil { +// t.Fatalf("unexpected diff (-want +got):\n%s", diff) +// } +// } diff --git a/internal/gitserver/grpc_test.go b/internal/gitserver/grpc_test.go index 201f52c065c..4ab2230392c 100644 --- a/internal/gitserver/grpc_test.go +++ b/internal/gitserver/grpc_test.go @@ -29,8 +29,8 @@ func TestClientSource_AddrMatchesTarget(t *testing.T) { ctx := context.Background() for _, repo := range []api.RepoName{"a", "b", "c", "d"} { - addr := source.AddrForRepo(ctx, "test", repo) - conn, err := conns.ConnForRepo(ctx, "test", repo) + addr := source.AddrForRepo(ctx, repo) + conn, err := conns.ConnForRepo(ctx, repo) if err != nil { t.Fatal(err) } diff --git a/internal/gitserver/mock.go b/internal/gitserver/mock.go index bad81ed0db6..862b35eae3f 100644 --- a/internal/gitserver/mock.go +++ b/internal/gitserver/mock.go @@ -26,6 +26,9 @@ type MockGitserverServiceClient struct { // BatchLogFunc is an instance of a mock function object controlling the // behavior of the method BatchLog. BatchLogFunc *GitserverServiceClientBatchLogFunc + // BlameFunc is an instance of a mock function object controlling the + // behavior of the method Blame. + BlameFunc *GitserverServiceClientBlameFunc // CheckPerforceCredentialsFunc is an instance of a mock function object // controlling the behavior of the method CheckPerforceCredentials. CheckPerforceCredentialsFunc *GitserverServiceClientCheckPerforceCredentialsFunc @@ -107,6 +110,11 @@ func NewMockGitserverServiceClient() *MockGitserverServiceClient { return }, }, + BlameFunc: &GitserverServiceClientBlameFunc{ + defaultHook: func(context.Context, *v1.BlameRequest, ...grpc.CallOption) (r0 v1.GitserverService_BlameClient, r1 error) { + return + }, + }, CheckPerforceCredentialsFunc: &GitserverServiceClientCheckPerforceCredentialsFunc{ defaultHook: func(context.Context, *v1.CheckPerforceCredentialsRequest, ...grpc.CallOption) (r0 *v1.CheckPerforceCredentialsResponse, r1 error) { return @@ -230,6 +238,11 @@ func NewStrictMockGitserverServiceClient() *MockGitserverServiceClient { panic("unexpected invocation of MockGitserverServiceClient.BatchLog") }, }, + BlameFunc: &GitserverServiceClientBlameFunc{ + defaultHook: func(context.Context, *v1.BlameRequest, ...grpc.CallOption) (v1.GitserverService_BlameClient, error) { + panic("unexpected invocation of MockGitserverServiceClient.Blame") + }, + }, CheckPerforceCredentialsFunc: &GitserverServiceClientCheckPerforceCredentialsFunc{ defaultHook: func(context.Context, *v1.CheckPerforceCredentialsRequest, ...grpc.CallOption) (*v1.CheckPerforceCredentialsResponse, error) { panic("unexpected invocation of MockGitserverServiceClient.CheckPerforceCredentials") @@ -349,6 +362,9 @@ func NewMockGitserverServiceClientFrom(i v1.GitserverServiceClient) *MockGitserv BatchLogFunc: &GitserverServiceClientBatchLogFunc{ defaultHook: i.BatchLog, }, + BlameFunc: &GitserverServiceClientBlameFunc{ + defaultHook: i.Blame, + }, CheckPerforceCredentialsFunc: &GitserverServiceClientCheckPerforceCredentialsFunc{ defaultHook: i.CheckPerforceCredentials, }, @@ -654,6 +670,124 @@ func (c GitserverServiceClientBatchLogFuncCall) Results() []interface{} { return []interface{}{c.Result0, c.Result1} } +// GitserverServiceClientBlameFunc describes the behavior when the Blame +// method of the parent MockGitserverServiceClient instance is invoked. +type GitserverServiceClientBlameFunc struct { + defaultHook func(context.Context, *v1.BlameRequest, ...grpc.CallOption) (v1.GitserverService_BlameClient, error) + hooks []func(context.Context, *v1.BlameRequest, ...grpc.CallOption) (v1.GitserverService_BlameClient, error) + history []GitserverServiceClientBlameFuncCall + mutex sync.Mutex +} + +// Blame delegates to the next hook function in the queue and stores the +// parameter and result values of this invocation. +func (m *MockGitserverServiceClient) Blame(v0 context.Context, v1 *v1.BlameRequest, v2 ...grpc.CallOption) (v1.GitserverService_BlameClient, error) { + r0, r1 := m.BlameFunc.nextHook()(v0, v1, v2...) + m.BlameFunc.appendCall(GitserverServiceClientBlameFuncCall{v0, v1, v2, r0, r1}) + return r0, r1 +} + +// SetDefaultHook sets function that is called when the Blame method of the +// parent MockGitserverServiceClient instance is invoked and the hook queue +// is empty. +func (f *GitserverServiceClientBlameFunc) SetDefaultHook(hook func(context.Context, *v1.BlameRequest, ...grpc.CallOption) (v1.GitserverService_BlameClient, error)) { + f.defaultHook = hook +} + +// PushHook adds a function to the end of hook queue. Each invocation of the +// Blame method of the parent MockGitserverServiceClient instance invokes +// the hook at the front of the queue and discards it. After the queue is +// empty, the default hook function is invoked for any future action. +func (f *GitserverServiceClientBlameFunc) PushHook(hook func(context.Context, *v1.BlameRequest, ...grpc.CallOption) (v1.GitserverService_BlameClient, error)) { + f.mutex.Lock() + f.hooks = append(f.hooks, hook) + f.mutex.Unlock() +} + +// SetDefaultReturn calls SetDefaultHook with a function that returns the +// given values. +func (f *GitserverServiceClientBlameFunc) SetDefaultReturn(r0 v1.GitserverService_BlameClient, r1 error) { + f.SetDefaultHook(func(context.Context, *v1.BlameRequest, ...grpc.CallOption) (v1.GitserverService_BlameClient, error) { + return r0, r1 + }) +} + +// PushReturn calls PushHook with a function that returns the given values. +func (f *GitserverServiceClientBlameFunc) PushReturn(r0 v1.GitserverService_BlameClient, r1 error) { + f.PushHook(func(context.Context, *v1.BlameRequest, ...grpc.CallOption) (v1.GitserverService_BlameClient, error) { + return r0, r1 + }) +} + +func (f *GitserverServiceClientBlameFunc) nextHook() func(context.Context, *v1.BlameRequest, ...grpc.CallOption) (v1.GitserverService_BlameClient, error) { + f.mutex.Lock() + defer f.mutex.Unlock() + + if len(f.hooks) == 0 { + return f.defaultHook + } + + hook := f.hooks[0] + f.hooks = f.hooks[1:] + return hook +} + +func (f *GitserverServiceClientBlameFunc) appendCall(r0 GitserverServiceClientBlameFuncCall) { + f.mutex.Lock() + f.history = append(f.history, r0) + f.mutex.Unlock() +} + +// History returns a sequence of GitserverServiceClientBlameFuncCall objects +// describing the invocations of this function. +func (f *GitserverServiceClientBlameFunc) History() []GitserverServiceClientBlameFuncCall { + f.mutex.Lock() + history := make([]GitserverServiceClientBlameFuncCall, len(f.history)) + copy(history, f.history) + f.mutex.Unlock() + + return history +} + +// GitserverServiceClientBlameFuncCall is an object that describes an +// invocation of method Blame on an instance of MockGitserverServiceClient. +type GitserverServiceClientBlameFuncCall struct { + // Arg0 is the value of the 1st argument passed to this method + // invocation. + Arg0 context.Context + // Arg1 is the value of the 2nd argument passed to this method + // invocation. + Arg1 *v1.BlameRequest + // Arg2 is a slice containing the values of the variadic arguments + // passed to this method invocation. + Arg2 []grpc.CallOption + // Result0 is the value of the 1st result returned from this method + // invocation. + Result0 v1.GitserverService_BlameClient + // Result1 is the value of the 2nd result returned from this method + // invocation. + Result1 error +} + +// Args returns an interface slice containing the arguments of this +// invocation. The variadic slice argument is flattened in this array such +// that one positional argument and three variadic arguments would result in +// a slice of four, not two. +func (c GitserverServiceClientBlameFuncCall) Args() []interface{} { + trailing := []interface{}{} + for _, val := range c.Arg2 { + trailing = append(trailing, val) + } + + return append([]interface{}{c.Arg0, c.Arg1}, trailing...) +} + +// Results returns an interface slice containing the results of this +// invocation. +func (c GitserverServiceClientBlameFuncCall) Results() []interface{} { + return []interface{}{c.Result0, c.Result1} +} + // GitserverServiceClientCheckPerforceCredentialsFunc describes the behavior // when the CheckPerforceCredentials method of the parent // MockGitserverServiceClient instance is invoked. @@ -3193,6 +3327,1751 @@ func (c GitserverServiceClientSearchFuncCall) Results() []interface{} { return []interface{}{c.Result0, c.Result1} } +// MockGitserverService_BlameClient is a mock implementation of the +// GitserverService_BlameClient interface (from the package +// github.com/sourcegraph/sourcegraph/internal/gitserver/v1) used for unit +// testing. +type MockGitserverService_BlameClient struct { + // CloseSendFunc is an instance of a mock function object controlling + // the behavior of the method CloseSend. + CloseSendFunc *GitserverService_BlameClientCloseSendFunc + // ContextFunc is an instance of a mock function object controlling the + // behavior of the method Context. + ContextFunc *GitserverService_BlameClientContextFunc + // HeaderFunc is an instance of a mock function object controlling the + // behavior of the method Header. + HeaderFunc *GitserverService_BlameClientHeaderFunc + // RecvFunc is an instance of a mock function object controlling the + // behavior of the method Recv. + RecvFunc *GitserverService_BlameClientRecvFunc + // RecvMsgFunc is an instance of a mock function object controlling the + // behavior of the method RecvMsg. + RecvMsgFunc *GitserverService_BlameClientRecvMsgFunc + // SendMsgFunc is an instance of a mock function object controlling the + // behavior of the method SendMsg. + SendMsgFunc *GitserverService_BlameClientSendMsgFunc + // TrailerFunc is an instance of a mock function object controlling the + // behavior of the method Trailer. + TrailerFunc *GitserverService_BlameClientTrailerFunc +} + +// NewMockGitserverService_BlameClient creates a new mock of the +// GitserverService_BlameClient interface. All methods return zero values +// for all results, unless overwritten. +func NewMockGitserverService_BlameClient() *MockGitserverService_BlameClient { + return &MockGitserverService_BlameClient{ + CloseSendFunc: &GitserverService_BlameClientCloseSendFunc{ + defaultHook: func() (r0 error) { + return + }, + }, + ContextFunc: &GitserverService_BlameClientContextFunc{ + defaultHook: func() (r0 context.Context) { + return + }, + }, + HeaderFunc: &GitserverService_BlameClientHeaderFunc{ + defaultHook: func() (r0 metadata.MD, r1 error) { + return + }, + }, + RecvFunc: &GitserverService_BlameClientRecvFunc{ + defaultHook: func() (r0 *v1.BlameResponse, r1 error) { + return + }, + }, + RecvMsgFunc: &GitserverService_BlameClientRecvMsgFunc{ + defaultHook: func(interface{}) (r0 error) { + return + }, + }, + SendMsgFunc: &GitserverService_BlameClientSendMsgFunc{ + defaultHook: func(interface{}) (r0 error) { + return + }, + }, + TrailerFunc: &GitserverService_BlameClientTrailerFunc{ + defaultHook: func() (r0 metadata.MD) { + return + }, + }, + } +} + +// NewStrictMockGitserverService_BlameClient creates a new mock of the +// GitserverService_BlameClient interface. All methods panic on invocation, +// unless overwritten. +func NewStrictMockGitserverService_BlameClient() *MockGitserverService_BlameClient { + return &MockGitserverService_BlameClient{ + CloseSendFunc: &GitserverService_BlameClientCloseSendFunc{ + defaultHook: func() error { + panic("unexpected invocation of MockGitserverService_BlameClient.CloseSend") + }, + }, + ContextFunc: &GitserverService_BlameClientContextFunc{ + defaultHook: func() context.Context { + panic("unexpected invocation of MockGitserverService_BlameClient.Context") + }, + }, + HeaderFunc: &GitserverService_BlameClientHeaderFunc{ + defaultHook: func() (metadata.MD, error) { + panic("unexpected invocation of MockGitserverService_BlameClient.Header") + }, + }, + RecvFunc: &GitserverService_BlameClientRecvFunc{ + defaultHook: func() (*v1.BlameResponse, error) { + panic("unexpected invocation of MockGitserverService_BlameClient.Recv") + }, + }, + RecvMsgFunc: &GitserverService_BlameClientRecvMsgFunc{ + defaultHook: func(interface{}) error { + panic("unexpected invocation of MockGitserverService_BlameClient.RecvMsg") + }, + }, + SendMsgFunc: &GitserverService_BlameClientSendMsgFunc{ + defaultHook: func(interface{}) error { + panic("unexpected invocation of MockGitserverService_BlameClient.SendMsg") + }, + }, + TrailerFunc: &GitserverService_BlameClientTrailerFunc{ + defaultHook: func() metadata.MD { + panic("unexpected invocation of MockGitserverService_BlameClient.Trailer") + }, + }, + } +} + +// NewMockGitserverService_BlameClientFrom creates a new mock of the +// MockGitserverService_BlameClient interface. All methods delegate to the +// given implementation, unless overwritten. +func NewMockGitserverService_BlameClientFrom(i v1.GitserverService_BlameClient) *MockGitserverService_BlameClient { + return &MockGitserverService_BlameClient{ + CloseSendFunc: &GitserverService_BlameClientCloseSendFunc{ + defaultHook: i.CloseSend, + }, + ContextFunc: &GitserverService_BlameClientContextFunc{ + defaultHook: i.Context, + }, + HeaderFunc: &GitserverService_BlameClientHeaderFunc{ + defaultHook: i.Header, + }, + RecvFunc: &GitserverService_BlameClientRecvFunc{ + defaultHook: i.Recv, + }, + RecvMsgFunc: &GitserverService_BlameClientRecvMsgFunc{ + defaultHook: i.RecvMsg, + }, + SendMsgFunc: &GitserverService_BlameClientSendMsgFunc{ + defaultHook: i.SendMsg, + }, + TrailerFunc: &GitserverService_BlameClientTrailerFunc{ + defaultHook: i.Trailer, + }, + } +} + +// GitserverService_BlameClientCloseSendFunc describes the behavior when the +// CloseSend method of the parent MockGitserverService_BlameClient instance +// is invoked. +type GitserverService_BlameClientCloseSendFunc struct { + defaultHook func() error + hooks []func() error + history []GitserverService_BlameClientCloseSendFuncCall + mutex sync.Mutex +} + +// CloseSend delegates to the next hook function in the queue and stores the +// parameter and result values of this invocation. +func (m *MockGitserverService_BlameClient) CloseSend() error { + r0 := m.CloseSendFunc.nextHook()() + m.CloseSendFunc.appendCall(GitserverService_BlameClientCloseSendFuncCall{r0}) + return r0 +} + +// SetDefaultHook sets function that is called when the CloseSend method of +// the parent MockGitserverService_BlameClient instance is invoked and the +// hook queue is empty. +func (f *GitserverService_BlameClientCloseSendFunc) SetDefaultHook(hook func() error) { + f.defaultHook = hook +} + +// PushHook adds a function to the end of hook queue. Each invocation of the +// CloseSend method of the parent MockGitserverService_BlameClient instance +// invokes the hook at the front of the queue and discards it. After the +// queue is empty, the default hook function is invoked for any future +// action. +func (f *GitserverService_BlameClientCloseSendFunc) PushHook(hook func() error) { + f.mutex.Lock() + f.hooks = append(f.hooks, hook) + f.mutex.Unlock() +} + +// SetDefaultReturn calls SetDefaultHook with a function that returns the +// given values. +func (f *GitserverService_BlameClientCloseSendFunc) SetDefaultReturn(r0 error) { + f.SetDefaultHook(func() error { + return r0 + }) +} + +// PushReturn calls PushHook with a function that returns the given values. +func (f *GitserverService_BlameClientCloseSendFunc) PushReturn(r0 error) { + f.PushHook(func() error { + return r0 + }) +} + +func (f *GitserverService_BlameClientCloseSendFunc) nextHook() func() error { + f.mutex.Lock() + defer f.mutex.Unlock() + + if len(f.hooks) == 0 { + return f.defaultHook + } + + hook := f.hooks[0] + f.hooks = f.hooks[1:] + return hook +} + +func (f *GitserverService_BlameClientCloseSendFunc) appendCall(r0 GitserverService_BlameClientCloseSendFuncCall) { + f.mutex.Lock() + f.history = append(f.history, r0) + f.mutex.Unlock() +} + +// History returns a sequence of +// GitserverService_BlameClientCloseSendFuncCall objects describing the +// invocations of this function. +func (f *GitserverService_BlameClientCloseSendFunc) History() []GitserverService_BlameClientCloseSendFuncCall { + f.mutex.Lock() + history := make([]GitserverService_BlameClientCloseSendFuncCall, len(f.history)) + copy(history, f.history) + f.mutex.Unlock() + + return history +} + +// GitserverService_BlameClientCloseSendFuncCall is an object that describes +// an invocation of method CloseSend on an instance of +// MockGitserverService_BlameClient. +type GitserverService_BlameClientCloseSendFuncCall struct { + // Result0 is the value of the 1st result returned from this method + // invocation. + Result0 error +} + +// Args returns an interface slice containing the arguments of this +// invocation. +func (c GitserverService_BlameClientCloseSendFuncCall) Args() []interface{} { + return []interface{}{} +} + +// Results returns an interface slice containing the results of this +// invocation. +func (c GitserverService_BlameClientCloseSendFuncCall) Results() []interface{} { + return []interface{}{c.Result0} +} + +// GitserverService_BlameClientContextFunc describes the behavior when the +// Context method of the parent MockGitserverService_BlameClient instance is +// invoked. +type GitserverService_BlameClientContextFunc struct { + defaultHook func() context.Context + hooks []func() context.Context + history []GitserverService_BlameClientContextFuncCall + mutex sync.Mutex +} + +// Context delegates to the next hook function in the queue and stores the +// parameter and result values of this invocation. +func (m *MockGitserverService_BlameClient) Context() context.Context { + r0 := m.ContextFunc.nextHook()() + m.ContextFunc.appendCall(GitserverService_BlameClientContextFuncCall{r0}) + return r0 +} + +// SetDefaultHook sets function that is called when the Context method of +// the parent MockGitserverService_BlameClient instance is invoked and the +// hook queue is empty. +func (f *GitserverService_BlameClientContextFunc) SetDefaultHook(hook func() context.Context) { + f.defaultHook = hook +} + +// PushHook adds a function to the end of hook queue. Each invocation of the +// Context method of the parent MockGitserverService_BlameClient instance +// invokes the hook at the front of the queue and discards it. After the +// queue is empty, the default hook function is invoked for any future +// action. +func (f *GitserverService_BlameClientContextFunc) PushHook(hook func() context.Context) { + f.mutex.Lock() + f.hooks = append(f.hooks, hook) + f.mutex.Unlock() +} + +// SetDefaultReturn calls SetDefaultHook with a function that returns the +// given values. +func (f *GitserverService_BlameClientContextFunc) SetDefaultReturn(r0 context.Context) { + f.SetDefaultHook(func() context.Context { + return r0 + }) +} + +// PushReturn calls PushHook with a function that returns the given values. +func (f *GitserverService_BlameClientContextFunc) PushReturn(r0 context.Context) { + f.PushHook(func() context.Context { + return r0 + }) +} + +func (f *GitserverService_BlameClientContextFunc) nextHook() func() context.Context { + f.mutex.Lock() + defer f.mutex.Unlock() + + if len(f.hooks) == 0 { + return f.defaultHook + } + + hook := f.hooks[0] + f.hooks = f.hooks[1:] + return hook +} + +func (f *GitserverService_BlameClientContextFunc) appendCall(r0 GitserverService_BlameClientContextFuncCall) { + f.mutex.Lock() + f.history = append(f.history, r0) + f.mutex.Unlock() +} + +// History returns a sequence of GitserverService_BlameClientContextFuncCall +// objects describing the invocations of this function. +func (f *GitserverService_BlameClientContextFunc) History() []GitserverService_BlameClientContextFuncCall { + f.mutex.Lock() + history := make([]GitserverService_BlameClientContextFuncCall, len(f.history)) + copy(history, f.history) + f.mutex.Unlock() + + return history +} + +// GitserverService_BlameClientContextFuncCall is an object that describes +// an invocation of method Context on an instance of +// MockGitserverService_BlameClient. +type GitserverService_BlameClientContextFuncCall struct { + // Result0 is the value of the 1st result returned from this method + // invocation. + Result0 context.Context +} + +// Args returns an interface slice containing the arguments of this +// invocation. +func (c GitserverService_BlameClientContextFuncCall) Args() []interface{} { + return []interface{}{} +} + +// Results returns an interface slice containing the results of this +// invocation. +func (c GitserverService_BlameClientContextFuncCall) Results() []interface{} { + return []interface{}{c.Result0} +} + +// GitserverService_BlameClientHeaderFunc describes the behavior when the +// Header method of the parent MockGitserverService_BlameClient instance is +// invoked. +type GitserverService_BlameClientHeaderFunc struct { + defaultHook func() (metadata.MD, error) + hooks []func() (metadata.MD, error) + history []GitserverService_BlameClientHeaderFuncCall + mutex sync.Mutex +} + +// Header delegates to the next hook function in the queue and stores the +// parameter and result values of this invocation. +func (m *MockGitserverService_BlameClient) Header() (metadata.MD, error) { + r0, r1 := m.HeaderFunc.nextHook()() + m.HeaderFunc.appendCall(GitserverService_BlameClientHeaderFuncCall{r0, r1}) + return r0, r1 +} + +// SetDefaultHook sets function that is called when the Header method of the +// parent MockGitserverService_BlameClient instance is invoked and the hook +// queue is empty. +func (f *GitserverService_BlameClientHeaderFunc) SetDefaultHook(hook func() (metadata.MD, error)) { + f.defaultHook = hook +} + +// PushHook adds a function to the end of hook queue. Each invocation of the +// Header method of the parent MockGitserverService_BlameClient instance +// invokes the hook at the front of the queue and discards it. After the +// queue is empty, the default hook function is invoked for any future +// action. +func (f *GitserverService_BlameClientHeaderFunc) PushHook(hook func() (metadata.MD, error)) { + f.mutex.Lock() + f.hooks = append(f.hooks, hook) + f.mutex.Unlock() +} + +// SetDefaultReturn calls SetDefaultHook with a function that returns the +// given values. +func (f *GitserverService_BlameClientHeaderFunc) SetDefaultReturn(r0 metadata.MD, r1 error) { + f.SetDefaultHook(func() (metadata.MD, error) { + return r0, r1 + }) +} + +// PushReturn calls PushHook with a function that returns the given values. +func (f *GitserverService_BlameClientHeaderFunc) PushReturn(r0 metadata.MD, r1 error) { + f.PushHook(func() (metadata.MD, error) { + return r0, r1 + }) +} + +func (f *GitserverService_BlameClientHeaderFunc) nextHook() func() (metadata.MD, error) { + f.mutex.Lock() + defer f.mutex.Unlock() + + if len(f.hooks) == 0 { + return f.defaultHook + } + + hook := f.hooks[0] + f.hooks = f.hooks[1:] + return hook +} + +func (f *GitserverService_BlameClientHeaderFunc) appendCall(r0 GitserverService_BlameClientHeaderFuncCall) { + f.mutex.Lock() + f.history = append(f.history, r0) + f.mutex.Unlock() +} + +// History returns a sequence of GitserverService_BlameClientHeaderFuncCall +// objects describing the invocations of this function. +func (f *GitserverService_BlameClientHeaderFunc) History() []GitserverService_BlameClientHeaderFuncCall { + f.mutex.Lock() + history := make([]GitserverService_BlameClientHeaderFuncCall, len(f.history)) + copy(history, f.history) + f.mutex.Unlock() + + return history +} + +// GitserverService_BlameClientHeaderFuncCall is an object that describes an +// invocation of method Header on an instance of +// MockGitserverService_BlameClient. +type GitserverService_BlameClientHeaderFuncCall struct { + // Result0 is the value of the 1st result returned from this method + // invocation. + Result0 metadata.MD + // Result1 is the value of the 2nd result returned from this method + // invocation. + Result1 error +} + +// Args returns an interface slice containing the arguments of this +// invocation. +func (c GitserverService_BlameClientHeaderFuncCall) Args() []interface{} { + return []interface{}{} +} + +// Results returns an interface slice containing the results of this +// invocation. +func (c GitserverService_BlameClientHeaderFuncCall) Results() []interface{} { + return []interface{}{c.Result0, c.Result1} +} + +// GitserverService_BlameClientRecvFunc describes the behavior when the Recv +// method of the parent MockGitserverService_BlameClient instance is +// invoked. +type GitserverService_BlameClientRecvFunc struct { + defaultHook func() (*v1.BlameResponse, error) + hooks []func() (*v1.BlameResponse, error) + history []GitserverService_BlameClientRecvFuncCall + mutex sync.Mutex +} + +// Recv delegates to the next hook function in the queue and stores the +// parameter and result values of this invocation. +func (m *MockGitserverService_BlameClient) Recv() (*v1.BlameResponse, error) { + r0, r1 := m.RecvFunc.nextHook()() + m.RecvFunc.appendCall(GitserverService_BlameClientRecvFuncCall{r0, r1}) + return r0, r1 +} + +// SetDefaultHook sets function that is called when the Recv method of the +// parent MockGitserverService_BlameClient instance is invoked and the hook +// queue is empty. +func (f *GitserverService_BlameClientRecvFunc) SetDefaultHook(hook func() (*v1.BlameResponse, error)) { + f.defaultHook = hook +} + +// PushHook adds a function to the end of hook queue. Each invocation of the +// Recv method of the parent MockGitserverService_BlameClient instance +// invokes the hook at the front of the queue and discards it. After the +// queue is empty, the default hook function is invoked for any future +// action. +func (f *GitserverService_BlameClientRecvFunc) PushHook(hook func() (*v1.BlameResponse, error)) { + f.mutex.Lock() + f.hooks = append(f.hooks, hook) + f.mutex.Unlock() +} + +// SetDefaultReturn calls SetDefaultHook with a function that returns the +// given values. +func (f *GitserverService_BlameClientRecvFunc) SetDefaultReturn(r0 *v1.BlameResponse, r1 error) { + f.SetDefaultHook(func() (*v1.BlameResponse, error) { + return r0, r1 + }) +} + +// PushReturn calls PushHook with a function that returns the given values. +func (f *GitserverService_BlameClientRecvFunc) PushReturn(r0 *v1.BlameResponse, r1 error) { + f.PushHook(func() (*v1.BlameResponse, error) { + return r0, r1 + }) +} + +func (f *GitserverService_BlameClientRecvFunc) nextHook() func() (*v1.BlameResponse, error) { + f.mutex.Lock() + defer f.mutex.Unlock() + + if len(f.hooks) == 0 { + return f.defaultHook + } + + hook := f.hooks[0] + f.hooks = f.hooks[1:] + return hook +} + +func (f *GitserverService_BlameClientRecvFunc) appendCall(r0 GitserverService_BlameClientRecvFuncCall) { + f.mutex.Lock() + f.history = append(f.history, r0) + f.mutex.Unlock() +} + +// History returns a sequence of GitserverService_BlameClientRecvFuncCall +// objects describing the invocations of this function. +func (f *GitserverService_BlameClientRecvFunc) History() []GitserverService_BlameClientRecvFuncCall { + f.mutex.Lock() + history := make([]GitserverService_BlameClientRecvFuncCall, len(f.history)) + copy(history, f.history) + f.mutex.Unlock() + + return history +} + +// GitserverService_BlameClientRecvFuncCall is an object that describes an +// invocation of method Recv on an instance of +// MockGitserverService_BlameClient. +type GitserverService_BlameClientRecvFuncCall struct { + // Result0 is the value of the 1st result returned from this method + // invocation. + Result0 *v1.BlameResponse + // Result1 is the value of the 2nd result returned from this method + // invocation. + Result1 error +} + +// Args returns an interface slice containing the arguments of this +// invocation. +func (c GitserverService_BlameClientRecvFuncCall) Args() []interface{} { + return []interface{}{} +} + +// Results returns an interface slice containing the results of this +// invocation. +func (c GitserverService_BlameClientRecvFuncCall) Results() []interface{} { + return []interface{}{c.Result0, c.Result1} +} + +// GitserverService_BlameClientRecvMsgFunc describes the behavior when the +// RecvMsg method of the parent MockGitserverService_BlameClient instance is +// invoked. +type GitserverService_BlameClientRecvMsgFunc struct { + defaultHook func(interface{}) error + hooks []func(interface{}) error + history []GitserverService_BlameClientRecvMsgFuncCall + mutex sync.Mutex +} + +// RecvMsg delegates to the next hook function in the queue and stores the +// parameter and result values of this invocation. +func (m *MockGitserverService_BlameClient) RecvMsg(v0 interface{}) error { + r0 := m.RecvMsgFunc.nextHook()(v0) + m.RecvMsgFunc.appendCall(GitserverService_BlameClientRecvMsgFuncCall{v0, r0}) + return r0 +} + +// SetDefaultHook sets function that is called when the RecvMsg method of +// the parent MockGitserverService_BlameClient instance is invoked and the +// hook queue is empty. +func (f *GitserverService_BlameClientRecvMsgFunc) SetDefaultHook(hook func(interface{}) error) { + f.defaultHook = hook +} + +// PushHook adds a function to the end of hook queue. Each invocation of the +// RecvMsg method of the parent MockGitserverService_BlameClient instance +// invokes the hook at the front of the queue and discards it. After the +// queue is empty, the default hook function is invoked for any future +// action. +func (f *GitserverService_BlameClientRecvMsgFunc) PushHook(hook func(interface{}) error) { + f.mutex.Lock() + f.hooks = append(f.hooks, hook) + f.mutex.Unlock() +} + +// SetDefaultReturn calls SetDefaultHook with a function that returns the +// given values. +func (f *GitserverService_BlameClientRecvMsgFunc) SetDefaultReturn(r0 error) { + f.SetDefaultHook(func(interface{}) error { + return r0 + }) +} + +// PushReturn calls PushHook with a function that returns the given values. +func (f *GitserverService_BlameClientRecvMsgFunc) PushReturn(r0 error) { + f.PushHook(func(interface{}) error { + return r0 + }) +} + +func (f *GitserverService_BlameClientRecvMsgFunc) nextHook() func(interface{}) error { + f.mutex.Lock() + defer f.mutex.Unlock() + + if len(f.hooks) == 0 { + return f.defaultHook + } + + hook := f.hooks[0] + f.hooks = f.hooks[1:] + return hook +} + +func (f *GitserverService_BlameClientRecvMsgFunc) appendCall(r0 GitserverService_BlameClientRecvMsgFuncCall) { + f.mutex.Lock() + f.history = append(f.history, r0) + f.mutex.Unlock() +} + +// History returns a sequence of GitserverService_BlameClientRecvMsgFuncCall +// objects describing the invocations of this function. +func (f *GitserverService_BlameClientRecvMsgFunc) History() []GitserverService_BlameClientRecvMsgFuncCall { + f.mutex.Lock() + history := make([]GitserverService_BlameClientRecvMsgFuncCall, len(f.history)) + copy(history, f.history) + f.mutex.Unlock() + + return history +} + +// GitserverService_BlameClientRecvMsgFuncCall is an object that describes +// an invocation of method RecvMsg on an instance of +// MockGitserverService_BlameClient. +type GitserverService_BlameClientRecvMsgFuncCall struct { + // Arg0 is the value of the 1st argument passed to this method + // invocation. + Arg0 interface{} + // Result0 is the value of the 1st result returned from this method + // invocation. + Result0 error +} + +// Args returns an interface slice containing the arguments of this +// invocation. +func (c GitserverService_BlameClientRecvMsgFuncCall) Args() []interface{} { + return []interface{}{c.Arg0} +} + +// Results returns an interface slice containing the results of this +// invocation. +func (c GitserverService_BlameClientRecvMsgFuncCall) Results() []interface{} { + return []interface{}{c.Result0} +} + +// GitserverService_BlameClientSendMsgFunc describes the behavior when the +// SendMsg method of the parent MockGitserverService_BlameClient instance is +// invoked. +type GitserverService_BlameClientSendMsgFunc struct { + defaultHook func(interface{}) error + hooks []func(interface{}) error + history []GitserverService_BlameClientSendMsgFuncCall + mutex sync.Mutex +} + +// SendMsg delegates to the next hook function in the queue and stores the +// parameter and result values of this invocation. +func (m *MockGitserverService_BlameClient) SendMsg(v0 interface{}) error { + r0 := m.SendMsgFunc.nextHook()(v0) + m.SendMsgFunc.appendCall(GitserverService_BlameClientSendMsgFuncCall{v0, r0}) + return r0 +} + +// SetDefaultHook sets function that is called when the SendMsg method of +// the parent MockGitserverService_BlameClient instance is invoked and the +// hook queue is empty. +func (f *GitserverService_BlameClientSendMsgFunc) SetDefaultHook(hook func(interface{}) error) { + f.defaultHook = hook +} + +// PushHook adds a function to the end of hook queue. Each invocation of the +// SendMsg method of the parent MockGitserverService_BlameClient instance +// invokes the hook at the front of the queue and discards it. After the +// queue is empty, the default hook function is invoked for any future +// action. +func (f *GitserverService_BlameClientSendMsgFunc) PushHook(hook func(interface{}) error) { + f.mutex.Lock() + f.hooks = append(f.hooks, hook) + f.mutex.Unlock() +} + +// SetDefaultReturn calls SetDefaultHook with a function that returns the +// given values. +func (f *GitserverService_BlameClientSendMsgFunc) SetDefaultReturn(r0 error) { + f.SetDefaultHook(func(interface{}) error { + return r0 + }) +} + +// PushReturn calls PushHook with a function that returns the given values. +func (f *GitserverService_BlameClientSendMsgFunc) PushReturn(r0 error) { + f.PushHook(func(interface{}) error { + return r0 + }) +} + +func (f *GitserverService_BlameClientSendMsgFunc) nextHook() func(interface{}) error { + f.mutex.Lock() + defer f.mutex.Unlock() + + if len(f.hooks) == 0 { + return f.defaultHook + } + + hook := f.hooks[0] + f.hooks = f.hooks[1:] + return hook +} + +func (f *GitserverService_BlameClientSendMsgFunc) appendCall(r0 GitserverService_BlameClientSendMsgFuncCall) { + f.mutex.Lock() + f.history = append(f.history, r0) + f.mutex.Unlock() +} + +// History returns a sequence of GitserverService_BlameClientSendMsgFuncCall +// objects describing the invocations of this function. +func (f *GitserverService_BlameClientSendMsgFunc) History() []GitserverService_BlameClientSendMsgFuncCall { + f.mutex.Lock() + history := make([]GitserverService_BlameClientSendMsgFuncCall, len(f.history)) + copy(history, f.history) + f.mutex.Unlock() + + return history +} + +// GitserverService_BlameClientSendMsgFuncCall is an object that describes +// an invocation of method SendMsg on an instance of +// MockGitserverService_BlameClient. +type GitserverService_BlameClientSendMsgFuncCall struct { + // Arg0 is the value of the 1st argument passed to this method + // invocation. + Arg0 interface{} + // Result0 is the value of the 1st result returned from this method + // invocation. + Result0 error +} + +// Args returns an interface slice containing the arguments of this +// invocation. +func (c GitserverService_BlameClientSendMsgFuncCall) Args() []interface{} { + return []interface{}{c.Arg0} +} + +// Results returns an interface slice containing the results of this +// invocation. +func (c GitserverService_BlameClientSendMsgFuncCall) Results() []interface{} { + return []interface{}{c.Result0} +} + +// GitserverService_BlameClientTrailerFunc describes the behavior when the +// Trailer method of the parent MockGitserverService_BlameClient instance is +// invoked. +type GitserverService_BlameClientTrailerFunc struct { + defaultHook func() metadata.MD + hooks []func() metadata.MD + history []GitserverService_BlameClientTrailerFuncCall + mutex sync.Mutex +} + +// Trailer delegates to the next hook function in the queue and stores the +// parameter and result values of this invocation. +func (m *MockGitserverService_BlameClient) Trailer() metadata.MD { + r0 := m.TrailerFunc.nextHook()() + m.TrailerFunc.appendCall(GitserverService_BlameClientTrailerFuncCall{r0}) + return r0 +} + +// SetDefaultHook sets function that is called when the Trailer method of +// the parent MockGitserverService_BlameClient instance is invoked and the +// hook queue is empty. +func (f *GitserverService_BlameClientTrailerFunc) SetDefaultHook(hook func() metadata.MD) { + f.defaultHook = hook +} + +// PushHook adds a function to the end of hook queue. Each invocation of the +// Trailer method of the parent MockGitserverService_BlameClient instance +// invokes the hook at the front of the queue and discards it. After the +// queue is empty, the default hook function is invoked for any future +// action. +func (f *GitserverService_BlameClientTrailerFunc) PushHook(hook func() metadata.MD) { + f.mutex.Lock() + f.hooks = append(f.hooks, hook) + f.mutex.Unlock() +} + +// SetDefaultReturn calls SetDefaultHook with a function that returns the +// given values. +func (f *GitserverService_BlameClientTrailerFunc) SetDefaultReturn(r0 metadata.MD) { + f.SetDefaultHook(func() metadata.MD { + return r0 + }) +} + +// PushReturn calls PushHook with a function that returns the given values. +func (f *GitserverService_BlameClientTrailerFunc) PushReturn(r0 metadata.MD) { + f.PushHook(func() metadata.MD { + return r0 + }) +} + +func (f *GitserverService_BlameClientTrailerFunc) nextHook() func() metadata.MD { + f.mutex.Lock() + defer f.mutex.Unlock() + + if len(f.hooks) == 0 { + return f.defaultHook + } + + hook := f.hooks[0] + f.hooks = f.hooks[1:] + return hook +} + +func (f *GitserverService_BlameClientTrailerFunc) appendCall(r0 GitserverService_BlameClientTrailerFuncCall) { + f.mutex.Lock() + f.history = append(f.history, r0) + f.mutex.Unlock() +} + +// History returns a sequence of GitserverService_BlameClientTrailerFuncCall +// objects describing the invocations of this function. +func (f *GitserverService_BlameClientTrailerFunc) History() []GitserverService_BlameClientTrailerFuncCall { + f.mutex.Lock() + history := make([]GitserverService_BlameClientTrailerFuncCall, len(f.history)) + copy(history, f.history) + f.mutex.Unlock() + + return history +} + +// GitserverService_BlameClientTrailerFuncCall is an object that describes +// an invocation of method Trailer on an instance of +// MockGitserverService_BlameClient. +type GitserverService_BlameClientTrailerFuncCall struct { + // Result0 is the value of the 1st result returned from this method + // invocation. + Result0 metadata.MD +} + +// Args returns an interface slice containing the arguments of this +// invocation. +func (c GitserverService_BlameClientTrailerFuncCall) Args() []interface{} { + return []interface{}{} +} + +// Results returns an interface slice containing the results of this +// invocation. +func (c GitserverService_BlameClientTrailerFuncCall) Results() []interface{} { + return []interface{}{c.Result0} +} + +// MockGitserverService_BlameServer is a mock implementation of the +// GitserverService_BlameServer interface (from the package +// github.com/sourcegraph/sourcegraph/internal/gitserver/v1) used for unit +// testing. +type MockGitserverService_BlameServer struct { + // ContextFunc is an instance of a mock function object controlling the + // behavior of the method Context. + ContextFunc *GitserverService_BlameServerContextFunc + // RecvMsgFunc is an instance of a mock function object controlling the + // behavior of the method RecvMsg. + RecvMsgFunc *GitserverService_BlameServerRecvMsgFunc + // SendFunc is an instance of a mock function object controlling the + // behavior of the method Send. + SendFunc *GitserverService_BlameServerSendFunc + // SendHeaderFunc is an instance of a mock function object controlling + // the behavior of the method SendHeader. + SendHeaderFunc *GitserverService_BlameServerSendHeaderFunc + // SendMsgFunc is an instance of a mock function object controlling the + // behavior of the method SendMsg. + SendMsgFunc *GitserverService_BlameServerSendMsgFunc + // SetHeaderFunc is an instance of a mock function object controlling + // the behavior of the method SetHeader. + SetHeaderFunc *GitserverService_BlameServerSetHeaderFunc + // SetTrailerFunc is an instance of a mock function object controlling + // the behavior of the method SetTrailer. + SetTrailerFunc *GitserverService_BlameServerSetTrailerFunc +} + +// NewMockGitserverService_BlameServer creates a new mock of the +// GitserverService_BlameServer interface. All methods return zero values +// for all results, unless overwritten. +func NewMockGitserverService_BlameServer() *MockGitserverService_BlameServer { + return &MockGitserverService_BlameServer{ + ContextFunc: &GitserverService_BlameServerContextFunc{ + defaultHook: func() (r0 context.Context) { + return + }, + }, + RecvMsgFunc: &GitserverService_BlameServerRecvMsgFunc{ + defaultHook: func(interface{}) (r0 error) { + return + }, + }, + SendFunc: &GitserverService_BlameServerSendFunc{ + defaultHook: func(*v1.BlameResponse) (r0 error) { + return + }, + }, + SendHeaderFunc: &GitserverService_BlameServerSendHeaderFunc{ + defaultHook: func(metadata.MD) (r0 error) { + return + }, + }, + SendMsgFunc: &GitserverService_BlameServerSendMsgFunc{ + defaultHook: func(interface{}) (r0 error) { + return + }, + }, + SetHeaderFunc: &GitserverService_BlameServerSetHeaderFunc{ + defaultHook: func(metadata.MD) (r0 error) { + return + }, + }, + SetTrailerFunc: &GitserverService_BlameServerSetTrailerFunc{ + defaultHook: func(metadata.MD) { + return + }, + }, + } +} + +// NewStrictMockGitserverService_BlameServer creates a new mock of the +// GitserverService_BlameServer interface. All methods panic on invocation, +// unless overwritten. +func NewStrictMockGitserverService_BlameServer() *MockGitserverService_BlameServer { + return &MockGitserverService_BlameServer{ + ContextFunc: &GitserverService_BlameServerContextFunc{ + defaultHook: func() context.Context { + panic("unexpected invocation of MockGitserverService_BlameServer.Context") + }, + }, + RecvMsgFunc: &GitserverService_BlameServerRecvMsgFunc{ + defaultHook: func(interface{}) error { + panic("unexpected invocation of MockGitserverService_BlameServer.RecvMsg") + }, + }, + SendFunc: &GitserverService_BlameServerSendFunc{ + defaultHook: func(*v1.BlameResponse) error { + panic("unexpected invocation of MockGitserverService_BlameServer.Send") + }, + }, + SendHeaderFunc: &GitserverService_BlameServerSendHeaderFunc{ + defaultHook: func(metadata.MD) error { + panic("unexpected invocation of MockGitserverService_BlameServer.SendHeader") + }, + }, + SendMsgFunc: &GitserverService_BlameServerSendMsgFunc{ + defaultHook: func(interface{}) error { + panic("unexpected invocation of MockGitserverService_BlameServer.SendMsg") + }, + }, + SetHeaderFunc: &GitserverService_BlameServerSetHeaderFunc{ + defaultHook: func(metadata.MD) error { + panic("unexpected invocation of MockGitserverService_BlameServer.SetHeader") + }, + }, + SetTrailerFunc: &GitserverService_BlameServerSetTrailerFunc{ + defaultHook: func(metadata.MD) { + panic("unexpected invocation of MockGitserverService_BlameServer.SetTrailer") + }, + }, + } +} + +// NewMockGitserverService_BlameServerFrom creates a new mock of the +// MockGitserverService_BlameServer interface. All methods delegate to the +// given implementation, unless overwritten. +func NewMockGitserverService_BlameServerFrom(i v1.GitserverService_BlameServer) *MockGitserverService_BlameServer { + return &MockGitserverService_BlameServer{ + ContextFunc: &GitserverService_BlameServerContextFunc{ + defaultHook: i.Context, + }, + RecvMsgFunc: &GitserverService_BlameServerRecvMsgFunc{ + defaultHook: i.RecvMsg, + }, + SendFunc: &GitserverService_BlameServerSendFunc{ + defaultHook: i.Send, + }, + SendHeaderFunc: &GitserverService_BlameServerSendHeaderFunc{ + defaultHook: i.SendHeader, + }, + SendMsgFunc: &GitserverService_BlameServerSendMsgFunc{ + defaultHook: i.SendMsg, + }, + SetHeaderFunc: &GitserverService_BlameServerSetHeaderFunc{ + defaultHook: i.SetHeader, + }, + SetTrailerFunc: &GitserverService_BlameServerSetTrailerFunc{ + defaultHook: i.SetTrailer, + }, + } +} + +// GitserverService_BlameServerContextFunc describes the behavior when the +// Context method of the parent MockGitserverService_BlameServer instance is +// invoked. +type GitserverService_BlameServerContextFunc struct { + defaultHook func() context.Context + hooks []func() context.Context + history []GitserverService_BlameServerContextFuncCall + mutex sync.Mutex +} + +// Context delegates to the next hook function in the queue and stores the +// parameter and result values of this invocation. +func (m *MockGitserverService_BlameServer) Context() context.Context { + r0 := m.ContextFunc.nextHook()() + m.ContextFunc.appendCall(GitserverService_BlameServerContextFuncCall{r0}) + return r0 +} + +// SetDefaultHook sets function that is called when the Context method of +// the parent MockGitserverService_BlameServer instance is invoked and the +// hook queue is empty. +func (f *GitserverService_BlameServerContextFunc) SetDefaultHook(hook func() context.Context) { + f.defaultHook = hook +} + +// PushHook adds a function to the end of hook queue. Each invocation of the +// Context method of the parent MockGitserverService_BlameServer instance +// invokes the hook at the front of the queue and discards it. After the +// queue is empty, the default hook function is invoked for any future +// action. +func (f *GitserverService_BlameServerContextFunc) PushHook(hook func() context.Context) { + f.mutex.Lock() + f.hooks = append(f.hooks, hook) + f.mutex.Unlock() +} + +// SetDefaultReturn calls SetDefaultHook with a function that returns the +// given values. +func (f *GitserverService_BlameServerContextFunc) SetDefaultReturn(r0 context.Context) { + f.SetDefaultHook(func() context.Context { + return r0 + }) +} + +// PushReturn calls PushHook with a function that returns the given values. +func (f *GitserverService_BlameServerContextFunc) PushReturn(r0 context.Context) { + f.PushHook(func() context.Context { + return r0 + }) +} + +func (f *GitserverService_BlameServerContextFunc) nextHook() func() context.Context { + f.mutex.Lock() + defer f.mutex.Unlock() + + if len(f.hooks) == 0 { + return f.defaultHook + } + + hook := f.hooks[0] + f.hooks = f.hooks[1:] + return hook +} + +func (f *GitserverService_BlameServerContextFunc) appendCall(r0 GitserverService_BlameServerContextFuncCall) { + f.mutex.Lock() + f.history = append(f.history, r0) + f.mutex.Unlock() +} + +// History returns a sequence of GitserverService_BlameServerContextFuncCall +// objects describing the invocations of this function. +func (f *GitserverService_BlameServerContextFunc) History() []GitserverService_BlameServerContextFuncCall { + f.mutex.Lock() + history := make([]GitserverService_BlameServerContextFuncCall, len(f.history)) + copy(history, f.history) + f.mutex.Unlock() + + return history +} + +// GitserverService_BlameServerContextFuncCall is an object that describes +// an invocation of method Context on an instance of +// MockGitserverService_BlameServer. +type GitserverService_BlameServerContextFuncCall struct { + // Result0 is the value of the 1st result returned from this method + // invocation. + Result0 context.Context +} + +// Args returns an interface slice containing the arguments of this +// invocation. +func (c GitserverService_BlameServerContextFuncCall) Args() []interface{} { + return []interface{}{} +} + +// Results returns an interface slice containing the results of this +// invocation. +func (c GitserverService_BlameServerContextFuncCall) Results() []interface{} { + return []interface{}{c.Result0} +} + +// GitserverService_BlameServerRecvMsgFunc describes the behavior when the +// RecvMsg method of the parent MockGitserverService_BlameServer instance is +// invoked. +type GitserverService_BlameServerRecvMsgFunc struct { + defaultHook func(interface{}) error + hooks []func(interface{}) error + history []GitserverService_BlameServerRecvMsgFuncCall + mutex sync.Mutex +} + +// RecvMsg delegates to the next hook function in the queue and stores the +// parameter and result values of this invocation. +func (m *MockGitserverService_BlameServer) RecvMsg(v0 interface{}) error { + r0 := m.RecvMsgFunc.nextHook()(v0) + m.RecvMsgFunc.appendCall(GitserverService_BlameServerRecvMsgFuncCall{v0, r0}) + return r0 +} + +// SetDefaultHook sets function that is called when the RecvMsg method of +// the parent MockGitserverService_BlameServer instance is invoked and the +// hook queue is empty. +func (f *GitserverService_BlameServerRecvMsgFunc) SetDefaultHook(hook func(interface{}) error) { + f.defaultHook = hook +} + +// PushHook adds a function to the end of hook queue. Each invocation of the +// RecvMsg method of the parent MockGitserverService_BlameServer instance +// invokes the hook at the front of the queue and discards it. After the +// queue is empty, the default hook function is invoked for any future +// action. +func (f *GitserverService_BlameServerRecvMsgFunc) PushHook(hook func(interface{}) error) { + f.mutex.Lock() + f.hooks = append(f.hooks, hook) + f.mutex.Unlock() +} + +// SetDefaultReturn calls SetDefaultHook with a function that returns the +// given values. +func (f *GitserverService_BlameServerRecvMsgFunc) SetDefaultReturn(r0 error) { + f.SetDefaultHook(func(interface{}) error { + return r0 + }) +} + +// PushReturn calls PushHook with a function that returns the given values. +func (f *GitserverService_BlameServerRecvMsgFunc) PushReturn(r0 error) { + f.PushHook(func(interface{}) error { + return r0 + }) +} + +func (f *GitserverService_BlameServerRecvMsgFunc) nextHook() func(interface{}) error { + f.mutex.Lock() + defer f.mutex.Unlock() + + if len(f.hooks) == 0 { + return f.defaultHook + } + + hook := f.hooks[0] + f.hooks = f.hooks[1:] + return hook +} + +func (f *GitserverService_BlameServerRecvMsgFunc) appendCall(r0 GitserverService_BlameServerRecvMsgFuncCall) { + f.mutex.Lock() + f.history = append(f.history, r0) + f.mutex.Unlock() +} + +// History returns a sequence of GitserverService_BlameServerRecvMsgFuncCall +// objects describing the invocations of this function. +func (f *GitserverService_BlameServerRecvMsgFunc) History() []GitserverService_BlameServerRecvMsgFuncCall { + f.mutex.Lock() + history := make([]GitserverService_BlameServerRecvMsgFuncCall, len(f.history)) + copy(history, f.history) + f.mutex.Unlock() + + return history +} + +// GitserverService_BlameServerRecvMsgFuncCall is an object that describes +// an invocation of method RecvMsg on an instance of +// MockGitserverService_BlameServer. +type GitserverService_BlameServerRecvMsgFuncCall struct { + // Arg0 is the value of the 1st argument passed to this method + // invocation. + Arg0 interface{} + // Result0 is the value of the 1st result returned from this method + // invocation. + Result0 error +} + +// Args returns an interface slice containing the arguments of this +// invocation. +func (c GitserverService_BlameServerRecvMsgFuncCall) Args() []interface{} { + return []interface{}{c.Arg0} +} + +// Results returns an interface slice containing the results of this +// invocation. +func (c GitserverService_BlameServerRecvMsgFuncCall) Results() []interface{} { + return []interface{}{c.Result0} +} + +// GitserverService_BlameServerSendFunc describes the behavior when the Send +// method of the parent MockGitserverService_BlameServer instance is +// invoked. +type GitserverService_BlameServerSendFunc struct { + defaultHook func(*v1.BlameResponse) error + hooks []func(*v1.BlameResponse) error + history []GitserverService_BlameServerSendFuncCall + mutex sync.Mutex +} + +// Send delegates to the next hook function in the queue and stores the +// parameter and result values of this invocation. +func (m *MockGitserverService_BlameServer) Send(v0 *v1.BlameResponse) error { + r0 := m.SendFunc.nextHook()(v0) + m.SendFunc.appendCall(GitserverService_BlameServerSendFuncCall{v0, r0}) + return r0 +} + +// SetDefaultHook sets function that is called when the Send method of the +// parent MockGitserverService_BlameServer instance is invoked and the hook +// queue is empty. +func (f *GitserverService_BlameServerSendFunc) SetDefaultHook(hook func(*v1.BlameResponse) error) { + f.defaultHook = hook +} + +// PushHook adds a function to the end of hook queue. Each invocation of the +// Send method of the parent MockGitserverService_BlameServer instance +// invokes the hook at the front of the queue and discards it. After the +// queue is empty, the default hook function is invoked for any future +// action. +func (f *GitserverService_BlameServerSendFunc) PushHook(hook func(*v1.BlameResponse) error) { + f.mutex.Lock() + f.hooks = append(f.hooks, hook) + f.mutex.Unlock() +} + +// SetDefaultReturn calls SetDefaultHook with a function that returns the +// given values. +func (f *GitserverService_BlameServerSendFunc) SetDefaultReturn(r0 error) { + f.SetDefaultHook(func(*v1.BlameResponse) error { + return r0 + }) +} + +// PushReturn calls PushHook with a function that returns the given values. +func (f *GitserverService_BlameServerSendFunc) PushReturn(r0 error) { + f.PushHook(func(*v1.BlameResponse) error { + return r0 + }) +} + +func (f *GitserverService_BlameServerSendFunc) nextHook() func(*v1.BlameResponse) error { + f.mutex.Lock() + defer f.mutex.Unlock() + + if len(f.hooks) == 0 { + return f.defaultHook + } + + hook := f.hooks[0] + f.hooks = f.hooks[1:] + return hook +} + +func (f *GitserverService_BlameServerSendFunc) appendCall(r0 GitserverService_BlameServerSendFuncCall) { + f.mutex.Lock() + f.history = append(f.history, r0) + f.mutex.Unlock() +} + +// History returns a sequence of GitserverService_BlameServerSendFuncCall +// objects describing the invocations of this function. +func (f *GitserverService_BlameServerSendFunc) History() []GitserverService_BlameServerSendFuncCall { + f.mutex.Lock() + history := make([]GitserverService_BlameServerSendFuncCall, len(f.history)) + copy(history, f.history) + f.mutex.Unlock() + + return history +} + +// GitserverService_BlameServerSendFuncCall is an object that describes an +// invocation of method Send on an instance of +// MockGitserverService_BlameServer. +type GitserverService_BlameServerSendFuncCall struct { + // Arg0 is the value of the 1st argument passed to this method + // invocation. + Arg0 *v1.BlameResponse + // Result0 is the value of the 1st result returned from this method + // invocation. + Result0 error +} + +// Args returns an interface slice containing the arguments of this +// invocation. +func (c GitserverService_BlameServerSendFuncCall) Args() []interface{} { + return []interface{}{c.Arg0} +} + +// Results returns an interface slice containing the results of this +// invocation. +func (c GitserverService_BlameServerSendFuncCall) Results() []interface{} { + return []interface{}{c.Result0} +} + +// GitserverService_BlameServerSendHeaderFunc describes the behavior when +// the SendHeader method of the parent MockGitserverService_BlameServer +// instance is invoked. +type GitserverService_BlameServerSendHeaderFunc struct { + defaultHook func(metadata.MD) error + hooks []func(metadata.MD) error + history []GitserverService_BlameServerSendHeaderFuncCall + mutex sync.Mutex +} + +// SendHeader delegates to the next hook function in the queue and stores +// the parameter and result values of this invocation. +func (m *MockGitserverService_BlameServer) SendHeader(v0 metadata.MD) error { + r0 := m.SendHeaderFunc.nextHook()(v0) + m.SendHeaderFunc.appendCall(GitserverService_BlameServerSendHeaderFuncCall{v0, r0}) + return r0 +} + +// SetDefaultHook sets function that is called when the SendHeader method of +// the parent MockGitserverService_BlameServer instance is invoked and the +// hook queue is empty. +func (f *GitserverService_BlameServerSendHeaderFunc) SetDefaultHook(hook func(metadata.MD) error) { + f.defaultHook = hook +} + +// PushHook adds a function to the end of hook queue. Each invocation of the +// SendHeader method of the parent MockGitserverService_BlameServer instance +// invokes the hook at the front of the queue and discards it. After the +// queue is empty, the default hook function is invoked for any future +// action. +func (f *GitserverService_BlameServerSendHeaderFunc) PushHook(hook func(metadata.MD) error) { + f.mutex.Lock() + f.hooks = append(f.hooks, hook) + f.mutex.Unlock() +} + +// SetDefaultReturn calls SetDefaultHook with a function that returns the +// given values. +func (f *GitserverService_BlameServerSendHeaderFunc) SetDefaultReturn(r0 error) { + f.SetDefaultHook(func(metadata.MD) error { + return r0 + }) +} + +// PushReturn calls PushHook with a function that returns the given values. +func (f *GitserverService_BlameServerSendHeaderFunc) PushReturn(r0 error) { + f.PushHook(func(metadata.MD) error { + return r0 + }) +} + +func (f *GitserverService_BlameServerSendHeaderFunc) nextHook() func(metadata.MD) error { + f.mutex.Lock() + defer f.mutex.Unlock() + + if len(f.hooks) == 0 { + return f.defaultHook + } + + hook := f.hooks[0] + f.hooks = f.hooks[1:] + return hook +} + +func (f *GitserverService_BlameServerSendHeaderFunc) appendCall(r0 GitserverService_BlameServerSendHeaderFuncCall) { + f.mutex.Lock() + f.history = append(f.history, r0) + f.mutex.Unlock() +} + +// History returns a sequence of +// GitserverService_BlameServerSendHeaderFuncCall objects describing the +// invocations of this function. +func (f *GitserverService_BlameServerSendHeaderFunc) History() []GitserverService_BlameServerSendHeaderFuncCall { + f.mutex.Lock() + history := make([]GitserverService_BlameServerSendHeaderFuncCall, len(f.history)) + copy(history, f.history) + f.mutex.Unlock() + + return history +} + +// GitserverService_BlameServerSendHeaderFuncCall is an object that +// describes an invocation of method SendHeader on an instance of +// MockGitserverService_BlameServer. +type GitserverService_BlameServerSendHeaderFuncCall struct { + // Arg0 is the value of the 1st argument passed to this method + // invocation. + Arg0 metadata.MD + // Result0 is the value of the 1st result returned from this method + // invocation. + Result0 error +} + +// Args returns an interface slice containing the arguments of this +// invocation. +func (c GitserverService_BlameServerSendHeaderFuncCall) Args() []interface{} { + return []interface{}{c.Arg0} +} + +// Results returns an interface slice containing the results of this +// invocation. +func (c GitserverService_BlameServerSendHeaderFuncCall) Results() []interface{} { + return []interface{}{c.Result0} +} + +// GitserverService_BlameServerSendMsgFunc describes the behavior when the +// SendMsg method of the parent MockGitserverService_BlameServer instance is +// invoked. +type GitserverService_BlameServerSendMsgFunc struct { + defaultHook func(interface{}) error + hooks []func(interface{}) error + history []GitserverService_BlameServerSendMsgFuncCall + mutex sync.Mutex +} + +// SendMsg delegates to the next hook function in the queue and stores the +// parameter and result values of this invocation. +func (m *MockGitserverService_BlameServer) SendMsg(v0 interface{}) error { + r0 := m.SendMsgFunc.nextHook()(v0) + m.SendMsgFunc.appendCall(GitserverService_BlameServerSendMsgFuncCall{v0, r0}) + return r0 +} + +// SetDefaultHook sets function that is called when the SendMsg method of +// the parent MockGitserverService_BlameServer instance is invoked and the +// hook queue is empty. +func (f *GitserverService_BlameServerSendMsgFunc) SetDefaultHook(hook func(interface{}) error) { + f.defaultHook = hook +} + +// PushHook adds a function to the end of hook queue. Each invocation of the +// SendMsg method of the parent MockGitserverService_BlameServer instance +// invokes the hook at the front of the queue and discards it. After the +// queue is empty, the default hook function is invoked for any future +// action. +func (f *GitserverService_BlameServerSendMsgFunc) PushHook(hook func(interface{}) error) { + f.mutex.Lock() + f.hooks = append(f.hooks, hook) + f.mutex.Unlock() +} + +// SetDefaultReturn calls SetDefaultHook with a function that returns the +// given values. +func (f *GitserverService_BlameServerSendMsgFunc) SetDefaultReturn(r0 error) { + f.SetDefaultHook(func(interface{}) error { + return r0 + }) +} + +// PushReturn calls PushHook with a function that returns the given values. +func (f *GitserverService_BlameServerSendMsgFunc) PushReturn(r0 error) { + f.PushHook(func(interface{}) error { + return r0 + }) +} + +func (f *GitserverService_BlameServerSendMsgFunc) nextHook() func(interface{}) error { + f.mutex.Lock() + defer f.mutex.Unlock() + + if len(f.hooks) == 0 { + return f.defaultHook + } + + hook := f.hooks[0] + f.hooks = f.hooks[1:] + return hook +} + +func (f *GitserverService_BlameServerSendMsgFunc) appendCall(r0 GitserverService_BlameServerSendMsgFuncCall) { + f.mutex.Lock() + f.history = append(f.history, r0) + f.mutex.Unlock() +} + +// History returns a sequence of GitserverService_BlameServerSendMsgFuncCall +// objects describing the invocations of this function. +func (f *GitserverService_BlameServerSendMsgFunc) History() []GitserverService_BlameServerSendMsgFuncCall { + f.mutex.Lock() + history := make([]GitserverService_BlameServerSendMsgFuncCall, len(f.history)) + copy(history, f.history) + f.mutex.Unlock() + + return history +} + +// GitserverService_BlameServerSendMsgFuncCall is an object that describes +// an invocation of method SendMsg on an instance of +// MockGitserverService_BlameServer. +type GitserverService_BlameServerSendMsgFuncCall struct { + // Arg0 is the value of the 1st argument passed to this method + // invocation. + Arg0 interface{} + // Result0 is the value of the 1st result returned from this method + // invocation. + Result0 error +} + +// Args returns an interface slice containing the arguments of this +// invocation. +func (c GitserverService_BlameServerSendMsgFuncCall) Args() []interface{} { + return []interface{}{c.Arg0} +} + +// Results returns an interface slice containing the results of this +// invocation. +func (c GitserverService_BlameServerSendMsgFuncCall) Results() []interface{} { + return []interface{}{c.Result0} +} + +// GitserverService_BlameServerSetHeaderFunc describes the behavior when the +// SetHeader method of the parent MockGitserverService_BlameServer instance +// is invoked. +type GitserverService_BlameServerSetHeaderFunc struct { + defaultHook func(metadata.MD) error + hooks []func(metadata.MD) error + history []GitserverService_BlameServerSetHeaderFuncCall + mutex sync.Mutex +} + +// SetHeader delegates to the next hook function in the queue and stores the +// parameter and result values of this invocation. +func (m *MockGitserverService_BlameServer) SetHeader(v0 metadata.MD) error { + r0 := m.SetHeaderFunc.nextHook()(v0) + m.SetHeaderFunc.appendCall(GitserverService_BlameServerSetHeaderFuncCall{v0, r0}) + return r0 +} + +// SetDefaultHook sets function that is called when the SetHeader method of +// the parent MockGitserverService_BlameServer instance is invoked and the +// hook queue is empty. +func (f *GitserverService_BlameServerSetHeaderFunc) SetDefaultHook(hook func(metadata.MD) error) { + f.defaultHook = hook +} + +// PushHook adds a function to the end of hook queue. Each invocation of the +// SetHeader method of the parent MockGitserverService_BlameServer instance +// invokes the hook at the front of the queue and discards it. After the +// queue is empty, the default hook function is invoked for any future +// action. +func (f *GitserverService_BlameServerSetHeaderFunc) PushHook(hook func(metadata.MD) error) { + f.mutex.Lock() + f.hooks = append(f.hooks, hook) + f.mutex.Unlock() +} + +// SetDefaultReturn calls SetDefaultHook with a function that returns the +// given values. +func (f *GitserverService_BlameServerSetHeaderFunc) SetDefaultReturn(r0 error) { + f.SetDefaultHook(func(metadata.MD) error { + return r0 + }) +} + +// PushReturn calls PushHook with a function that returns the given values. +func (f *GitserverService_BlameServerSetHeaderFunc) PushReturn(r0 error) { + f.PushHook(func(metadata.MD) error { + return r0 + }) +} + +func (f *GitserverService_BlameServerSetHeaderFunc) nextHook() func(metadata.MD) error { + f.mutex.Lock() + defer f.mutex.Unlock() + + if len(f.hooks) == 0 { + return f.defaultHook + } + + hook := f.hooks[0] + f.hooks = f.hooks[1:] + return hook +} + +func (f *GitserverService_BlameServerSetHeaderFunc) appendCall(r0 GitserverService_BlameServerSetHeaderFuncCall) { + f.mutex.Lock() + f.history = append(f.history, r0) + f.mutex.Unlock() +} + +// History returns a sequence of +// GitserverService_BlameServerSetHeaderFuncCall objects describing the +// invocations of this function. +func (f *GitserverService_BlameServerSetHeaderFunc) History() []GitserverService_BlameServerSetHeaderFuncCall { + f.mutex.Lock() + history := make([]GitserverService_BlameServerSetHeaderFuncCall, len(f.history)) + copy(history, f.history) + f.mutex.Unlock() + + return history +} + +// GitserverService_BlameServerSetHeaderFuncCall is an object that describes +// an invocation of method SetHeader on an instance of +// MockGitserverService_BlameServer. +type GitserverService_BlameServerSetHeaderFuncCall struct { + // Arg0 is the value of the 1st argument passed to this method + // invocation. + Arg0 metadata.MD + // Result0 is the value of the 1st result returned from this method + // invocation. + Result0 error +} + +// Args returns an interface slice containing the arguments of this +// invocation. +func (c GitserverService_BlameServerSetHeaderFuncCall) Args() []interface{} { + return []interface{}{c.Arg0} +} + +// Results returns an interface slice containing the results of this +// invocation. +func (c GitserverService_BlameServerSetHeaderFuncCall) Results() []interface{} { + return []interface{}{c.Result0} +} + +// GitserverService_BlameServerSetTrailerFunc describes the behavior when +// the SetTrailer method of the parent MockGitserverService_BlameServer +// instance is invoked. +type GitserverService_BlameServerSetTrailerFunc struct { + defaultHook func(metadata.MD) + hooks []func(metadata.MD) + history []GitserverService_BlameServerSetTrailerFuncCall + mutex sync.Mutex +} + +// SetTrailer delegates to the next hook function in the queue and stores +// the parameter and result values of this invocation. +func (m *MockGitserverService_BlameServer) SetTrailer(v0 metadata.MD) { + m.SetTrailerFunc.nextHook()(v0) + m.SetTrailerFunc.appendCall(GitserverService_BlameServerSetTrailerFuncCall{v0}) + return +} + +// SetDefaultHook sets function that is called when the SetTrailer method of +// the parent MockGitserverService_BlameServer instance is invoked and the +// hook queue is empty. +func (f *GitserverService_BlameServerSetTrailerFunc) SetDefaultHook(hook func(metadata.MD)) { + f.defaultHook = hook +} + +// PushHook adds a function to the end of hook queue. Each invocation of the +// SetTrailer method of the parent MockGitserverService_BlameServer instance +// invokes the hook at the front of the queue and discards it. After the +// queue is empty, the default hook function is invoked for any future +// action. +func (f *GitserverService_BlameServerSetTrailerFunc) PushHook(hook func(metadata.MD)) { + f.mutex.Lock() + f.hooks = append(f.hooks, hook) + f.mutex.Unlock() +} + +// SetDefaultReturn calls SetDefaultHook with a function that returns the +// given values. +func (f *GitserverService_BlameServerSetTrailerFunc) SetDefaultReturn() { + f.SetDefaultHook(func(metadata.MD) { + return + }) +} + +// PushReturn calls PushHook with a function that returns the given values. +func (f *GitserverService_BlameServerSetTrailerFunc) PushReturn() { + f.PushHook(func(metadata.MD) { + return + }) +} + +func (f *GitserverService_BlameServerSetTrailerFunc) nextHook() func(metadata.MD) { + f.mutex.Lock() + defer f.mutex.Unlock() + + if len(f.hooks) == 0 { + return f.defaultHook + } + + hook := f.hooks[0] + f.hooks = f.hooks[1:] + return hook +} + +func (f *GitserverService_BlameServerSetTrailerFunc) appendCall(r0 GitserverService_BlameServerSetTrailerFuncCall) { + f.mutex.Lock() + f.history = append(f.history, r0) + f.mutex.Unlock() +} + +// History returns a sequence of +// GitserverService_BlameServerSetTrailerFuncCall objects describing the +// invocations of this function. +func (f *GitserverService_BlameServerSetTrailerFunc) History() []GitserverService_BlameServerSetTrailerFuncCall { + f.mutex.Lock() + history := make([]GitserverService_BlameServerSetTrailerFuncCall, len(f.history)) + copy(history, f.history) + f.mutex.Unlock() + + return history +} + +// GitserverService_BlameServerSetTrailerFuncCall is an object that +// describes an invocation of method SetTrailer on an instance of +// MockGitserverService_BlameServer. +type GitserverService_BlameServerSetTrailerFuncCall struct { + // Arg0 is the value of the 1st argument passed to this method + // invocation. + Arg0 metadata.MD +} + +// Args returns an interface slice containing the arguments of this +// invocation. +func (c GitserverService_BlameServerSetTrailerFuncCall) Args() []interface{} { + return []interface{}{c.Arg0} +} + +// Results returns an interface slice containing the results of this +// invocation. +func (c GitserverService_BlameServerSetTrailerFuncCall) Results() []interface{} { + return []interface{}{} +} + // MockGitserverService_ExecServer is a mock implementation of the // GitserverService_ExecServer interface (from the package // github.com/sourcegraph/sourcegraph/internal/gitserver/v1) used for unit diff --git a/internal/gitserver/retry.go b/internal/gitserver/retry.go index a4a1185f215..c43cf84309c 100644 --- a/internal/gitserver/retry.go +++ b/internal/gitserver/retry.go @@ -146,4 +146,9 @@ func (r *automaticRetryClient) MergeBase(ctx context.Context, in *proto.MergeBas return r.base.MergeBase(ctx, in, opts...) } +func (r *automaticRetryClient) Blame(ctx context.Context, in *proto.BlameRequest, opts ...grpc.CallOption) (proto.GitserverService_BlameClient, error) { + opts = append(defaults.RetryPolicy, opts...) + return r.base.Blame(ctx, in, opts...) +} + var _ proto.GitserverServiceClient = &automaticRetryClient{} diff --git a/internal/gitserver/v1/gitserver.pb.go b/internal/gitserver/v1/gitserver.pb.go index 33fcaf06a3f..b2fa6284380 100644 --- a/internal/gitserver/v1/gitserver.pb.go +++ b/internal/gitserver/v1/gitserver.pb.go @@ -126,7 +126,7 @@ func (x GitObject_ObjectType) Number() protoreflect.EnumNumber { // Deprecated: Use GitObject_ObjectType.Descriptor instead. func (GitObject_ObjectType) EnumDescriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{49, 0} + return file_gitserver_proto_rawDescGZIP(), []int{54, 0} } // PerforceChangelistState is the valid state values of a Perforce changelist. @@ -184,7 +184,311 @@ func (x PerforceChangelist_PerforceChangelistState) Number() protoreflect.EnumNu // Deprecated: Use PerforceChangelist_PerforceChangelistState.Descriptor instead. func (PerforceChangelist_PerforceChangelistState) EnumDescriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{57, 0} + return file_gitserver_proto_rawDescGZIP(), []int{62, 0} +} + +type BlameRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // repo_name is the name of the repo to run the blame operation in. + // Note: We use field ID 2 here to reserve 1 for a future repo int32 field. + RepoName string `protobuf:"bytes,2,opt,name=repo_name,json=repoName,proto3" json:"repo_name,omitempty"` + // commit is the commit to start the blame operation in. If not given, the latest + // HEAD is used. + Commit *string `protobuf:"bytes,3,opt,name=commit,proto3,oneof" json:"commit,omitempty"` + Path string `protobuf:"bytes,4,opt,name=path,proto3" json:"path,omitempty"` + IgnoreWhitespace bool `protobuf:"varint,5,opt,name=ignore_whitespace,json=ignoreWhitespace,proto3" json:"ignore_whitespace,omitempty"` + StartLine *uint32 `protobuf:"varint,6,opt,name=start_line,json=startLine,proto3,oneof" json:"start_line,omitempty"` + EndLine *uint32 `protobuf:"varint,7,opt,name=end_line,json=endLine,proto3,oneof" json:"end_line,omitempty"` +} + +func (x *BlameRequest) Reset() { + *x = BlameRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_gitserver_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BlameRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BlameRequest) ProtoMessage() {} + +func (x *BlameRequest) ProtoReflect() protoreflect.Message { + mi := &file_gitserver_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BlameRequest.ProtoReflect.Descriptor instead. +func (*BlameRequest) Descriptor() ([]byte, []int) { + return file_gitserver_proto_rawDescGZIP(), []int{0} +} + +func (x *BlameRequest) GetRepoName() string { + if x != nil { + return x.RepoName + } + return "" +} + +func (x *BlameRequest) GetCommit() string { + if x != nil && x.Commit != nil { + return *x.Commit + } + return "" +} + +func (x *BlameRequest) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +func (x *BlameRequest) GetIgnoreWhitespace() bool { + if x != nil { + return x.IgnoreWhitespace + } + return false +} + +func (x *BlameRequest) GetStartLine() uint32 { + if x != nil && x.StartLine != nil { + return *x.StartLine + } + return 0 +} + +func (x *BlameRequest) GetEndLine() uint32 { + if x != nil && x.EndLine != nil { + return *x.EndLine + } + return 0 +} + +type BlameResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Hunk *BlameHunk `protobuf:"bytes,1,opt,name=hunk,proto3" json:"hunk,omitempty"` +} + +func (x *BlameResponse) Reset() { + *x = BlameResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_gitserver_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BlameResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BlameResponse) ProtoMessage() {} + +func (x *BlameResponse) ProtoReflect() protoreflect.Message { + mi := &file_gitserver_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BlameResponse.ProtoReflect.Descriptor instead. +func (*BlameResponse) Descriptor() ([]byte, []int) { + return file_gitserver_proto_rawDescGZIP(), []int{1} +} + +func (x *BlameResponse) GetHunk() *BlameHunk { + if x != nil { + return x.Hunk + } + return nil +} + +type BlameHunk struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + StartLine uint32 `protobuf:"varint,1,opt,name=start_line,json=startLine,proto3" json:"start_line,omitempty"` + EndLine uint32 `protobuf:"varint,2,opt,name=end_line,json=endLine,proto3" json:"end_line,omitempty"` + StartByte uint32 `protobuf:"varint,3,opt,name=start_byte,json=startByte,proto3" json:"start_byte,omitempty"` + EndByte uint32 `protobuf:"varint,4,opt,name=end_byte,json=endByte,proto3" json:"end_byte,omitempty"` + Commit string `protobuf:"bytes,5,opt,name=commit,proto3" json:"commit,omitempty"` + Author *BlameAuthor `protobuf:"bytes,6,opt,name=author,proto3" json:"author,omitempty"` + Message string `protobuf:"bytes,7,opt,name=message,proto3" json:"message,omitempty"` + Filename string `protobuf:"bytes,8,opt,name=filename,proto3" json:"filename,omitempty"` +} + +func (x *BlameHunk) Reset() { + *x = BlameHunk{} + if protoimpl.UnsafeEnabled { + mi := &file_gitserver_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BlameHunk) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BlameHunk) ProtoMessage() {} + +func (x *BlameHunk) ProtoReflect() protoreflect.Message { + mi := &file_gitserver_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BlameHunk.ProtoReflect.Descriptor instead. +func (*BlameHunk) Descriptor() ([]byte, []int) { + return file_gitserver_proto_rawDescGZIP(), []int{2} +} + +func (x *BlameHunk) GetStartLine() uint32 { + if x != nil { + return x.StartLine + } + return 0 +} + +func (x *BlameHunk) GetEndLine() uint32 { + if x != nil { + return x.EndLine + } + return 0 +} + +func (x *BlameHunk) GetStartByte() uint32 { + if x != nil { + return x.StartByte + } + return 0 +} + +func (x *BlameHunk) GetEndByte() uint32 { + if x != nil { + return x.EndByte + } + return 0 +} + +func (x *BlameHunk) GetCommit() string { + if x != nil { + return x.Commit + } + return "" +} + +func (x *BlameHunk) GetAuthor() *BlameAuthor { + if x != nil { + return x.Author + } + return nil +} + +func (x *BlameHunk) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +func (x *BlameHunk) GetFilename() string { + if x != nil { + return x.Filename + } + return "" +} + +type BlameAuthor struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Email string `protobuf:"bytes,2,opt,name=email,proto3" json:"email,omitempty"` + Date *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=date,proto3" json:"date,omitempty"` +} + +func (x *BlameAuthor) Reset() { + *x = BlameAuthor{} + if protoimpl.UnsafeEnabled { + mi := &file_gitserver_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BlameAuthor) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BlameAuthor) ProtoMessage() {} + +func (x *BlameAuthor) ProtoReflect() protoreflect.Message { + mi := &file_gitserver_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BlameAuthor.ProtoReflect.Descriptor instead. +func (*BlameAuthor) Descriptor() ([]byte, []int) { + return file_gitserver_proto_rawDescGZIP(), []int{3} +} + +func (x *BlameAuthor) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *BlameAuthor) GetEmail() string { + if x != nil { + return x.Email + } + return "" +} + +func (x *BlameAuthor) GetDate() *timestamppb.Timestamp { + if x != nil { + return x.Date + } + return nil } // DiskInfoRequest is a empty request for the DiskInfo RPC. @@ -197,7 +501,7 @@ type DiskInfoRequest struct { func (x *DiskInfoRequest) Reset() { *x = DiskInfoRequest{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[0] + mi := &file_gitserver_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -210,7 +514,7 @@ func (x *DiskInfoRequest) String() string { func (*DiskInfoRequest) ProtoMessage() {} func (x *DiskInfoRequest) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[0] + mi := &file_gitserver_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -223,7 +527,7 @@ func (x *DiskInfoRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DiskInfoRequest.ProtoReflect.Descriptor instead. func (*DiskInfoRequest) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{0} + return file_gitserver_proto_rawDescGZIP(), []int{4} } // DiskInfoResponse contains the results of the DiskInfo RPC request. @@ -243,7 +547,7 @@ type DiskInfoResponse struct { func (x *DiskInfoResponse) Reset() { *x = DiskInfoResponse{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[1] + mi := &file_gitserver_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -256,7 +560,7 @@ func (x *DiskInfoResponse) String() string { func (*DiskInfoResponse) ProtoMessage() {} func (x *DiskInfoResponse) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[1] + mi := &file_gitserver_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -269,7 +573,7 @@ func (x *DiskInfoResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DiskInfoResponse.ProtoReflect.Descriptor instead. func (*DiskInfoResponse) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{1} + return file_gitserver_proto_rawDescGZIP(), []int{5} } func (x *DiskInfoResponse) GetFreeSpace() uint64 { @@ -315,7 +619,7 @@ type BatchLogRequest struct { func (x *BatchLogRequest) Reset() { *x = BatchLogRequest{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[2] + mi := &file_gitserver_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -328,7 +632,7 @@ func (x *BatchLogRequest) String() string { func (*BatchLogRequest) ProtoMessage() {} func (x *BatchLogRequest) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[2] + mi := &file_gitserver_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -341,7 +645,7 @@ func (x *BatchLogRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use BatchLogRequest.ProtoReflect.Descriptor instead. func (*BatchLogRequest) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{2} + return file_gitserver_proto_rawDescGZIP(), []int{6} } // Deprecated: Marked as deprecated in gitserver.proto. @@ -376,7 +680,7 @@ type BatchLogResponse struct { func (x *BatchLogResponse) Reset() { *x = BatchLogResponse{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[3] + mi := &file_gitserver_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -389,7 +693,7 @@ func (x *BatchLogResponse) String() string { func (*BatchLogResponse) ProtoMessage() {} func (x *BatchLogResponse) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[3] + mi := &file_gitserver_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -402,7 +706,7 @@ func (x *BatchLogResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use BatchLogResponse.ProtoReflect.Descriptor instead. func (*BatchLogResponse) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{3} + return file_gitserver_proto_rawDescGZIP(), []int{7} } // Deprecated: Marked as deprecated in gitserver.proto. @@ -440,7 +744,7 @@ type BatchLogResult struct { func (x *BatchLogResult) Reset() { *x = BatchLogResult{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[4] + mi := &file_gitserver_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -453,7 +757,7 @@ func (x *BatchLogResult) String() string { func (*BatchLogResult) ProtoMessage() {} func (x *BatchLogResult) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[4] + mi := &file_gitserver_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -466,7 +770,7 @@ func (x *BatchLogResult) ProtoReflect() protoreflect.Message { // Deprecated: Use BatchLogResult.ProtoReflect.Descriptor instead. func (*BatchLogResult) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{4} + return file_gitserver_proto_rawDescGZIP(), []int{8} } // Deprecated: Marked as deprecated in gitserver.proto. @@ -508,7 +812,7 @@ type RepoCommit struct { func (x *RepoCommit) Reset() { *x = RepoCommit{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[5] + mi := &file_gitserver_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -521,7 +825,7 @@ func (x *RepoCommit) String() string { func (*RepoCommit) ProtoMessage() {} func (x *RepoCommit) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[5] + mi := &file_gitserver_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -534,7 +838,7 @@ func (x *RepoCommit) ProtoReflect() protoreflect.Message { // Deprecated: Use RepoCommit.ProtoReflect.Descriptor instead. func (*RepoCommit) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{5} + return file_gitserver_proto_rawDescGZIP(), []int{9} } // Deprecated: Marked as deprecated in gitserver.proto. @@ -575,7 +879,7 @@ type PatchCommitInfo struct { func (x *PatchCommitInfo) Reset() { *x = PatchCommitInfo{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[6] + mi := &file_gitserver_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -588,7 +892,7 @@ func (x *PatchCommitInfo) String() string { func (*PatchCommitInfo) ProtoMessage() {} func (x *PatchCommitInfo) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[6] + mi := &file_gitserver_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -601,7 +905,7 @@ func (x *PatchCommitInfo) ProtoReflect() protoreflect.Message { // Deprecated: Use PatchCommitInfo.ProtoReflect.Descriptor instead. func (*PatchCommitInfo) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{6} + return file_gitserver_proto_rawDescGZIP(), []int{10} } func (x *PatchCommitInfo) GetMessages() []string { @@ -667,7 +971,7 @@ type PushConfig struct { func (x *PushConfig) Reset() { *x = PushConfig{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[7] + mi := &file_gitserver_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -680,7 +984,7 @@ func (x *PushConfig) String() string { func (*PushConfig) ProtoMessage() {} func (x *PushConfig) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[7] + mi := &file_gitserver_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -693,7 +997,7 @@ func (x *PushConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use PushConfig.ProtoReflect.Descriptor instead. func (*PushConfig) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{7} + return file_gitserver_proto_rawDescGZIP(), []int{11} } func (x *PushConfig) GetRemoteUrl() string { @@ -734,7 +1038,7 @@ type CreateCommitFromPatchBinaryRequest struct { func (x *CreateCommitFromPatchBinaryRequest) Reset() { *x = CreateCommitFromPatchBinaryRequest{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[8] + mi := &file_gitserver_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -747,7 +1051,7 @@ func (x *CreateCommitFromPatchBinaryRequest) String() string { func (*CreateCommitFromPatchBinaryRequest) ProtoMessage() {} func (x *CreateCommitFromPatchBinaryRequest) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[8] + mi := &file_gitserver_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -760,7 +1064,7 @@ func (x *CreateCommitFromPatchBinaryRequest) ProtoReflect() protoreflect.Message // Deprecated: Use CreateCommitFromPatchBinaryRequest.ProtoReflect.Descriptor instead. func (*CreateCommitFromPatchBinaryRequest) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{8} + return file_gitserver_proto_rawDescGZIP(), []int{12} } func (m *CreateCommitFromPatchBinaryRequest) GetPayload() isCreateCommitFromPatchBinaryRequest_Payload { @@ -818,7 +1122,7 @@ type CreateCommitFromPatchError struct { func (x *CreateCommitFromPatchError) Reset() { *x = CreateCommitFromPatchError{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[9] + mi := &file_gitserver_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -831,7 +1135,7 @@ func (x *CreateCommitFromPatchError) String() string { func (*CreateCommitFromPatchError) ProtoMessage() {} func (x *CreateCommitFromPatchError) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[9] + mi := &file_gitserver_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -844,7 +1148,7 @@ func (x *CreateCommitFromPatchError) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateCommitFromPatchError.ProtoReflect.Descriptor instead. func (*CreateCommitFromPatchError) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{9} + return file_gitserver_proto_rawDescGZIP(), []int{13} } func (x *CreateCommitFromPatchError) GetRepositoryName() string { @@ -891,7 +1195,7 @@ type CreateCommitFromPatchBinaryResponse struct { func (x *CreateCommitFromPatchBinaryResponse) Reset() { *x = CreateCommitFromPatchBinaryResponse{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[10] + mi := &file_gitserver_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -904,7 +1208,7 @@ func (x *CreateCommitFromPatchBinaryResponse) String() string { func (*CreateCommitFromPatchBinaryResponse) ProtoMessage() {} func (x *CreateCommitFromPatchBinaryResponse) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[10] + mi := &file_gitserver_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -917,7 +1221,7 @@ func (x *CreateCommitFromPatchBinaryResponse) ProtoReflect() protoreflect.Messag // Deprecated: Use CreateCommitFromPatchBinaryResponse.ProtoReflect.Descriptor instead. func (*CreateCommitFromPatchBinaryResponse) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{10} + return file_gitserver_proto_rawDescGZIP(), []int{14} } func (x *CreateCommitFromPatchBinaryResponse) GetRev() string { @@ -950,7 +1254,7 @@ type ExecRequest struct { func (x *ExecRequest) Reset() { *x = ExecRequest{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[11] + mi := &file_gitserver_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -963,7 +1267,7 @@ func (x *ExecRequest) String() string { func (*ExecRequest) ProtoMessage() {} func (x *ExecRequest) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[11] + mi := &file_gitserver_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -976,7 +1280,7 @@ func (x *ExecRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecRequest.ProtoReflect.Descriptor instead. func (*ExecRequest) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{11} + return file_gitserver_proto_rawDescGZIP(), []int{15} } func (x *ExecRequest) GetRepo() string { @@ -1026,7 +1330,7 @@ type ExecResponse struct { func (x *ExecResponse) Reset() { *x = ExecResponse{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[12] + mi := &file_gitserver_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1039,7 +1343,7 @@ func (x *ExecResponse) String() string { func (*ExecResponse) ProtoMessage() {} func (x *ExecResponse) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[12] + mi := &file_gitserver_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1052,7 +1356,7 @@ func (x *ExecResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecResponse.ProtoReflect.Descriptor instead. func (*ExecResponse) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{12} + return file_gitserver_proto_rawDescGZIP(), []int{16} } func (x *ExecResponse) GetData() []byte { @@ -1075,7 +1379,7 @@ type NotFoundPayload struct { func (x *NotFoundPayload) Reset() { *x = NotFoundPayload{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[13] + mi := &file_gitserver_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1088,7 +1392,7 @@ func (x *NotFoundPayload) String() string { func (*NotFoundPayload) ProtoMessage() {} func (x *NotFoundPayload) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[13] + mi := &file_gitserver_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1101,7 +1405,7 @@ func (x *NotFoundPayload) ProtoReflect() protoreflect.Message { // Deprecated: Use NotFoundPayload.ProtoReflect.Descriptor instead. func (*NotFoundPayload) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{13} + return file_gitserver_proto_rawDescGZIP(), []int{17} } func (x *NotFoundPayload) GetRepo() string { @@ -1137,7 +1441,7 @@ type ExecStatusPayload struct { func (x *ExecStatusPayload) Reset() { *x = ExecStatusPayload{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[14] + mi := &file_gitserver_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1150,7 +1454,7 @@ func (x *ExecStatusPayload) String() string { func (*ExecStatusPayload) ProtoMessage() {} func (x *ExecStatusPayload) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[14] + mi := &file_gitserver_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1163,7 +1467,7 @@ func (x *ExecStatusPayload) ProtoReflect() protoreflect.Message { // Deprecated: Use ExecStatusPayload.ProtoReflect.Descriptor instead. func (*ExecStatusPayload) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{14} + return file_gitserver_proto_rawDescGZIP(), []int{18} } func (x *ExecStatusPayload) GetStatusCode() int32 { @@ -1180,6 +1484,72 @@ func (x *ExecStatusPayload) GetStderr() string { return "" } +// UnauthorizedPayload is the payload returned when an actor cannot access +// a commit or file due to subrepo permissions. +type UnauthorizedPayload struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Note: We use field ID 2 here to reserve 1 for a future repo int32 field. + RepoName string `protobuf:"bytes,2,opt,name=repo_name,json=repoName,proto3" json:"repo_name,omitempty"` + Path *string `protobuf:"bytes,3,opt,name=path,proto3,oneof" json:"path,omitempty"` + Commit *string `protobuf:"bytes,4,opt,name=commit,proto3,oneof" json:"commit,omitempty"` +} + +func (x *UnauthorizedPayload) Reset() { + *x = UnauthorizedPayload{} + if protoimpl.UnsafeEnabled { + mi := &file_gitserver_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UnauthorizedPayload) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UnauthorizedPayload) ProtoMessage() {} + +func (x *UnauthorizedPayload) ProtoReflect() protoreflect.Message { + mi := &file_gitserver_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UnauthorizedPayload.ProtoReflect.Descriptor instead. +func (*UnauthorizedPayload) Descriptor() ([]byte, []int) { + return file_gitserver_proto_rawDescGZIP(), []int{19} +} + +func (x *UnauthorizedPayload) GetRepoName() string { + if x != nil { + return x.RepoName + } + return "" +} + +func (x *UnauthorizedPayload) GetPath() string { + if x != nil && x.Path != nil { + return *x.Path + } + return "" +} + +func (x *UnauthorizedPayload) GetCommit() string { + if x != nil && x.Commit != nil { + return *x.Commit + } + return "" +} + type SearchRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1207,7 +1577,7 @@ type SearchRequest struct { func (x *SearchRequest) Reset() { *x = SearchRequest{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[15] + mi := &file_gitserver_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1220,7 +1590,7 @@ func (x *SearchRequest) String() string { func (*SearchRequest) ProtoMessage() {} func (x *SearchRequest) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[15] + mi := &file_gitserver_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1233,7 +1603,7 @@ func (x *SearchRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SearchRequest.ProtoReflect.Descriptor instead. func (*SearchRequest) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{15} + return file_gitserver_proto_rawDescGZIP(), []int{20} } func (x *SearchRequest) GetRepo() string { @@ -1291,7 +1661,7 @@ type RevisionSpecifier struct { func (x *RevisionSpecifier) Reset() { *x = RevisionSpecifier{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[16] + mi := &file_gitserver_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1304,7 +1674,7 @@ func (x *RevisionSpecifier) String() string { func (*RevisionSpecifier) ProtoMessage() {} func (x *RevisionSpecifier) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[16] + mi := &file_gitserver_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1317,7 +1687,7 @@ func (x *RevisionSpecifier) ProtoReflect() protoreflect.Message { // Deprecated: Use RevisionSpecifier.ProtoReflect.Descriptor instead. func (*RevisionSpecifier) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{16} + return file_gitserver_proto_rawDescGZIP(), []int{21} } func (x *RevisionSpecifier) GetRevSpec() string { @@ -1341,7 +1711,7 @@ type AuthorMatchesNode struct { func (x *AuthorMatchesNode) Reset() { *x = AuthorMatchesNode{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[17] + mi := &file_gitserver_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1354,7 +1724,7 @@ func (x *AuthorMatchesNode) String() string { func (*AuthorMatchesNode) ProtoMessage() {} func (x *AuthorMatchesNode) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[17] + mi := &file_gitserver_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1367,7 +1737,7 @@ func (x *AuthorMatchesNode) ProtoReflect() protoreflect.Message { // Deprecated: Use AuthorMatchesNode.ProtoReflect.Descriptor instead. func (*AuthorMatchesNode) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{17} + return file_gitserver_proto_rawDescGZIP(), []int{22} } func (x *AuthorMatchesNode) GetExpr() string { @@ -1398,7 +1768,7 @@ type CommitterMatchesNode struct { func (x *CommitterMatchesNode) Reset() { *x = CommitterMatchesNode{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[18] + mi := &file_gitserver_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1411,7 +1781,7 @@ func (x *CommitterMatchesNode) String() string { func (*CommitterMatchesNode) ProtoMessage() {} func (x *CommitterMatchesNode) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[18] + mi := &file_gitserver_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1424,7 +1794,7 @@ func (x *CommitterMatchesNode) ProtoReflect() protoreflect.Message { // Deprecated: Use CommitterMatchesNode.ProtoReflect.Descriptor instead. func (*CommitterMatchesNode) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{18} + return file_gitserver_proto_rawDescGZIP(), []int{23} } func (x *CommitterMatchesNode) GetExpr() string { @@ -1454,7 +1824,7 @@ type CommitBeforeNode struct { func (x *CommitBeforeNode) Reset() { *x = CommitBeforeNode{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[19] + mi := &file_gitserver_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1467,7 +1837,7 @@ func (x *CommitBeforeNode) String() string { func (*CommitBeforeNode) ProtoMessage() {} func (x *CommitBeforeNode) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[19] + mi := &file_gitserver_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1480,7 +1850,7 @@ func (x *CommitBeforeNode) ProtoReflect() protoreflect.Message { // Deprecated: Use CommitBeforeNode.ProtoReflect.Descriptor instead. func (*CommitBeforeNode) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{19} + return file_gitserver_proto_rawDescGZIP(), []int{24} } func (x *CommitBeforeNode) GetTimestamp() *timestamppb.Timestamp { @@ -1503,7 +1873,7 @@ type CommitAfterNode struct { func (x *CommitAfterNode) Reset() { *x = CommitAfterNode{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[20] + mi := &file_gitserver_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1516,7 +1886,7 @@ func (x *CommitAfterNode) String() string { func (*CommitAfterNode) ProtoMessage() {} func (x *CommitAfterNode) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[20] + mi := &file_gitserver_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1529,7 +1899,7 @@ func (x *CommitAfterNode) ProtoReflect() protoreflect.Message { // Deprecated: Use CommitAfterNode.ProtoReflect.Descriptor instead. func (*CommitAfterNode) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{20} + return file_gitserver_proto_rawDescGZIP(), []int{25} } func (x *CommitAfterNode) GetTimestamp() *timestamppb.Timestamp { @@ -1553,7 +1923,7 @@ type MessageMatchesNode struct { func (x *MessageMatchesNode) Reset() { *x = MessageMatchesNode{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[21] + mi := &file_gitserver_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1566,7 +1936,7 @@ func (x *MessageMatchesNode) String() string { func (*MessageMatchesNode) ProtoMessage() {} func (x *MessageMatchesNode) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[21] + mi := &file_gitserver_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1579,7 +1949,7 @@ func (x *MessageMatchesNode) ProtoReflect() protoreflect.Message { // Deprecated: Use MessageMatchesNode.ProtoReflect.Descriptor instead. func (*MessageMatchesNode) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{21} + return file_gitserver_proto_rawDescGZIP(), []int{26} } func (x *MessageMatchesNode) GetExpr() string { @@ -1610,7 +1980,7 @@ type DiffMatchesNode struct { func (x *DiffMatchesNode) Reset() { *x = DiffMatchesNode{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[22] + mi := &file_gitserver_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1623,7 +1993,7 @@ func (x *DiffMatchesNode) String() string { func (*DiffMatchesNode) ProtoMessage() {} func (x *DiffMatchesNode) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[22] + mi := &file_gitserver_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1636,7 +2006,7 @@ func (x *DiffMatchesNode) ProtoReflect() protoreflect.Message { // Deprecated: Use DiffMatchesNode.ProtoReflect.Descriptor instead. func (*DiffMatchesNode) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{22} + return file_gitserver_proto_rawDescGZIP(), []int{27} } func (x *DiffMatchesNode) GetExpr() string { @@ -1667,7 +2037,7 @@ type DiffModifiesFileNode struct { func (x *DiffModifiesFileNode) Reset() { *x = DiffModifiesFileNode{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[23] + mi := &file_gitserver_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1680,7 +2050,7 @@ func (x *DiffModifiesFileNode) String() string { func (*DiffModifiesFileNode) ProtoMessage() {} func (x *DiffModifiesFileNode) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[23] + mi := &file_gitserver_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1693,7 +2063,7 @@ func (x *DiffModifiesFileNode) ProtoReflect() protoreflect.Message { // Deprecated: Use DiffModifiesFileNode.ProtoReflect.Descriptor instead. func (*DiffModifiesFileNode) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{23} + return file_gitserver_proto_rawDescGZIP(), []int{28} } func (x *DiffModifiesFileNode) GetExpr() string { @@ -1722,7 +2092,7 @@ type BooleanNode struct { func (x *BooleanNode) Reset() { *x = BooleanNode{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[24] + mi := &file_gitserver_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1735,7 +2105,7 @@ func (x *BooleanNode) String() string { func (*BooleanNode) ProtoMessage() {} func (x *BooleanNode) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[24] + mi := &file_gitserver_proto_msgTypes[29] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1748,7 +2118,7 @@ func (x *BooleanNode) ProtoReflect() protoreflect.Message { // Deprecated: Use BooleanNode.ProtoReflect.Descriptor instead. func (*BooleanNode) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{24} + return file_gitserver_proto_rawDescGZIP(), []int{29} } func (x *BooleanNode) GetValue() bool { @@ -1770,7 +2140,7 @@ type OperatorNode struct { func (x *OperatorNode) Reset() { *x = OperatorNode{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[25] + mi := &file_gitserver_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1783,7 +2153,7 @@ func (x *OperatorNode) String() string { func (*OperatorNode) ProtoMessage() {} func (x *OperatorNode) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[25] + mi := &file_gitserver_proto_msgTypes[30] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1796,7 +2166,7 @@ func (x *OperatorNode) ProtoReflect() protoreflect.Message { // Deprecated: Use OperatorNode.ProtoReflect.Descriptor instead. func (*OperatorNode) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{25} + return file_gitserver_proto_rawDescGZIP(), []int{30} } func (x *OperatorNode) GetKind() OperatorKind { @@ -1835,7 +2205,7 @@ type QueryNode struct { func (x *QueryNode) Reset() { *x = QueryNode{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[26] + mi := &file_gitserver_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1848,7 +2218,7 @@ func (x *QueryNode) String() string { func (*QueryNode) ProtoMessage() {} func (x *QueryNode) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[26] + mi := &file_gitserver_proto_msgTypes[31] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1861,7 +2231,7 @@ func (x *QueryNode) ProtoReflect() protoreflect.Message { // Deprecated: Use QueryNode.ProtoReflect.Descriptor instead. func (*QueryNode) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{26} + return file_gitserver_proto_rawDescGZIP(), []int{31} } func (m *QueryNode) GetValue() isQueryNode_Value { @@ -2007,7 +2377,7 @@ type SearchResponse struct { func (x *SearchResponse) Reset() { *x = SearchResponse{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[27] + mi := &file_gitserver_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2020,7 +2390,7 @@ func (x *SearchResponse) String() string { func (*SearchResponse) ProtoMessage() {} func (x *SearchResponse) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[27] + mi := &file_gitserver_proto_msgTypes[32] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2033,7 +2403,7 @@ func (x *SearchResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SearchResponse.ProtoReflect.Descriptor instead. func (*SearchResponse) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{27} + return file_gitserver_proto_rawDescGZIP(), []int{32} } func (m *SearchResponse) GetMessage() isSearchResponse_Message { @@ -2101,7 +2471,7 @@ type CommitMatch struct { func (x *CommitMatch) Reset() { *x = CommitMatch{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[28] + mi := &file_gitserver_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2114,7 +2484,7 @@ func (x *CommitMatch) String() string { func (*CommitMatch) ProtoMessage() {} func (x *CommitMatch) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[28] + mi := &file_gitserver_proto_msgTypes[33] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2127,7 +2497,7 @@ func (x *CommitMatch) ProtoReflect() protoreflect.Message { // Deprecated: Use CommitMatch.ProtoReflect.Descriptor instead. func (*CommitMatch) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{28} + return file_gitserver_proto_rawDescGZIP(), []int{33} } func (x *CommitMatch) GetOid() string { @@ -2213,7 +2583,7 @@ type ArchiveRequest struct { func (x *ArchiveRequest) Reset() { *x = ArchiveRequest{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[29] + mi := &file_gitserver_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2226,7 +2596,7 @@ func (x *ArchiveRequest) String() string { func (*ArchiveRequest) ProtoMessage() {} func (x *ArchiveRequest) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[29] + mi := &file_gitserver_proto_msgTypes[34] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2239,7 +2609,7 @@ func (x *ArchiveRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ArchiveRequest.ProtoReflect.Descriptor instead. func (*ArchiveRequest) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{29} + return file_gitserver_proto_rawDescGZIP(), []int{34} } func (x *ArchiveRequest) GetRepo() string { @@ -2283,7 +2653,7 @@ type ArchiveResponse struct { func (x *ArchiveResponse) Reset() { *x = ArchiveResponse{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[30] + mi := &file_gitserver_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2296,7 +2666,7 @@ func (x *ArchiveResponse) String() string { func (*ArchiveResponse) ProtoMessage() {} func (x *ArchiveResponse) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[30] + mi := &file_gitserver_proto_msgTypes[35] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2309,7 +2679,7 @@ func (x *ArchiveResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ArchiveResponse.ProtoReflect.Descriptor instead. func (*ArchiveResponse) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{30} + return file_gitserver_proto_rawDescGZIP(), []int{35} } func (x *ArchiveResponse) GetData() []byte { @@ -2332,7 +2702,7 @@ type IsRepoCloneableRequest struct { func (x *IsRepoCloneableRequest) Reset() { *x = IsRepoCloneableRequest{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[31] + mi := &file_gitserver_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2345,7 +2715,7 @@ func (x *IsRepoCloneableRequest) String() string { func (*IsRepoCloneableRequest) ProtoMessage() {} func (x *IsRepoCloneableRequest) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[31] + mi := &file_gitserver_proto_msgTypes[36] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2358,7 +2728,7 @@ func (x *IsRepoCloneableRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use IsRepoCloneableRequest.ProtoReflect.Descriptor instead. func (*IsRepoCloneableRequest) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{31} + return file_gitserver_proto_rawDescGZIP(), []int{36} } func (x *IsRepoCloneableRequest) GetRepo() string { @@ -2385,7 +2755,7 @@ type IsRepoCloneableResponse struct { func (x *IsRepoCloneableResponse) Reset() { *x = IsRepoCloneableResponse{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[32] + mi := &file_gitserver_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2398,7 +2768,7 @@ func (x *IsRepoCloneableResponse) String() string { func (*IsRepoCloneableResponse) ProtoMessage() {} func (x *IsRepoCloneableResponse) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[32] + mi := &file_gitserver_proto_msgTypes[37] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2411,7 +2781,7 @@ func (x *IsRepoCloneableResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use IsRepoCloneableResponse.ProtoReflect.Descriptor instead. func (*IsRepoCloneableResponse) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{32} + return file_gitserver_proto_rawDescGZIP(), []int{37} } func (x *IsRepoCloneableResponse) GetCloneable() bool { @@ -2448,7 +2818,7 @@ type RepoCloneRequest struct { func (x *RepoCloneRequest) Reset() { *x = RepoCloneRequest{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[33] + mi := &file_gitserver_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2461,7 +2831,7 @@ func (x *RepoCloneRequest) String() string { func (*RepoCloneRequest) ProtoMessage() {} func (x *RepoCloneRequest) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[33] + mi := &file_gitserver_proto_msgTypes[38] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2474,7 +2844,7 @@ func (x *RepoCloneRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RepoCloneRequest.ProtoReflect.Descriptor instead. func (*RepoCloneRequest) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{33} + return file_gitserver_proto_rawDescGZIP(), []int{38} } func (x *RepoCloneRequest) GetRepo() string { @@ -2496,7 +2866,7 @@ type RepoCloneResponse struct { func (x *RepoCloneResponse) Reset() { *x = RepoCloneResponse{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[34] + mi := &file_gitserver_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2509,7 +2879,7 @@ func (x *RepoCloneResponse) String() string { func (*RepoCloneResponse) ProtoMessage() {} func (x *RepoCloneResponse) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[34] + mi := &file_gitserver_proto_msgTypes[39] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2522,7 +2892,7 @@ func (x *RepoCloneResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RepoCloneResponse.ProtoReflect.Descriptor instead. func (*RepoCloneResponse) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{34} + return file_gitserver_proto_rawDescGZIP(), []int{39} } func (x *RepoCloneResponse) GetError() string { @@ -2545,7 +2915,7 @@ type RepoCloneProgressRequest struct { func (x *RepoCloneProgressRequest) Reset() { *x = RepoCloneProgressRequest{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[35] + mi := &file_gitserver_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2558,7 +2928,7 @@ func (x *RepoCloneProgressRequest) String() string { func (*RepoCloneProgressRequest) ProtoMessage() {} func (x *RepoCloneProgressRequest) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[35] + mi := &file_gitserver_proto_msgTypes[40] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2571,7 +2941,7 @@ func (x *RepoCloneProgressRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RepoCloneProgressRequest.ProtoReflect.Descriptor instead. func (*RepoCloneProgressRequest) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{35} + return file_gitserver_proto_rawDescGZIP(), []int{40} } func (x *RepoCloneProgressRequest) GetRepos() []string { @@ -2598,7 +2968,7 @@ type RepoCloneProgress struct { func (x *RepoCloneProgress) Reset() { *x = RepoCloneProgress{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[36] + mi := &file_gitserver_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2611,7 +2981,7 @@ func (x *RepoCloneProgress) String() string { func (*RepoCloneProgress) ProtoMessage() {} func (x *RepoCloneProgress) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[36] + mi := &file_gitserver_proto_msgTypes[41] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2624,7 +2994,7 @@ func (x *RepoCloneProgress) ProtoReflect() protoreflect.Message { // Deprecated: Use RepoCloneProgress.ProtoReflect.Descriptor instead. func (*RepoCloneProgress) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{36} + return file_gitserver_proto_rawDescGZIP(), []int{41} } func (x *RepoCloneProgress) GetCloneInProgress() bool { @@ -2662,7 +3032,7 @@ type RepoCloneProgressResponse struct { func (x *RepoCloneProgressResponse) Reset() { *x = RepoCloneProgressResponse{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[37] + mi := &file_gitserver_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2675,7 +3045,7 @@ func (x *RepoCloneProgressResponse) String() string { func (*RepoCloneProgressResponse) ProtoMessage() {} func (x *RepoCloneProgressResponse) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[37] + mi := &file_gitserver_proto_msgTypes[42] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2688,7 +3058,7 @@ func (x *RepoCloneProgressResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RepoCloneProgressResponse.ProtoReflect.Descriptor instead. func (*RepoCloneProgressResponse) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{37} + return file_gitserver_proto_rawDescGZIP(), []int{42} } func (x *RepoCloneProgressResponse) GetResults() map[string]*RepoCloneProgress { @@ -2711,7 +3081,7 @@ type RepoDeleteRequest struct { func (x *RepoDeleteRequest) Reset() { *x = RepoDeleteRequest{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[38] + mi := &file_gitserver_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2724,7 +3094,7 @@ func (x *RepoDeleteRequest) String() string { func (*RepoDeleteRequest) ProtoMessage() {} func (x *RepoDeleteRequest) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[38] + mi := &file_gitserver_proto_msgTypes[43] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2737,7 +3107,7 @@ func (x *RepoDeleteRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RepoDeleteRequest.ProtoReflect.Descriptor instead. func (*RepoDeleteRequest) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{38} + return file_gitserver_proto_rawDescGZIP(), []int{43} } func (x *RepoDeleteRequest) GetRepo() string { @@ -2757,7 +3127,7 @@ type RepoDeleteResponse struct { func (x *RepoDeleteResponse) Reset() { *x = RepoDeleteResponse{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[39] + mi := &file_gitserver_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2770,7 +3140,7 @@ func (x *RepoDeleteResponse) String() string { func (*RepoDeleteResponse) ProtoMessage() {} func (x *RepoDeleteResponse) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[39] + mi := &file_gitserver_proto_msgTypes[44] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2783,7 +3153,7 @@ func (x *RepoDeleteResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RepoDeleteResponse.ProtoReflect.Descriptor instead. func (*RepoDeleteResponse) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{39} + return file_gitserver_proto_rawDescGZIP(), []int{44} } // RepoUpdateRequest is a request to update a repository. @@ -2802,7 +3172,7 @@ type RepoUpdateRequest struct { func (x *RepoUpdateRequest) Reset() { *x = RepoUpdateRequest{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[40] + mi := &file_gitserver_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2815,7 +3185,7 @@ func (x *RepoUpdateRequest) String() string { func (*RepoUpdateRequest) ProtoMessage() {} func (x *RepoUpdateRequest) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[40] + mi := &file_gitserver_proto_msgTypes[45] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2828,7 +3198,7 @@ func (x *RepoUpdateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RepoUpdateRequest.ProtoReflect.Descriptor instead. func (*RepoUpdateRequest) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{40} + return file_gitserver_proto_rawDescGZIP(), []int{45} } func (x *RepoUpdateRequest) GetRepo() string { @@ -2862,7 +3232,7 @@ type RepoUpdateResponse struct { func (x *RepoUpdateResponse) Reset() { *x = RepoUpdateResponse{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[41] + mi := &file_gitserver_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2875,7 +3245,7 @@ func (x *RepoUpdateResponse) String() string { func (*RepoUpdateResponse) ProtoMessage() {} func (x *RepoUpdateResponse) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[41] + mi := &file_gitserver_proto_msgTypes[46] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2888,7 +3258,7 @@ func (x *RepoUpdateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RepoUpdateResponse.ProtoReflect.Descriptor instead. func (*RepoUpdateResponse) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{41} + return file_gitserver_proto_rawDescGZIP(), []int{46} } func (x *RepoUpdateResponse) GetLastFetched() *timestamppb.Timestamp { @@ -2931,7 +3301,7 @@ type P4ExecRequest struct { func (x *P4ExecRequest) Reset() { *x = P4ExecRequest{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[42] + mi := &file_gitserver_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2944,7 +3314,7 @@ func (x *P4ExecRequest) String() string { func (*P4ExecRequest) ProtoMessage() {} func (x *P4ExecRequest) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[42] + mi := &file_gitserver_proto_msgTypes[47] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2957,7 +3327,7 @@ func (x *P4ExecRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use P4ExecRequest.ProtoReflect.Descriptor instead. func (*P4ExecRequest) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{42} + return file_gitserver_proto_rawDescGZIP(), []int{47} } // Deprecated: Marked as deprecated in gitserver.proto. @@ -3005,7 +3375,7 @@ type P4ExecResponse struct { func (x *P4ExecResponse) Reset() { *x = P4ExecResponse{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[43] + mi := &file_gitserver_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3018,7 +3388,7 @@ func (x *P4ExecResponse) String() string { func (*P4ExecResponse) ProtoMessage() {} func (x *P4ExecResponse) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[43] + mi := &file_gitserver_proto_msgTypes[48] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3031,7 +3401,7 @@ func (x *P4ExecResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use P4ExecResponse.ProtoReflect.Descriptor instead. func (*P4ExecResponse) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{43} + return file_gitserver_proto_rawDescGZIP(), []int{48} } // Deprecated: Marked as deprecated in gitserver.proto. @@ -3055,7 +3425,7 @@ type ListGitoliteRequest struct { func (x *ListGitoliteRequest) Reset() { *x = ListGitoliteRequest{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[44] + mi := &file_gitserver_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3068,7 +3438,7 @@ func (x *ListGitoliteRequest) String() string { func (*ListGitoliteRequest) ProtoMessage() {} func (x *ListGitoliteRequest) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[44] + mi := &file_gitserver_proto_msgTypes[49] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3081,7 +3451,7 @@ func (x *ListGitoliteRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListGitoliteRequest.ProtoReflect.Descriptor instead. func (*ListGitoliteRequest) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{44} + return file_gitserver_proto_rawDescGZIP(), []int{49} } func (x *ListGitoliteRequest) GetGitoliteHost() string { @@ -3106,7 +3476,7 @@ type GitoliteRepo struct { func (x *GitoliteRepo) Reset() { *x = GitoliteRepo{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[45] + mi := &file_gitserver_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3119,7 +3489,7 @@ func (x *GitoliteRepo) String() string { func (*GitoliteRepo) ProtoMessage() {} func (x *GitoliteRepo) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[45] + mi := &file_gitserver_proto_msgTypes[50] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3132,7 +3502,7 @@ func (x *GitoliteRepo) ProtoReflect() protoreflect.Message { // Deprecated: Use GitoliteRepo.ProtoReflect.Descriptor instead. func (*GitoliteRepo) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{45} + return file_gitserver_proto_rawDescGZIP(), []int{50} } func (x *GitoliteRepo) GetName() string { @@ -3162,7 +3532,7 @@ type ListGitoliteResponse struct { func (x *ListGitoliteResponse) Reset() { *x = ListGitoliteResponse{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[46] + mi := &file_gitserver_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3175,7 +3545,7 @@ func (x *ListGitoliteResponse) String() string { func (*ListGitoliteResponse) ProtoMessage() {} func (x *ListGitoliteResponse) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[46] + mi := &file_gitserver_proto_msgTypes[51] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3188,7 +3558,7 @@ func (x *ListGitoliteResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListGitoliteResponse.ProtoReflect.Descriptor instead. func (*ListGitoliteResponse) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{46} + return file_gitserver_proto_rawDescGZIP(), []int{51} } func (x *ListGitoliteResponse) GetRepos() []*GitoliteRepo { @@ -3213,7 +3583,7 @@ type GetObjectRequest struct { func (x *GetObjectRequest) Reset() { *x = GetObjectRequest{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[47] + mi := &file_gitserver_proto_msgTypes[52] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3226,7 +3596,7 @@ func (x *GetObjectRequest) String() string { func (*GetObjectRequest) ProtoMessage() {} func (x *GetObjectRequest) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[47] + mi := &file_gitserver_proto_msgTypes[52] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3239,7 +3609,7 @@ func (x *GetObjectRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetObjectRequest.ProtoReflect.Descriptor instead. func (*GetObjectRequest) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{47} + return file_gitserver_proto_rawDescGZIP(), []int{52} } func (x *GetObjectRequest) GetRepo() string { @@ -3269,7 +3639,7 @@ type GetObjectResponse struct { func (x *GetObjectResponse) Reset() { *x = GetObjectResponse{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[48] + mi := &file_gitserver_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3282,7 +3652,7 @@ func (x *GetObjectResponse) String() string { func (*GetObjectResponse) ProtoMessage() {} func (x *GetObjectResponse) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[48] + mi := &file_gitserver_proto_msgTypes[53] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3295,7 +3665,7 @@ func (x *GetObjectResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetObjectResponse.ProtoReflect.Descriptor instead. func (*GetObjectResponse) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{48} + return file_gitserver_proto_rawDescGZIP(), []int{53} } func (x *GetObjectResponse) GetObject() *GitObject { @@ -3320,7 +3690,7 @@ type GitObject struct { func (x *GitObject) Reset() { *x = GitObject{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[49] + mi := &file_gitserver_proto_msgTypes[54] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3333,7 +3703,7 @@ func (x *GitObject) String() string { func (*GitObject) ProtoMessage() {} func (x *GitObject) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[49] + mi := &file_gitserver_proto_msgTypes[54] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3346,7 +3716,7 @@ func (x *GitObject) ProtoReflect() protoreflect.Message { // Deprecated: Use GitObject.ProtoReflect.Descriptor instead. func (*GitObject) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{49} + return file_gitserver_proto_rawDescGZIP(), []int{54} } func (x *GitObject) GetId() []byte { @@ -3376,7 +3746,7 @@ type IsPerforcePathCloneableRequest struct { func (x *IsPerforcePathCloneableRequest) Reset() { *x = IsPerforcePathCloneableRequest{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[50] + mi := &file_gitserver_proto_msgTypes[55] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3389,7 +3759,7 @@ func (x *IsPerforcePathCloneableRequest) String() string { func (*IsPerforcePathCloneableRequest) ProtoMessage() {} func (x *IsPerforcePathCloneableRequest) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[50] + mi := &file_gitserver_proto_msgTypes[55] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3402,7 +3772,7 @@ func (x *IsPerforcePathCloneableRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use IsPerforcePathCloneableRequest.ProtoReflect.Descriptor instead. func (*IsPerforcePathCloneableRequest) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{50} + return file_gitserver_proto_rawDescGZIP(), []int{55} } func (x *IsPerforcePathCloneableRequest) GetConnectionDetails() *PerforceConnectionDetails { @@ -3429,7 +3799,7 @@ type IsPerforcePathCloneableResponse struct { func (x *IsPerforcePathCloneableResponse) Reset() { *x = IsPerforcePathCloneableResponse{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[51] + mi := &file_gitserver_proto_msgTypes[56] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3442,7 +3812,7 @@ func (x *IsPerforcePathCloneableResponse) String() string { func (*IsPerforcePathCloneableResponse) ProtoMessage() {} func (x *IsPerforcePathCloneableResponse) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[51] + mi := &file_gitserver_proto_msgTypes[56] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3455,7 +3825,7 @@ func (x *IsPerforcePathCloneableResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use IsPerforcePathCloneableResponse.ProtoReflect.Descriptor instead. func (*IsPerforcePathCloneableResponse) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{51} + return file_gitserver_proto_rawDescGZIP(), []int{56} } // CheckPerforceCredentialsRequest is the request to check if given Perforce credentials are valid. @@ -3470,7 +3840,7 @@ type CheckPerforceCredentialsRequest struct { func (x *CheckPerforceCredentialsRequest) Reset() { *x = CheckPerforceCredentialsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[52] + mi := &file_gitserver_proto_msgTypes[57] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3483,7 +3853,7 @@ func (x *CheckPerforceCredentialsRequest) String() string { func (*CheckPerforceCredentialsRequest) ProtoMessage() {} func (x *CheckPerforceCredentialsRequest) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[52] + mi := &file_gitserver_proto_msgTypes[57] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3496,7 +3866,7 @@ func (x *CheckPerforceCredentialsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CheckPerforceCredentialsRequest.ProtoReflect.Descriptor instead. func (*CheckPerforceCredentialsRequest) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{52} + return file_gitserver_proto_rawDescGZIP(), []int{57} } func (x *CheckPerforceCredentialsRequest) GetConnectionDetails() *PerforceConnectionDetails { @@ -3516,7 +3886,7 @@ type CheckPerforceCredentialsResponse struct { func (x *CheckPerforceCredentialsResponse) Reset() { *x = CheckPerforceCredentialsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[53] + mi := &file_gitserver_proto_msgTypes[58] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3529,7 +3899,7 @@ func (x *CheckPerforceCredentialsResponse) String() string { func (*CheckPerforceCredentialsResponse) ProtoMessage() {} func (x *CheckPerforceCredentialsResponse) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[53] + mi := &file_gitserver_proto_msgTypes[58] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3542,7 +3912,7 @@ func (x *CheckPerforceCredentialsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CheckPerforceCredentialsResponse.ProtoReflect.Descriptor instead. func (*CheckPerforceCredentialsResponse) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{53} + return file_gitserver_proto_rawDescGZIP(), []int{58} } // PerforceConnectionDetails holds all the details required to talk to a Perforce server. @@ -3559,7 +3929,7 @@ type PerforceConnectionDetails struct { func (x *PerforceConnectionDetails) Reset() { *x = PerforceConnectionDetails{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[54] + mi := &file_gitserver_proto_msgTypes[59] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3572,7 +3942,7 @@ func (x *PerforceConnectionDetails) String() string { func (*PerforceConnectionDetails) ProtoMessage() {} func (x *PerforceConnectionDetails) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[54] + mi := &file_gitserver_proto_msgTypes[59] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3585,7 +3955,7 @@ func (x *PerforceConnectionDetails) ProtoReflect() protoreflect.Message { // Deprecated: Use PerforceConnectionDetails.ProtoReflect.Descriptor instead. func (*PerforceConnectionDetails) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{54} + return file_gitserver_proto_rawDescGZIP(), []int{59} } func (x *PerforceConnectionDetails) GetP4Port() string { @@ -3623,7 +3993,7 @@ type PerforceGetChangelistRequest struct { func (x *PerforceGetChangelistRequest) Reset() { *x = PerforceGetChangelistRequest{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[55] + mi := &file_gitserver_proto_msgTypes[60] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3636,7 +4006,7 @@ func (x *PerforceGetChangelistRequest) String() string { func (*PerforceGetChangelistRequest) ProtoMessage() {} func (x *PerforceGetChangelistRequest) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[55] + mi := &file_gitserver_proto_msgTypes[60] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3649,7 +4019,7 @@ func (x *PerforceGetChangelistRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PerforceGetChangelistRequest.ProtoReflect.Descriptor instead. func (*PerforceGetChangelistRequest) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{55} + return file_gitserver_proto_rawDescGZIP(), []int{60} } func (x *PerforceGetChangelistRequest) GetConnectionDetails() *PerforceConnectionDetails { @@ -3678,7 +4048,7 @@ type PerforceGetChangelistResponse struct { func (x *PerforceGetChangelistResponse) Reset() { *x = PerforceGetChangelistResponse{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[56] + mi := &file_gitserver_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3691,7 +4061,7 @@ func (x *PerforceGetChangelistResponse) String() string { func (*PerforceGetChangelistResponse) ProtoMessage() {} func (x *PerforceGetChangelistResponse) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[56] + mi := &file_gitserver_proto_msgTypes[61] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3704,7 +4074,7 @@ func (x *PerforceGetChangelistResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PerforceGetChangelistResponse.ProtoReflect.Descriptor instead. func (*PerforceGetChangelistResponse) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{56} + return file_gitserver_proto_rawDescGZIP(), []int{61} } func (x *PerforceGetChangelistResponse) GetChangelist() *PerforceChangelist { @@ -3731,7 +4101,7 @@ type PerforceChangelist struct { func (x *PerforceChangelist) Reset() { *x = PerforceChangelist{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[57] + mi := &file_gitserver_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3744,7 +4114,7 @@ func (x *PerforceChangelist) String() string { func (*PerforceChangelist) ProtoMessage() {} func (x *PerforceChangelist) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[57] + mi := &file_gitserver_proto_msgTypes[62] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3757,7 +4127,7 @@ func (x *PerforceChangelist) ProtoReflect() protoreflect.Message { // Deprecated: Use PerforceChangelist.ProtoReflect.Descriptor instead. func (*PerforceChangelist) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{57} + return file_gitserver_proto_rawDescGZIP(), []int{62} } func (x *PerforceChangelist) GetId() string { @@ -3815,7 +4185,7 @@ type IsPerforceSuperUserRequest struct { func (x *IsPerforceSuperUserRequest) Reset() { *x = IsPerforceSuperUserRequest{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[58] + mi := &file_gitserver_proto_msgTypes[63] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3828,7 +4198,7 @@ func (x *IsPerforceSuperUserRequest) String() string { func (*IsPerforceSuperUserRequest) ProtoMessage() {} func (x *IsPerforceSuperUserRequest) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[58] + mi := &file_gitserver_proto_msgTypes[63] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3841,7 +4211,7 @@ func (x *IsPerforceSuperUserRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use IsPerforceSuperUserRequest.ProtoReflect.Descriptor instead. func (*IsPerforceSuperUserRequest) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{58} + return file_gitserver_proto_rawDescGZIP(), []int{63} } func (x *IsPerforceSuperUserRequest) GetConnectionDetails() *PerforceConnectionDetails { @@ -3863,7 +4233,7 @@ type IsPerforceSuperUserResponse struct { func (x *IsPerforceSuperUserResponse) Reset() { *x = IsPerforceSuperUserResponse{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[59] + mi := &file_gitserver_proto_msgTypes[64] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3876,7 +4246,7 @@ func (x *IsPerforceSuperUserResponse) String() string { func (*IsPerforceSuperUserResponse) ProtoMessage() {} func (x *IsPerforceSuperUserResponse) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[59] + mi := &file_gitserver_proto_msgTypes[64] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3889,7 +4259,7 @@ func (x *IsPerforceSuperUserResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use IsPerforceSuperUserResponse.ProtoReflect.Descriptor instead. func (*IsPerforceSuperUserResponse) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{59} + return file_gitserver_proto_rawDescGZIP(), []int{64} } // PerforceProtectsForDepotRequest requests all the protections that apply to the @@ -3906,7 +4276,7 @@ type PerforceProtectsForDepotRequest struct { func (x *PerforceProtectsForDepotRequest) Reset() { *x = PerforceProtectsForDepotRequest{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[60] + mi := &file_gitserver_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3919,7 +4289,7 @@ func (x *PerforceProtectsForDepotRequest) String() string { func (*PerforceProtectsForDepotRequest) ProtoMessage() {} func (x *PerforceProtectsForDepotRequest) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[60] + mi := &file_gitserver_proto_msgTypes[65] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3932,7 +4302,7 @@ func (x *PerforceProtectsForDepotRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PerforceProtectsForDepotRequest.ProtoReflect.Descriptor instead. func (*PerforceProtectsForDepotRequest) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{60} + return file_gitserver_proto_rawDescGZIP(), []int{65} } func (x *PerforceProtectsForDepotRequest) GetConnectionDetails() *PerforceConnectionDetails { @@ -3962,7 +4332,7 @@ type PerforceProtectsForDepotResponse struct { func (x *PerforceProtectsForDepotResponse) Reset() { *x = PerforceProtectsForDepotResponse{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[61] + mi := &file_gitserver_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3975,7 +4345,7 @@ func (x *PerforceProtectsForDepotResponse) String() string { func (*PerforceProtectsForDepotResponse) ProtoMessage() {} func (x *PerforceProtectsForDepotResponse) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[61] + mi := &file_gitserver_proto_msgTypes[66] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3988,7 +4358,7 @@ func (x *PerforceProtectsForDepotResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PerforceProtectsForDepotResponse.ProtoReflect.Descriptor instead. func (*PerforceProtectsForDepotResponse) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{61} + return file_gitserver_proto_rawDescGZIP(), []int{66} } func (x *PerforceProtectsForDepotResponse) GetProtects() []*PerforceProtect { @@ -4012,7 +4382,7 @@ type PerforceProtectsForUserRequest struct { func (x *PerforceProtectsForUserRequest) Reset() { *x = PerforceProtectsForUserRequest{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[62] + mi := &file_gitserver_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4025,7 +4395,7 @@ func (x *PerforceProtectsForUserRequest) String() string { func (*PerforceProtectsForUserRequest) ProtoMessage() {} func (x *PerforceProtectsForUserRequest) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[62] + mi := &file_gitserver_proto_msgTypes[67] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4038,7 +4408,7 @@ func (x *PerforceProtectsForUserRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PerforceProtectsForUserRequest.ProtoReflect.Descriptor instead. func (*PerforceProtectsForUserRequest) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{62} + return file_gitserver_proto_rawDescGZIP(), []int{67} } func (x *PerforceProtectsForUserRequest) GetConnectionDetails() *PerforceConnectionDetails { @@ -4068,7 +4438,7 @@ type PerforceProtectsForUserResponse struct { func (x *PerforceProtectsForUserResponse) Reset() { *x = PerforceProtectsForUserResponse{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[63] + mi := &file_gitserver_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4081,7 +4451,7 @@ func (x *PerforceProtectsForUserResponse) String() string { func (*PerforceProtectsForUserResponse) ProtoMessage() {} func (x *PerforceProtectsForUserResponse) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[63] + mi := &file_gitserver_proto_msgTypes[68] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4094,7 +4464,7 @@ func (x *PerforceProtectsForUserResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PerforceProtectsForUserResponse.ProtoReflect.Descriptor instead. func (*PerforceProtectsForUserResponse) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{63} + return file_gitserver_proto_rawDescGZIP(), []int{68} } func (x *PerforceProtectsForUserResponse) GetProtects() []*PerforceProtect { @@ -4121,7 +4491,7 @@ type PerforceProtect struct { func (x *PerforceProtect) Reset() { *x = PerforceProtect{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[64] + mi := &file_gitserver_proto_msgTypes[69] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4134,7 +4504,7 @@ func (x *PerforceProtect) String() string { func (*PerforceProtect) ProtoMessage() {} func (x *PerforceProtect) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[64] + mi := &file_gitserver_proto_msgTypes[69] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4147,7 +4517,7 @@ func (x *PerforceProtect) ProtoReflect() protoreflect.Message { // Deprecated: Use PerforceProtect.ProtoReflect.Descriptor instead. func (*PerforceProtect) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{64} + return file_gitserver_proto_rawDescGZIP(), []int{69} } func (x *PerforceProtect) GetLevel() string { @@ -4205,7 +4575,7 @@ type PerforceGroupMembersRequest struct { func (x *PerforceGroupMembersRequest) Reset() { *x = PerforceGroupMembersRequest{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[65] + mi := &file_gitserver_proto_msgTypes[70] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4218,7 +4588,7 @@ func (x *PerforceGroupMembersRequest) String() string { func (*PerforceGroupMembersRequest) ProtoMessage() {} func (x *PerforceGroupMembersRequest) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[65] + mi := &file_gitserver_proto_msgTypes[70] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4231,7 +4601,7 @@ func (x *PerforceGroupMembersRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PerforceGroupMembersRequest.ProtoReflect.Descriptor instead. func (*PerforceGroupMembersRequest) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{65} + return file_gitserver_proto_rawDescGZIP(), []int{70} } func (x *PerforceGroupMembersRequest) GetConnectionDetails() *PerforceConnectionDetails { @@ -4260,7 +4630,7 @@ type PerforceGroupMembersResponse struct { func (x *PerforceGroupMembersResponse) Reset() { *x = PerforceGroupMembersResponse{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[66] + mi := &file_gitserver_proto_msgTypes[71] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4273,7 +4643,7 @@ func (x *PerforceGroupMembersResponse) String() string { func (*PerforceGroupMembersResponse) ProtoMessage() {} func (x *PerforceGroupMembersResponse) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[66] + mi := &file_gitserver_proto_msgTypes[71] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4286,7 +4656,7 @@ func (x *PerforceGroupMembersResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PerforceGroupMembersResponse.ProtoReflect.Descriptor instead. func (*PerforceGroupMembersResponse) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{66} + return file_gitserver_proto_rawDescGZIP(), []int{71} } func (x *PerforceGroupMembersResponse) GetUsernames() []string { @@ -4308,7 +4678,7 @@ type PerforceUsersRequest struct { func (x *PerforceUsersRequest) Reset() { *x = PerforceUsersRequest{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[67] + mi := &file_gitserver_proto_msgTypes[72] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4321,7 +4691,7 @@ func (x *PerforceUsersRequest) String() string { func (*PerforceUsersRequest) ProtoMessage() {} func (x *PerforceUsersRequest) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[67] + mi := &file_gitserver_proto_msgTypes[72] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4334,7 +4704,7 @@ func (x *PerforceUsersRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PerforceUsersRequest.ProtoReflect.Descriptor instead. func (*PerforceUsersRequest) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{67} + return file_gitserver_proto_rawDescGZIP(), []int{72} } func (x *PerforceUsersRequest) GetConnectionDetails() *PerforceConnectionDetails { @@ -4356,7 +4726,7 @@ type PerforceUsersResponse struct { func (x *PerforceUsersResponse) Reset() { *x = PerforceUsersResponse{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[68] + mi := &file_gitserver_proto_msgTypes[73] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4369,7 +4739,7 @@ func (x *PerforceUsersResponse) String() string { func (*PerforceUsersResponse) ProtoMessage() {} func (x *PerforceUsersResponse) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[68] + mi := &file_gitserver_proto_msgTypes[73] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4382,7 +4752,7 @@ func (x *PerforceUsersResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PerforceUsersResponse.ProtoReflect.Descriptor instead. func (*PerforceUsersResponse) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{68} + return file_gitserver_proto_rawDescGZIP(), []int{73} } func (x *PerforceUsersResponse) GetUsers() []*PerforceUser { @@ -4405,7 +4775,7 @@ type PerforceUser struct { func (x *PerforceUser) Reset() { *x = PerforceUser{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[69] + mi := &file_gitserver_proto_msgTypes[74] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4418,7 +4788,7 @@ func (x *PerforceUser) String() string { func (*PerforceUser) ProtoMessage() {} func (x *PerforceUser) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[69] + mi := &file_gitserver_proto_msgTypes[74] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4431,7 +4801,7 @@ func (x *PerforceUser) ProtoReflect() protoreflect.Message { // Deprecated: Use PerforceUser.ProtoReflect.Descriptor instead. func (*PerforceUser) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{69} + return file_gitserver_proto_rawDescGZIP(), []int{74} } func (x *PerforceUser) GetUsername() string { @@ -4466,7 +4836,7 @@ type MergeBaseRequest struct { func (x *MergeBaseRequest) Reset() { *x = MergeBaseRequest{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[70] + mi := &file_gitserver_proto_msgTypes[75] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4479,7 +4849,7 @@ func (x *MergeBaseRequest) String() string { func (*MergeBaseRequest) ProtoMessage() {} func (x *MergeBaseRequest) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[70] + mi := &file_gitserver_proto_msgTypes[75] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4492,7 +4862,7 @@ func (x *MergeBaseRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MergeBaseRequest.ProtoReflect.Descriptor instead. func (*MergeBaseRequest) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{70} + return file_gitserver_proto_rawDescGZIP(), []int{75} } func (x *MergeBaseRequest) GetRepoName() string { @@ -4528,7 +4898,7 @@ type MergeBaseResponse struct { func (x *MergeBaseResponse) Reset() { *x = MergeBaseResponse{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[71] + mi := &file_gitserver_proto_msgTypes[76] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4541,7 +4911,7 @@ func (x *MergeBaseResponse) String() string { func (*MergeBaseResponse) ProtoMessage() {} func (x *MergeBaseResponse) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[71] + mi := &file_gitserver_proto_msgTypes[76] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4554,7 +4924,7 @@ func (x *MergeBaseResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MergeBaseResponse.ProtoReflect.Descriptor instead. func (*MergeBaseResponse) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{71} + return file_gitserver_proto_rawDescGZIP(), []int{76} } func (x *MergeBaseResponse) GetMergeBaseCommitSha() string { @@ -4591,7 +4961,7 @@ type CreateCommitFromPatchBinaryRequest_Metadata struct { func (x *CreateCommitFromPatchBinaryRequest_Metadata) Reset() { *x = CreateCommitFromPatchBinaryRequest_Metadata{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[72] + mi := &file_gitserver_proto_msgTypes[77] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4604,7 +4974,7 @@ func (x *CreateCommitFromPatchBinaryRequest_Metadata) String() string { func (*CreateCommitFromPatchBinaryRequest_Metadata) ProtoMessage() {} func (x *CreateCommitFromPatchBinaryRequest_Metadata) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[72] + mi := &file_gitserver_proto_msgTypes[77] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4617,7 +4987,7 @@ func (x *CreateCommitFromPatchBinaryRequest_Metadata) ProtoReflect() protoreflec // Deprecated: Use CreateCommitFromPatchBinaryRequest_Metadata.ProtoReflect.Descriptor instead. func (*CreateCommitFromPatchBinaryRequest_Metadata) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{8, 0} + return file_gitserver_proto_rawDescGZIP(), []int{12, 0} } func (x *CreateCommitFromPatchBinaryRequest_Metadata) GetRepo() string { @@ -4688,7 +5058,7 @@ type CreateCommitFromPatchBinaryRequest_Patch struct { func (x *CreateCommitFromPatchBinaryRequest_Patch) Reset() { *x = CreateCommitFromPatchBinaryRequest_Patch{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[73] + mi := &file_gitserver_proto_msgTypes[78] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4701,7 +5071,7 @@ func (x *CreateCommitFromPatchBinaryRequest_Patch) String() string { func (*CreateCommitFromPatchBinaryRequest_Patch) ProtoMessage() {} func (x *CreateCommitFromPatchBinaryRequest_Patch) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[73] + mi := &file_gitserver_proto_msgTypes[78] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4714,7 +5084,7 @@ func (x *CreateCommitFromPatchBinaryRequest_Patch) ProtoReflect() protoreflect.M // Deprecated: Use CreateCommitFromPatchBinaryRequest_Patch.ProtoReflect.Descriptor instead. func (*CreateCommitFromPatchBinaryRequest_Patch) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{8, 1} + return file_gitserver_proto_rawDescGZIP(), []int{12, 1} } func (x *CreateCommitFromPatchBinaryRequest_Patch) GetData() []byte { @@ -4737,7 +5107,7 @@ type CommitMatch_Signature struct { func (x *CommitMatch_Signature) Reset() { *x = CommitMatch_Signature{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[74] + mi := &file_gitserver_proto_msgTypes[79] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4750,7 +5120,7 @@ func (x *CommitMatch_Signature) String() string { func (*CommitMatch_Signature) ProtoMessage() {} func (x *CommitMatch_Signature) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[74] + mi := &file_gitserver_proto_msgTypes[79] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4763,7 +5133,7 @@ func (x *CommitMatch_Signature) ProtoReflect() protoreflect.Message { // Deprecated: Use CommitMatch_Signature.ProtoReflect.Descriptor instead. func (*CommitMatch_Signature) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{28, 0} + return file_gitserver_proto_rawDescGZIP(), []int{33, 0} } func (x *CommitMatch_Signature) GetName() string { @@ -4799,7 +5169,7 @@ type CommitMatch_MatchedString struct { func (x *CommitMatch_MatchedString) Reset() { *x = CommitMatch_MatchedString{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[75] + mi := &file_gitserver_proto_msgTypes[80] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4812,7 +5182,7 @@ func (x *CommitMatch_MatchedString) String() string { func (*CommitMatch_MatchedString) ProtoMessage() {} func (x *CommitMatch_MatchedString) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[75] + mi := &file_gitserver_proto_msgTypes[80] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4825,7 +5195,7 @@ func (x *CommitMatch_MatchedString) ProtoReflect() protoreflect.Message { // Deprecated: Use CommitMatch_MatchedString.ProtoReflect.Descriptor instead. func (*CommitMatch_MatchedString) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{28, 1} + return file_gitserver_proto_rawDescGZIP(), []int{33, 1} } func (x *CommitMatch_MatchedString) GetContent() string { @@ -4855,7 +5225,7 @@ type CommitMatch_Range struct { func (x *CommitMatch_Range) Reset() { *x = CommitMatch_Range{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[76] + mi := &file_gitserver_proto_msgTypes[81] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4868,7 +5238,7 @@ func (x *CommitMatch_Range) String() string { func (*CommitMatch_Range) ProtoMessage() {} func (x *CommitMatch_Range) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[76] + mi := &file_gitserver_proto_msgTypes[81] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4881,7 +5251,7 @@ func (x *CommitMatch_Range) ProtoReflect() protoreflect.Message { // Deprecated: Use CommitMatch_Range.ProtoReflect.Descriptor instead. func (*CommitMatch_Range) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{28, 2} + return file_gitserver_proto_rawDescGZIP(), []int{33, 2} } func (x *CommitMatch_Range) GetStart() *CommitMatch_Location { @@ -4911,7 +5281,7 @@ type CommitMatch_Location struct { func (x *CommitMatch_Location) Reset() { *x = CommitMatch_Location{} if protoimpl.UnsafeEnabled { - mi := &file_gitserver_proto_msgTypes[77] + mi := &file_gitserver_proto_msgTypes[82] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4924,7 +5294,7 @@ func (x *CommitMatch_Location) String() string { func (*CommitMatch_Location) ProtoMessage() {} func (x *CommitMatch_Location) ProtoReflect() protoreflect.Message { - mi := &file_gitserver_proto_msgTypes[77] + mi := &file_gitserver_proto_msgTypes[82] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4937,7 +5307,7 @@ func (x *CommitMatch_Location) ProtoReflect() protoreflect.Message { // Deprecated: Use CommitMatch_Location.ProtoReflect.Descriptor instead. func (*CommitMatch_Location) Descriptor() ([]byte, []int) { - return file_gitserver_proto_rawDescGZIP(), []int{28, 3} + return file_gitserver_proto_rawDescGZIP(), []int{33, 3} } func (x *CommitMatch_Location) GetOffset() uint32 { @@ -4970,737 +5340,792 @@ var file_gitserver_proto_rawDesc = []byte{ 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x22, 0x11, 0x0a, 0x0f, 0x44, 0x69, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x22, 0x75, 0x0a, 0x10, 0x44, 0x69, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x66, 0x72, 0x65, 0x65, 0x5f, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x66, 0x72, 0x65, - 0x65, 0x53, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x74, 0x6f, 0x74, - 0x61, 0x6c, 0x53, 0x70, 0x61, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x65, 0x72, 0x63, 0x65, - 0x6e, 0x74, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0b, 0x70, - 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x55, 0x73, 0x65, 0x64, 0x22, 0x6e, 0x0a, 0x0f, 0x42, 0x61, - 0x74, 0x63, 0x68, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, - 0x0c, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, + 0x22, 0xf4, 0x01, 0x0a, 0x0c, 0x42, 0x6c, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x70, 0x6f, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1b, + 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, + 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x88, 0x01, 0x01, 0x12, 0x12, 0x0a, 0x04, 0x70, + 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, + 0x2b, 0x0a, 0x11, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x77, 0x68, 0x69, 0x74, 0x65, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x69, 0x67, 0x6e, 0x6f, + 0x72, 0x65, 0x57, 0x68, 0x69, 0x74, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x22, 0x0a, 0x0a, + 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, + 0x48, 0x01, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4c, 0x69, 0x6e, 0x65, 0x88, 0x01, 0x01, + 0x12, 0x1e, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x0d, 0x48, 0x02, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x4c, 0x69, 0x6e, 0x65, 0x88, 0x01, 0x01, + 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, + 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x65, + 0x6e, 0x64, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x3c, 0x0a, 0x0d, 0x42, 0x6c, 0x61, 0x6d, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x04, 0x68, 0x75, 0x6e, 0x6b, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6c, 0x61, 0x6d, 0x65, 0x48, 0x75, 0x6e, 0x6b, 0x52, + 0x04, 0x68, 0x75, 0x6e, 0x6b, 0x22, 0x80, 0x02, 0x0a, 0x09, 0x42, 0x6c, 0x61, 0x6d, 0x65, 0x48, + 0x75, 0x6e, 0x6b, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x6c, 0x69, 0x6e, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4c, 0x69, + 0x6e, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x4c, 0x69, 0x6e, 0x65, 0x12, 0x1d, 0x0a, + 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x42, 0x79, 0x74, 0x65, 0x12, 0x19, 0x0a, 0x08, + 0x65, 0x6e, 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, + 0x65, 0x6e, 0x64, 0x42, 0x79, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, + 0x31, 0x0a, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x19, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x42, + 0x6c, 0x61, 0x6d, 0x65, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x52, 0x06, 0x61, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1a, 0x0a, 0x08, + 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x67, 0x0a, 0x0b, 0x42, 0x6c, 0x61, 0x6d, + 0x65, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, + 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, + 0x6c, 0x12, 0x2e, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x64, 0x61, 0x74, + 0x65, 0x22, 0x11, 0x0a, 0x0f, 0x44, 0x69, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x22, 0x75, 0x0a, 0x10, 0x44, 0x69, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x66, 0x72, 0x65, 0x65, + 0x5f, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x66, 0x72, + 0x65, 0x65, 0x53, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, + 0x5f, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x74, 0x6f, + 0x74, 0x61, 0x6c, 0x53, 0x70, 0x61, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x65, 0x72, 0x63, + 0x65, 0x6e, 0x74, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0b, + 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x55, 0x73, 0x65, 0x64, 0x22, 0x6e, 0x0a, 0x0f, 0x42, + 0x61, 0x74, 0x63, 0x68, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, + 0x0a, 0x0c, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x42, 0x02, + 0x18, 0x01, 0x52, 0x0b, 0x72, 0x65, 0x70, 0x6f, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x12, + 0x1a, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x02, 0x18, 0x01, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0x4e, 0x0a, 0x10, 0x42, + 0x61, 0x74, 0x63, 0x68, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x3a, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x1c, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, + 0x42, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x42, 0x02, + 0x18, 0x01, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0xba, 0x01, 0x0a, 0x0e, + 0x42, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x3d, + 0x0a, 0x0b, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x42, 0x02, 0x18, - 0x01, 0x52, 0x0b, 0x72, 0x65, 0x70, 0x6f, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x1a, - 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, - 0x18, 0x01, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0x4e, 0x0a, 0x10, 0x42, 0x61, - 0x74, 0x63, 0x68, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, - 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x1c, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x42, - 0x61, 0x74, 0x63, 0x68, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x42, 0x02, 0x18, - 0x01, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0xba, 0x01, 0x0a, 0x0e, 0x42, - 0x61, 0x74, 0x63, 0x68, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x3d, 0x0a, - 0x0b, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x42, 0x02, 0x18, 0x01, - 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x29, 0x0a, 0x0e, - 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, - 0x64, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x2c, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x6d, 0x61, - 0x6e, 0x64, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, - 0x18, 0x01, 0x48, 0x00, 0x52, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, 0x72, 0x72, - 0x6f, 0x72, 0x88, 0x01, 0x01, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, - 0x64, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x40, 0x0a, 0x0a, 0x52, 0x65, 0x70, 0x6f, 0x43, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x16, 0x0a, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x12, 0x1a, 0x0a, - 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, - 0x01, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x22, 0xf1, 0x01, 0x0a, 0x0f, 0x50, 0x61, - 0x74, 0x63, 0x68, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1a, 0x0a, - 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x75, 0x74, - 0x68, 0x6f, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, - 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x75, - 0x74, 0x68, 0x6f, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x25, 0x0a, - 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, - 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x2e, 0x0a, - 0x04, 0x64, 0x61, 0x74, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x64, 0x61, 0x74, 0x65, 0x22, 0x6c, 0x0a, - 0x0a, 0x50, 0x75, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x72, - 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, - 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0a, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x70, - 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0a, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x22, 0xb6, 0x04, 0x0a, 0x22, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x72, 0x6f, 0x6d, - 0x50, 0x61, 0x74, 0x63, 0x68, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x57, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, - 0x46, 0x72, 0x6f, 0x6d, 0x50, 0x61, 0x74, 0x63, 0x68, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x48, - 0x00, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x4e, 0x0a, 0x05, 0x70, - 0x61, 0x74, 0x63, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x67, 0x69, 0x74, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x50, 0x61, 0x74, 0x63, 0x68, 0x42, - 0x69, 0x6e, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x50, 0x61, 0x74, - 0x63, 0x68, 0x48, 0x00, 0x52, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x1a, 0xbe, 0x02, 0x0a, 0x08, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x70, 0x6f, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x12, 0x1f, 0x0a, 0x0b, - 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0a, 0x62, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x1d, 0x0a, - 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x09, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x66, 0x12, 0x1d, 0x0a, 0x0a, - 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x5f, 0x72, 0x65, 0x66, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x09, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x52, 0x65, 0x66, 0x12, 0x3e, 0x0a, 0x0b, 0x63, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, - 0x50, 0x61, 0x74, 0x63, 0x68, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, - 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2c, 0x0a, 0x04, 0x70, - 0x75, 0x73, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x67, 0x69, 0x74, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x73, 0x68, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x52, 0x04, 0x70, 0x75, 0x73, 0x68, 0x12, 0x24, 0x0a, 0x0e, 0x67, 0x69, 0x74, - 0x5f, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x0c, 0x67, 0x69, 0x74, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x41, 0x72, 0x67, 0x73, 0x12, - 0x1e, 0x0a, 0x08, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x72, 0x65, 0x66, 0x18, 0x08, 0x20, 0x01, 0x28, - 0x09, 0x48, 0x00, 0x52, 0x07, 0x70, 0x75, 0x73, 0x68, 0x52, 0x65, 0x66, 0x88, 0x01, 0x01, 0x42, - 0x0b, 0x0a, 0x09, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x72, 0x65, 0x66, 0x1a, 0x1b, 0x0a, 0x05, - 0x50, 0x61, 0x74, 0x63, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, - 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xaf, 0x01, 0x0a, 0x1a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x50, 0x61, 0x74, 0x63, 0x68, 0x45, 0x72, - 0x72, 0x6f, 0x72, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, - 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x65, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x45, 0x72, - 0x72, 0x6f, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x27, 0x0a, - 0x0f, 0x63, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x64, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x64, - 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0x69, 0x0a, 0x23, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x50, 0x61, 0x74, 0x63, 0x68, 0x42, - 0x69, 0x6e, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, - 0x03, 0x72, 0x65, 0x76, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x72, 0x65, 0x76, 0x12, - 0x23, 0x0a, 0x0d, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x69, 0x64, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x69, - 0x73, 0x74, 0x49, 0x64, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x22, 0x97, 0x01, 0x0a, 0x0b, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x72, 0x65, 0x70, 0x6f, 0x12, 0x27, 0x0a, 0x0f, 0x65, 0x6e, 0x73, 0x75, 0x72, 0x65, 0x5f, - 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, - 0x65, 0x6e, 0x73, 0x75, 0x72, 0x65, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, - 0x0a, 0x04, 0x61, 0x72, 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x04, 0x61, 0x72, - 0x67, 0x73, 0x12, 0x18, 0x0a, 0x05, 0x73, 0x74, 0x64, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0c, 0x42, 0x02, 0x18, 0x01, 0x52, 0x05, 0x73, 0x74, 0x64, 0x69, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, - 0x6e, 0x6f, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x09, 0x6e, 0x6f, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0x22, 0x0a, 0x0c, 0x45, - 0x78, 0x65, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, - 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, - 0x78, 0x0a, 0x0f, 0x4e, 0x6f, 0x74, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x50, 0x61, 0x79, 0x6c, 0x6f, - 0x61, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x12, 0x2a, 0x0a, 0x11, 0x63, 0x6c, 0x6f, 0x6e, 0x65, 0x5f, - 0x69, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x0f, 0x63, 0x6c, 0x6f, 0x6e, 0x65, 0x49, 0x6e, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, - 0x73, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6c, 0x6f, 0x6e, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x67, - 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6c, 0x6f, 0x6e, - 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x22, 0x4c, 0x0a, 0x11, 0x45, 0x78, 0x65, - 0x63, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x1f, - 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x12, - 0x16, 0x0a, 0x06, 0x73, 0x74, 0x64, 0x65, 0x72, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x73, 0x74, 0x64, 0x65, 0x72, 0x72, 0x22, 0x80, 0x02, 0x0a, 0x0d, 0x53, 0x65, 0x61, 0x72, - 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x70, - 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x12, 0x3d, 0x0a, - 0x09, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, - 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, - 0x72, 0x52, 0x09, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x14, 0x0a, 0x05, - 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, - 0x69, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x64, 0x69, - 0x66, 0x66, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, - 0x65, 0x44, 0x69, 0x66, 0x66, 0x12, 0x34, 0x0a, 0x16, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, - 0x5f, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x4d, 0x6f, - 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x2d, 0x0a, 0x05, 0x71, - 0x75, 0x65, 0x72, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x69, 0x74, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4e, - 0x6f, 0x64, 0x65, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0x3a, 0x0a, 0x11, 0x52, 0x65, - 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, - 0x19, 0x0a, 0x08, 0x72, 0x65, 0x76, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x07, 0x72, 0x65, 0x76, 0x53, 0x70, 0x65, 0x63, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, - 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x22, 0x48, 0x0a, 0x11, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, - 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x65, - 0x78, 0x70, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x65, 0x78, 0x70, 0x72, 0x12, - 0x1f, 0x0a, 0x0b, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x63, 0x61, 0x73, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x43, 0x61, 0x73, 0x65, - 0x22, 0x4b, 0x0a, 0x14, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x4d, 0x61, 0x74, - 0x63, 0x68, 0x65, 0x73, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x78, 0x70, 0x72, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x65, 0x78, 0x70, 0x72, 0x12, 0x1f, 0x0a, 0x0b, - 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x63, 0x61, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x0a, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x43, 0x61, 0x73, 0x65, 0x22, 0x4c, 0x0a, - 0x10, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x4e, 0x6f, 0x64, - 0x65, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x4b, 0x0a, 0x0f, 0x43, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x66, 0x74, 0x65, 0x72, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x38, - 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x49, 0x0a, 0x12, 0x4d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x12, - 0x0a, 0x04, 0x65, 0x78, 0x70, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x65, 0x78, - 0x70, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x63, 0x61, 0x73, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x43, - 0x61, 0x73, 0x65, 0x22, 0x46, 0x0a, 0x0f, 0x44, 0x69, 0x66, 0x66, 0x4d, 0x61, 0x74, 0x63, 0x68, - 0x65, 0x73, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x78, 0x70, 0x72, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x65, 0x78, 0x70, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x67, - 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x63, 0x61, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x0a, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x43, 0x61, 0x73, 0x65, 0x22, 0x4b, 0x0a, 0x14, 0x44, - 0x69, 0x66, 0x66, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x73, 0x46, 0x69, 0x6c, 0x65, 0x4e, - 0x6f, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x78, 0x70, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x65, 0x78, 0x70, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x67, 0x6e, 0x6f, 0x72, - 0x65, 0x5f, 0x63, 0x61, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x67, - 0x6e, 0x6f, 0x72, 0x65, 0x43, 0x61, 0x73, 0x65, 0x22, 0x23, 0x0a, 0x0b, 0x42, 0x6f, 0x6f, 0x6c, - 0x65, 0x61, 0x6e, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x73, 0x0a, - 0x0c, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x2e, 0x0a, - 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x67, 0x69, - 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, - 0x74, 0x6f, 0x72, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x33, 0x0a, - 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x6e, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x17, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x51, - 0x75, 0x65, 0x72, 0x79, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x6e, - 0x64, 0x73, 0x22, 0x92, 0x05, 0x0a, 0x09, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4e, 0x6f, 0x64, 0x65, - 0x12, 0x48, 0x0a, 0x0e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x4d, 0x61, - 0x74, 0x63, 0x68, 0x65, 0x73, 0x4e, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x0d, 0x61, 0x75, 0x74, - 0x68, 0x6f, 0x72, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x12, 0x51, 0x0a, 0x11, 0x63, 0x6f, - 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x4d, 0x61, - 0x74, 0x63, 0x68, 0x65, 0x73, 0x4e, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x10, 0x63, 0x6f, 0x6d, - 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x12, 0x45, 0x0a, - 0x0d, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, - 0x4e, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x42, 0x65, - 0x66, 0x6f, 0x72, 0x65, 0x12, 0x42, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x61, - 0x66, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x69, 0x74, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, - 0x41, 0x66, 0x74, 0x65, 0x72, 0x4e, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x0b, 0x63, 0x6f, 0x6d, - 0x6d, 0x69, 0x74, 0x41, 0x66, 0x74, 0x65, 0x72, 0x12, 0x4b, 0x0a, 0x0f, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x20, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x4e, - 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x0e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4d, 0x61, - 0x74, 0x63, 0x68, 0x65, 0x73, 0x12, 0x42, 0x0a, 0x0c, 0x64, 0x69, 0x66, 0x66, 0x5f, 0x6d, 0x61, - 0x74, 0x63, 0x68, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x69, - 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x66, 0x66, 0x4d, - 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x4e, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x0b, 0x64, 0x69, - 0x66, 0x66, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x12, 0x52, 0x0a, 0x12, 0x64, 0x69, 0x66, - 0x66, 0x5f, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x73, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x66, 0x66, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, - 0x73, 0x46, 0x69, 0x6c, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x10, 0x64, 0x69, 0x66, - 0x66, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x73, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x35, 0x0a, - 0x07, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, - 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6f, - 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x4e, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x07, 0x62, 0x6f, 0x6f, - 0x6c, 0x65, 0x61, 0x6e, 0x12, 0x38, 0x0a, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, - 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x4e, 0x6f, - 0x64, 0x65, 0x48, 0x00, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x42, 0x07, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x6d, 0x0a, 0x0e, 0x53, 0x65, 0x61, 0x72, 0x63, - 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x05, 0x6d, 0x61, 0x74, - 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x61, - 0x74, 0x63, 0x68, 0x48, 0x00, 0x52, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x1d, 0x0a, 0x09, - 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x68, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x48, - 0x00, 0x52, 0x08, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x48, 0x69, 0x74, 0x42, 0x09, 0x0a, 0x07, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xa9, 0x06, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x69, - 0x74, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x10, 0x0a, 0x03, 0x6f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x6f, 0x69, 0x64, 0x12, 0x3b, 0x0a, 0x06, 0x61, 0x75, 0x74, 0x68, - 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x61, - 0x74, 0x63, 0x68, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x06, 0x61, - 0x75, 0x74, 0x68, 0x6f, 0x72, 0x12, 0x41, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, - 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x61, - 0x74, 0x63, 0x68, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x63, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x72, 0x65, - 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x70, 0x61, 0x72, 0x65, 0x6e, - 0x74, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x66, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x04, 0x72, 0x65, 0x66, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x5f, 0x72, 0x65, 0x66, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x52, 0x65, 0x66, 0x73, 0x12, 0x41, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x61, - 0x74, 0x63, 0x68, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x53, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x64, 0x69, - 0x66, 0x66, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x61, - 0x74, 0x63, 0x68, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x53, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x52, 0x04, 0x64, 0x69, 0x66, 0x66, 0x12, 0x25, 0x0a, 0x0e, 0x6d, 0x6f, 0x64, 0x69, 0x66, - 0x69, 0x65, 0x64, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x0d, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x1a, 0x65, - 0x0a, 0x09, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, - 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x2e, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x29, 0x0a, + 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x6d, 0x61, + 0x6e, 0x64, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x2c, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x6d, + 0x61, 0x6e, 0x64, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x02, 0x18, 0x01, 0x48, 0x00, 0x52, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, 0x72, + 0x72, 0x6f, 0x72, 0x88, 0x01, 0x01, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, + 0x6e, 0x64, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x40, 0x0a, 0x0a, 0x52, 0x65, 0x70, 0x6f, + 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x16, 0x0a, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x12, 0x1a, + 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, + 0x18, 0x01, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x22, 0xf1, 0x01, 0x0a, 0x0f, 0x50, + 0x61, 0x74, 0x63, 0x68, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1a, + 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x61, + 0x75, 0x74, 0x68, 0x6f, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0b, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x25, + 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, + 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, + 0x65, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, + 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x2e, + 0x0a, 0x04, 0x64, 0x61, 0x74, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x64, 0x61, 0x74, 0x65, 0x22, 0x6c, + 0x0a, 0x0a, 0x50, 0x75, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1d, 0x0a, 0x0a, + 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x70, + 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x1e, 0x0a, 0x0a, + 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x22, 0xb6, 0x04, 0x0a, + 0x22, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x72, 0x6f, + 0x6d, 0x50, 0x61, 0x74, 0x63, 0x68, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x57, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x50, 0x61, 0x74, 0x63, 0x68, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x48, 0x00, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x4e, 0x0a, 0x05, + 0x70, 0x61, 0x74, 0x63, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x67, 0x69, + 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x50, 0x61, 0x74, 0x63, 0x68, + 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x50, 0x61, + 0x74, 0x63, 0x68, 0x48, 0x00, 0x52, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x1a, 0xbe, 0x02, 0x0a, + 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x70, + 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x12, 0x1f, 0x0a, + 0x0b, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x62, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x1d, + 0x0a, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x66, 0x12, 0x1d, 0x0a, + 0x0a, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x5f, 0x72, 0x65, 0x66, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x09, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x52, 0x65, 0x66, 0x12, 0x3e, 0x0a, 0x0b, + 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, + 0x2e, 0x50, 0x61, 0x74, 0x63, 0x68, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x6e, 0x66, 0x6f, + 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2c, 0x0a, 0x04, + 0x70, 0x75, 0x73, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x67, 0x69, 0x74, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x73, 0x68, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x52, 0x04, 0x70, 0x75, 0x73, 0x68, 0x12, 0x24, 0x0a, 0x0e, 0x67, 0x69, + 0x74, 0x5f, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x18, 0x07, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x0c, 0x67, 0x69, 0x74, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x41, 0x72, 0x67, 0x73, + 0x12, 0x1e, 0x0a, 0x08, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x72, 0x65, 0x66, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x09, 0x48, 0x00, 0x52, 0x07, 0x70, 0x75, 0x73, 0x68, 0x52, 0x65, 0x66, 0x88, 0x01, 0x01, + 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x72, 0x65, 0x66, 0x1a, 0x1b, 0x0a, + 0x05, 0x50, 0x61, 0x74, 0x63, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, + 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xaf, 0x01, 0x0a, 0x1a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x50, 0x61, 0x74, 0x63, 0x68, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0x72, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, + 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x27, + 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x64, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, + 0x64, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0x69, 0x0a, 0x23, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x50, 0x61, 0x74, 0x63, 0x68, + 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, + 0x0a, 0x03, 0x72, 0x65, 0x76, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x72, 0x65, 0x76, + 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x69, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x6c, + 0x69, 0x73, 0x74, 0x49, 0x64, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x05, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x22, 0x97, 0x01, 0x0a, 0x0b, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x12, 0x27, 0x0a, 0x0f, 0x65, 0x6e, 0x73, 0x75, 0x72, 0x65, + 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x0e, 0x65, 0x6e, 0x73, 0x75, 0x72, 0x65, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x12, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x04, 0x61, + 0x72, 0x67, 0x73, 0x12, 0x18, 0x0a, 0x05, 0x73, 0x74, 0x64, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0c, 0x42, 0x02, 0x18, 0x01, 0x52, 0x05, 0x73, 0x74, 0x64, 0x69, 0x6e, 0x12, 0x1d, 0x0a, + 0x0a, 0x6e, 0x6f, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x09, 0x6e, 0x6f, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0x22, 0x0a, 0x0c, + 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, + 0x22, 0x78, 0x0a, 0x0f, 0x4e, 0x6f, 0x74, 0x46, 0x6f, 0x75, 0x6e, 0x64, 0x50, 0x61, 0x79, 0x6c, + 0x6f, 0x61, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x12, 0x2a, 0x0a, 0x11, 0x63, 0x6c, 0x6f, 0x6e, 0x65, + 0x5f, 0x69, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0f, 0x63, 0x6c, 0x6f, 0x6e, 0x65, 0x49, 0x6e, 0x50, 0x72, 0x6f, 0x67, 0x72, + 0x65, 0x73, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6c, 0x6f, 0x6e, 0x65, 0x5f, 0x70, 0x72, 0x6f, + 0x67, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6c, 0x6f, + 0x6e, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x22, 0x4c, 0x0a, 0x11, 0x45, 0x78, + 0x65, 0x63, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, + 0x1f, 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65, + 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x64, 0x65, 0x72, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x73, 0x74, 0x64, 0x65, 0x72, 0x72, 0x22, 0x7c, 0x0a, 0x13, 0x55, 0x6e, 0x61, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, + 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x70, 0x6f, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x04, + 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x70, 0x61, + 0x74, 0x68, 0x88, 0x01, 0x01, 0x12, 0x1b, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x88, + 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x42, 0x09, 0x0a, 0x07, 0x5f, + 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x22, 0x80, 0x02, 0x0a, 0x0d, 0x53, 0x65, 0x61, 0x72, 0x63, + 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x70, 0x6f, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x12, 0x3d, 0x0a, 0x09, + 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, + 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x72, + 0x52, 0x09, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6c, + 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, + 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x64, 0x69, 0x66, + 0x66, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, + 0x44, 0x69, 0x66, 0x66, 0x12, 0x34, 0x0a, 0x16, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, + 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x4d, 0x6f, 0x64, + 0x69, 0x66, 0x69, 0x65, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x2d, 0x0a, 0x05, 0x71, 0x75, + 0x65, 0x72, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x69, 0x74, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4e, 0x6f, + 0x64, 0x65, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0x3a, 0x0a, 0x11, 0x52, 0x65, 0x76, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x19, + 0x0a, 0x08, 0x72, 0x65, 0x76, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x72, 0x65, 0x76, 0x53, 0x70, 0x65, 0x63, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, + 0x04, 0x08, 0x03, 0x10, 0x04, 0x22, 0x48, 0x0a, 0x11, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x4d, + 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x78, + 0x70, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x65, 0x78, 0x70, 0x72, 0x12, 0x1f, + 0x0a, 0x0b, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x63, 0x61, 0x73, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x43, 0x61, 0x73, 0x65, 0x22, + 0x4b, 0x0a, 0x14, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x4d, 0x61, 0x74, 0x63, + 0x68, 0x65, 0x73, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x78, 0x70, 0x72, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x65, 0x78, 0x70, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x69, + 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x63, 0x61, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0a, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x43, 0x61, 0x73, 0x65, 0x22, 0x4c, 0x0a, 0x10, + 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x4e, 0x6f, 0x64, 0x65, + 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, - 0x04, 0x64, 0x61, 0x74, 0x65, 0x1a, 0x62, 0x0a, 0x0d, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, - 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, - 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, - 0x12, 0x37, 0x0a, 0x06, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x2e, 0x52, 0x61, 0x6e, 0x67, - 0x65, 0x52, 0x06, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x1a, 0x77, 0x0a, 0x05, 0x52, 0x61, 0x6e, - 0x67, 0x65, 0x12, 0x38, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x22, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x2e, 0x4c, 0x6f, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x34, 0x0a, 0x03, - 0x65, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x67, 0x69, 0x74, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, - 0x61, 0x74, 0x63, 0x68, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x03, 0x65, - 0x6e, 0x64, 0x1a, 0x4e, 0x0a, 0x08, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, - 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, - 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, - 0x6c, 0x75, 0x6d, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x63, 0x6f, 0x6c, 0x75, - 0x6d, 0x6e, 0x22, 0x74, 0x0a, 0x0e, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x72, 0x65, 0x65, - 0x69, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x72, 0x65, 0x65, 0x69, - 0x73, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x61, - 0x74, 0x68, 0x73, 0x70, 0x65, 0x63, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x70, - 0x61, 0x74, 0x68, 0x73, 0x70, 0x65, 0x63, 0x73, 0x22, 0x25, 0x0a, 0x0f, 0x41, 0x72, 0x63, 0x68, - 0x69, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, - 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, - 0x2c, 0x0a, 0x16, 0x49, 0x73, 0x52, 0x65, 0x70, 0x6f, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x61, 0x62, - 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x70, - 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x22, 0x67, 0x0a, - 0x17, 0x49, 0x73, 0x52, 0x65, 0x70, 0x6f, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x61, 0x62, 0x6c, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x6f, 0x6e, - 0x65, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x63, 0x6c, 0x6f, - 0x6e, 0x65, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6c, 0x6f, 0x6e, 0x65, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x63, 0x6c, 0x6f, 0x6e, 0x65, 0x64, 0x12, 0x16, - 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x26, 0x0a, 0x10, 0x52, 0x65, 0x70, 0x6f, 0x43, 0x6c, - 0x6f, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, - 0x70, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x22, 0x29, - 0x0a, 0x11, 0x52, 0x65, 0x70, 0x6f, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x30, 0x0a, 0x18, 0x52, 0x65, 0x70, - 0x6f, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x22, 0x7e, 0x0a, 0x11, 0x52, - 0x65, 0x70, 0x6f, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, - 0x12, 0x2a, 0x0a, 0x11, 0x63, 0x6c, 0x6f, 0x6e, 0x65, 0x5f, 0x69, 0x6e, 0x5f, 0x70, 0x72, 0x6f, - 0x67, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x63, 0x6c, 0x6f, - 0x6e, 0x65, 0x49, 0x6e, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x25, 0x0a, 0x0e, - 0x63, 0x6c, 0x6f, 0x6e, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6c, 0x6f, 0x6e, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, - 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6c, 0x6f, 0x6e, 0x65, 0x64, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x06, 0x63, 0x6c, 0x6f, 0x6e, 0x65, 0x64, 0x22, 0xc8, 0x01, 0x0a, 0x19, - 0x52, 0x65, 0x70, 0x6f, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x07, 0x72, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x67, 0x69, 0x74, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x43, 0x6c, - 0x6f, 0x6e, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x1a, 0x5b, 0x0a, 0x0c, 0x52, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x35, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x67, 0x69, 0x74, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x43, 0x6c, - 0x6f, 0x6e, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x27, 0x0a, 0x11, 0x52, 0x65, 0x70, 0x6f, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x72, - 0x65, 0x70, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x22, - 0x14, 0x0a, 0x12, 0x52, 0x65, 0x70, 0x6f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5e, 0x0a, 0x11, 0x52, 0x65, 0x70, 0x6f, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, - 0x70, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x12, 0x2f, - 0x0a, 0x05, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x4a, - 0x04, 0x08, 0x03, 0x10, 0x04, 0x22, 0xa8, 0x01, 0x0a, 0x12, 0x52, 0x65, 0x70, 0x6f, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x0c, - 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x66, 0x65, 0x74, 0x63, 0x68, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x4b, 0x0a, 0x0f, 0x43, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x66, 0x74, 0x65, 0x72, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x38, 0x0a, + 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x49, 0x0a, 0x12, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x65, 0x78, 0x70, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x65, 0x78, 0x70, + 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x63, 0x61, 0x73, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x43, 0x61, + 0x73, 0x65, 0x22, 0x46, 0x0a, 0x0f, 0x44, 0x69, 0x66, 0x66, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, + 0x73, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x78, 0x70, 0x72, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x65, 0x78, 0x70, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x67, 0x6e, + 0x6f, 0x72, 0x65, 0x5f, 0x63, 0x61, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, + 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x43, 0x61, 0x73, 0x65, 0x22, 0x4b, 0x0a, 0x14, 0x44, 0x69, + 0x66, 0x66, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x73, 0x46, 0x69, 0x6c, 0x65, 0x4e, 0x6f, + 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x78, 0x70, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x65, 0x78, 0x70, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, + 0x5f, 0x63, 0x61, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x67, 0x6e, + 0x6f, 0x72, 0x65, 0x43, 0x61, 0x73, 0x65, 0x22, 0x23, 0x0a, 0x0b, 0x42, 0x6f, 0x6f, 0x6c, 0x65, + 0x61, 0x6e, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x73, 0x0a, 0x0c, + 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x2e, 0x0a, 0x04, + 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x67, 0x69, 0x74, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, + 0x6f, 0x72, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x33, 0x0a, 0x08, + 0x6f, 0x70, 0x65, 0x72, 0x61, 0x6e, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, + 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x6e, 0x64, + 0x73, 0x22, 0x92, 0x05, 0x0a, 0x09, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4e, 0x6f, 0x64, 0x65, 0x12, + 0x48, 0x0a, 0x0e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x4d, 0x61, 0x74, + 0x63, 0x68, 0x65, 0x73, 0x4e, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x0d, 0x61, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x12, 0x51, 0x0a, 0x11, 0x63, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x4d, 0x61, 0x74, + 0x63, 0x68, 0x65, 0x73, 0x4e, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x10, 0x63, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x74, 0x65, 0x72, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x12, 0x45, 0x0a, 0x0d, + 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x4e, + 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x42, 0x65, 0x66, + 0x6f, 0x72, 0x65, 0x12, 0x42, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x61, 0x66, + 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x41, + 0x66, 0x74, 0x65, 0x72, 0x4e, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x41, 0x66, 0x74, 0x65, 0x72, 0x12, 0x4b, 0x0a, 0x0f, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x20, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x4e, 0x6f, + 0x64, 0x65, 0x48, 0x00, 0x52, 0x0e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4d, 0x61, 0x74, + 0x63, 0x68, 0x65, 0x73, 0x12, 0x42, 0x0a, 0x0c, 0x64, 0x69, 0x66, 0x66, 0x5f, 0x6d, 0x61, 0x74, + 0x63, 0x68, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x69, 0x74, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x66, 0x66, 0x4d, 0x61, + 0x74, 0x63, 0x68, 0x65, 0x73, 0x4e, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x0b, 0x64, 0x69, 0x66, + 0x66, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x12, 0x52, 0x0a, 0x12, 0x64, 0x69, 0x66, 0x66, + 0x5f, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x73, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x66, 0x66, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x73, + 0x46, 0x69, 0x6c, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x10, 0x64, 0x69, 0x66, 0x66, + 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x73, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x35, 0x0a, 0x07, + 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, + 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6f, 0x6f, + 0x6c, 0x65, 0x61, 0x6e, 0x4e, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x07, 0x62, 0x6f, 0x6f, 0x6c, + 0x65, 0x61, 0x6e, 0x12, 0x38, 0x0a, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x4e, 0x6f, 0x64, + 0x65, 0x48, 0x00, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x42, 0x07, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x6d, 0x0a, 0x0e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x05, 0x6d, 0x61, 0x74, 0x63, + 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x61, 0x74, + 0x63, 0x68, 0x48, 0x00, 0x52, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x1d, 0x0a, 0x09, 0x6c, + 0x69, 0x6d, 0x69, 0x74, 0x5f, 0x68, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, + 0x52, 0x08, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x48, 0x69, 0x74, 0x42, 0x09, 0x0a, 0x07, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xa9, 0x06, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x10, 0x0a, 0x03, 0x6f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6f, 0x69, 0x64, 0x12, 0x3b, 0x0a, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x61, 0x74, + 0x63, 0x68, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x06, 0x61, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x12, 0x41, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, + 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x61, 0x74, + 0x63, 0x68, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x63, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x73, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x66, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x04, 0x72, 0x65, 0x66, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, + 0x72, 0x65, 0x66, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x52, 0x65, 0x66, 0x73, 0x12, 0x41, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x61, 0x74, + 0x63, 0x68, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x64, 0x69, 0x66, + 0x66, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x61, 0x74, + 0x63, 0x68, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x52, 0x04, 0x64, 0x69, 0x66, 0x66, 0x12, 0x25, 0x0a, 0x0e, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, + 0x65, 0x64, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, + 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x1a, 0x65, 0x0a, + 0x09, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, + 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, + 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x2e, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0b, - 0x6c, 0x61, 0x73, 0x74, 0x46, 0x65, 0x74, 0x63, 0x68, 0x65, 0x64, 0x12, 0x3d, 0x0a, 0x0c, 0x6c, - 0x61, 0x73, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, + 0x64, 0x61, 0x74, 0x65, 0x1a, 0x62, 0x0a, 0x0d, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x53, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, + 0x37, 0x0a, 0x06, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x2e, 0x52, 0x61, 0x6e, 0x67, 0x65, + 0x52, 0x06, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x1a, 0x77, 0x0a, 0x05, 0x52, 0x61, 0x6e, 0x67, + 0x65, 0x12, 0x38, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x22, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, + 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x2e, 0x4c, 0x6f, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x34, 0x0a, 0x03, 0x65, + 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x61, + 0x74, 0x63, 0x68, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x03, 0x65, 0x6e, + 0x64, 0x1a, 0x4e, 0x0a, 0x08, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, + 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6f, + 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6c, + 0x75, 0x6d, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x63, 0x6f, 0x6c, 0x75, 0x6d, + 0x6e, 0x22, 0x74, 0x0a, 0x0e, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x72, 0x65, 0x65, 0x69, + 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x72, 0x65, 0x65, 0x69, 0x73, + 0x68, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x61, 0x74, + 0x68, 0x73, 0x70, 0x65, 0x63, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, + 0x74, 0x68, 0x73, 0x70, 0x65, 0x63, 0x73, 0x22, 0x25, 0x0a, 0x0f, 0x41, 0x72, 0x63, 0x68, 0x69, + 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x2c, + 0x0a, 0x16, 0x49, 0x73, 0x52, 0x65, 0x70, 0x6f, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x61, 0x62, 0x6c, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x70, 0x6f, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x22, 0x67, 0x0a, 0x17, + 0x49, 0x73, 0x52, 0x65, 0x70, 0x6f, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x61, 0x62, 0x6c, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x6f, 0x6e, 0x65, + 0x61, 0x62, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x63, 0x6c, 0x6f, 0x6e, + 0x65, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6c, 0x6f, 0x6e, 0x65, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x63, 0x6c, 0x6f, 0x6e, 0x65, 0x64, 0x12, 0x16, 0x0a, + 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, + 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x26, 0x0a, 0x10, 0x52, 0x65, 0x70, 0x6f, 0x43, 0x6c, 0x6f, + 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x70, + 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x22, 0x29, 0x0a, + 0x11, 0x52, 0x65, 0x70, 0x6f, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x30, 0x0a, 0x18, 0x52, 0x65, 0x70, 0x6f, + 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x05, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x22, 0x7e, 0x0a, 0x11, 0x52, 0x65, + 0x70, 0x6f, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, + 0x2a, 0x0a, 0x11, 0x63, 0x6c, 0x6f, 0x6e, 0x65, 0x5f, 0x69, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x67, + 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x63, 0x6c, 0x6f, 0x6e, + 0x65, 0x49, 0x6e, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x63, + 0x6c, 0x6f, 0x6e, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6c, 0x6f, 0x6e, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, + 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6c, 0x6f, 0x6e, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x06, 0x63, 0x6c, 0x6f, 0x6e, 0x65, 0x64, 0x22, 0xc8, 0x01, 0x0a, 0x19, 0x52, + 0x65, 0x70, 0x6f, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x67, 0x69, 0x74, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x43, 0x6c, 0x6f, + 0x6e, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, + 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x1a, 0x5b, 0x0a, 0x0c, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x35, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x43, 0x6c, 0x6f, + 0x6e, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x27, 0x0a, 0x11, 0x52, 0x65, 0x70, 0x6f, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, + 0x70, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x22, 0x14, + 0x0a, 0x12, 0x52, 0x65, 0x70, 0x6f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5e, 0x0a, 0x11, 0x52, 0x65, 0x70, 0x6f, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x70, + 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x12, 0x2f, 0x0a, + 0x05, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, + 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x4a, 0x04, + 0x08, 0x03, 0x10, 0x04, 0x22, 0xa8, 0x01, 0x0a, 0x12, 0x52, 0x65, 0x70, 0x6f, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x0c, 0x6c, + 0x61, 0x73, 0x74, 0x5f, 0x66, 0x65, 0x74, 0x63, 0x68, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0b, 0x6c, - 0x61, 0x73, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x22, 0x7f, 0x0a, 0x0d, 0x50, 0x34, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x1a, 0x0a, 0x06, 0x70, 0x34, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x06, 0x70, 0x34, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x1a, 0x0a, - 0x06, 0x70, 0x34, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, - 0x01, 0x52, 0x06, 0x70, 0x34, 0x75, 0x73, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x08, 0x70, 0x34, 0x70, - 0x61, 0x73, 0x73, 0x77, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, - 0x08, 0x70, 0x34, 0x70, 0x61, 0x73, 0x73, 0x77, 0x64, 0x12, 0x16, 0x0a, 0x04, 0x61, 0x72, 0x67, - 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x02, 0x18, 0x01, 0x52, 0x04, 0x61, 0x72, 0x67, - 0x73, 0x22, 0x28, 0x0a, 0x0e, 0x50, 0x34, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x42, 0x02, 0x18, 0x01, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x3a, 0x0a, 0x13, 0x4c, - 0x69, 0x73, 0x74, 0x47, 0x69, 0x74, 0x6f, 0x6c, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x67, 0x69, 0x74, 0x6f, 0x6c, 0x69, 0x74, 0x65, 0x5f, 0x68, - 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x67, 0x69, 0x74, 0x6f, 0x6c, - 0x69, 0x74, 0x65, 0x48, 0x6f, 0x73, 0x74, 0x22, 0x34, 0x0a, 0x0c, 0x47, 0x69, 0x74, 0x6f, 0x6c, - 0x69, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, - 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0x48, 0x0a, - 0x14, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, 0x74, 0x6f, 0x6c, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x05, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x6f, 0x6c, 0x69, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, - 0x52, 0x05, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x22, 0x47, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x4f, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x72, - 0x65, 0x70, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x12, - 0x1f, 0x0a, 0x0b, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, - 0x22, 0x44, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x06, - 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0xd8, 0x01, 0x0a, 0x09, 0x47, 0x69, 0x74, 0x4f, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x02, 0x69, 0x64, 0x12, 0x36, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x2e, 0x47, 0x69, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x4f, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x82, 0x01, 0x0a, - 0x0a, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x4f, - 0x42, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, - 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x4f, 0x42, 0x4a, 0x45, - 0x43, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x10, 0x01, - 0x12, 0x13, 0x0a, 0x0f, 0x4f, 0x42, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, - 0x54, 0x41, 0x47, 0x10, 0x02, 0x12, 0x14, 0x0a, 0x10, 0x4f, 0x42, 0x4a, 0x45, 0x43, 0x54, 0x5f, - 0x54, 0x59, 0x50, 0x45, 0x5f, 0x54, 0x52, 0x45, 0x45, 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x4f, - 0x42, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x4c, 0x4f, 0x42, 0x10, - 0x04, 0x22, 0x97, 0x01, 0x0a, 0x1e, 0x49, 0x73, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, - 0x50, 0x61, 0x74, 0x68, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x56, 0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x27, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, - 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x11, 0x63, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x1d, 0x0a, 0x0a, - 0x64, 0x65, 0x70, 0x6f, 0x74, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x64, 0x65, 0x70, 0x6f, 0x74, 0x50, 0x61, 0x74, 0x68, 0x22, 0x21, 0x0a, 0x1f, 0x49, - 0x73, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x43, 0x6c, 0x6f, - 0x6e, 0x65, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x79, - 0x0a, 0x1f, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x43, - 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x56, 0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, - 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, - 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, - 0x66, 0x6f, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, - 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x11, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x22, 0x0a, 0x20, 0x43, 0x68, 0x65, - 0x63, 0x6b, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, - 0x74, 0x69, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x67, 0x0a, - 0x19, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x34, - 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x34, 0x70, 0x6f, - 0x72, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x34, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x70, 0x34, 0x75, 0x73, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x34, - 0x70, 0x61, 0x73, 0x73, 0x77, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x34, - 0x70, 0x61, 0x73, 0x73, 0x77, 0x64, 0x22, 0x9b, 0x01, 0x0a, 0x1c, 0x50, 0x65, 0x72, 0x66, 0x6f, - 0x72, 0x63, 0x65, 0x47, 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x69, 0x73, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x56, 0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, - 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x11, 0x63, 0x6f, - 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, - 0x23, 0x0a, 0x0d, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x69, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x69, - 0x73, 0x74, 0x49, 0x64, 0x22, 0x61, 0x0a, 0x1d, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, - 0x47, 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x6c, - 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x67, 0x69, 0x74, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, - 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x52, 0x0a, 0x63, 0x68, 0x61, - 0x6e, 0x67, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x22, 0xe1, 0x03, 0x0a, 0x12, 0x50, 0x65, 0x72, 0x66, - 0x6f, 0x72, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x0e, - 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x3f, - 0x0a, 0x0d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x52, 0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x65, 0x12, - 0x4e, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x38, - 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, - 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x69, 0x73, 0x74, - 0x2e, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x6c, - 0x69, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, - 0x16, 0x0a, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x18, 0x0a, - 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xe1, 0x01, 0x0a, 0x17, 0x50, 0x65, 0x72, 0x66, - 0x6f, 0x72, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x12, 0x29, 0x0a, 0x25, 0x50, 0x45, 0x52, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x5f, - 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x4c, 0x49, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, - 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x27, - 0x0a, 0x23, 0x50, 0x45, 0x52, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, - 0x45, 0x4c, 0x49, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x55, 0x42, 0x4d, - 0x49, 0x54, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x25, 0x0a, 0x21, 0x50, 0x45, 0x52, 0x46, 0x4f, - 0x52, 0x43, 0x45, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x4c, 0x49, 0x53, 0x54, 0x5f, 0x53, - 0x54, 0x41, 0x54, 0x45, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x25, - 0x0a, 0x21, 0x50, 0x45, 0x52, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, - 0x45, 0x4c, 0x49, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x48, 0x45, 0x4c, - 0x56, 0x45, 0x44, 0x10, 0x03, 0x12, 0x24, 0x0a, 0x20, 0x50, 0x45, 0x52, 0x46, 0x4f, 0x52, 0x43, - 0x45, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x4c, 0x49, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x41, - 0x54, 0x45, 0x5f, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0x10, 0x04, 0x22, 0x74, 0x0a, 0x1a, 0x49, - 0x73, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x53, 0x75, 0x70, 0x65, 0x72, 0x55, 0x73, - 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x56, 0x0a, 0x12, 0x63, 0x6f, 0x6e, - 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, - 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x11, - 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, - 0x73, 0x22, 0x1d, 0x0a, 0x1b, 0x49, 0x73, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x53, - 0x75, 0x70, 0x65, 0x72, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x8f, 0x01, 0x0a, 0x1f, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x50, 0x72, 0x6f, - 0x74, 0x65, 0x63, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x44, 0x65, 0x70, 0x6f, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x56, 0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x27, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, - 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x11, 0x63, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x14, 0x0a, 0x05, - 0x64, 0x65, 0x70, 0x6f, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x64, 0x65, 0x70, - 0x6f, 0x74, 0x22, 0x5d, 0x0a, 0x20, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x50, 0x72, - 0x6f, 0x74, 0x65, 0x63, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x44, 0x65, 0x70, 0x6f, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, - 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, - 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, - 0x73, 0x22, 0x94, 0x01, 0x0a, 0x1e, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x50, 0x72, - 0x6f, 0x74, 0x65, 0x63, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x56, 0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x27, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, - 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x11, 0x63, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x1a, 0x0a, 0x08, - 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x5c, 0x0a, 0x1f, 0x50, 0x65, 0x72, 0x66, - 0x6f, 0x72, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x55, - 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x08, 0x70, - 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, - 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, - 0x66, 0x6f, 0x72, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x52, 0x08, 0x70, 0x72, - 0x6f, 0x74, 0x65, 0x63, 0x74, 0x73, 0x22, 0xb6, 0x01, 0x0a, 0x0f, 0x50, 0x65, 0x72, 0x66, 0x6f, - 0x72, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x65, - 0x76, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, - 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x4e, 0x61, - 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x65, - 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, - 0x69, 0x73, 0x45, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x68, - 0x6f, 0x73, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x22, - 0x8b, 0x01, 0x0a, 0x1b, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, - 0x70, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x56, 0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x65, - 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x67, 0x69, - 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x6f, - 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, - 0x61, 0x69, 0x6c, 0x73, 0x52, 0x11, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x3c, 0x0a, - 0x1c, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, - 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, - 0x09, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x6e, 0x0a, 0x14, 0x50, - 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x61, 0x73, 0x74, 0x46, 0x65, 0x74, 0x63, 0x68, 0x65, 0x64, 0x12, 0x3d, 0x0a, 0x0c, 0x6c, 0x61, + 0x73, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0b, 0x6c, 0x61, + 0x73, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, + 0x7f, 0x0a, 0x0d, 0x50, 0x34, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x1a, 0x0a, 0x06, 0x70, 0x34, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x02, 0x18, 0x01, 0x52, 0x06, 0x70, 0x34, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x1a, 0x0a, 0x06, + 0x70, 0x34, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, + 0x52, 0x06, 0x70, 0x34, 0x75, 0x73, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x08, 0x70, 0x34, 0x70, 0x61, + 0x73, 0x73, 0x77, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x08, + 0x70, 0x34, 0x70, 0x61, 0x73, 0x73, 0x77, 0x64, 0x12, 0x16, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x73, + 0x18, 0x04, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x02, 0x18, 0x01, 0x52, 0x04, 0x61, 0x72, 0x67, 0x73, + 0x22, 0x28, 0x0a, 0x0e, 0x50, 0x34, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x16, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x42, 0x02, 0x18, 0x01, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x3a, 0x0a, 0x13, 0x4c, 0x69, + 0x73, 0x74, 0x47, 0x69, 0x74, 0x6f, 0x6c, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x67, 0x69, 0x74, 0x6f, 0x6c, 0x69, 0x74, 0x65, 0x5f, 0x68, 0x6f, + 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x67, 0x69, 0x74, 0x6f, 0x6c, 0x69, + 0x74, 0x65, 0x48, 0x6f, 0x73, 0x74, 0x22, 0x34, 0x0a, 0x0c, 0x47, 0x69, 0x74, 0x6f, 0x6c, 0x69, + 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, + 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0x48, 0x0a, 0x14, + 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, 0x74, 0x6f, 0x6c, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x05, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x6f, 0x6c, 0x69, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x52, + 0x05, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x22, 0x47, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x4f, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, + 0x70, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x12, 0x1f, + 0x0a, 0x0b, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x22, + 0x44, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x06, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0xd8, 0x01, 0x0a, 0x09, 0x47, 0x69, 0x74, 0x4f, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x02, 0x69, 0x64, 0x12, 0x36, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x22, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, + 0x2e, 0x47, 0x69, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x82, 0x01, 0x0a, 0x0a, + 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x4f, 0x42, + 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x4f, 0x42, 0x4a, 0x45, 0x43, + 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x10, 0x01, 0x12, + 0x13, 0x0a, 0x0f, 0x4f, 0x42, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x54, + 0x41, 0x47, 0x10, 0x02, 0x12, 0x14, 0x0a, 0x10, 0x4f, 0x42, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x54, + 0x59, 0x50, 0x45, 0x5f, 0x54, 0x52, 0x45, 0x45, 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x4f, 0x42, + 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x4c, 0x4f, 0x42, 0x10, 0x04, + 0x22, 0x97, 0x01, 0x0a, 0x1e, 0x49, 0x73, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x50, + 0x61, 0x74, 0x68, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x56, 0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x11, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x49, 0x0a, 0x15, 0x50, - 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, - 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, - 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x22, 0x40, 0x0a, 0x0c, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, - 0x63, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x57, 0x0a, 0x10, 0x4d, 0x65, 0x72, 0x67, - 0x65, 0x42, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, - 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x72, 0x65, 0x70, 0x6f, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x61, 0x73, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x62, 0x61, 0x73, 0x65, 0x12, 0x12, 0x0a, - 0x04, 0x68, 0x65, 0x61, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x65, 0x61, - 0x64, 0x22, 0x46, 0x0a, 0x11, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x42, 0x61, 0x73, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x15, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x5f, - 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x73, 0x68, 0x61, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x42, 0x61, 0x73, 0x65, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x68, 0x61, 0x2a, 0x71, 0x0a, 0x0c, 0x4f, 0x70, 0x65, - 0x72, 0x61, 0x74, 0x6f, 0x72, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x1d, 0x0a, 0x19, 0x4f, 0x50, 0x45, - 0x52, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, - 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x4f, 0x50, 0x45, 0x52, - 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x41, 0x4e, 0x44, 0x10, 0x01, 0x12, - 0x14, 0x0a, 0x10, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x4b, 0x49, 0x4e, 0x44, - 0x5f, 0x4f, 0x52, 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x4f, - 0x52, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4e, 0x4f, 0x54, 0x10, 0x03, 0x32, 0xeb, 0x11, 0x0a, - 0x10, 0x47, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x12, 0x51, 0x0a, 0x08, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x6f, 0x67, 0x12, 0x1d, 0x2e, - 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, - 0x63, 0x68, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x67, + 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x64, + 0x65, 0x70, 0x6f, 0x74, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x64, 0x65, 0x70, 0x6f, 0x74, 0x50, 0x61, 0x74, 0x68, 0x22, 0x21, 0x0a, 0x1f, 0x49, 0x73, + 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x43, 0x6c, 0x6f, 0x6e, + 0x65, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x79, 0x0a, + 0x1f, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x43, 0x72, + 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x56, 0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, + 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x67, + 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x66, + 0x6f, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, + 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x11, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x22, 0x0a, 0x20, 0x43, 0x68, 0x65, 0x63, + 0x6b, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x67, 0x0a, 0x19, + 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x34, 0x70, + 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x34, 0x70, 0x6f, 0x72, + 0x74, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x34, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x70, 0x34, 0x75, 0x73, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x34, 0x70, + 0x61, 0x73, 0x73, 0x77, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x34, 0x70, + 0x61, 0x73, 0x73, 0x77, 0x64, 0x22, 0x9b, 0x01, 0x0a, 0x1c, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, + 0x63, 0x65, 0x47, 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x56, 0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, + 0x31, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x11, 0x63, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x23, + 0x0a, 0x0d, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x69, 0x73, + 0x74, 0x49, 0x64, 0x22, 0x61, 0x0a, 0x1d, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x47, + 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x69, + 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, + 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x52, 0x0a, 0x63, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x22, 0xe1, 0x03, 0x0a, 0x12, 0x50, 0x65, 0x72, 0x66, 0x6f, + 0x72, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x3f, 0x0a, + 0x0d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x52, 0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x65, 0x12, 0x4e, + 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x38, 0x2e, + 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, + 0x66, 0x6f, 0x72, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x2e, + 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x69, + 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x16, + 0x0a, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xe1, 0x01, 0x0a, 0x17, 0x50, 0x65, 0x72, 0x66, 0x6f, + 0x72, 0x63, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x12, 0x29, 0x0a, 0x25, 0x50, 0x45, 0x52, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x5f, 0x43, + 0x48, 0x41, 0x4e, 0x47, 0x45, 0x4c, 0x49, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, + 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x27, 0x0a, + 0x23, 0x50, 0x45, 0x52, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, + 0x4c, 0x49, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x55, 0x42, 0x4d, 0x49, + 0x54, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x25, 0x0a, 0x21, 0x50, 0x45, 0x52, 0x46, 0x4f, 0x52, + 0x43, 0x45, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x4c, 0x49, 0x53, 0x54, 0x5f, 0x53, 0x54, + 0x41, 0x54, 0x45, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x25, 0x0a, + 0x21, 0x50, 0x45, 0x52, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, + 0x4c, 0x49, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x48, 0x45, 0x4c, 0x56, + 0x45, 0x44, 0x10, 0x03, 0x12, 0x24, 0x0a, 0x20, 0x50, 0x45, 0x52, 0x46, 0x4f, 0x52, 0x43, 0x45, + 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x4c, 0x49, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, + 0x45, 0x5f, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0x10, 0x04, 0x22, 0x74, 0x0a, 0x1a, 0x49, 0x73, + 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x53, 0x75, 0x70, 0x65, 0x72, 0x55, 0x73, 0x65, + 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x56, 0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x11, 0x63, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, + 0x22, 0x1d, 0x0a, 0x1b, 0x49, 0x73, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x53, 0x75, + 0x70, 0x65, 0x72, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x8f, 0x01, 0x0a, 0x1f, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, + 0x65, 0x63, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x44, 0x65, 0x70, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x56, 0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x27, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, + 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x11, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x64, + 0x65, 0x70, 0x6f, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x64, 0x65, 0x70, 0x6f, + 0x74, 0x22, 0x5d, 0x0a, 0x20, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x50, 0x72, 0x6f, + 0x74, 0x65, 0x63, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x44, 0x65, 0x70, 0x6f, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x50, + 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x73, + 0x22, 0x94, 0x01, 0x0a, 0x1e, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x50, 0x72, 0x6f, + 0x74, 0x65, 0x63, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x56, 0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x27, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, + 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x11, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x75, + 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, + 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x5c, 0x0a, 0x1f, 0x50, 0x65, 0x72, 0x66, 0x6f, + 0x72, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x55, 0x73, + 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x08, 0x70, 0x72, + 0x6f, 0x74, 0x65, 0x63, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, + 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x66, + 0x6f, 0x72, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x52, 0x08, 0x70, 0x72, 0x6f, + 0x74, 0x65, 0x63, 0x74, 0x73, 0x22, 0xb6, 0x01, 0x0a, 0x0f, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, + 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x65, 0x76, + 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, + 0x1f, 0x0a, 0x0b, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x65, 0x78, + 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, + 0x73, 0x45, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, + 0x73, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x22, 0x8b, + 0x01, 0x0a, 0x1b, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, + 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x56, + 0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x65, 0x74, + 0x61, 0x69, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x67, 0x69, 0x74, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, + 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, + 0x69, 0x6c, 0x73, 0x52, 0x11, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, + 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x3c, 0x0a, 0x1c, + 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, + 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x09, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x6e, 0x0a, 0x14, 0x50, 0x65, + 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x56, 0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, + 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, + 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x11, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x49, 0x0a, 0x15, 0x50, 0x65, + 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, + 0x31, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x05, + 0x75, 0x73, 0x65, 0x72, 0x73, 0x22, 0x40, 0x0a, 0x0c, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, + 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x57, 0x0a, 0x10, 0x4d, 0x65, 0x72, 0x67, 0x65, + 0x42, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x72, + 0x65, 0x70, 0x6f, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x72, 0x65, 0x70, 0x6f, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x61, 0x73, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x62, 0x61, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x68, 0x65, 0x61, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x65, 0x61, 0x64, + 0x22, 0x46, 0x0a, 0x11, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x42, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x15, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x5f, 0x62, + 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x73, 0x68, 0x61, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x42, 0x61, 0x73, 0x65, 0x43, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x68, 0x61, 0x2a, 0x71, 0x0a, 0x0c, 0x4f, 0x70, 0x65, 0x72, + 0x61, 0x74, 0x6f, 0x72, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x1d, 0x0a, 0x19, 0x4f, 0x50, 0x45, 0x52, + 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x4f, 0x50, 0x45, 0x52, 0x41, + 0x54, 0x4f, 0x52, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x41, 0x4e, 0x44, 0x10, 0x01, 0x12, 0x14, + 0x0a, 0x10, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, + 0x4f, 0x52, 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x4f, 0x52, + 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4e, 0x4f, 0x54, 0x10, 0x03, 0x32, 0xb4, 0x12, 0x0a, 0x10, + 0x47, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x12, 0x51, 0x0a, 0x08, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x6f, 0x67, 0x12, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, - 0x68, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0x88, 0x02, - 0x01, 0x90, 0x02, 0x01, 0x12, 0x86, 0x01, 0x0a, 0x1b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x50, 0x61, 0x74, 0x63, 0x68, 0x42, 0x69, - 0x6e, 0x61, 0x72, 0x79, 0x12, 0x30, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, - 0x46, 0x72, 0x6f, 0x6d, 0x50, 0x61, 0x74, 0x63, 0x68, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x50, 0x61, 0x74, 0x63, 0x68, 0x42, 0x69, 0x6e, 0x61, 0x72, - 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x12, 0x4e, 0x0a, - 0x08, 0x44, 0x69, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x6b, 0x49, 0x6e, 0x66, - 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, + 0x68, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x67, 0x69, + 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, + 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x06, 0x88, 0x02, 0x01, + 0x90, 0x02, 0x01, 0x12, 0x86, 0x01, 0x0a, 0x1b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x50, 0x61, 0x74, 0x63, 0x68, 0x42, 0x69, 0x6e, + 0x61, 0x72, 0x79, 0x12, 0x30, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x46, + 0x72, 0x6f, 0x6d, 0x50, 0x61, 0x74, 0x63, 0x68, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x50, 0x61, 0x74, 0x63, 0x68, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x12, 0x4e, 0x0a, 0x08, + 0x44, 0x69, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x41, 0x0a, - 0x04, 0x45, 0x78, 0x65, 0x63, 0x12, 0x19, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, - 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, - 0x12, 0x51, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1e, 0x2e, - 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, - 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, - 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, - 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, - 0x90, 0x02, 0x01, 0x12, 0x63, 0x0a, 0x0f, 0x49, 0x73, 0x52, 0x65, 0x70, 0x6f, 0x43, 0x6c, 0x6f, - 0x6e, 0x65, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x24, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x73, 0x52, 0x65, 0x70, 0x6f, 0x43, 0x6c, 0x6f, 0x6e, - 0x65, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x67, - 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x73, 0x52, 0x65, - 0x70, 0x6f, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x5a, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, - 0x47, 0x69, 0x74, 0x6f, 0x6c, 0x69, 0x74, 0x65, 0x12, 0x21, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, 0x74, 0x6f, - 0x6c, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x67, 0x69, - 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, - 0x69, 0x74, 0x6f, 0x6c, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x03, 0x90, 0x02, 0x01, 0x12, 0x4a, 0x0a, 0x06, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x1b, - 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, - 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x67, 0x69, - 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, - 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x30, 0x01, - 0x12, 0x4d, 0x0a, 0x07, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x12, 0x1c, 0x2e, 0x67, 0x69, - 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x72, 0x63, 0x68, 0x69, - 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x41, 0x0a, 0x04, + 0x45, 0x78, 0x65, 0x63, 0x12, 0x19, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x45, + 0x78, 0x65, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, + 0x51, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1e, 0x2e, 0x67, + 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x67, + 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, + 0x02, 0x01, 0x12, 0x63, 0x0a, 0x0f, 0x49, 0x73, 0x52, 0x65, 0x70, 0x6f, 0x43, 0x6c, 0x6f, 0x6e, + 0x65, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x24, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x73, 0x52, 0x65, 0x70, 0x6f, 0x43, 0x6c, 0x6f, 0x6e, 0x65, + 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x67, 0x69, + 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x73, 0x52, 0x65, 0x70, + 0x6f, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x5a, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x47, + 0x69, 0x74, 0x6f, 0x6c, 0x69, 0x74, 0x65, 0x12, 0x21, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, 0x74, 0x6f, 0x6c, + 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x67, 0x69, 0x74, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, + 0x74, 0x6f, 0x6c, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, + 0x90, 0x02, 0x01, 0x12, 0x4a, 0x0a, 0x06, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x1b, 0x2e, + 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x61, + 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x67, 0x69, 0x74, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x30, 0x01, 0x12, - 0x4a, 0x0a, 0x06, 0x50, 0x34, 0x45, 0x78, 0x65, 0x63, 0x12, 0x1b, 0x2e, 0x67, 0x69, 0x74, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x34, 0x45, 0x78, 0x65, 0x63, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x34, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x88, 0x02, 0x01, 0x30, 0x01, 0x12, 0x51, 0x0a, 0x09, 0x52, - 0x65, 0x70, 0x6f, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x12, 0x1e, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x43, 0x6c, 0x6f, 0x6e, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x43, 0x6c, 0x6f, 0x6e, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x02, 0x12, 0x69, - 0x0a, 0x11, 0x52, 0x65, 0x70, 0x6f, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, - 0x65, 0x73, 0x73, 0x12, 0x26, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, - 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x50, 0x72, 0x6f, 0x67, - 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x67, 0x69, - 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x43, - 0x6c, 0x6f, 0x6e, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x51, 0x0a, 0x0a, 0x52, 0x65, 0x70, - 0x6f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, + 0x4d, 0x0a, 0x07, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x12, 0x1c, 0x2e, 0x67, 0x69, 0x74, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x30, 0x01, 0x12, 0x4a, + 0x0a, 0x06, 0x50, 0x34, 0x45, 0x78, 0x65, 0x63, 0x12, 0x1b, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x34, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x34, 0x45, 0x78, 0x65, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x03, 0x88, 0x02, 0x01, 0x30, 0x01, 0x12, 0x51, 0x0a, 0x09, 0x52, 0x65, + 0x70, 0x6f, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x12, 0x1e, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x43, 0x6c, 0x6f, 0x6e, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x43, 0x6c, 0x6f, 0x6e, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x02, 0x12, 0x69, 0x0a, + 0x11, 0x52, 0x65, 0x70, 0x6f, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, + 0x73, 0x73, 0x12, 0x26, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, + 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, + 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x67, 0x69, 0x74, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x43, 0x6c, + 0x6f, 0x6e, 0x65, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x51, 0x0a, 0x0a, 0x52, 0x65, 0x70, 0x6f, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x54, 0x0a, 0x0a, - 0x52, 0x65, 0x70, 0x6f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x1f, 0x2e, 0x67, 0x69, 0x74, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x54, 0x0a, 0x0a, 0x52, + 0x65, 0x70, 0x6f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x67, 0x69, - 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, - 0x02, 0x02, 0x12, 0x7b, 0x0a, 0x17, 0x49, 0x73, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, - 0x50, 0x61, 0x74, 0x68, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x2c, 0x2e, - 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x73, 0x50, - 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x43, 0x6c, 0x6f, 0x6e, 0x65, - 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x67, 0x69, - 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x73, 0x50, 0x65, 0x72, - 0x66, 0x6f, 0x72, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x61, 0x62, - 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, - 0x7e, 0x0a, 0x18, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, - 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x2d, 0x2e, 0x67, 0x69, - 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, - 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x67, 0x69, 0x74, + 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, + 0x02, 0x12, 0x7b, 0x0a, 0x17, 0x49, 0x73, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x50, + 0x61, 0x74, 0x68, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x2c, 0x2e, 0x67, + 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x73, 0x50, 0x65, + 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x61, + 0x62, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x67, 0x69, 0x74, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x73, 0x50, 0x65, 0x72, 0x66, + 0x6f, 0x72, 0x63, 0x65, 0x50, 0x61, 0x74, 0x68, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x61, 0x62, 0x6c, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x7e, + 0x0a, 0x18, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x43, + 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x2d, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, - 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, - 0x5d, 0x0a, 0x0d, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x55, 0x73, 0x65, 0x72, 0x73, - 0x12, 0x22, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, - 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x55, 0x73, 0x65, 0x72, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x7b, - 0x0a, 0x17, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, - 0x74, 0x73, 0x46, 0x6f, 0x72, 0x55, 0x73, 0x65, 0x72, 0x12, 0x2c, 0x2e, 0x67, 0x69, 0x74, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, - 0x65, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x55, 0x73, 0x65, 0x72, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x50, - 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x7e, 0x0a, 0x18, 0x50, - 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x73, 0x46, - 0x6f, 0x72, 0x44, 0x65, 0x70, 0x6f, 0x74, 0x12, 0x2d, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x50, - 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x44, 0x65, 0x70, 0x6f, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, + 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x67, 0x69, 0x74, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x50, 0x65, + 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x5d, + 0x0a, 0x0d, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, + 0x22, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, + 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x55, 0x73, 0x65, 0x72, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x7b, 0x0a, + 0x17, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, + 0x73, 0x46, 0x6f, 0x72, 0x55, 0x73, 0x65, 0x72, 0x12, 0x2c, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, + 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x55, 0x73, 0x65, 0x72, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x50, 0x72, + 0x6f, 0x74, 0x65, 0x63, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x7e, 0x0a, 0x18, 0x50, 0x65, + 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x73, 0x46, 0x6f, + 0x72, 0x44, 0x65, 0x70, 0x6f, 0x74, 0x12, 0x2d, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x44, 0x65, 0x70, 0x6f, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x72, 0x0a, 0x14, 0x50, - 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, 0x6d, 0x62, - 0x65, 0x72, 0x73, 0x12, 0x29, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, - 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, - 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, - 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x50, 0x72, 0x6f, + 0x74, 0x65, 0x63, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x44, 0x65, 0x70, 0x6f, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x72, 0x0a, 0x14, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, 0x6d, 0x62, 0x65, - 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, - 0x6f, 0x0a, 0x13, 0x49, 0x73, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x53, 0x75, 0x70, - 0x65, 0x72, 0x55, 0x73, 0x65, 0x72, 0x12, 0x28, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x73, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, - 0x53, 0x75, 0x70, 0x65, 0x72, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x29, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, - 0x49, 0x73, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x53, 0x75, 0x70, 0x65, 0x72, 0x55, - 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, - 0x12, 0x75, 0x0a, 0x15, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x47, 0x65, 0x74, 0x43, - 0x68, 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x2a, 0x2e, 0x67, 0x69, 0x74, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, - 0x65, 0x47, 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x47, 0x65, 0x74, - 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x51, 0x0a, 0x09, 0x4d, 0x65, 0x72, 0x67, 0x65, - 0x42, 0x61, 0x73, 0x65, 0x12, 0x1e, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x42, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x42, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x42, 0x3a, 0x5a, 0x38, 0x67, 0x69, - 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x67, - 0x72, 0x61, 0x70, 0x68, 0x2f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x67, 0x72, 0x61, 0x70, 0x68, - 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x72, 0x73, 0x12, 0x29, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, + 0x31, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d, + 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, + 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, + 0x66, 0x6f, 0x72, 0x63, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x6f, + 0x0a, 0x13, 0x49, 0x73, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x53, 0x75, 0x70, 0x65, + 0x72, 0x55, 0x73, 0x65, 0x72, 0x12, 0x28, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x73, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x53, + 0x75, 0x70, 0x65, 0x72, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x29, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x49, + 0x73, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x53, 0x75, 0x70, 0x65, 0x72, 0x55, 0x73, + 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, + 0x75, 0x0a, 0x15, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x47, 0x65, 0x74, 0x43, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x2a, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, + 0x47, 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x47, 0x65, 0x74, 0x43, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x51, 0x0a, 0x09, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x42, + 0x61, 0x73, 0x65, 0x12, 0x1e, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x42, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x42, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x47, 0x0a, 0x05, 0x42, 0x6c, 0x61, + 0x6d, 0x65, 0x12, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, + 0x31, 0x2e, 0x42, 0x6c, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, + 0x2e, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6c, + 0x61, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, + 0x30, 0x01, 0x42, 0x3a, 0x5a, 0x38, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x2f, 0x67, 0x69, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -5716,199 +6141,209 @@ func file_gitserver_proto_rawDescGZIP() []byte { } var file_gitserver_proto_enumTypes = make([]protoimpl.EnumInfo, 3) -var file_gitserver_proto_msgTypes = make([]protoimpl.MessageInfo, 79) +var file_gitserver_proto_msgTypes = make([]protoimpl.MessageInfo, 84) var file_gitserver_proto_goTypes = []interface{}{ (OperatorKind)(0), // 0: gitserver.v1.OperatorKind (GitObject_ObjectType)(0), // 1: gitserver.v1.GitObject.ObjectType (PerforceChangelist_PerforceChangelistState)(0), // 2: gitserver.v1.PerforceChangelist.PerforceChangelistState - (*DiskInfoRequest)(nil), // 3: gitserver.v1.DiskInfoRequest - (*DiskInfoResponse)(nil), // 4: gitserver.v1.DiskInfoResponse - (*BatchLogRequest)(nil), // 5: gitserver.v1.BatchLogRequest - (*BatchLogResponse)(nil), // 6: gitserver.v1.BatchLogResponse - (*BatchLogResult)(nil), // 7: gitserver.v1.BatchLogResult - (*RepoCommit)(nil), // 8: gitserver.v1.RepoCommit - (*PatchCommitInfo)(nil), // 9: gitserver.v1.PatchCommitInfo - (*PushConfig)(nil), // 10: gitserver.v1.PushConfig - (*CreateCommitFromPatchBinaryRequest)(nil), // 11: gitserver.v1.CreateCommitFromPatchBinaryRequest - (*CreateCommitFromPatchError)(nil), // 12: gitserver.v1.CreateCommitFromPatchError - (*CreateCommitFromPatchBinaryResponse)(nil), // 13: gitserver.v1.CreateCommitFromPatchBinaryResponse - (*ExecRequest)(nil), // 14: gitserver.v1.ExecRequest - (*ExecResponse)(nil), // 15: gitserver.v1.ExecResponse - (*NotFoundPayload)(nil), // 16: gitserver.v1.NotFoundPayload - (*ExecStatusPayload)(nil), // 17: gitserver.v1.ExecStatusPayload - (*SearchRequest)(nil), // 18: gitserver.v1.SearchRequest - (*RevisionSpecifier)(nil), // 19: gitserver.v1.RevisionSpecifier - (*AuthorMatchesNode)(nil), // 20: gitserver.v1.AuthorMatchesNode - (*CommitterMatchesNode)(nil), // 21: gitserver.v1.CommitterMatchesNode - (*CommitBeforeNode)(nil), // 22: gitserver.v1.CommitBeforeNode - (*CommitAfterNode)(nil), // 23: gitserver.v1.CommitAfterNode - (*MessageMatchesNode)(nil), // 24: gitserver.v1.MessageMatchesNode - (*DiffMatchesNode)(nil), // 25: gitserver.v1.DiffMatchesNode - (*DiffModifiesFileNode)(nil), // 26: gitserver.v1.DiffModifiesFileNode - (*BooleanNode)(nil), // 27: gitserver.v1.BooleanNode - (*OperatorNode)(nil), // 28: gitserver.v1.OperatorNode - (*QueryNode)(nil), // 29: gitserver.v1.QueryNode - (*SearchResponse)(nil), // 30: gitserver.v1.SearchResponse - (*CommitMatch)(nil), // 31: gitserver.v1.CommitMatch - (*ArchiveRequest)(nil), // 32: gitserver.v1.ArchiveRequest - (*ArchiveResponse)(nil), // 33: gitserver.v1.ArchiveResponse - (*IsRepoCloneableRequest)(nil), // 34: gitserver.v1.IsRepoCloneableRequest - (*IsRepoCloneableResponse)(nil), // 35: gitserver.v1.IsRepoCloneableResponse - (*RepoCloneRequest)(nil), // 36: gitserver.v1.RepoCloneRequest - (*RepoCloneResponse)(nil), // 37: gitserver.v1.RepoCloneResponse - (*RepoCloneProgressRequest)(nil), // 38: gitserver.v1.RepoCloneProgressRequest - (*RepoCloneProgress)(nil), // 39: gitserver.v1.RepoCloneProgress - (*RepoCloneProgressResponse)(nil), // 40: gitserver.v1.RepoCloneProgressResponse - (*RepoDeleteRequest)(nil), // 41: gitserver.v1.RepoDeleteRequest - (*RepoDeleteResponse)(nil), // 42: gitserver.v1.RepoDeleteResponse - (*RepoUpdateRequest)(nil), // 43: gitserver.v1.RepoUpdateRequest - (*RepoUpdateResponse)(nil), // 44: gitserver.v1.RepoUpdateResponse - (*P4ExecRequest)(nil), // 45: gitserver.v1.P4ExecRequest - (*P4ExecResponse)(nil), // 46: gitserver.v1.P4ExecResponse - (*ListGitoliteRequest)(nil), // 47: gitserver.v1.ListGitoliteRequest - (*GitoliteRepo)(nil), // 48: gitserver.v1.GitoliteRepo - (*ListGitoliteResponse)(nil), // 49: gitserver.v1.ListGitoliteResponse - (*GetObjectRequest)(nil), // 50: gitserver.v1.GetObjectRequest - (*GetObjectResponse)(nil), // 51: gitserver.v1.GetObjectResponse - (*GitObject)(nil), // 52: gitserver.v1.GitObject - (*IsPerforcePathCloneableRequest)(nil), // 53: gitserver.v1.IsPerforcePathCloneableRequest - (*IsPerforcePathCloneableResponse)(nil), // 54: gitserver.v1.IsPerforcePathCloneableResponse - (*CheckPerforceCredentialsRequest)(nil), // 55: gitserver.v1.CheckPerforceCredentialsRequest - (*CheckPerforceCredentialsResponse)(nil), // 56: gitserver.v1.CheckPerforceCredentialsResponse - (*PerforceConnectionDetails)(nil), // 57: gitserver.v1.PerforceConnectionDetails - (*PerforceGetChangelistRequest)(nil), // 58: gitserver.v1.PerforceGetChangelistRequest - (*PerforceGetChangelistResponse)(nil), // 59: gitserver.v1.PerforceGetChangelistResponse - (*PerforceChangelist)(nil), // 60: gitserver.v1.PerforceChangelist - (*IsPerforceSuperUserRequest)(nil), // 61: gitserver.v1.IsPerforceSuperUserRequest - (*IsPerforceSuperUserResponse)(nil), // 62: gitserver.v1.IsPerforceSuperUserResponse - (*PerforceProtectsForDepotRequest)(nil), // 63: gitserver.v1.PerforceProtectsForDepotRequest - (*PerforceProtectsForDepotResponse)(nil), // 64: gitserver.v1.PerforceProtectsForDepotResponse - (*PerforceProtectsForUserRequest)(nil), // 65: gitserver.v1.PerforceProtectsForUserRequest - (*PerforceProtectsForUserResponse)(nil), // 66: gitserver.v1.PerforceProtectsForUserResponse - (*PerforceProtect)(nil), // 67: gitserver.v1.PerforceProtect - (*PerforceGroupMembersRequest)(nil), // 68: gitserver.v1.PerforceGroupMembersRequest - (*PerforceGroupMembersResponse)(nil), // 69: gitserver.v1.PerforceGroupMembersResponse - (*PerforceUsersRequest)(nil), // 70: gitserver.v1.PerforceUsersRequest - (*PerforceUsersResponse)(nil), // 71: gitserver.v1.PerforceUsersResponse - (*PerforceUser)(nil), // 72: gitserver.v1.PerforceUser - (*MergeBaseRequest)(nil), // 73: gitserver.v1.MergeBaseRequest - (*MergeBaseResponse)(nil), // 74: gitserver.v1.MergeBaseResponse - (*CreateCommitFromPatchBinaryRequest_Metadata)(nil), // 75: gitserver.v1.CreateCommitFromPatchBinaryRequest.Metadata - (*CreateCommitFromPatchBinaryRequest_Patch)(nil), // 76: gitserver.v1.CreateCommitFromPatchBinaryRequest.Patch - (*CommitMatch_Signature)(nil), // 77: gitserver.v1.CommitMatch.Signature - (*CommitMatch_MatchedString)(nil), // 78: gitserver.v1.CommitMatch.MatchedString - (*CommitMatch_Range)(nil), // 79: gitserver.v1.CommitMatch.Range - (*CommitMatch_Location)(nil), // 80: gitserver.v1.CommitMatch.Location - nil, // 81: gitserver.v1.RepoCloneProgressResponse.ResultsEntry - (*timestamppb.Timestamp)(nil), // 82: google.protobuf.Timestamp - (*durationpb.Duration)(nil), // 83: google.protobuf.Duration + (*BlameRequest)(nil), // 3: gitserver.v1.BlameRequest + (*BlameResponse)(nil), // 4: gitserver.v1.BlameResponse + (*BlameHunk)(nil), // 5: gitserver.v1.BlameHunk + (*BlameAuthor)(nil), // 6: gitserver.v1.BlameAuthor + (*DiskInfoRequest)(nil), // 7: gitserver.v1.DiskInfoRequest + (*DiskInfoResponse)(nil), // 8: gitserver.v1.DiskInfoResponse + (*BatchLogRequest)(nil), // 9: gitserver.v1.BatchLogRequest + (*BatchLogResponse)(nil), // 10: gitserver.v1.BatchLogResponse + (*BatchLogResult)(nil), // 11: gitserver.v1.BatchLogResult + (*RepoCommit)(nil), // 12: gitserver.v1.RepoCommit + (*PatchCommitInfo)(nil), // 13: gitserver.v1.PatchCommitInfo + (*PushConfig)(nil), // 14: gitserver.v1.PushConfig + (*CreateCommitFromPatchBinaryRequest)(nil), // 15: gitserver.v1.CreateCommitFromPatchBinaryRequest + (*CreateCommitFromPatchError)(nil), // 16: gitserver.v1.CreateCommitFromPatchError + (*CreateCommitFromPatchBinaryResponse)(nil), // 17: gitserver.v1.CreateCommitFromPatchBinaryResponse + (*ExecRequest)(nil), // 18: gitserver.v1.ExecRequest + (*ExecResponse)(nil), // 19: gitserver.v1.ExecResponse + (*NotFoundPayload)(nil), // 20: gitserver.v1.NotFoundPayload + (*ExecStatusPayload)(nil), // 21: gitserver.v1.ExecStatusPayload + (*UnauthorizedPayload)(nil), // 22: gitserver.v1.UnauthorizedPayload + (*SearchRequest)(nil), // 23: gitserver.v1.SearchRequest + (*RevisionSpecifier)(nil), // 24: gitserver.v1.RevisionSpecifier + (*AuthorMatchesNode)(nil), // 25: gitserver.v1.AuthorMatchesNode + (*CommitterMatchesNode)(nil), // 26: gitserver.v1.CommitterMatchesNode + (*CommitBeforeNode)(nil), // 27: gitserver.v1.CommitBeforeNode + (*CommitAfterNode)(nil), // 28: gitserver.v1.CommitAfterNode + (*MessageMatchesNode)(nil), // 29: gitserver.v1.MessageMatchesNode + (*DiffMatchesNode)(nil), // 30: gitserver.v1.DiffMatchesNode + (*DiffModifiesFileNode)(nil), // 31: gitserver.v1.DiffModifiesFileNode + (*BooleanNode)(nil), // 32: gitserver.v1.BooleanNode + (*OperatorNode)(nil), // 33: gitserver.v1.OperatorNode + (*QueryNode)(nil), // 34: gitserver.v1.QueryNode + (*SearchResponse)(nil), // 35: gitserver.v1.SearchResponse + (*CommitMatch)(nil), // 36: gitserver.v1.CommitMatch + (*ArchiveRequest)(nil), // 37: gitserver.v1.ArchiveRequest + (*ArchiveResponse)(nil), // 38: gitserver.v1.ArchiveResponse + (*IsRepoCloneableRequest)(nil), // 39: gitserver.v1.IsRepoCloneableRequest + (*IsRepoCloneableResponse)(nil), // 40: gitserver.v1.IsRepoCloneableResponse + (*RepoCloneRequest)(nil), // 41: gitserver.v1.RepoCloneRequest + (*RepoCloneResponse)(nil), // 42: gitserver.v1.RepoCloneResponse + (*RepoCloneProgressRequest)(nil), // 43: gitserver.v1.RepoCloneProgressRequest + (*RepoCloneProgress)(nil), // 44: gitserver.v1.RepoCloneProgress + (*RepoCloneProgressResponse)(nil), // 45: gitserver.v1.RepoCloneProgressResponse + (*RepoDeleteRequest)(nil), // 46: gitserver.v1.RepoDeleteRequest + (*RepoDeleteResponse)(nil), // 47: gitserver.v1.RepoDeleteResponse + (*RepoUpdateRequest)(nil), // 48: gitserver.v1.RepoUpdateRequest + (*RepoUpdateResponse)(nil), // 49: gitserver.v1.RepoUpdateResponse + (*P4ExecRequest)(nil), // 50: gitserver.v1.P4ExecRequest + (*P4ExecResponse)(nil), // 51: gitserver.v1.P4ExecResponse + (*ListGitoliteRequest)(nil), // 52: gitserver.v1.ListGitoliteRequest + (*GitoliteRepo)(nil), // 53: gitserver.v1.GitoliteRepo + (*ListGitoliteResponse)(nil), // 54: gitserver.v1.ListGitoliteResponse + (*GetObjectRequest)(nil), // 55: gitserver.v1.GetObjectRequest + (*GetObjectResponse)(nil), // 56: gitserver.v1.GetObjectResponse + (*GitObject)(nil), // 57: gitserver.v1.GitObject + (*IsPerforcePathCloneableRequest)(nil), // 58: gitserver.v1.IsPerforcePathCloneableRequest + (*IsPerforcePathCloneableResponse)(nil), // 59: gitserver.v1.IsPerforcePathCloneableResponse + (*CheckPerforceCredentialsRequest)(nil), // 60: gitserver.v1.CheckPerforceCredentialsRequest + (*CheckPerforceCredentialsResponse)(nil), // 61: gitserver.v1.CheckPerforceCredentialsResponse + (*PerforceConnectionDetails)(nil), // 62: gitserver.v1.PerforceConnectionDetails + (*PerforceGetChangelistRequest)(nil), // 63: gitserver.v1.PerforceGetChangelistRequest + (*PerforceGetChangelistResponse)(nil), // 64: gitserver.v1.PerforceGetChangelistResponse + (*PerforceChangelist)(nil), // 65: gitserver.v1.PerforceChangelist + (*IsPerforceSuperUserRequest)(nil), // 66: gitserver.v1.IsPerforceSuperUserRequest + (*IsPerforceSuperUserResponse)(nil), // 67: gitserver.v1.IsPerforceSuperUserResponse + (*PerforceProtectsForDepotRequest)(nil), // 68: gitserver.v1.PerforceProtectsForDepotRequest + (*PerforceProtectsForDepotResponse)(nil), // 69: gitserver.v1.PerforceProtectsForDepotResponse + (*PerforceProtectsForUserRequest)(nil), // 70: gitserver.v1.PerforceProtectsForUserRequest + (*PerforceProtectsForUserResponse)(nil), // 71: gitserver.v1.PerforceProtectsForUserResponse + (*PerforceProtect)(nil), // 72: gitserver.v1.PerforceProtect + (*PerforceGroupMembersRequest)(nil), // 73: gitserver.v1.PerforceGroupMembersRequest + (*PerforceGroupMembersResponse)(nil), // 74: gitserver.v1.PerforceGroupMembersResponse + (*PerforceUsersRequest)(nil), // 75: gitserver.v1.PerforceUsersRequest + (*PerforceUsersResponse)(nil), // 76: gitserver.v1.PerforceUsersResponse + (*PerforceUser)(nil), // 77: gitserver.v1.PerforceUser + (*MergeBaseRequest)(nil), // 78: gitserver.v1.MergeBaseRequest + (*MergeBaseResponse)(nil), // 79: gitserver.v1.MergeBaseResponse + (*CreateCommitFromPatchBinaryRequest_Metadata)(nil), // 80: gitserver.v1.CreateCommitFromPatchBinaryRequest.Metadata + (*CreateCommitFromPatchBinaryRequest_Patch)(nil), // 81: gitserver.v1.CreateCommitFromPatchBinaryRequest.Patch + (*CommitMatch_Signature)(nil), // 82: gitserver.v1.CommitMatch.Signature + (*CommitMatch_MatchedString)(nil), // 83: gitserver.v1.CommitMatch.MatchedString + (*CommitMatch_Range)(nil), // 84: gitserver.v1.CommitMatch.Range + (*CommitMatch_Location)(nil), // 85: gitserver.v1.CommitMatch.Location + nil, // 86: gitserver.v1.RepoCloneProgressResponse.ResultsEntry + (*timestamppb.Timestamp)(nil), // 87: google.protobuf.Timestamp + (*durationpb.Duration)(nil), // 88: google.protobuf.Duration } var file_gitserver_proto_depIdxs = []int32{ - 8, // 0: gitserver.v1.BatchLogRequest.repo_commits:type_name -> gitserver.v1.RepoCommit - 7, // 1: gitserver.v1.BatchLogResponse.results:type_name -> gitserver.v1.BatchLogResult - 8, // 2: gitserver.v1.BatchLogResult.repo_commit:type_name -> gitserver.v1.RepoCommit - 82, // 3: gitserver.v1.PatchCommitInfo.date:type_name -> google.protobuf.Timestamp - 75, // 4: gitserver.v1.CreateCommitFromPatchBinaryRequest.metadata:type_name -> gitserver.v1.CreateCommitFromPatchBinaryRequest.Metadata - 76, // 5: gitserver.v1.CreateCommitFromPatchBinaryRequest.patch:type_name -> gitserver.v1.CreateCommitFromPatchBinaryRequest.Patch - 19, // 6: gitserver.v1.SearchRequest.revisions:type_name -> gitserver.v1.RevisionSpecifier - 29, // 7: gitserver.v1.SearchRequest.query:type_name -> gitserver.v1.QueryNode - 82, // 8: gitserver.v1.CommitBeforeNode.timestamp:type_name -> google.protobuf.Timestamp - 82, // 9: gitserver.v1.CommitAfterNode.timestamp:type_name -> google.protobuf.Timestamp - 0, // 10: gitserver.v1.OperatorNode.kind:type_name -> gitserver.v1.OperatorKind - 29, // 11: gitserver.v1.OperatorNode.operands:type_name -> gitserver.v1.QueryNode - 20, // 12: gitserver.v1.QueryNode.author_matches:type_name -> gitserver.v1.AuthorMatchesNode - 21, // 13: gitserver.v1.QueryNode.committer_matches:type_name -> gitserver.v1.CommitterMatchesNode - 22, // 14: gitserver.v1.QueryNode.commit_before:type_name -> gitserver.v1.CommitBeforeNode - 23, // 15: gitserver.v1.QueryNode.commit_after:type_name -> gitserver.v1.CommitAfterNode - 24, // 16: gitserver.v1.QueryNode.message_matches:type_name -> gitserver.v1.MessageMatchesNode - 25, // 17: gitserver.v1.QueryNode.diff_matches:type_name -> gitserver.v1.DiffMatchesNode - 26, // 18: gitserver.v1.QueryNode.diff_modifies_file:type_name -> gitserver.v1.DiffModifiesFileNode - 27, // 19: gitserver.v1.QueryNode.boolean:type_name -> gitserver.v1.BooleanNode - 28, // 20: gitserver.v1.QueryNode.operator:type_name -> gitserver.v1.OperatorNode - 31, // 21: gitserver.v1.SearchResponse.match:type_name -> gitserver.v1.CommitMatch - 77, // 22: gitserver.v1.CommitMatch.author:type_name -> gitserver.v1.CommitMatch.Signature - 77, // 23: gitserver.v1.CommitMatch.committer:type_name -> gitserver.v1.CommitMatch.Signature - 78, // 24: gitserver.v1.CommitMatch.message:type_name -> gitserver.v1.CommitMatch.MatchedString - 78, // 25: gitserver.v1.CommitMatch.diff:type_name -> gitserver.v1.CommitMatch.MatchedString - 81, // 26: gitserver.v1.RepoCloneProgressResponse.results:type_name -> gitserver.v1.RepoCloneProgressResponse.ResultsEntry - 83, // 27: gitserver.v1.RepoUpdateRequest.since:type_name -> google.protobuf.Duration - 82, // 28: gitserver.v1.RepoUpdateResponse.last_fetched:type_name -> google.protobuf.Timestamp - 82, // 29: gitserver.v1.RepoUpdateResponse.last_changed:type_name -> google.protobuf.Timestamp - 48, // 30: gitserver.v1.ListGitoliteResponse.repos:type_name -> gitserver.v1.GitoliteRepo - 52, // 31: gitserver.v1.GetObjectResponse.object:type_name -> gitserver.v1.GitObject - 1, // 32: gitserver.v1.GitObject.type:type_name -> gitserver.v1.GitObject.ObjectType - 57, // 33: gitserver.v1.IsPerforcePathCloneableRequest.connection_details:type_name -> gitserver.v1.PerforceConnectionDetails - 57, // 34: gitserver.v1.CheckPerforceCredentialsRequest.connection_details:type_name -> gitserver.v1.PerforceConnectionDetails - 57, // 35: gitserver.v1.PerforceGetChangelistRequest.connection_details:type_name -> gitserver.v1.PerforceConnectionDetails - 60, // 36: gitserver.v1.PerforceGetChangelistResponse.changelist:type_name -> gitserver.v1.PerforceChangelist - 82, // 37: gitserver.v1.PerforceChangelist.creation_date:type_name -> google.protobuf.Timestamp - 2, // 38: gitserver.v1.PerforceChangelist.state:type_name -> gitserver.v1.PerforceChangelist.PerforceChangelistState - 57, // 39: gitserver.v1.IsPerforceSuperUserRequest.connection_details:type_name -> gitserver.v1.PerforceConnectionDetails - 57, // 40: gitserver.v1.PerforceProtectsForDepotRequest.connection_details:type_name -> gitserver.v1.PerforceConnectionDetails - 67, // 41: gitserver.v1.PerforceProtectsForDepotResponse.protects:type_name -> gitserver.v1.PerforceProtect - 57, // 42: gitserver.v1.PerforceProtectsForUserRequest.connection_details:type_name -> gitserver.v1.PerforceConnectionDetails - 67, // 43: gitserver.v1.PerforceProtectsForUserResponse.protects:type_name -> gitserver.v1.PerforceProtect - 57, // 44: gitserver.v1.PerforceGroupMembersRequest.connection_details:type_name -> gitserver.v1.PerforceConnectionDetails - 57, // 45: gitserver.v1.PerforceUsersRequest.connection_details:type_name -> gitserver.v1.PerforceConnectionDetails - 72, // 46: gitserver.v1.PerforceUsersResponse.users:type_name -> gitserver.v1.PerforceUser - 9, // 47: gitserver.v1.CreateCommitFromPatchBinaryRequest.Metadata.commit_info:type_name -> gitserver.v1.PatchCommitInfo - 10, // 48: gitserver.v1.CreateCommitFromPatchBinaryRequest.Metadata.push:type_name -> gitserver.v1.PushConfig - 82, // 49: gitserver.v1.CommitMatch.Signature.date:type_name -> google.protobuf.Timestamp - 79, // 50: gitserver.v1.CommitMatch.MatchedString.ranges:type_name -> gitserver.v1.CommitMatch.Range - 80, // 51: gitserver.v1.CommitMatch.Range.start:type_name -> gitserver.v1.CommitMatch.Location - 80, // 52: gitserver.v1.CommitMatch.Range.end:type_name -> gitserver.v1.CommitMatch.Location - 39, // 53: gitserver.v1.RepoCloneProgressResponse.ResultsEntry.value:type_name -> gitserver.v1.RepoCloneProgress - 5, // 54: gitserver.v1.GitserverService.BatchLog:input_type -> gitserver.v1.BatchLogRequest - 11, // 55: gitserver.v1.GitserverService.CreateCommitFromPatchBinary:input_type -> gitserver.v1.CreateCommitFromPatchBinaryRequest - 3, // 56: gitserver.v1.GitserverService.DiskInfo:input_type -> gitserver.v1.DiskInfoRequest - 14, // 57: gitserver.v1.GitserverService.Exec:input_type -> gitserver.v1.ExecRequest - 50, // 58: gitserver.v1.GitserverService.GetObject:input_type -> gitserver.v1.GetObjectRequest - 34, // 59: gitserver.v1.GitserverService.IsRepoCloneable:input_type -> gitserver.v1.IsRepoCloneableRequest - 47, // 60: gitserver.v1.GitserverService.ListGitolite:input_type -> gitserver.v1.ListGitoliteRequest - 18, // 61: gitserver.v1.GitserverService.Search:input_type -> gitserver.v1.SearchRequest - 32, // 62: gitserver.v1.GitserverService.Archive:input_type -> gitserver.v1.ArchiveRequest - 45, // 63: gitserver.v1.GitserverService.P4Exec:input_type -> gitserver.v1.P4ExecRequest - 36, // 64: gitserver.v1.GitserverService.RepoClone:input_type -> gitserver.v1.RepoCloneRequest - 38, // 65: gitserver.v1.GitserverService.RepoCloneProgress:input_type -> gitserver.v1.RepoCloneProgressRequest - 41, // 66: gitserver.v1.GitserverService.RepoDelete:input_type -> gitserver.v1.RepoDeleteRequest - 43, // 67: gitserver.v1.GitserverService.RepoUpdate:input_type -> gitserver.v1.RepoUpdateRequest - 53, // 68: gitserver.v1.GitserverService.IsPerforcePathCloneable:input_type -> gitserver.v1.IsPerforcePathCloneableRequest - 55, // 69: gitserver.v1.GitserverService.CheckPerforceCredentials:input_type -> gitserver.v1.CheckPerforceCredentialsRequest - 70, // 70: gitserver.v1.GitserverService.PerforceUsers:input_type -> gitserver.v1.PerforceUsersRequest - 65, // 71: gitserver.v1.GitserverService.PerforceProtectsForUser:input_type -> gitserver.v1.PerforceProtectsForUserRequest - 63, // 72: gitserver.v1.GitserverService.PerforceProtectsForDepot:input_type -> gitserver.v1.PerforceProtectsForDepotRequest - 68, // 73: gitserver.v1.GitserverService.PerforceGroupMembers:input_type -> gitserver.v1.PerforceGroupMembersRequest - 61, // 74: gitserver.v1.GitserverService.IsPerforceSuperUser:input_type -> gitserver.v1.IsPerforceSuperUserRequest - 58, // 75: gitserver.v1.GitserverService.PerforceGetChangelist:input_type -> gitserver.v1.PerforceGetChangelistRequest - 73, // 76: gitserver.v1.GitserverService.MergeBase:input_type -> gitserver.v1.MergeBaseRequest - 6, // 77: gitserver.v1.GitserverService.BatchLog:output_type -> gitserver.v1.BatchLogResponse - 13, // 78: gitserver.v1.GitserverService.CreateCommitFromPatchBinary:output_type -> gitserver.v1.CreateCommitFromPatchBinaryResponse - 4, // 79: gitserver.v1.GitserverService.DiskInfo:output_type -> gitserver.v1.DiskInfoResponse - 15, // 80: gitserver.v1.GitserverService.Exec:output_type -> gitserver.v1.ExecResponse - 51, // 81: gitserver.v1.GitserverService.GetObject:output_type -> gitserver.v1.GetObjectResponse - 35, // 82: gitserver.v1.GitserverService.IsRepoCloneable:output_type -> gitserver.v1.IsRepoCloneableResponse - 49, // 83: gitserver.v1.GitserverService.ListGitolite:output_type -> gitserver.v1.ListGitoliteResponse - 30, // 84: gitserver.v1.GitserverService.Search:output_type -> gitserver.v1.SearchResponse - 33, // 85: gitserver.v1.GitserverService.Archive:output_type -> gitserver.v1.ArchiveResponse - 46, // 86: gitserver.v1.GitserverService.P4Exec:output_type -> gitserver.v1.P4ExecResponse - 37, // 87: gitserver.v1.GitserverService.RepoClone:output_type -> gitserver.v1.RepoCloneResponse - 40, // 88: gitserver.v1.GitserverService.RepoCloneProgress:output_type -> gitserver.v1.RepoCloneProgressResponse - 42, // 89: gitserver.v1.GitserverService.RepoDelete:output_type -> gitserver.v1.RepoDeleteResponse - 44, // 90: gitserver.v1.GitserverService.RepoUpdate:output_type -> gitserver.v1.RepoUpdateResponse - 54, // 91: gitserver.v1.GitserverService.IsPerforcePathCloneable:output_type -> gitserver.v1.IsPerforcePathCloneableResponse - 56, // 92: gitserver.v1.GitserverService.CheckPerforceCredentials:output_type -> gitserver.v1.CheckPerforceCredentialsResponse - 71, // 93: gitserver.v1.GitserverService.PerforceUsers:output_type -> gitserver.v1.PerforceUsersResponse - 66, // 94: gitserver.v1.GitserverService.PerforceProtectsForUser:output_type -> gitserver.v1.PerforceProtectsForUserResponse - 64, // 95: gitserver.v1.GitserverService.PerforceProtectsForDepot:output_type -> gitserver.v1.PerforceProtectsForDepotResponse - 69, // 96: gitserver.v1.GitserverService.PerforceGroupMembers:output_type -> gitserver.v1.PerforceGroupMembersResponse - 62, // 97: gitserver.v1.GitserverService.IsPerforceSuperUser:output_type -> gitserver.v1.IsPerforceSuperUserResponse - 59, // 98: gitserver.v1.GitserverService.PerforceGetChangelist:output_type -> gitserver.v1.PerforceGetChangelistResponse - 74, // 99: gitserver.v1.GitserverService.MergeBase:output_type -> gitserver.v1.MergeBaseResponse - 77, // [77:100] is the sub-list for method output_type - 54, // [54:77] is the sub-list for method input_type - 54, // [54:54] is the sub-list for extension type_name - 54, // [54:54] is the sub-list for extension extendee - 0, // [0:54] is the sub-list for field type_name + 5, // 0: gitserver.v1.BlameResponse.hunk:type_name -> gitserver.v1.BlameHunk + 6, // 1: gitserver.v1.BlameHunk.author:type_name -> gitserver.v1.BlameAuthor + 87, // 2: gitserver.v1.BlameAuthor.date:type_name -> google.protobuf.Timestamp + 12, // 3: gitserver.v1.BatchLogRequest.repo_commits:type_name -> gitserver.v1.RepoCommit + 11, // 4: gitserver.v1.BatchLogResponse.results:type_name -> gitserver.v1.BatchLogResult + 12, // 5: gitserver.v1.BatchLogResult.repo_commit:type_name -> gitserver.v1.RepoCommit + 87, // 6: gitserver.v1.PatchCommitInfo.date:type_name -> google.protobuf.Timestamp + 80, // 7: gitserver.v1.CreateCommitFromPatchBinaryRequest.metadata:type_name -> gitserver.v1.CreateCommitFromPatchBinaryRequest.Metadata + 81, // 8: gitserver.v1.CreateCommitFromPatchBinaryRequest.patch:type_name -> gitserver.v1.CreateCommitFromPatchBinaryRequest.Patch + 24, // 9: gitserver.v1.SearchRequest.revisions:type_name -> gitserver.v1.RevisionSpecifier + 34, // 10: gitserver.v1.SearchRequest.query:type_name -> gitserver.v1.QueryNode + 87, // 11: gitserver.v1.CommitBeforeNode.timestamp:type_name -> google.protobuf.Timestamp + 87, // 12: gitserver.v1.CommitAfterNode.timestamp:type_name -> google.protobuf.Timestamp + 0, // 13: gitserver.v1.OperatorNode.kind:type_name -> gitserver.v1.OperatorKind + 34, // 14: gitserver.v1.OperatorNode.operands:type_name -> gitserver.v1.QueryNode + 25, // 15: gitserver.v1.QueryNode.author_matches:type_name -> gitserver.v1.AuthorMatchesNode + 26, // 16: gitserver.v1.QueryNode.committer_matches:type_name -> gitserver.v1.CommitterMatchesNode + 27, // 17: gitserver.v1.QueryNode.commit_before:type_name -> gitserver.v1.CommitBeforeNode + 28, // 18: gitserver.v1.QueryNode.commit_after:type_name -> gitserver.v1.CommitAfterNode + 29, // 19: gitserver.v1.QueryNode.message_matches:type_name -> gitserver.v1.MessageMatchesNode + 30, // 20: gitserver.v1.QueryNode.diff_matches:type_name -> gitserver.v1.DiffMatchesNode + 31, // 21: gitserver.v1.QueryNode.diff_modifies_file:type_name -> gitserver.v1.DiffModifiesFileNode + 32, // 22: gitserver.v1.QueryNode.boolean:type_name -> gitserver.v1.BooleanNode + 33, // 23: gitserver.v1.QueryNode.operator:type_name -> gitserver.v1.OperatorNode + 36, // 24: gitserver.v1.SearchResponse.match:type_name -> gitserver.v1.CommitMatch + 82, // 25: gitserver.v1.CommitMatch.author:type_name -> gitserver.v1.CommitMatch.Signature + 82, // 26: gitserver.v1.CommitMatch.committer:type_name -> gitserver.v1.CommitMatch.Signature + 83, // 27: gitserver.v1.CommitMatch.message:type_name -> gitserver.v1.CommitMatch.MatchedString + 83, // 28: gitserver.v1.CommitMatch.diff:type_name -> gitserver.v1.CommitMatch.MatchedString + 86, // 29: gitserver.v1.RepoCloneProgressResponse.results:type_name -> gitserver.v1.RepoCloneProgressResponse.ResultsEntry + 88, // 30: gitserver.v1.RepoUpdateRequest.since:type_name -> google.protobuf.Duration + 87, // 31: gitserver.v1.RepoUpdateResponse.last_fetched:type_name -> google.protobuf.Timestamp + 87, // 32: gitserver.v1.RepoUpdateResponse.last_changed:type_name -> google.protobuf.Timestamp + 53, // 33: gitserver.v1.ListGitoliteResponse.repos:type_name -> gitserver.v1.GitoliteRepo + 57, // 34: gitserver.v1.GetObjectResponse.object:type_name -> gitserver.v1.GitObject + 1, // 35: gitserver.v1.GitObject.type:type_name -> gitserver.v1.GitObject.ObjectType + 62, // 36: gitserver.v1.IsPerforcePathCloneableRequest.connection_details:type_name -> gitserver.v1.PerforceConnectionDetails + 62, // 37: gitserver.v1.CheckPerforceCredentialsRequest.connection_details:type_name -> gitserver.v1.PerforceConnectionDetails + 62, // 38: gitserver.v1.PerforceGetChangelistRequest.connection_details:type_name -> gitserver.v1.PerforceConnectionDetails + 65, // 39: gitserver.v1.PerforceGetChangelistResponse.changelist:type_name -> gitserver.v1.PerforceChangelist + 87, // 40: gitserver.v1.PerforceChangelist.creation_date:type_name -> google.protobuf.Timestamp + 2, // 41: gitserver.v1.PerforceChangelist.state:type_name -> gitserver.v1.PerforceChangelist.PerforceChangelistState + 62, // 42: gitserver.v1.IsPerforceSuperUserRequest.connection_details:type_name -> gitserver.v1.PerforceConnectionDetails + 62, // 43: gitserver.v1.PerforceProtectsForDepotRequest.connection_details:type_name -> gitserver.v1.PerforceConnectionDetails + 72, // 44: gitserver.v1.PerforceProtectsForDepotResponse.protects:type_name -> gitserver.v1.PerforceProtect + 62, // 45: gitserver.v1.PerforceProtectsForUserRequest.connection_details:type_name -> gitserver.v1.PerforceConnectionDetails + 72, // 46: gitserver.v1.PerforceProtectsForUserResponse.protects:type_name -> gitserver.v1.PerforceProtect + 62, // 47: gitserver.v1.PerforceGroupMembersRequest.connection_details:type_name -> gitserver.v1.PerforceConnectionDetails + 62, // 48: gitserver.v1.PerforceUsersRequest.connection_details:type_name -> gitserver.v1.PerforceConnectionDetails + 77, // 49: gitserver.v1.PerforceUsersResponse.users:type_name -> gitserver.v1.PerforceUser + 13, // 50: gitserver.v1.CreateCommitFromPatchBinaryRequest.Metadata.commit_info:type_name -> gitserver.v1.PatchCommitInfo + 14, // 51: gitserver.v1.CreateCommitFromPatchBinaryRequest.Metadata.push:type_name -> gitserver.v1.PushConfig + 87, // 52: gitserver.v1.CommitMatch.Signature.date:type_name -> google.protobuf.Timestamp + 84, // 53: gitserver.v1.CommitMatch.MatchedString.ranges:type_name -> gitserver.v1.CommitMatch.Range + 85, // 54: gitserver.v1.CommitMatch.Range.start:type_name -> gitserver.v1.CommitMatch.Location + 85, // 55: gitserver.v1.CommitMatch.Range.end:type_name -> gitserver.v1.CommitMatch.Location + 44, // 56: gitserver.v1.RepoCloneProgressResponse.ResultsEntry.value:type_name -> gitserver.v1.RepoCloneProgress + 9, // 57: gitserver.v1.GitserverService.BatchLog:input_type -> gitserver.v1.BatchLogRequest + 15, // 58: gitserver.v1.GitserverService.CreateCommitFromPatchBinary:input_type -> gitserver.v1.CreateCommitFromPatchBinaryRequest + 7, // 59: gitserver.v1.GitserverService.DiskInfo:input_type -> gitserver.v1.DiskInfoRequest + 18, // 60: gitserver.v1.GitserverService.Exec:input_type -> gitserver.v1.ExecRequest + 55, // 61: gitserver.v1.GitserverService.GetObject:input_type -> gitserver.v1.GetObjectRequest + 39, // 62: gitserver.v1.GitserverService.IsRepoCloneable:input_type -> gitserver.v1.IsRepoCloneableRequest + 52, // 63: gitserver.v1.GitserverService.ListGitolite:input_type -> gitserver.v1.ListGitoliteRequest + 23, // 64: gitserver.v1.GitserverService.Search:input_type -> gitserver.v1.SearchRequest + 37, // 65: gitserver.v1.GitserverService.Archive:input_type -> gitserver.v1.ArchiveRequest + 50, // 66: gitserver.v1.GitserverService.P4Exec:input_type -> gitserver.v1.P4ExecRequest + 41, // 67: gitserver.v1.GitserverService.RepoClone:input_type -> gitserver.v1.RepoCloneRequest + 43, // 68: gitserver.v1.GitserverService.RepoCloneProgress:input_type -> gitserver.v1.RepoCloneProgressRequest + 46, // 69: gitserver.v1.GitserverService.RepoDelete:input_type -> gitserver.v1.RepoDeleteRequest + 48, // 70: gitserver.v1.GitserverService.RepoUpdate:input_type -> gitserver.v1.RepoUpdateRequest + 58, // 71: gitserver.v1.GitserverService.IsPerforcePathCloneable:input_type -> gitserver.v1.IsPerforcePathCloneableRequest + 60, // 72: gitserver.v1.GitserverService.CheckPerforceCredentials:input_type -> gitserver.v1.CheckPerforceCredentialsRequest + 75, // 73: gitserver.v1.GitserverService.PerforceUsers:input_type -> gitserver.v1.PerforceUsersRequest + 70, // 74: gitserver.v1.GitserverService.PerforceProtectsForUser:input_type -> gitserver.v1.PerforceProtectsForUserRequest + 68, // 75: gitserver.v1.GitserverService.PerforceProtectsForDepot:input_type -> gitserver.v1.PerforceProtectsForDepotRequest + 73, // 76: gitserver.v1.GitserverService.PerforceGroupMembers:input_type -> gitserver.v1.PerforceGroupMembersRequest + 66, // 77: gitserver.v1.GitserverService.IsPerforceSuperUser:input_type -> gitserver.v1.IsPerforceSuperUserRequest + 63, // 78: gitserver.v1.GitserverService.PerforceGetChangelist:input_type -> gitserver.v1.PerforceGetChangelistRequest + 78, // 79: gitserver.v1.GitserverService.MergeBase:input_type -> gitserver.v1.MergeBaseRequest + 3, // 80: gitserver.v1.GitserverService.Blame:input_type -> gitserver.v1.BlameRequest + 10, // 81: gitserver.v1.GitserverService.BatchLog:output_type -> gitserver.v1.BatchLogResponse + 17, // 82: gitserver.v1.GitserverService.CreateCommitFromPatchBinary:output_type -> gitserver.v1.CreateCommitFromPatchBinaryResponse + 8, // 83: gitserver.v1.GitserverService.DiskInfo:output_type -> gitserver.v1.DiskInfoResponse + 19, // 84: gitserver.v1.GitserverService.Exec:output_type -> gitserver.v1.ExecResponse + 56, // 85: gitserver.v1.GitserverService.GetObject:output_type -> gitserver.v1.GetObjectResponse + 40, // 86: gitserver.v1.GitserverService.IsRepoCloneable:output_type -> gitserver.v1.IsRepoCloneableResponse + 54, // 87: gitserver.v1.GitserverService.ListGitolite:output_type -> gitserver.v1.ListGitoliteResponse + 35, // 88: gitserver.v1.GitserverService.Search:output_type -> gitserver.v1.SearchResponse + 38, // 89: gitserver.v1.GitserverService.Archive:output_type -> gitserver.v1.ArchiveResponse + 51, // 90: gitserver.v1.GitserverService.P4Exec:output_type -> gitserver.v1.P4ExecResponse + 42, // 91: gitserver.v1.GitserverService.RepoClone:output_type -> gitserver.v1.RepoCloneResponse + 45, // 92: gitserver.v1.GitserverService.RepoCloneProgress:output_type -> gitserver.v1.RepoCloneProgressResponse + 47, // 93: gitserver.v1.GitserverService.RepoDelete:output_type -> gitserver.v1.RepoDeleteResponse + 49, // 94: gitserver.v1.GitserverService.RepoUpdate:output_type -> gitserver.v1.RepoUpdateResponse + 59, // 95: gitserver.v1.GitserverService.IsPerforcePathCloneable:output_type -> gitserver.v1.IsPerforcePathCloneableResponse + 61, // 96: gitserver.v1.GitserverService.CheckPerforceCredentials:output_type -> gitserver.v1.CheckPerforceCredentialsResponse + 76, // 97: gitserver.v1.GitserverService.PerforceUsers:output_type -> gitserver.v1.PerforceUsersResponse + 71, // 98: gitserver.v1.GitserverService.PerforceProtectsForUser:output_type -> gitserver.v1.PerforceProtectsForUserResponse + 69, // 99: gitserver.v1.GitserverService.PerforceProtectsForDepot:output_type -> gitserver.v1.PerforceProtectsForDepotResponse + 74, // 100: gitserver.v1.GitserverService.PerforceGroupMembers:output_type -> gitserver.v1.PerforceGroupMembersResponse + 67, // 101: gitserver.v1.GitserverService.IsPerforceSuperUser:output_type -> gitserver.v1.IsPerforceSuperUserResponse + 64, // 102: gitserver.v1.GitserverService.PerforceGetChangelist:output_type -> gitserver.v1.PerforceGetChangelistResponse + 79, // 103: gitserver.v1.GitserverService.MergeBase:output_type -> gitserver.v1.MergeBaseResponse + 4, // 104: gitserver.v1.GitserverService.Blame:output_type -> gitserver.v1.BlameResponse + 81, // [81:105] is the sub-list for method output_type + 57, // [57:81] is the sub-list for method input_type + 57, // [57:57] is the sub-list for extension type_name + 57, // [57:57] is the sub-list for extension extendee + 0, // [0:57] is the sub-list for field type_name } func init() { file_gitserver_proto_init() } @@ -5918,7 +6353,7 @@ func file_gitserver_proto_init() { } if !protoimpl.UnsafeEnabled { file_gitserver_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DiskInfoRequest); i { + switch v := v.(*BlameRequest); i { case 0: return &v.state case 1: @@ -5930,7 +6365,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DiskInfoResponse); i { + switch v := v.(*BlameResponse); i { case 0: return &v.state case 1: @@ -5942,7 +6377,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BatchLogRequest); i { + switch v := v.(*BlameHunk); i { case 0: return &v.state case 1: @@ -5954,7 +6389,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BatchLogResponse); i { + switch v := v.(*BlameAuthor); i { case 0: return &v.state case 1: @@ -5966,7 +6401,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BatchLogResult); i { + switch v := v.(*DiskInfoRequest); i { case 0: return &v.state case 1: @@ -5978,7 +6413,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RepoCommit); i { + switch v := v.(*DiskInfoResponse); i { case 0: return &v.state case 1: @@ -5990,7 +6425,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PatchCommitInfo); i { + switch v := v.(*BatchLogRequest); i { case 0: return &v.state case 1: @@ -6002,7 +6437,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PushConfig); i { + switch v := v.(*BatchLogResponse); i { case 0: return &v.state case 1: @@ -6014,7 +6449,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateCommitFromPatchBinaryRequest); i { + switch v := v.(*BatchLogResult); i { case 0: return &v.state case 1: @@ -6026,7 +6461,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateCommitFromPatchError); i { + switch v := v.(*RepoCommit); i { case 0: return &v.state case 1: @@ -6038,7 +6473,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateCommitFromPatchBinaryResponse); i { + switch v := v.(*PatchCommitInfo); i { case 0: return &v.state case 1: @@ -6050,7 +6485,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ExecRequest); i { + switch v := v.(*PushConfig); i { case 0: return &v.state case 1: @@ -6062,7 +6497,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ExecResponse); i { + switch v := v.(*CreateCommitFromPatchBinaryRequest); i { case 0: return &v.state case 1: @@ -6074,7 +6509,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NotFoundPayload); i { + switch v := v.(*CreateCommitFromPatchError); i { case 0: return &v.state case 1: @@ -6086,7 +6521,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ExecStatusPayload); i { + switch v := v.(*CreateCommitFromPatchBinaryResponse); i { case 0: return &v.state case 1: @@ -6098,7 +6533,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SearchRequest); i { + switch v := v.(*ExecRequest); i { case 0: return &v.state case 1: @@ -6110,7 +6545,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RevisionSpecifier); i { + switch v := v.(*ExecResponse); i { case 0: return &v.state case 1: @@ -6122,7 +6557,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AuthorMatchesNode); i { + switch v := v.(*NotFoundPayload); i { case 0: return &v.state case 1: @@ -6134,7 +6569,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CommitterMatchesNode); i { + switch v := v.(*ExecStatusPayload); i { case 0: return &v.state case 1: @@ -6146,7 +6581,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CommitBeforeNode); i { + switch v := v.(*UnauthorizedPayload); i { case 0: return &v.state case 1: @@ -6158,7 +6593,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CommitAfterNode); i { + switch v := v.(*SearchRequest); i { case 0: return &v.state case 1: @@ -6170,7 +6605,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MessageMatchesNode); i { + switch v := v.(*RevisionSpecifier); i { case 0: return &v.state case 1: @@ -6182,7 +6617,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DiffMatchesNode); i { + switch v := v.(*AuthorMatchesNode); i { case 0: return &v.state case 1: @@ -6194,7 +6629,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DiffModifiesFileNode); i { + switch v := v.(*CommitterMatchesNode); i { case 0: return &v.state case 1: @@ -6206,7 +6641,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BooleanNode); i { + switch v := v.(*CommitBeforeNode); i { case 0: return &v.state case 1: @@ -6218,7 +6653,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*OperatorNode); i { + switch v := v.(*CommitAfterNode); i { case 0: return &v.state case 1: @@ -6230,7 +6665,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*QueryNode); i { + switch v := v.(*MessageMatchesNode); i { case 0: return &v.state case 1: @@ -6242,7 +6677,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SearchResponse); i { + switch v := v.(*DiffMatchesNode); i { case 0: return &v.state case 1: @@ -6254,7 +6689,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CommitMatch); i { + switch v := v.(*DiffModifiesFileNode); i { case 0: return &v.state case 1: @@ -6266,7 +6701,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ArchiveRequest); i { + switch v := v.(*BooleanNode); i { case 0: return &v.state case 1: @@ -6278,7 +6713,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ArchiveResponse); i { + switch v := v.(*OperatorNode); i { case 0: return &v.state case 1: @@ -6290,7 +6725,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*IsRepoCloneableRequest); i { + switch v := v.(*QueryNode); i { case 0: return &v.state case 1: @@ -6302,7 +6737,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*IsRepoCloneableResponse); i { + switch v := v.(*SearchResponse); i { case 0: return &v.state case 1: @@ -6314,7 +6749,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RepoCloneRequest); i { + switch v := v.(*CommitMatch); i { case 0: return &v.state case 1: @@ -6326,7 +6761,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RepoCloneResponse); i { + switch v := v.(*ArchiveRequest); i { case 0: return &v.state case 1: @@ -6338,7 +6773,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RepoCloneProgressRequest); i { + switch v := v.(*ArchiveResponse); i { case 0: return &v.state case 1: @@ -6350,7 +6785,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RepoCloneProgress); i { + switch v := v.(*IsRepoCloneableRequest); i { case 0: return &v.state case 1: @@ -6362,7 +6797,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RepoCloneProgressResponse); i { + switch v := v.(*IsRepoCloneableResponse); i { case 0: return &v.state case 1: @@ -6374,7 +6809,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RepoDeleteRequest); i { + switch v := v.(*RepoCloneRequest); i { case 0: return &v.state case 1: @@ -6386,7 +6821,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RepoDeleteResponse); i { + switch v := v.(*RepoCloneResponse); i { case 0: return &v.state case 1: @@ -6398,7 +6833,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RepoUpdateRequest); i { + switch v := v.(*RepoCloneProgressRequest); i { case 0: return &v.state case 1: @@ -6410,7 +6845,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RepoUpdateResponse); i { + switch v := v.(*RepoCloneProgress); i { case 0: return &v.state case 1: @@ -6422,7 +6857,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*P4ExecRequest); i { + switch v := v.(*RepoCloneProgressResponse); i { case 0: return &v.state case 1: @@ -6434,7 +6869,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*P4ExecResponse); i { + switch v := v.(*RepoDeleteRequest); i { case 0: return &v.state case 1: @@ -6446,7 +6881,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListGitoliteRequest); i { + switch v := v.(*RepoDeleteResponse); i { case 0: return &v.state case 1: @@ -6458,7 +6893,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GitoliteRepo); i { + switch v := v.(*RepoUpdateRequest); i { case 0: return &v.state case 1: @@ -6470,7 +6905,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListGitoliteResponse); i { + switch v := v.(*RepoUpdateResponse); i { case 0: return &v.state case 1: @@ -6482,7 +6917,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetObjectRequest); i { + switch v := v.(*P4ExecRequest); i { case 0: return &v.state case 1: @@ -6494,7 +6929,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetObjectResponse); i { + switch v := v.(*P4ExecResponse); i { case 0: return &v.state case 1: @@ -6506,7 +6941,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GitObject); i { + switch v := v.(*ListGitoliteRequest); i { case 0: return &v.state case 1: @@ -6518,7 +6953,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[50].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*IsPerforcePathCloneableRequest); i { + switch v := v.(*GitoliteRepo); i { case 0: return &v.state case 1: @@ -6530,7 +6965,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[51].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*IsPerforcePathCloneableResponse); i { + switch v := v.(*ListGitoliteResponse); i { case 0: return &v.state case 1: @@ -6542,7 +6977,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[52].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CheckPerforceCredentialsRequest); i { + switch v := v.(*GetObjectRequest); i { case 0: return &v.state case 1: @@ -6554,7 +6989,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[53].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CheckPerforceCredentialsResponse); i { + switch v := v.(*GetObjectResponse); i { case 0: return &v.state case 1: @@ -6566,7 +7001,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[54].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PerforceConnectionDetails); i { + switch v := v.(*GitObject); i { case 0: return &v.state case 1: @@ -6578,7 +7013,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[55].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PerforceGetChangelistRequest); i { + switch v := v.(*IsPerforcePathCloneableRequest); i { case 0: return &v.state case 1: @@ -6590,7 +7025,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[56].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PerforceGetChangelistResponse); i { + switch v := v.(*IsPerforcePathCloneableResponse); i { case 0: return &v.state case 1: @@ -6602,7 +7037,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[57].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PerforceChangelist); i { + switch v := v.(*CheckPerforceCredentialsRequest); i { case 0: return &v.state case 1: @@ -6614,7 +7049,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[58].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*IsPerforceSuperUserRequest); i { + switch v := v.(*CheckPerforceCredentialsResponse); i { case 0: return &v.state case 1: @@ -6626,7 +7061,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[59].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*IsPerforceSuperUserResponse); i { + switch v := v.(*PerforceConnectionDetails); i { case 0: return &v.state case 1: @@ -6638,7 +7073,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[60].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PerforceProtectsForDepotRequest); i { + switch v := v.(*PerforceGetChangelistRequest); i { case 0: return &v.state case 1: @@ -6650,7 +7085,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[61].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PerforceProtectsForDepotResponse); i { + switch v := v.(*PerforceGetChangelistResponse); i { case 0: return &v.state case 1: @@ -6662,7 +7097,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[62].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PerforceProtectsForUserRequest); i { + switch v := v.(*PerforceChangelist); i { case 0: return &v.state case 1: @@ -6674,7 +7109,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[63].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PerforceProtectsForUserResponse); i { + switch v := v.(*IsPerforceSuperUserRequest); i { case 0: return &v.state case 1: @@ -6686,7 +7121,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[64].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PerforceProtect); i { + switch v := v.(*IsPerforceSuperUserResponse); i { case 0: return &v.state case 1: @@ -6698,7 +7133,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[65].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PerforceGroupMembersRequest); i { + switch v := v.(*PerforceProtectsForDepotRequest); i { case 0: return &v.state case 1: @@ -6710,7 +7145,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[66].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PerforceGroupMembersResponse); i { + switch v := v.(*PerforceProtectsForDepotResponse); i { case 0: return &v.state case 1: @@ -6722,7 +7157,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[67].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PerforceUsersRequest); i { + switch v := v.(*PerforceProtectsForUserRequest); i { case 0: return &v.state case 1: @@ -6734,7 +7169,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[68].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PerforceUsersResponse); i { + switch v := v.(*PerforceProtectsForUserResponse); i { case 0: return &v.state case 1: @@ -6746,7 +7181,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[69].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PerforceUser); i { + switch v := v.(*PerforceProtect); i { case 0: return &v.state case 1: @@ -6758,7 +7193,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[70].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MergeBaseRequest); i { + switch v := v.(*PerforceGroupMembersRequest); i { case 0: return &v.state case 1: @@ -6770,7 +7205,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[71].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MergeBaseResponse); i { + switch v := v.(*PerforceGroupMembersResponse); i { case 0: return &v.state case 1: @@ -6782,7 +7217,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[72].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateCommitFromPatchBinaryRequest_Metadata); i { + switch v := v.(*PerforceUsersRequest); i { case 0: return &v.state case 1: @@ -6794,7 +7229,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[73].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateCommitFromPatchBinaryRequest_Patch); i { + switch v := v.(*PerforceUsersResponse); i { case 0: return &v.state case 1: @@ -6806,7 +7241,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[74].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CommitMatch_Signature); i { + switch v := v.(*PerforceUser); i { case 0: return &v.state case 1: @@ -6818,7 +7253,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[75].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CommitMatch_MatchedString); i { + switch v := v.(*MergeBaseRequest); i { case 0: return &v.state case 1: @@ -6830,7 +7265,7 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[76].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CommitMatch_Range); i { + switch v := v.(*MergeBaseResponse); i { case 0: return &v.state case 1: @@ -6842,6 +7277,66 @@ func file_gitserver_proto_init() { } } file_gitserver_proto_msgTypes[77].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateCommitFromPatchBinaryRequest_Metadata); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gitserver_proto_msgTypes[78].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateCommitFromPatchBinaryRequest_Patch); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gitserver_proto_msgTypes[79].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CommitMatch_Signature); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gitserver_proto_msgTypes[80].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CommitMatch_MatchedString); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gitserver_proto_msgTypes[81].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CommitMatch_Range); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gitserver_proto_msgTypes[82].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CommitMatch_Location); i { case 0: return &v.state @@ -6854,12 +7349,14 @@ func file_gitserver_proto_init() { } } } - file_gitserver_proto_msgTypes[4].OneofWrappers = []interface{}{} - file_gitserver_proto_msgTypes[8].OneofWrappers = []interface{}{ + file_gitserver_proto_msgTypes[0].OneofWrappers = []interface{}{} + file_gitserver_proto_msgTypes[8].OneofWrappers = []interface{}{} + file_gitserver_proto_msgTypes[12].OneofWrappers = []interface{}{ (*CreateCommitFromPatchBinaryRequest_Metadata_)(nil), (*CreateCommitFromPatchBinaryRequest_Patch_)(nil), } - file_gitserver_proto_msgTypes[26].OneofWrappers = []interface{}{ + file_gitserver_proto_msgTypes[19].OneofWrappers = []interface{}{} + file_gitserver_proto_msgTypes[31].OneofWrappers = []interface{}{ (*QueryNode_AuthorMatches)(nil), (*QueryNode_CommitterMatches)(nil), (*QueryNode_CommitBefore)(nil), @@ -6870,18 +7367,18 @@ func file_gitserver_proto_init() { (*QueryNode_Boolean)(nil), (*QueryNode_Operator)(nil), } - file_gitserver_proto_msgTypes[27].OneofWrappers = []interface{}{ + file_gitserver_proto_msgTypes[32].OneofWrappers = []interface{}{ (*SearchResponse_Match)(nil), (*SearchResponse_LimitHit)(nil), } - file_gitserver_proto_msgTypes[72].OneofWrappers = []interface{}{} + file_gitserver_proto_msgTypes[77].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_gitserver_proto_rawDesc, NumEnums: 3, - NumMessages: 79, + NumMessages: 84, NumExtensions: 0, NumServices: 1, }, diff --git a/internal/gitserver/v1/gitserver.proto b/internal/gitserver/v1/gitserver.proto index 9d51a01ddea..2d334a1c1bb 100644 --- a/internal/gitserver/v1/gitserver.proto +++ b/internal/gitserver/v1/gitserver.proto @@ -77,6 +77,52 @@ service GitserverService { rpc MergeBase(MergeBaseRequest) returns (MergeBaseResponse) { option idempotency_level = NO_SIDE_EFFECTS; } + // Blame runs a blame operation on the specified file. It returns a stream of + // hunks as they are found. The --incremental flag is used on the git CLI level + // to achieve this behavior. + // The endpoint will verify that the user is allowed to blame the given file + // if subrepo permissions are enabled for the repo. If access is denied, an error + // with a UnauthorizedPayload in the details is returned. + // + // If the given repo is not cloned, it will be enqueued for cloning and a NotFound + // error will be returned, with a NotFoundPayload in the details. + rpc Blame(BlameRequest) returns (stream BlameResponse) { + option idempotency_level = NO_SIDE_EFFECTS; + } +} + +message BlameRequest { + // repo_name is the name of the repo to run the blame operation in. + // Note: We use field ID 2 here to reserve 1 for a future repo int32 field. + string repo_name = 2; + // commit is the commit to start the blame operation in. If not given, the latest + // HEAD is used. + optional string commit = 3; + string path = 4; + bool ignore_whitespace = 5; + optional uint32 start_line = 6; + optional uint32 end_line = 7; +} + +message BlameResponse { + BlameHunk hunk = 1; +} + +message BlameHunk { + uint32 start_line = 1; + uint32 end_line = 2; + uint32 start_byte = 3; + uint32 end_byte = 4; + string commit = 5; + BlameAuthor author = 6; + string message = 7; + string filename = 8; +} + +message BlameAuthor { + string name = 1; + string email = 2; + google.protobuf.Timestamp date = 3; } // DiskInfoRequest is a empty request for the DiskInfo RPC. @@ -241,6 +287,15 @@ message ExecStatusPayload { string stderr = 2; } +// UnauthorizedPayload is the payload returned when an actor cannot access +// a commit or file due to subrepo permissions. +message UnauthorizedPayload { + // Note: We use field ID 2 here to reserve 1 for a future repo int32 field. + string repo_name = 2; + optional string path = 3; + optional string commit = 4; +} + message SearchRequest { // repo is the name of the repo to be searched string repo = 1; diff --git a/internal/gitserver/v1/gitserver_grpc.pb.go b/internal/gitserver/v1/gitserver_grpc.pb.go index e672d34f008..5850867942e 100644 --- a/internal/gitserver/v1/gitserver_grpc.pb.go +++ b/internal/gitserver/v1/gitserver_grpc.pb.go @@ -42,6 +42,7 @@ const ( GitserverService_IsPerforceSuperUser_FullMethodName = "/gitserver.v1.GitserverService/IsPerforceSuperUser" GitserverService_PerforceGetChangelist_FullMethodName = "/gitserver.v1.GitserverService/PerforceGetChangelist" GitserverService_MergeBase_FullMethodName = "/gitserver.v1.GitserverService/MergeBase" + GitserverService_Blame_FullMethodName = "/gitserver.v1.GitserverService/Blame" ) // GitserverServiceClient is the client API for GitserverService service. @@ -78,6 +79,16 @@ type GitserverServiceClient interface { // If the given repo is not cloned, it will be enqueued for cloning and a NotFound // error will be returned, with a NotFoundPayload in the details. MergeBase(ctx context.Context, in *MergeBaseRequest, opts ...grpc.CallOption) (*MergeBaseResponse, error) + // Blame runs a blame operation on the specified file. It returns a stream of + // hunks as they are found. The --incremental flag is used on the git CLI level + // to achieve this behavior. + // The endpoint will verify that the user is allowed to blame the given file + // if subrepo permissions are enabled for the repo. If access is denied, an error + // with a UnauthorizedPayload in the details is returned. + // + // If the given repo is not cloned, it will be enqueued for cloning and a NotFound + // error will be returned, with a NotFoundPayload in the details. + Blame(ctx context.Context, in *BlameRequest, opts ...grpc.CallOption) (GitserverService_BlameClient, error) } type gitserverServiceClient struct { @@ -414,6 +425,38 @@ func (c *gitserverServiceClient) MergeBase(ctx context.Context, in *MergeBaseReq return out, nil } +func (c *gitserverServiceClient) Blame(ctx context.Context, in *BlameRequest, opts ...grpc.CallOption) (GitserverService_BlameClient, error) { + stream, err := c.cc.NewStream(ctx, &GitserverService_ServiceDesc.Streams[5], GitserverService_Blame_FullMethodName, opts...) + if err != nil { + return nil, err + } + x := &gitserverServiceBlameClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type GitserverService_BlameClient interface { + Recv() (*BlameResponse, error) + grpc.ClientStream +} + +type gitserverServiceBlameClient struct { + grpc.ClientStream +} + +func (x *gitserverServiceBlameClient) Recv() (*BlameResponse, error) { + m := new(BlameResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + // GitserverServiceServer is the server API for GitserverService service. // All implementations must embed UnimplementedGitserverServiceServer // for forward compatibility @@ -448,6 +491,16 @@ type GitserverServiceServer interface { // If the given repo is not cloned, it will be enqueued for cloning and a NotFound // error will be returned, with a NotFoundPayload in the details. MergeBase(context.Context, *MergeBaseRequest) (*MergeBaseResponse, error) + // Blame runs a blame operation on the specified file. It returns a stream of + // hunks as they are found. The --incremental flag is used on the git CLI level + // to achieve this behavior. + // The endpoint will verify that the user is allowed to blame the given file + // if subrepo permissions are enabled for the repo. If access is denied, an error + // with a UnauthorizedPayload in the details is returned. + // + // If the given repo is not cloned, it will be enqueued for cloning and a NotFound + // error will be returned, with a NotFoundPayload in the details. + Blame(*BlameRequest, GitserverService_BlameServer) error mustEmbedUnimplementedGitserverServiceServer() } @@ -524,6 +577,9 @@ func (UnimplementedGitserverServiceServer) PerforceGetChangelist(context.Context func (UnimplementedGitserverServiceServer) MergeBase(context.Context, *MergeBaseRequest) (*MergeBaseResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method MergeBase not implemented") } +func (UnimplementedGitserverServiceServer) Blame(*BlameRequest, GitserverService_BlameServer) error { + return status.Errorf(codes.Unimplemented, "method Blame not implemented") +} func (UnimplementedGitserverServiceServer) mustEmbedUnimplementedGitserverServiceServer() {} // UnsafeGitserverServiceServer may be embedded to opt out of forward compatibility for this service. @@ -971,6 +1027,27 @@ func _GitserverService_MergeBase_Handler(srv interface{}, ctx context.Context, d return interceptor(ctx, in, info, handler) } +func _GitserverService_Blame_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(BlameRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(GitserverServiceServer).Blame(m, &gitserverServiceBlameServer{stream}) +} + +type GitserverService_BlameServer interface { + Send(*BlameResponse) error + grpc.ServerStream +} + +type gitserverServiceBlameServer struct { + grpc.ServerStream +} + +func (x *gitserverServiceBlameServer) Send(m *BlameResponse) error { + return x.ServerStream.SendMsg(m) +} + // GitserverService_ServiceDesc is the grpc.ServiceDesc for GitserverService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -1077,6 +1154,11 @@ var GitserverService_ServiceDesc = grpc.ServiceDesc{ Handler: _GitserverService_P4Exec_Handler, ServerStreams: true, }, + { + StreamName: "Blame", + Handler: _GitserverService_Blame_Handler, + ServerStreams: true, + }, }, Metadata: "gitserver.proto", } diff --git a/mockgen.temp.yaml b/mockgen.temp.yaml index 85640283e12..b38b0594061 100644 --- a/mockgen.temp.yaml +++ b/mockgen.temp.yaml @@ -137,8 +137,11 @@ interfaces: - GitserverServiceClient - GitserverService_ExecServer + - GitserverService_BlameServer + - GitserverService_BlameClient - filename: cmd/gitserver/internal/git/mock.go path: github.com/sourcegraph/sourcegraph/cmd/gitserver/internal/git interfaces: - GitBackend - GitConfigBackend + - BlameHunkReader diff --git a/mockgen.test.yaml b/mockgen.test.yaml index 39aa5630063..63cb2201034 100644 --- a/mockgen.test.yaml +++ b/mockgen.test.yaml @@ -415,3 +415,9 @@ interfaces: - RepositoryLocker - RepositoryLock +- filename: cmd/gitserver/internal/mocks_test.go + package: internal + sources: + - path: github.com/sourcegraph/sourcegraph/cmd/gitserver/internal + interfaces: + - service