From b45da91240d3a8d97acef8605e7d4f8ce25f81b2 Mon Sep 17 00:00:00 2001 From: Camden Cheek Date: Mon, 5 Jun 2023 15:32:45 -0600 Subject: [PATCH] Add a gRPC API (#577) This adds a gRPC API alongside the existing gob API. It is enabled whenever the RPC setting is enabled. I didn't think it made sense to have a separate setting to enable it. It is only used when a gRPC request is detected (Content-Type: application/grpc). Eventually, we should likely open a separate port for gRPC traffic, but this should be okay for now. In order to minimize the footprint of this change, we only use the protobuf definitions in the RPC layer. They are translated to/from the existing go types. This results in a small perf penalty. --- BUILD.bazel | 8 + WORKSPACE | 2 +- api.go | 2 +- api_proto.go | 723 ++++++++ api_proto_test.go | 454 +++++ cmd/zoekt-webserver/BUILD.bazel | 5 + cmd/zoekt-webserver/main.go | 28 +- go.mod | 4 +- go.sum | 9 +- grpc/BUILD.bazel | 33 + grpc/server.go | 65 + grpc/server_test.go | 94 + grpc/v1/BUILD.bazel | 29 + grpc/v1/buf.gen.yaml | 11 + grpc/v1/query.pb.go | 1793 ++++++++++++++++++ grpc/v1/query.proto | 147 ++ grpc/v1/webserver.pb.go | 3020 +++++++++++++++++++++++++++++++ grpc/v1/webserver.proto | 491 +++++ grpc/v1/webserver_grpc.pb.go | 215 +++ query/BUILD.bazel | 3 + query/query_proto.go | 458 +++++ query/query_proto_test.go | 99 + testdata/search_result_1.pb | Bin 0 -> 7252 bytes web/trace.go | 4 + 24 files changed, 7690 insertions(+), 7 deletions(-) create mode 100644 api_proto.go create mode 100644 api_proto_test.go create mode 100644 grpc/BUILD.bazel create mode 100644 grpc/server.go create mode 100644 grpc/server_test.go create mode 100644 grpc/v1/BUILD.bazel create mode 100644 grpc/v1/buf.gen.yaml create mode 100644 grpc/v1/query.pb.go create mode 100644 grpc/v1/query.proto create mode 100644 grpc/v1/webserver.pb.go create mode 100644 grpc/v1/webserver.proto create mode 100644 grpc/v1/webserver_grpc.pb.go create mode 100644 query/query_proto.go create mode 100644 query/query_proto_test.go create mode 100755 testdata/search_result_1.pb diff --git a/BUILD.bazel b/BUILD.bazel index 9c9ec5e70..f7d964f47 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -21,6 +21,7 @@ go_library( name = "zoekt", srcs = [ "api.go", + "api_proto.go", "bits.go", "btree.go", "contentprovider.go", @@ -45,12 +46,15 @@ go_library( importpath = "github.com/sourcegraph/zoekt", visibility = ["//visibility:public"], deps = [ + "//grpc/v1:grpc", "//query", "@com_github_edsrzf_mmap_go//:mmap-go", "@com_github_go_enry_go_enry_v2//:go-enry", "@com_github_go_enry_go_enry_v2//data", "@com_github_grafana_regexp//:regexp", "@com_github_rs_xid//:xid", + "@org_golang_google_protobuf//types/known/durationpb", + "@org_golang_google_protobuf//types/known/timestamppb", ] + select({ "@io_bazel_rules_go//go/platform:aix": [ "@org_golang_x_sys//unix", @@ -98,6 +102,7 @@ go_library( go_test( name = "zoekt_test", srcs = [ + "api_proto_test.go", "api_test.go", "bits_test.go", "btree_test.go", @@ -114,12 +119,15 @@ go_test( ], data = [":testdata"], embed = [":zoekt"], + embedsrcs = ["//testdata:search_result_1.pb"], #keep deps = [ + "//grpc/v1:grpc", "//query", "@com_github_google_go_cmp//cmp", "@com_github_google_go_cmp//cmp/cmpopts", "@com_github_grafana_regexp//:regexp", "@com_github_kylelemons_godebug//pretty", "@com_github_roaringbitmap_roaring//:roaring", + "@org_golang_google_protobuf//proto", ], ) diff --git a/WORKSPACE b/WORKSPACE index 31fd79256..0b8fcc2cc 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -49,7 +49,7 @@ http_archive( # Go toolchain setup load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies") -load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies", "go_repository") +load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies") load("//:deps.bzl", "go_dependencies") # gazelle:repository_macro deps.bzl%go_dependencies diff --git a/api.go b/api.go index 3d679899b..801dea5c0 100644 --- a/api.go +++ b/api.go @@ -525,7 +525,7 @@ func (r RepositoryBranch) String() string { // Repository holds repository metadata. type Repository struct { - // Sourcergaph's repository ID + // Sourcegraph's repository ID ID uint32 // The repository name diff --git a/api_proto.go b/api_proto.go new file mode 100644 index 000000000..3a7f04622 --- /dev/null +++ b/api_proto.go @@ -0,0 +1,723 @@ +// Copyright 2016 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zoekt // import "github.com/sourcegraph/zoekt" + +import ( + "math/rand" + "reflect" + + proto "github.com/sourcegraph/zoekt/grpc/v1" + "google.golang.org/protobuf/types/known/durationpb" + "google.golang.org/protobuf/types/known/timestamppb" +) + +func FileMatchFromProto(p *proto.FileMatch) FileMatch { + lineMatches := make([]LineMatch, len(p.GetLineMatches())) + for i, lineMatch := range p.GetLineMatches() { + lineMatches[i] = LineMatchFromProto(lineMatch) + } + + chunkMatches := make([]ChunkMatch, len(p.GetChunkMatches())) + for i, chunkMatch := range p.GetChunkMatches() { + chunkMatches[i] = ChunkMatchFromProto(chunkMatch) + } + + return FileMatch{ + Score: p.GetScore(), + Debug: p.GetDebug(), + FileName: p.GetFileName(), + Repository: p.GetRepository(), + Branches: p.GetBranches(), + LineMatches: lineMatches, + ChunkMatches: chunkMatches, + RepositoryID: p.GetRepositoryId(), + RepositoryPriority: p.GetRepositoryPriority(), + Content: p.GetContent(), + Checksum: p.GetChecksum(), + Language: p.GetLanguage(), + SubRepositoryName: p.GetSubRepositoryName(), + SubRepositoryPath: p.GetSubRepositoryPath(), + Version: p.GetVersion(), + } +} + +func (m *FileMatch) ToProto() *proto.FileMatch { + lineMatches := make([]*proto.LineMatch, len(m.LineMatches)) + for i, lm := range m.LineMatches { + lineMatches[i] = lm.ToProto() + } + + chunkMatches := make([]*proto.ChunkMatch, len(m.ChunkMatches)) + for i, cm := range m.ChunkMatches { + chunkMatches[i] = cm.ToProto() + } + + return &proto.FileMatch{ + Score: m.Score, + Debug: m.Debug, + FileName: m.FileName, + Repository: m.Repository, + Branches: m.Branches, + LineMatches: lineMatches, + ChunkMatches: chunkMatches, + RepositoryId: m.RepositoryID, + RepositoryPriority: m.RepositoryPriority, + Content: m.Content, + Checksum: m.Checksum, + Language: m.Language, + SubRepositoryName: m.SubRepositoryName, + SubRepositoryPath: m.SubRepositoryPath, + Version: m.Version, + } +} + +func ChunkMatchFromProto(p *proto.ChunkMatch) ChunkMatch { + ranges := make([]Range, len(p.GetRanges())) + for i, r := range p.GetRanges() { + ranges[i] = RangeFromProto(r) + } + + symbols := make([]*Symbol, len(p.GetSymbolInfo())) + for i, r := range p.GetSymbolInfo() { + symbols[i] = SymbolFromProto(r) + } + + return ChunkMatch{ + Content: p.GetContent(), + ContentStart: LocationFromProto(p.GetContentStart()), + FileName: p.GetFileName(), + Ranges: ranges, + SymbolInfo: symbols, + Score: p.GetScore(), + DebugScore: p.GetDebugScore(), + } +} + +func (cm *ChunkMatch) ToProto() *proto.ChunkMatch { + ranges := make([]*proto.Range, len(cm.Ranges)) + for i, r := range cm.Ranges { + ranges[i] = r.ToProto() + } + + symbolInfo := make([]*proto.SymbolInfo, len(cm.SymbolInfo)) + for i, si := range cm.SymbolInfo { + symbolInfo[i] = si.ToProto() + } + + return &proto.ChunkMatch{ + Content: cm.Content, + ContentStart: cm.ContentStart.ToProto(), + FileName: cm.FileName, + Ranges: ranges, + SymbolInfo: symbolInfo, + Score: cm.Score, + DebugScore: cm.DebugScore, + } +} + +func RangeFromProto(p *proto.Range) Range { + return Range{ + Start: LocationFromProto(p.GetStart()), + End: LocationFromProto(p.GetEnd()), + } +} + +func (r *Range) ToProto() *proto.Range { + return &proto.Range{ + Start: r.Start.ToProto(), + End: r.End.ToProto(), + } +} + +func LocationFromProto(p *proto.Location) Location { + return Location{ + ByteOffset: p.GetByteOffset(), + LineNumber: p.GetLineNumber(), + Column: p.GetColumn(), + } +} + +func (l *Location) ToProto() *proto.Location { + return &proto.Location{ + ByteOffset: l.ByteOffset, + LineNumber: l.LineNumber, + Column: l.Column, + } +} + +func LineMatchFromProto(p *proto.LineMatch) LineMatch { + lineFragments := make([]LineFragmentMatch, len(p.GetLineFragments())) + for i, lineFragment := range p.GetLineFragments() { + lineFragments[i] = LineFragmentMatchFromProto(lineFragment) + } + + return LineMatch{ + Line: p.GetLine(), + LineStart: int(p.GetLineStart()), + LineEnd: int(p.GetLineEnd()), + LineNumber: int(p.GetLineNumber()), + Before: p.GetBefore(), + After: p.GetAfter(), + FileName: p.GetFileName(), + Score: p.GetScore(), + DebugScore: p.GetDebugScore(), + LineFragments: lineFragments, + } +} + +func (lm *LineMatch) ToProto() *proto.LineMatch { + fragments := make([]*proto.LineFragmentMatch, len(lm.LineFragments)) + for i, fragment := range lm.LineFragments { + fragments[i] = fragment.ToProto() + } + + return &proto.LineMatch{ + Line: lm.Line, + LineStart: int64(lm.LineStart), + LineEnd: int64(lm.LineEnd), + LineNumber: int64(lm.LineNumber), + Before: lm.Before, + After: lm.After, + FileName: lm.FileName, + Score: lm.Score, + DebugScore: lm.DebugScore, + LineFragments: fragments, + } +} + +func SymbolFromProto(p *proto.SymbolInfo) *Symbol { + if p == nil { + return nil + } + + return &Symbol{ + Sym: p.GetSym(), + Kind: p.GetKind(), + Parent: p.GetParent(), + ParentKind: p.GetParentKind(), + } +} + +func (s *Symbol) ToProto() *proto.SymbolInfo { + if s == nil { + return nil + } + + return &proto.SymbolInfo{ + Sym: s.Sym, + Kind: s.Kind, + Parent: s.Parent, + ParentKind: s.ParentKind, + } +} + +func LineFragmentMatchFromProto(p *proto.LineFragmentMatch) LineFragmentMatch { + return LineFragmentMatch{ + LineOffset: int(p.GetLineOffset()), + Offset: p.GetOffset(), + MatchLength: int(p.GetMatchLength()), + SymbolInfo: SymbolFromProto(p.GetSymbolInfo()), + } +} + +func (lfm *LineFragmentMatch) ToProto() *proto.LineFragmentMatch { + return &proto.LineFragmentMatch{ + LineOffset: int64(lfm.LineOffset), + Offset: lfm.Offset, + MatchLength: int64(lfm.MatchLength), + SymbolInfo: lfm.SymbolInfo.ToProto(), + } +} + +func FlushReasonFromProto(p proto.FlushReason) FlushReason { + switch p { + case proto.FlushReason_TIMER_EXPIRED: + return FlushReasonTimerExpired + case proto.FlushReason_FINAL_FLUSH: + return FlushReasonFinalFlush + case proto.FlushReason_MAX_SIZE: + return FlushReasonMaxSize + default: + return FlushReason(0) + } +} + +func (fr FlushReason) ToProto() proto.FlushReason { + switch fr { + case FlushReasonTimerExpired: + return proto.FlushReason_TIMER_EXPIRED + case FlushReasonFinalFlush: + return proto.FlushReason_FINAL_FLUSH + case FlushReasonMaxSize: + return proto.FlushReason_MAX_SIZE + default: + return proto.FlushReason_UNKNOWN + } +} + +// Generate valid reasons for quickchecks +func (fr FlushReason) Generate(rand *rand.Rand, size int) reflect.Value { + switch rand.Int() % 4 { + case 1: + return reflect.ValueOf(FlushReasonMaxSize) + case 2: + return reflect.ValueOf(FlushReasonFinalFlush) + case 3: + return reflect.ValueOf(FlushReasonTimerExpired) + default: + return reflect.ValueOf(FlushReason(0)) + } +} + +func StatsFromProto(p *proto.Stats) Stats { + return Stats{ + ContentBytesLoaded: p.GetContentBytesLoaded(), + IndexBytesLoaded: p.GetIndexBytesLoaded(), + Crashes: int(p.GetCrashes()), + Duration: p.GetDuration().AsDuration(), + FileCount: int(p.GetFileCount()), + ShardFilesConsidered: int(p.GetShardFilesConsidered()), + FilesConsidered: int(p.GetFilesConsidered()), + FilesLoaded: int(p.GetFilesLoaded()), + FilesSkipped: int(p.GetFilesSkipped()), + ShardsScanned: int(p.GetShardsScanned()), + ShardsSkipped: int(p.GetShardsSkipped()), + ShardsSkippedFilter: int(p.GetShardsSkippedFilter()), + MatchCount: int(p.GetMatchCount()), + NgramMatches: int(p.GetNgramMatches()), + Wait: p.GetWait().AsDuration(), + RegexpsConsidered: int(p.GetRegexpsConsidered()), + FlushReason: FlushReasonFromProto(p.GetFlushReason()), + } +} + +func (s *Stats) ToProto() *proto.Stats { + return &proto.Stats{ + ContentBytesLoaded: s.ContentBytesLoaded, + IndexBytesLoaded: s.IndexBytesLoaded, + Crashes: int64(s.Crashes), + Duration: durationpb.New(s.Duration), + FileCount: int64(s.FileCount), + ShardFilesConsidered: int64(s.ShardFilesConsidered), + FilesConsidered: int64(s.FilesConsidered), + FilesLoaded: int64(s.FilesLoaded), + FilesSkipped: int64(s.FilesSkipped), + ShardsScanned: int64(s.ShardsScanned), + ShardsSkipped: int64(s.ShardsSkipped), + ShardsSkippedFilter: int64(s.ShardsSkippedFilter), + MatchCount: int64(s.MatchCount), + NgramMatches: int64(s.NgramMatches), + Wait: durationpb.New(s.Wait), + RegexpsConsidered: int64(s.RegexpsConsidered), + FlushReason: s.FlushReason.ToProto(), + } +} + +func ProgressFromProto(p *proto.Progress) Progress { + return Progress{ + Priority: p.GetPriority(), + MaxPendingPriority: p.GetMaxPendingPriority(), + } +} + +func (p *Progress) ToProto() *proto.Progress { + return &proto.Progress{ + Priority: p.Priority, + MaxPendingPriority: p.MaxPendingPriority, + } +} + +func SearchResultFromProto(p *proto.SearchResponse) *SearchResult { + if p == nil { + return nil + } + + files := make([]FileMatch, len(p.GetFiles())) + for i, file := range p.GetFiles() { + files[i] = FileMatchFromProto(file) + } + + return &SearchResult{ + Stats: StatsFromProto(p.GetStats()), + Progress: ProgressFromProto(p.GetProgress()), + Files: files, + RepoURLs: p.RepoUrls, + LineFragments: p.LineFragments, + } +} + +func (sr *SearchResult) ToProto() *proto.SearchResponse { + if sr == nil { + return nil + } + + files := make([]*proto.FileMatch, len(sr.Files)) + for i, file := range sr.Files { + files[i] = file.ToProto() + } + + return &proto.SearchResponse{ + Stats: sr.Stats.ToProto(), + Progress: sr.Progress.ToProto(), + Files: files, + RepoUrls: sr.RepoURLs, + LineFragments: sr.LineFragments, + } +} + +func RepositoryBranchFromProto(p *proto.RepositoryBranch) RepositoryBranch { + return RepositoryBranch{ + Name: p.GetName(), + Version: p.GetVersion(), + } + +} + +func (r *RepositoryBranch) ToProto() *proto.RepositoryBranch { + return &proto.RepositoryBranch{ + Name: r.Name, + Version: r.Version, + } +} + +func RepositoryFromProto(p *proto.Repository) Repository { + branches := make([]RepositoryBranch, len(p.GetBranches())) + for i, branch := range p.GetBranches() { + branches[i] = RepositoryBranchFromProto(branch) + } + + subRepoMap := make(map[string]*Repository, len(p.GetSubRepoMap())) + for name, repo := range p.GetSubRepoMap() { + r := RepositoryFromProto(repo) + subRepoMap[name] = &r + } + + fileTombstones := make(map[string]struct{}, len(p.GetFileTombstones())) + for _, file := range p.GetFileTombstones() { + fileTombstones[file] = struct{}{} + } + + return Repository{ + ID: p.GetId(), + Name: p.GetName(), + URL: p.GetUrl(), + Source: p.GetSource(), + Branches: branches, + SubRepoMap: subRepoMap, + CommitURLTemplate: p.GetCommitUrlTemplate(), + FileURLTemplate: p.GetFileUrlTemplate(), + LineFragmentTemplate: p.GetLineFragmentTemplate(), + priority: p.GetPriority(), + RawConfig: p.GetRawConfig(), + Rank: uint16(p.GetRank()), + IndexOptions: p.GetIndexOptions(), + HasSymbols: p.GetHasSymbols(), + Tombstone: p.GetTombstone(), + LatestCommitDate: p.GetLatestCommitDate().AsTime(), + FileTombstones: fileTombstones, + } +} + +func (r *Repository) ToProto() *proto.Repository { + if r == nil { + return nil + } + + branches := make([]*proto.RepositoryBranch, len(r.Branches)) + for i, branch := range r.Branches { + branches[i] = branch.ToProto() + } + + subRepoMap := make(map[string]*proto.Repository, len(r.SubRepoMap)) + for name, repo := range r.SubRepoMap { + subRepoMap[name] = repo.ToProto() + } + + fileTombstones := make([]string, 0, len(r.FileTombstones)) + for file := range r.FileTombstones { + fileTombstones = append(fileTombstones, file) + } + + return &proto.Repository{ + Id: r.ID, + Name: r.Name, + Url: r.URL, + Source: r.Source, + Branches: branches, + SubRepoMap: subRepoMap, + CommitUrlTemplate: r.CommitURLTemplate, + FileUrlTemplate: r.FileURLTemplate, + LineFragmentTemplate: r.LineFragmentTemplate, + Priority: r.priority, + RawConfig: r.RawConfig, + Rank: uint32(r.Rank), + IndexOptions: r.IndexOptions, + HasSymbols: r.HasSymbols, + Tombstone: r.Tombstone, + LatestCommitDate: timestamppb.New(r.LatestCommitDate), + FileTombstones: fileTombstones, + } +} + +func IndexMetadataFromProto(p *proto.IndexMetadata) IndexMetadata { + languageMap := make(map[string]uint16, len(p.GetLanguageMap())) + for language, id := range p.GetLanguageMap() { + languageMap[language] = uint16(id) + } + + return IndexMetadata{ + IndexFormatVersion: int(p.GetIndexFormatVersion()), + IndexFeatureVersion: int(p.GetIndexFeatureVersion()), + IndexMinReaderVersion: int(p.GetIndexMinReaderVersion()), + IndexTime: p.GetIndexTime().AsTime(), + PlainASCII: p.GetPlainAscii(), + LanguageMap: languageMap, + ZoektVersion: p.GetZoektVersion(), + ID: p.GetId(), + } +} + +func (m *IndexMetadata) ToProto() *proto.IndexMetadata { + if m == nil { + return nil + } + + languageMap := make(map[string]uint32, len(m.LanguageMap)) + for language, id := range m.LanguageMap { + languageMap[language] = uint32(id) + } + + return &proto.IndexMetadata{ + IndexFormatVersion: int64(m.IndexFormatVersion), + IndexFeatureVersion: int64(m.IndexFeatureVersion), + IndexMinReaderVersion: int64(m.IndexMinReaderVersion), + IndexTime: timestamppb.New(m.IndexTime), + PlainAscii: m.PlainASCII, + LanguageMap: languageMap, + ZoektVersion: m.ZoektVersion, + Id: m.ID, + } +} + +func RepoStatsFromProto(p *proto.RepoStats) RepoStats { + return RepoStats{ + Repos: int(p.GetRepos()), + Shards: int(p.GetShards()), + Documents: int(p.GetDocuments()), + IndexBytes: p.GetIndexBytes(), + ContentBytes: p.GetContentBytes(), + NewLinesCount: p.GetNewLinesCount(), + DefaultBranchNewLinesCount: p.GetDefaultBranchNewLinesCount(), + OtherBranchesNewLinesCount: p.GetOtherBranchesNewLinesCount(), + } +} + +func (s *RepoStats) ToProto() *proto.RepoStats { + return &proto.RepoStats{ + Repos: int64(s.Repos), + Shards: int64(s.Shards), + Documents: int64(s.Documents), + IndexBytes: s.IndexBytes, + ContentBytes: s.ContentBytes, + NewLinesCount: s.NewLinesCount, + DefaultBranchNewLinesCount: s.DefaultBranchNewLinesCount, + OtherBranchesNewLinesCount: s.OtherBranchesNewLinesCount, + } +} + +func RepoListEntryFromProto(p *proto.RepoListEntry) *RepoListEntry { + if p == nil { + return nil + } + + return &RepoListEntry{ + Repository: RepositoryFromProto(p.GetRepository()), + IndexMetadata: IndexMetadataFromProto(p.GetIndexMetadata()), + Stats: RepoStatsFromProto(p.GetStats()), + } +} + +func (r *RepoListEntry) ToProto() *proto.RepoListEntry { + if r == nil { + return nil + } + + return &proto.RepoListEntry{ + Repository: r.Repository.ToProto(), + IndexMetadata: r.IndexMetadata.ToProto(), + Stats: r.Stats.ToProto(), + } +} + +func MinimalRepoListEntryFromProto(p *proto.MinimalRepoListEntry) MinimalRepoListEntry { + branches := make([]RepositoryBranch, len(p.GetBranches())) + for i, branch := range p.GetBranches() { + branches[i] = RepositoryBranchFromProto(branch) + } + + return MinimalRepoListEntry{ + HasSymbols: p.GetHasSymbols(), + Branches: branches, + } +} + +func (m *MinimalRepoListEntry) ToProto() *proto.MinimalRepoListEntry { + branches := make([]*proto.RepositoryBranch, len(m.Branches)) + for i, branch := range m.Branches { + branches[i] = branch.ToProto() + } + return &proto.MinimalRepoListEntry{ + HasSymbols: m.HasSymbols, + Branches: branches, + } +} + +func RepoListFromProto(p *proto.ListResponse) *RepoList { + repos := make([]*RepoListEntry, len(p.GetRepos())) + for i, repo := range p.GetRepos() { + repos[i] = RepoListEntryFromProto(repo) + } + + reposMap := make(map[uint32]MinimalRepoListEntry, len(p.GetReposMap())) + for id, mle := range p.GetReposMap() { + reposMap[id] = MinimalRepoListEntryFromProto(mle) + } + + minimal := make(map[uint32]*MinimalRepoListEntry, len(p.GetMinimal())) + for id, mle := range p.GetMinimal() { + m := MinimalRepoListEntryFromProto(mle) + minimal[id] = &m + } + + return &RepoList{ + Repos: repos, + ReposMap: reposMap, + Crashes: int(p.GetCrashes()), + Stats: RepoStatsFromProto(p.GetStats()), + Minimal: minimal, + } +} + +func (r *RepoList) ToProto() *proto.ListResponse { + repos := make([]*proto.RepoListEntry, len(r.Repos)) + for i, repo := range r.Repos { + repos[i] = repo.ToProto() + } + + reposMap := make(map[uint32]*proto.MinimalRepoListEntry, len(r.ReposMap)) + for id, repo := range r.ReposMap { + reposMap[id] = repo.ToProto() + } + + minimal := make(map[uint32]*proto.MinimalRepoListEntry, len(r.Minimal)) + for id, repo := range r.Minimal { + minimal[id] = repo.ToProto() + } + + return &proto.ListResponse{ + Repos: []*proto.RepoListEntry{}, + ReposMap: reposMap, + Crashes: int64(r.Crashes), + Stats: r.Stats.ToProto(), + Minimal: minimal, + } +} + +func (l *ListOptions) ToProto() *proto.ListOptions { + if l == nil { + return nil + } + var field proto.ListOptions_RepoListField + switch l.Field { + case RepoListFieldRepos: + field = proto.ListOptions_REPO_LIST_FIELD_REPOS + case RepoListFieldMinimal: + field = proto.ListOptions_REPO_LIST_FIELD_MINIMAL + case RepoListFieldReposMap: + field = proto.ListOptions_REPO_LIST_FIELD_REPOS_MAP + } + + return &proto.ListOptions{ + Field: field, + Minimal: l.Minimal, + } +} + +func ListOptionsFromProto(p *proto.ListOptions) *ListOptions { + if p == nil { + return nil + } + var field RepoListField + switch p.GetField() { + case proto.ListOptions_REPO_LIST_FIELD_REPOS: + field = RepoListFieldRepos + case proto.ListOptions_REPO_LIST_FIELD_MINIMAL: + field = RepoListFieldMinimal + case proto.ListOptions_REPO_LIST_FIELD_REPOS_MAP: + field = RepoListFieldReposMap + } + return &ListOptions{ + Field: field, + Minimal: p.GetMinimal(), + } +} + +func SearchOptionsFromProto(p *proto.SearchOptions) *SearchOptions { + if p == nil { + return nil + } + + return &SearchOptions{ + EstimateDocCount: p.GetEstimateDocCount(), + Whole: p.GetWhole(), + ShardMaxMatchCount: int(p.GetShardMaxMatchCount()), + TotalMaxMatchCount: int(p.GetTotalMaxMatchCount()), + ShardRepoMaxMatchCount: int(p.GetShardRepoMaxMatchCount()), + MaxWallTime: p.GetMaxWallTime().AsDuration(), + FlushWallTime: p.GetFlushWallTime().AsDuration(), + MaxDocDisplayCount: int(p.GetMaxDocDisplayCount()), + NumContextLines: int(p.GetNumContextLines()), + ChunkMatches: p.GetChunkMatches(), + UseDocumentRanks: p.GetUseDocumentRanks(), + DocumentRanksWeight: p.GetDocumentRanksWeight(), + Trace: p.GetTrace(), + DebugScore: p.GetDebugScore(), + UseKeywordScoring: p.GetUseKeywordScoring(), + } +} + +func (s *SearchOptions) ToProto() *proto.SearchOptions { + if s == nil { + return nil + } + + return &proto.SearchOptions{ + EstimateDocCount: s.EstimateDocCount, + Whole: s.Whole, + ShardMaxMatchCount: int64(s.ShardMaxMatchCount), + TotalMaxMatchCount: int64(s.TotalMaxMatchCount), + ShardRepoMaxMatchCount: int64(s.ShardRepoMaxMatchCount), + MaxWallTime: durationpb.New(s.MaxWallTime), + FlushWallTime: durationpb.New(s.FlushWallTime), + MaxDocDisplayCount: int64(s.MaxDocDisplayCount), + NumContextLines: int64(s.NumContextLines), + ChunkMatches: s.ChunkMatches, + UseDocumentRanks: s.UseDocumentRanks, + DocumentRanksWeight: s.DocumentRanksWeight, + Trace: s.Trace, + DebugScore: s.DebugScore, + UseKeywordScoring: s.UseKeywordScoring, + } +} diff --git a/api_proto_test.go b/api_proto_test.go new file mode 100644 index 000000000..b29ed643a --- /dev/null +++ b/api_proto_test.go @@ -0,0 +1,454 @@ +// Copyright 2016 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package zoekt // import "github.com/sourcegraph/zoekt" + +import ( + "bytes" + _ "embed" + "encoding/gob" + "fmt" + "math/rand" + "reflect" + "testing" + "testing/quick" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "google.golang.org/protobuf/proto" + + v1 "github.com/sourcegraph/zoekt/grpc/v1" +) + +func TestProtoRoundtrip(t *testing.T) { + t.Run("FileMatch", func(t *testing.T) { + f := func(f1 FileMatch) bool { + p1 := f1.ToProto() + f2 := FileMatchFromProto(p1) + return reflect.DeepEqual(f1, f2) + } + if err := quick.Check(f, nil); err != nil { + t.Fatal(err) + } + }) + + t.Run("ChunkMatch", func(t *testing.T) { + f := func(f1 ChunkMatch) bool { + p1 := f1.ToProto() + f2 := ChunkMatchFromProto(p1) + return reflect.DeepEqual(f1, f2) + } + if err := quick.Check(f, nil); err != nil { + t.Fatal(err) + } + }) + + t.Run("Range", func(t *testing.T) { + f := func(f1 Range) bool { + p1 := f1.ToProto() + f2 := RangeFromProto(p1) + return reflect.DeepEqual(f1, f2) + } + if err := quick.Check(f, nil); err != nil { + t.Fatal(err) + } + }) + + t.Run("Location", func(t *testing.T) { + f := func(f1 Range) bool { + p1 := f1.ToProto() + f2 := RangeFromProto(p1) + return reflect.DeepEqual(f1, f2) + } + if err := quick.Check(f, nil); err != nil { + t.Fatal(err) + } + }) + + t.Run("LineMatch", func(t *testing.T) { + f := func(f1 LineMatch) bool { + p1 := f1.ToProto() + f2 := LineMatchFromProto(p1) + return reflect.DeepEqual(f1, f2) + } + if err := quick.Check(f, nil); err != nil { + t.Fatal(err) + } + }) + + t.Run("Symbol", func(t *testing.T) { + f := func(f1 *Symbol) bool { + p1 := f1.ToProto() + f2 := SymbolFromProto(p1) + return reflect.DeepEqual(f1, f2) + } + if err := quick.Check(f, nil); err != nil { + t.Fatal(err) + } + }) + + t.Run("FlushReson", func(t *testing.T) { + f := func(f1 FlushReason) bool { + p1 := f1.ToProto() + f2 := FlushReasonFromProto(p1) + return reflect.DeepEqual(f1.String(), f2.String()) + } + if err := quick.Check(f, nil); err != nil { + t.Fatal(err) + } + }) + + t.Run("Stats", func(t *testing.T) { + f := func(f1 Stats) bool { + p1 := f1.ToProto() + f2 := StatsFromProto(p1) + return reflect.DeepEqual(f1, f2) + } + if err := quick.Check(f, nil); err != nil { + t.Fatal(err) + } + }) + + t.Run("Progress", func(t *testing.T) { + f := func(f1 Progress) bool { + p1 := f1.ToProto() + f2 := ProgressFromProto(p1) + return reflect.DeepEqual(f1, f2) + } + if err := quick.Check(f, nil); err != nil { + t.Fatal(err) + } + }) + + t.Run("SearchResult", func(t *testing.T) { + f := func(f1 *SearchResult) bool { + p1 := f1.ToProto() + f2 := SearchResultFromProto(p1) + return reflect.DeepEqual(f1, f2) + } + if err := quick.Check(f, nil); err != nil { + t.Fatal(err) + } + }) + + t.Run("Repository", func(t *testing.T) { + f := func(f1 *Repository) bool { + p1 := f1.ToProto() + f2 := RepositoryFromProto(p1) + if diff := cmp.Diff(f1, &f2, cmpopts.IgnoreUnexported(Repository{})); diff != "" { + fmt.Printf("got diff: %s", diff) + return false + } + return true + } + if err := quick.Check(f, nil); err != nil { + t.Fatal(err) + } + }) + + t.Run("IndexMetadata", func(t *testing.T) { + f := func(f1 *IndexMetadata) bool { + p1 := f1.ToProto() + f2 := IndexMetadataFromProto(p1) + if diff := cmp.Diff(f1, &f2); diff != "" { + fmt.Printf("got diff: %s", diff) + return false + } + return true + } + if err := quick.Check(f, nil); err != nil { + t.Fatal(err) + } + }) + + t.Run("RepoStats", func(t *testing.T) { + f := func(f1 RepoStats) bool { + p1 := f1.ToProto() + f2 := RepoStatsFromProto(p1) + if diff := cmp.Diff(f1, f2); diff != "" { + fmt.Printf("got diff: %s", diff) + return false + } + return true + } + if err := quick.Check(f, nil); err != nil { + t.Fatal(err) + } + }) + + t.Run("RepoListEntry", func(t *testing.T) { + r1 := &RepoListEntry{ + Repository: Repository{ + ID: 1, + Name: "test", + URL: "testurl", + Source: "testsource", + Branches: []RepositoryBranch{{ + Name: "branch", + Version: "version", + }}, + SubRepoMap: map[string]*Repository{ + "test": { + ID: 2, + Name: "subrepo", + Branches: []RepositoryBranch{}, + SubRepoMap: map[string]*Repository{}, + FileTombstones: map[string]struct{}{}, + }, + }, + CommitURLTemplate: "committemplate", + FileURLTemplate: "fileurltemplate", + LineFragmentTemplate: "linefragmenttemplate", + priority: 10, + RawConfig: map[string]string{ + "a": "b", + }, + Rank: 32, + IndexOptions: "indexoptions", + HasSymbols: true, + Tombstone: false, + LatestCommitDate: time.Now(), + FileTombstones: map[string]struct{}{ + "test1": {}, + }, + }, + IndexMetadata: IndexMetadata{ + IndexFormatVersion: 32, + IndexFeatureVersion: 42, + IndexMinReaderVersion: 52, + IndexTime: time.Now(), + PlainASCII: true, + LanguageMap: map[string]uint16{ + "go": 1, + }, + ZoektVersion: "32", + ID: "52", + }, + Stats: RepoStats{ + Repos: 3, + Shards: 4, + Documents: 5, + IndexBytes: 6, + ContentBytes: 7, + NewLinesCount: 8, + DefaultBranchNewLinesCount: 9, + OtherBranchesNewLinesCount: 10, + }, + } + + p1 := r1.ToProto() + r2 := RepoListEntryFromProto(p1) + if diff := cmp.Diff(r1, r2, cmpopts.IgnoreUnexported(Repository{})); diff != "" { + t.Fatalf("got diff: %s", diff) + } + }) + + t.Run("RepositoryBranch", func(t *testing.T) { + f := func(f1 RepositoryBranch) bool { + p1 := f1.ToProto() + f2 := RepositoryBranchFromProto(p1) + if diff := cmp.Diff(f1, f2); diff != "" { + fmt.Printf("got diff: %s", diff) + return false + } + return true + } + if err := quick.Check(f, nil); err != nil { + t.Fatal(err) + } + }) + + t.Run("MinimalRepoListEntry", func(t *testing.T) { + f := func(f1 MinimalRepoListEntry) bool { + p1 := f1.ToProto() + f2 := MinimalRepoListEntryFromProto(p1) + if diff := cmp.Diff(f1, f2); diff != "" { + fmt.Printf("got diff: %s", diff) + return false + } + return true + } + if err := quick.Check(f, nil); err != nil { + t.Fatal(err) + } + }) + + t.Run("ListOptions", func(t *testing.T) { + f := func(f1 *ListOptions) bool { + p1 := f1.ToProto() + f2 := ListOptionsFromProto(p1) + if diff := cmp.Diff(f1, f2); diff != "" { + fmt.Printf("got diff: %s", diff) + return false + } + return true + } + if err := quick.Check(f, nil); err != nil { + t.Fatal(err) + } + }) + + t.Run("SearchOptions", func(t *testing.T) { + f := func(f1 *SearchOptions) bool { + if f1 != nil { + // Ignore deprecated and unimplemented fields + f1.ShardMaxImportantMatch = 0 + f1.TotalMaxImportantMatch = 0 + f1.SpanContext = nil + } + p1 := f1.ToProto() + f2 := SearchOptionsFromProto(p1) + if diff := cmp.Diff(f1, f2); diff != "" { + fmt.Printf("got diff: %s", diff) + return false + } + return true + } + if err := quick.Check(f, nil); err != nil { + t.Fatal(err) + } + }) +} + +func (*IndexMetadata) Generate(r *rand.Rand, _ int) reflect.Value { + indexTime := time.Now().Add(time.Duration(r.Int63n(1000)) * time.Hour) + var i IndexMetadata + i.IndexFormatVersion = gen(i.IndexFormatVersion, r) + i.IndexFeatureVersion = gen(i.IndexFeatureVersion, r) + i.IndexMinReaderVersion = gen(i.IndexMinReaderVersion, r) + i.IndexTime = indexTime + i.PlainASCII = gen(i.PlainASCII, r) + i.LanguageMap = gen(i.LanguageMap, r) + i.ZoektVersion = gen(i.ZoektVersion, r) + i.ID = gen(i.ID, r) + return reflect.ValueOf(&i) +} + +func (*Repository) Generate(rng *rand.Rand, _ int) reflect.Value { + latestCommitDate := time.Now().Add(time.Duration(rng.Int63n(1000)) * time.Hour) + var r Repository + v := &Repository{ + ID: gen(r.ID, rng), + Name: gen(r.Name, rng), + URL: gen(r.URL, rng), + Source: gen(r.Source, rng), + Branches: gen(r.Branches, rng), + SubRepoMap: map[string]*Repository{}, + CommitURLTemplate: gen(r.CommitURLTemplate, rng), + FileURLTemplate: gen(r.FileURLTemplate, rng), + LineFragmentTemplate: gen(r.LineFragmentTemplate, rng), + priority: gen(r.priority, rng), + RawConfig: gen(r.RawConfig, rng), + Rank: gen(r.Rank, rng), + IndexOptions: gen(r.IndexOptions, rng), + HasSymbols: gen(r.HasSymbols, rng), + Tombstone: gen(r.Tombstone, rng), + LatestCommitDate: latestCommitDate, + FileTombstones: gen(r.FileTombstones, rng), + } + return reflect.ValueOf(v) +} + +func (RepoListField) Generate(rng *rand.Rand, _ int) reflect.Value { + switch rng.Int() % 3 { + case 0: + return reflect.ValueOf(RepoListField(RepoListFieldRepos)) + case 1: + return reflect.ValueOf(RepoListField(RepoListFieldMinimal)) + default: + return reflect.ValueOf(RepoListField(RepoListFieldReposMap)) + } +} + +func gen[T any](sample T, r *rand.Rand) T { + var t T + v, _ := quick.Value(reflect.TypeOf(t), r) + return v.Interface().(T) +} + +// This is a real search result that is intended to be a reasonable representative +// for serialization benchmarks. +// Generated by modifying the code to dump the proto to a file, then running a +// fairly broadly-matching search. +var ( + //go:embed testdata/search_result_1.pb + exampleSearchResultBytes []byte + + // The proto struct representation of the search result + exampleSearchResultProto = func() *v1.SearchResponse { + sr := new(v1.SearchResponse) + err := proto.Unmarshal(exampleSearchResultBytes, sr) + if err != nil { + panic(err) + } + return sr + }() + + // The non-proto struct representation of the search result + exampleSearchResultGo = SearchResultFromProto(exampleSearchResultProto) +) + +func BenchmarkGobRoundtrip(b *testing.B) { + for _, count := range []int{1, 100, 1000, 10000} { + b.Run(fmt.Sprintf("count=%d", count), func(b *testing.B) { + for i := 0; i < b.N; i++ { + var buf bytes.Buffer + enc := gob.NewEncoder(&buf) + + for i := 0; i < count; i++ { + err := enc.Encode(exampleSearchResultGo) + if err != nil { + panic(err) + } + + } + + dec := gob.NewDecoder(&buf) + for i := 0; i < count; i++ { + var res SearchResult + err := dec.Decode(&res) + if err != nil { + panic(err) + } + } + } + }) + } +} + +func BenchmarkProtoRoundtrip(b *testing.B) { + for _, count := range []int{1, 100, 1000, 10000} { + b.Run(fmt.Sprintf("count=%d", count), func(b *testing.B) { + for i := 0; i < b.N; i++ { + buffers := make([][]byte, 0, count) + for i := 0; i < count; i++ { + buf, err := proto.Marshal(exampleSearchResultProto) + if err != nil { + b.Fatal(err) + } + buffers = append(buffers, buf) + } + + for _, buf := range buffers { + res := new(v1.SearchResponse) + err := proto.Unmarshal(buf, res) + if err != nil { + b.Fatal(err) + } + } + } + }) + } +} diff --git a/cmd/zoekt-webserver/BUILD.bazel b/cmd/zoekt-webserver/BUILD.bazel index 37c417670..2052631e1 100644 --- a/cmd/zoekt-webserver/BUILD.bazel +++ b/cmd/zoekt-webserver/BUILD.bazel @@ -15,6 +15,8 @@ go_library( "//:zoekt", "//build", "//debugserver", + "//grpc", + "//grpc/v1:grpc", "//internal/profiler", "//internal/tracer", "//query", @@ -29,6 +31,9 @@ go_library( "@com_github_sourcegraph_mountinfo//:mountinfo", "@com_github_uber_jaeger_client_go//:jaeger-client-go", "@io_opentelemetry_go_otel_trace//:trace", + "@org_golang_google_grpc//:go_default_library", + "@org_golang_x_net//http2", + "@org_golang_x_net//http2/h2c", "@org_uber_go_automaxprocs//maxprocs", ] + select({ "@io_bazel_rules_go//go/platform:aix": [ diff --git a/cmd/zoekt-webserver/main.go b/cmd/zoekt-webserver/main.go index a8367e709..8df5026d3 100644 --- a/cmd/zoekt-webserver/main.go +++ b/cmd/zoekt-webserver/main.go @@ -38,10 +38,15 @@ import ( "time" "github.com/sourcegraph/mountinfo" + "golang.org/x/net/http2" + "golang.org/x/net/http2/h2c" + "google.golang.org/grpc" "github.com/sourcegraph/zoekt" "github.com/sourcegraph/zoekt/build" "github.com/sourcegraph/zoekt/debugserver" + zoektgrpc "github.com/sourcegraph/zoekt/grpc" + v1 "github.com/sourcegraph/zoekt/grpc/v1" "github.com/sourcegraph/zoekt/internal/profiler" "github.com/sourcegraph/zoekt/internal/tracer" "github.com/sourcegraph/zoekt/query" @@ -277,9 +282,12 @@ func main() { log.Println("watchdog disabled") } + grpcServer := grpc.NewServer() + v1.RegisterWebserverServiceServer(grpcServer, zoektgrpc.NewServer(web.NewTraceAwareSearcher(s.Searcher))) + srv := &http.Server{ Addr: *listen, - Handler: handler, + Handler: multiplexGRPC(grpcServer, handler), } go func() { @@ -311,6 +319,24 @@ func main() { } } +// multiplexGRPC takes a gRPC server and a plain HTTP handler and multiplexes the +// request handling. Any requests that declare themselves as gRPC requests are routed +// to the gRPC server, all others are routed to the httpHandler. +func multiplexGRPC(grpcServer *grpc.Server, httpHandler http.Handler) http.Handler { + newHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.ProtoMajor == 2 && strings.Contains(r.Header.Get("Content-Type"), "application/grpc") { + grpcServer.ServeHTTP(w, r) + } else { + httpHandler.ServeHTTP(w, r) + } + }) + + // Until we enable TLS, we need to fall back to the h2c protocol, which is + // basically HTTP2 without TLS. The standard library does not implement the + // h2s protocol, so this hijacks h2s requests and handles them correctly. + return h2c.NewHandler(newHandler, &http2.Server{}) +} + // addProxyHandler adds a handler to "mux" that proxies all requests with base // /indexserver to "socket". func addProxyHandler(mux *http.ServeMux, socket string) { diff --git a/go.mod b/go.mod index a8558c791..52c02acfa 100644 --- a/go.mod +++ b/go.mod @@ -62,6 +62,7 @@ require ( github.com/Microsoft/go-winio v0.6.0 // indirect github.com/ProtonMail/go-crypto v0.0.0-20230214155104-81033d7f4442 // indirect github.com/acomagu/bufpipe v1.0.3 // indirect + github.com/benbjohnson/clock v1.3.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.5.0 // indirect github.com/cenkalti/backoff/v4 v4.2.0 // indirect @@ -108,8 +109,9 @@ require ( github.com/rogpeppe/go-internal v1.9.0 // indirect github.com/sergi/go-diff v1.3.1 // indirect github.com/skeema/knownhosts v1.1.0 // indirect + github.com/stretchr/testify v1.8.2 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect - github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect + github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect go.opencensus.io v0.24.0 // indirect diff --git a/go.sum b/go.sum index a25968edb..6d4449032 100644 --- a/go.sum +++ b/go.sum @@ -73,7 +73,8 @@ github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5 github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= -github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= +github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= +github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= @@ -469,8 +470,9 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI= github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4= github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o= @@ -491,8 +493,9 @@ github.com/xanzy/go-gitlab v0.80.0 h1:2d6RwUrI3ZC2Xh9urnqiiHCLzWNndrGtje3yByZubd github.com/xanzy/go-gitlab v0.80.0/go.mod h1:DlByVTSXhPsJMYL6+cm8e8fTJjeBmhrXdC/yvkKKt6M= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= +github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= diff --git a/grpc/BUILD.bazel b/grpc/BUILD.bazel new file mode 100644 index 000000000..d0fbdf451 --- /dev/null +++ b/grpc/BUILD.bazel @@ -0,0 +1,33 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "grpc", + srcs = ["server.go"], + importpath = "github.com/sourcegraph/zoekt/grpc", + visibility = ["//visibility:public"], + deps = [ + "//:zoekt", + "//grpc/v1:grpc", + "//query", + "//stream", + "@org_golang_google_grpc//codes", + "@org_golang_google_grpc//status", + ], +) + +go_test( + name = "grpc_test", + srcs = ["server_test.go"], + embed = [":grpc"], + deps = [ + "//:zoekt", + "//grpc/v1:grpc", + "//internal/mockSearcher", + "//query", + "@org_golang_google_grpc//:go_default_library", + "@org_golang_google_grpc//credentials/insecure", + "@org_golang_google_protobuf//proto", + "@org_golang_x_net//http2", + "@org_golang_x_net//http2/h2c", + ], +) diff --git a/grpc/server.go b/grpc/server.go new file mode 100644 index 000000000..a6a498201 --- /dev/null +++ b/grpc/server.go @@ -0,0 +1,65 @@ +package grpc + +import ( + "context" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + "github.com/sourcegraph/zoekt" + v1 "github.com/sourcegraph/zoekt/grpc/v1" + "github.com/sourcegraph/zoekt/query" + "github.com/sourcegraph/zoekt/stream" +) + +func NewServer(s zoekt.Streamer) *Server { + return &Server{ + streamer: s, + } +} + +type Server struct { + v1.UnimplementedWebserverServiceServer + streamer zoekt.Streamer +} + +func (s *Server) Search(ctx context.Context, req *v1.SearchRequest) (*v1.SearchResponse, error) { + q, err := query.QFromProto(req.GetQuery()) + if err != nil { + return nil, status.Error(codes.InvalidArgument, err.Error()) + } + + res, err := s.streamer.Search(ctx, q, zoekt.SearchOptionsFromProto(req.GetOpts())) + if err != nil { + return nil, err + } + + return res.ToProto(), nil +} + +func (s *Server) StreamSearch(req *v1.SearchRequest, ss v1.WebserverService_StreamSearchServer) error { + q, err := query.QFromProto(req.GetQuery()) + if err != nil { + return status.Error(codes.InvalidArgument, err.Error()) + } + + onMatch := stream.SenderFunc(func(res *zoekt.SearchResult) { + ss.Send(res.ToProto()) + }) + + return s.streamer.StreamSearch(ss.Context(), q, zoekt.SearchOptionsFromProto(req.GetOpts()), onMatch) +} + +func (s *Server) List(ctx context.Context, req *v1.ListRequest) (*v1.ListResponse, error) { + q, err := query.QFromProto(req.GetQuery()) + if err != nil { + return nil, status.Error(codes.InvalidArgument, err.Error()) + } + + repoList, err := s.streamer.List(ctx, q, zoekt.ListOptionsFromProto(req.GetOpts())) + if err != nil { + return nil, err + } + + return repoList.ToProto(), nil +} diff --git a/grpc/server_test.go b/grpc/server_test.go new file mode 100644 index 000000000..f7e2c8316 --- /dev/null +++ b/grpc/server_test.go @@ -0,0 +1,94 @@ +package grpc + +import ( + "context" + "net/http/httptest" + "net/url" + "testing" + + "golang.org/x/net/http2" + "golang.org/x/net/http2/h2c" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + "google.golang.org/protobuf/proto" + + "github.com/sourcegraph/zoekt" + v1 "github.com/sourcegraph/zoekt/grpc/v1" + "github.com/sourcegraph/zoekt/internal/mockSearcher" + "github.com/sourcegraph/zoekt/query" +) + +func TestClientServer(t *testing.T) { + mock := &mockSearcher.MockSearcher{ + WantSearch: query.NewAnd(mustParse("hello world|universe"), query.NewSingleBranchesRepos("HEAD", 1, 2)), + SearchResult: &zoekt.SearchResult{ + Files: []zoekt.FileMatch{ + {FileName: "bin.go"}, + }, + }, + + WantList: &query.Const{Value: true}, + RepoList: &zoekt.RepoList{ + Repos: []*zoekt.RepoListEntry{ + { + Repository: zoekt.Repository{ + ID: 2, + Name: "foo/bar", + }, + }, + }, + }, + } + + gs := grpc.NewServer() + v1.RegisterWebserverServiceServer(gs, NewServer(adapter{mock})) + ts := httptest.NewServer(h2c.NewHandler(gs, &http2.Server{})) + + u, err := url.Parse(ts.URL) + if err != nil { + t.Fatal(err) + } + cc, err := grpc.Dial(u.Host, grpc.WithTransportCredentials(insecure.NewCredentials())) + if err != nil { + t.Fatal(err) + } + client := v1.NewWebserverServiceClient(cc) + + r, err := client.Search(context.Background(), &v1.SearchRequest{Query: query.QToProto(mock.WantSearch)}) + if err != nil { + t.Fatal(err) + } + if !proto.Equal(r, mock.SearchResult.ToProto()) { + t.Fatalf("got %+v, want %+v", r, mock.SearchResult.ToProto()) + } + + l, err := client.List(context.Background(), &v1.ListRequest{Query: query.QToProto(mock.WantList)}) + if err != nil { + t.Fatal(err) + } + + if !proto.Equal(l, mock.RepoList.ToProto()) { + t.Fatalf("got %+v, want %+v", l, mock.RepoList.ToProto()) + } +} + +func mustParse(s string) query.Q { + q, err := query.Parse(s) + if err != nil { + panic(err) + } + return q +} + +type adapter struct { + zoekt.Searcher +} + +func (a adapter) StreamSearch(ctx context.Context, q query.Q, opts *zoekt.SearchOptions, sender zoekt.Sender) (err error) { + sr, err := a.Searcher.Search(ctx, q, opts) + if err != nil { + return err + } + sender.Send(sr) + return nil +} diff --git a/grpc/v1/BUILD.bazel b/grpc/v1/BUILD.bazel new file mode 100644 index 000000000..e03464c71 --- /dev/null +++ b/grpc/v1/BUILD.bazel @@ -0,0 +1,29 @@ +load("@rules_proto//proto:defs.bzl", "proto_library") +load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") + +proto_library( + name = "v1_proto", + srcs = ["webserver.proto"], + visibility = ["//visibility:public"], + deps = [ + "@com_google_protobuf//:duration_proto", + "@com_google_protobuf//:empty_proto", + "@com_google_protobuf//:timestamp_proto", + ], +) + +go_proto_library( + name = "v1_go_proto", + compilers = ["@io_bazel_rules_go//proto:go_grpc"], + importpath = "github.com/sourcegraph/zoekt/grpc/v1", + proto = ":v1_proto", + visibility = ["//visibility:public"], +) + +go_library( + name = "grpc", + embed = [":v1_go_proto"], + importpath = "github.com/sourcegraph/zoekt/grpc/v1", + visibility = ["//visibility:public"], +) diff --git a/grpc/v1/buf.gen.yaml b/grpc/v1/buf.gen.yaml new file mode 100644 index 000000000..f914e5d33 --- /dev/null +++ b/grpc/v1/buf.gen.yaml @@ -0,0 +1,11 @@ +# Configuration file for https://buf.build/, which we use for Protobuf code generation. +version: v1 +plugins: + - plugin: buf.build/protocolbuffers/go:v1.29.1 + out: . + opt: + - paths=source_relative + - plugin: buf.build/grpc/go:v1.3.0 + out: . + opt: + - paths=source_relative diff --git a/grpc/v1/query.pb.go b/grpc/v1/query.pb.go new file mode 100644 index 000000000..84e38c207 --- /dev/null +++ b/grpc/v1/query.pb.go @@ -0,0 +1,1793 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.29.1 +// protoc (unknown) +// source: query.proto + +package v1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + _ "google.golang.org/protobuf/types/known/durationpb" + _ "google.golang.org/protobuf/types/known/emptypb" + _ "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type RawConfig_Flag int32 + +const ( + RawConfig_UNKNOWN RawConfig_Flag = 0 + RawConfig_ONLY_PUBLIC RawConfig_Flag = 1 + RawConfig_ONLY_PRIVATE RawConfig_Flag = 2 + RawConfig_ONLY_FORKS RawConfig_Flag = 4 + RawConfig_NO_FORKS RawConfig_Flag = 8 + RawConfig_ONLY_ARCHIVED RawConfig_Flag = 16 + RawConfig_NO_ARCHIVED RawConfig_Flag = 32 +) + +// Enum value maps for RawConfig_Flag. +var ( + RawConfig_Flag_name = map[int32]string{ + 0: "UNKNOWN", + 1: "ONLY_PUBLIC", + 2: "ONLY_PRIVATE", + 4: "ONLY_FORKS", + 8: "NO_FORKS", + 16: "ONLY_ARCHIVED", + 32: "NO_ARCHIVED", + } + RawConfig_Flag_value = map[string]int32{ + "UNKNOWN": 0, + "ONLY_PUBLIC": 1, + "ONLY_PRIVATE": 2, + "ONLY_FORKS": 4, + "NO_FORKS": 8, + "ONLY_ARCHIVED": 16, + "NO_ARCHIVED": 32, + } +) + +func (x RawConfig_Flag) Enum() *RawConfig_Flag { + p := new(RawConfig_Flag) + *p = x + return p +} + +func (x RawConfig_Flag) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (RawConfig_Flag) Descriptor() protoreflect.EnumDescriptor { + return file_query_proto_enumTypes[0].Descriptor() +} + +func (RawConfig_Flag) Type() protoreflect.EnumType { + return &file_query_proto_enumTypes[0] +} + +func (x RawConfig_Flag) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use RawConfig_Flag.Descriptor instead. +func (RawConfig_Flag) EnumDescriptor() ([]byte, []int) { + return file_query_proto_rawDescGZIP(), []int{1, 0} +} + +type Type_Kind int32 + +const ( + Type_UNKNOWN Type_Kind = 0 + Type_FILE_MATCH Type_Kind = 1 + Type_FILE_NAME Type_Kind = 2 + Type_REPO Type_Kind = 3 +) + +// Enum value maps for Type_Kind. +var ( + Type_Kind_name = map[int32]string{ + 0: "UNKNOWN", + 1: "FILE_MATCH", + 2: "FILE_NAME", + 3: "REPO", + } + Type_Kind_value = map[string]int32{ + "UNKNOWN": 0, + "FILE_MATCH": 1, + "FILE_NAME": 2, + "REPO": 3, + } +) + +func (x Type_Kind) Enum() *Type_Kind { + p := new(Type_Kind) + *p = x + return p +} + +func (x Type_Kind) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Type_Kind) Descriptor() protoreflect.EnumDescriptor { + return file_query_proto_enumTypes[1].Descriptor() +} + +func (Type_Kind) Type() protoreflect.EnumType { + return &file_query_proto_enumTypes[1] +} + +func (x Type_Kind) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Type_Kind.Descriptor instead. +func (Type_Kind) EnumDescriptor() ([]byte, []int) { + return file_query_proto_rawDescGZIP(), []int{12, 0} +} + +type Q struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Query: + // + // *Q_RawConfig + // *Q_Regexp + // *Q_Symbol + // *Q_Language + // *Q_Const + // *Q_Repo + // *Q_RepoRegexp + // *Q_BranchesRepos + // *Q_RepoIds + // *Q_RepoSet + // *Q_FileNameSet + // *Q_Type + // *Q_Substring + // *Q_And + // *Q_Or + // *Q_Not + // *Q_Branch + Query isQ_Query `protobuf_oneof:"query"` +} + +func (x *Q) Reset() { + *x = Q{} + if protoimpl.UnsafeEnabled { + mi := &file_query_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Q) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Q) ProtoMessage() {} + +func (x *Q) ProtoReflect() protoreflect.Message { + mi := &file_query_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 Q.ProtoReflect.Descriptor instead. +func (*Q) Descriptor() ([]byte, []int) { + return file_query_proto_rawDescGZIP(), []int{0} +} + +func (m *Q) GetQuery() isQ_Query { + if m != nil { + return m.Query + } + return nil +} + +func (x *Q) GetRawConfig() *RawConfig { + if x, ok := x.GetQuery().(*Q_RawConfig); ok { + return x.RawConfig + } + return nil +} + +func (x *Q) GetRegexp() *Regexp { + if x, ok := x.GetQuery().(*Q_Regexp); ok { + return x.Regexp + } + return nil +} + +func (x *Q) GetSymbol() *Symbol { + if x, ok := x.GetQuery().(*Q_Symbol); ok { + return x.Symbol + } + return nil +} + +func (x *Q) GetLanguage() *Language { + if x, ok := x.GetQuery().(*Q_Language); ok { + return x.Language + } + return nil +} + +func (x *Q) GetConst() bool { + if x, ok := x.GetQuery().(*Q_Const); ok { + return x.Const + } + return false +} + +func (x *Q) GetRepo() *Repo { + if x, ok := x.GetQuery().(*Q_Repo); ok { + return x.Repo + } + return nil +} + +func (x *Q) GetRepoRegexp() *RepoRegexp { + if x, ok := x.GetQuery().(*Q_RepoRegexp); ok { + return x.RepoRegexp + } + return nil +} + +func (x *Q) GetBranchesRepos() *BranchesRepos { + if x, ok := x.GetQuery().(*Q_BranchesRepos); ok { + return x.BranchesRepos + } + return nil +} + +func (x *Q) GetRepoIds() *RepoIds { + if x, ok := x.GetQuery().(*Q_RepoIds); ok { + return x.RepoIds + } + return nil +} + +func (x *Q) GetRepoSet() *RepoSet { + if x, ok := x.GetQuery().(*Q_RepoSet); ok { + return x.RepoSet + } + return nil +} + +func (x *Q) GetFileNameSet() *FileNameSet { + if x, ok := x.GetQuery().(*Q_FileNameSet); ok { + return x.FileNameSet + } + return nil +} + +func (x *Q) GetType() *Type { + if x, ok := x.GetQuery().(*Q_Type); ok { + return x.Type + } + return nil +} + +func (x *Q) GetSubstring() *Substring { + if x, ok := x.GetQuery().(*Q_Substring); ok { + return x.Substring + } + return nil +} + +func (x *Q) GetAnd() *And { + if x, ok := x.GetQuery().(*Q_And); ok { + return x.And + } + return nil +} + +func (x *Q) GetOr() *Or { + if x, ok := x.GetQuery().(*Q_Or); ok { + return x.Or + } + return nil +} + +func (x *Q) GetNot() *Not { + if x, ok := x.GetQuery().(*Q_Not); ok { + return x.Not + } + return nil +} + +func (x *Q) GetBranch() *Branch { + if x, ok := x.GetQuery().(*Q_Branch); ok { + return x.Branch + } + return nil +} + +type isQ_Query interface { + isQ_Query() +} + +type Q_RawConfig struct { + RawConfig *RawConfig `protobuf:"bytes,1,opt,name=raw_config,json=rawConfig,proto3,oneof"` +} + +type Q_Regexp struct { + Regexp *Regexp `protobuf:"bytes,2,opt,name=regexp,proto3,oneof"` +} + +type Q_Symbol struct { + Symbol *Symbol `protobuf:"bytes,3,opt,name=symbol,proto3,oneof"` +} + +type Q_Language struct { + Language *Language `protobuf:"bytes,4,opt,name=language,proto3,oneof"` +} + +type Q_Const struct { + Const bool `protobuf:"varint,5,opt,name=const,proto3,oneof"` +} + +type Q_Repo struct { + Repo *Repo `protobuf:"bytes,6,opt,name=repo,proto3,oneof"` +} + +type Q_RepoRegexp struct { + RepoRegexp *RepoRegexp `protobuf:"bytes,7,opt,name=repo_regexp,json=repoRegexp,proto3,oneof"` +} + +type Q_BranchesRepos struct { + BranchesRepos *BranchesRepos `protobuf:"bytes,8,opt,name=branches_repos,json=branchesRepos,proto3,oneof"` +} + +type Q_RepoIds struct { + RepoIds *RepoIds `protobuf:"bytes,9,opt,name=repo_ids,json=repoIds,proto3,oneof"` +} + +type Q_RepoSet struct { + RepoSet *RepoSet `protobuf:"bytes,10,opt,name=repo_set,json=repoSet,proto3,oneof"` +} + +type Q_FileNameSet struct { + FileNameSet *FileNameSet `protobuf:"bytes,11,opt,name=file_name_set,json=fileNameSet,proto3,oneof"` +} + +type Q_Type struct { + Type *Type `protobuf:"bytes,12,opt,name=type,proto3,oneof"` +} + +type Q_Substring struct { + Substring *Substring `protobuf:"bytes,13,opt,name=substring,proto3,oneof"` +} + +type Q_And struct { + And *And `protobuf:"bytes,14,opt,name=and,proto3,oneof"` +} + +type Q_Or struct { + Or *Or `protobuf:"bytes,15,opt,name=or,proto3,oneof"` +} + +type Q_Not struct { + Not *Not `protobuf:"bytes,16,opt,name=not,proto3,oneof"` +} + +type Q_Branch struct { + Branch *Branch `protobuf:"bytes,17,opt,name=branch,proto3,oneof"` +} + +func (*Q_RawConfig) isQ_Query() {} + +func (*Q_Regexp) isQ_Query() {} + +func (*Q_Symbol) isQ_Query() {} + +func (*Q_Language) isQ_Query() {} + +func (*Q_Const) isQ_Query() {} + +func (*Q_Repo) isQ_Query() {} + +func (*Q_RepoRegexp) isQ_Query() {} + +func (*Q_BranchesRepos) isQ_Query() {} + +func (*Q_RepoIds) isQ_Query() {} + +func (*Q_RepoSet) isQ_Query() {} + +func (*Q_FileNameSet) isQ_Query() {} + +func (*Q_Type) isQ_Query() {} + +func (*Q_Substring) isQ_Query() {} + +func (*Q_And) isQ_Query() {} + +func (*Q_Or) isQ_Query() {} + +func (*Q_Not) isQ_Query() {} + +func (*Q_Branch) isQ_Query() {} + +// RawConfig filters repositories based on their encoded RawConfig map. +type RawConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Flags []RawConfig_Flag `protobuf:"varint,1,rep,packed,name=flags,proto3,enum=grpc.v1.RawConfig_Flag" json:"flags,omitempty"` +} + +func (x *RawConfig) Reset() { + *x = RawConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_query_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RawConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RawConfig) ProtoMessage() {} + +func (x *RawConfig) ProtoReflect() protoreflect.Message { + mi := &file_query_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 RawConfig.ProtoReflect.Descriptor instead. +func (*RawConfig) Descriptor() ([]byte, []int) { + return file_query_proto_rawDescGZIP(), []int{1} +} + +func (x *RawConfig) GetFlags() []RawConfig_Flag { + if x != nil { + return x.Flags + } + return nil +} + +// Regexp is a query looking for regular expressions matches. +type Regexp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Regexp string `protobuf:"bytes,1,opt,name=regexp,proto3" json:"regexp,omitempty"` + FileName bool `protobuf:"varint,2,opt,name=file_name,json=fileName,proto3" json:"file_name,omitempty"` + Content bool `protobuf:"varint,3,opt,name=content,proto3" json:"content,omitempty"` + CaseSensitive bool `protobuf:"varint,4,opt,name=case_sensitive,json=caseSensitive,proto3" json:"case_sensitive,omitempty"` +} + +func (x *Regexp) Reset() { + *x = Regexp{} + if protoimpl.UnsafeEnabled { + mi := &file_query_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Regexp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Regexp) ProtoMessage() {} + +func (x *Regexp) ProtoReflect() protoreflect.Message { + mi := &file_query_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 Regexp.ProtoReflect.Descriptor instead. +func (*Regexp) Descriptor() ([]byte, []int) { + return file_query_proto_rawDescGZIP(), []int{2} +} + +func (x *Regexp) GetRegexp() string { + if x != nil { + return x.Regexp + } + return "" +} + +func (x *Regexp) GetFileName() bool { + if x != nil { + return x.FileName + } + return false +} + +func (x *Regexp) GetContent() bool { + if x != nil { + return x.Content + } + return false +} + +func (x *Regexp) GetCaseSensitive() bool { + if x != nil { + return x.CaseSensitive + } + return false +} + +type Symbol struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Expr *Q `protobuf:"bytes,1,opt,name=expr,proto3" json:"expr,omitempty"` +} + +func (x *Symbol) Reset() { + *x = Symbol{} + if protoimpl.UnsafeEnabled { + mi := &file_query_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Symbol) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Symbol) ProtoMessage() {} + +func (x *Symbol) ProtoReflect() protoreflect.Message { + mi := &file_query_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 Symbol.ProtoReflect.Descriptor instead. +func (*Symbol) Descriptor() ([]byte, []int) { + return file_query_proto_rawDescGZIP(), []int{3} +} + +func (x *Symbol) GetExpr() *Q { + if x != nil { + return x.Expr + } + return nil +} + +type Language struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Language string `protobuf:"bytes,1,opt,name=language,proto3" json:"language,omitempty"` +} + +func (x *Language) Reset() { + *x = Language{} + if protoimpl.UnsafeEnabled { + mi := &file_query_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Language) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Language) ProtoMessage() {} + +func (x *Language) ProtoReflect() protoreflect.Message { + mi := &file_query_proto_msgTypes[4] + 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 Language.ProtoReflect.Descriptor instead. +func (*Language) Descriptor() ([]byte, []int) { + return file_query_proto_rawDescGZIP(), []int{4} +} + +func (x *Language) GetLanguage() string { + if x != nil { + return x.Language + } + return "" +} + +type Repo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Regexp string `protobuf:"bytes,1,opt,name=regexp,proto3" json:"regexp,omitempty"` +} + +func (x *Repo) Reset() { + *x = Repo{} + if protoimpl.UnsafeEnabled { + mi := &file_query_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Repo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Repo) ProtoMessage() {} + +func (x *Repo) ProtoReflect() protoreflect.Message { + mi := &file_query_proto_msgTypes[5] + 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 Repo.ProtoReflect.Descriptor instead. +func (*Repo) Descriptor() ([]byte, []int) { + return file_query_proto_rawDescGZIP(), []int{5} +} + +func (x *Repo) GetRegexp() string { + if x != nil { + return x.Regexp + } + return "" +} + +type RepoRegexp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Regexp string `protobuf:"bytes,1,opt,name=regexp,proto3" json:"regexp,omitempty"` +} + +func (x *RepoRegexp) Reset() { + *x = RepoRegexp{} + if protoimpl.UnsafeEnabled { + mi := &file_query_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RepoRegexp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RepoRegexp) ProtoMessage() {} + +func (x *RepoRegexp) ProtoReflect() protoreflect.Message { + mi := &file_query_proto_msgTypes[6] + 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 RepoRegexp.ProtoReflect.Descriptor instead. +func (*RepoRegexp) Descriptor() ([]byte, []int) { + return file_query_proto_rawDescGZIP(), []int{6} +} + +func (x *RepoRegexp) GetRegexp() string { + if x != nil { + return x.Regexp + } + return "" +} + +// BranchesRepos is a slice of BranchRepos to match. +type BranchesRepos struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + List []*BranchRepos `protobuf:"bytes,1,rep,name=list,proto3" json:"list,omitempty"` +} + +func (x *BranchesRepos) Reset() { + *x = BranchesRepos{} + if protoimpl.UnsafeEnabled { + mi := &file_query_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BranchesRepos) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BranchesRepos) ProtoMessage() {} + +func (x *BranchesRepos) ProtoReflect() protoreflect.Message { + mi := &file_query_proto_msgTypes[7] + 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 BranchesRepos.ProtoReflect.Descriptor instead. +func (*BranchesRepos) Descriptor() ([]byte, []int) { + return file_query_proto_rawDescGZIP(), []int{7} +} + +func (x *BranchesRepos) GetList() []*BranchRepos { + if x != nil { + return x.List + } + return nil +} + +// BranchRepos is a (branch, sourcegraph repo ids bitmap) tuple. It is a +// Sourcegraph addition. +type BranchRepos struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Branch string `protobuf:"bytes,1,opt,name=branch,proto3" json:"branch,omitempty"` + // a serialized roaring bitmap of the target repo ids + Repos []byte `protobuf:"bytes,2,opt,name=repos,proto3" json:"repos,omitempty"` +} + +func (x *BranchRepos) Reset() { + *x = BranchRepos{} + if protoimpl.UnsafeEnabled { + mi := &file_query_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BranchRepos) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BranchRepos) ProtoMessage() {} + +func (x *BranchRepos) ProtoReflect() protoreflect.Message { + mi := &file_query_proto_msgTypes[8] + 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 BranchRepos.ProtoReflect.Descriptor instead. +func (*BranchRepos) Descriptor() ([]byte, []int) { + return file_query_proto_rawDescGZIP(), []int{8} +} + +func (x *BranchRepos) GetBranch() string { + if x != nil { + return x.Branch + } + return "" +} + +func (x *BranchRepos) GetRepos() []byte { + if x != nil { + return x.Repos + } + return nil +} + +// Similar to BranchRepos but will be used to match only by repoid and +// therefore matches all branches +type RepoIds struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // a serialized roaring bitmap of the target repo ids + Repos []byte `protobuf:"bytes,1,opt,name=repos,proto3" json:"repos,omitempty"` +} + +func (x *RepoIds) Reset() { + *x = RepoIds{} + if protoimpl.UnsafeEnabled { + mi := &file_query_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RepoIds) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RepoIds) ProtoMessage() {} + +func (x *RepoIds) ProtoReflect() protoreflect.Message { + mi := &file_query_proto_msgTypes[9] + 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 RepoIds.ProtoReflect.Descriptor instead. +func (*RepoIds) Descriptor() ([]byte, []int) { + return file_query_proto_rawDescGZIP(), []int{9} +} + +func (x *RepoIds) GetRepos() []byte { + if x != nil { + return x.Repos + } + return nil +} + +// RepoSet is a list of repos to match. +type RepoSet struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Set map[string]bool `protobuf:"bytes,1,rep,name=set,proto3" json:"set,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` +} + +func (x *RepoSet) Reset() { + *x = RepoSet{} + if protoimpl.UnsafeEnabled { + mi := &file_query_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RepoSet) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RepoSet) ProtoMessage() {} + +func (x *RepoSet) ProtoReflect() protoreflect.Message { + mi := &file_query_proto_msgTypes[10] + 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 RepoSet.ProtoReflect.Descriptor instead. +func (*RepoSet) Descriptor() ([]byte, []int) { + return file_query_proto_rawDescGZIP(), []int{10} +} + +func (x *RepoSet) GetSet() map[string]bool { + if x != nil { + return x.Set + } + return nil +} + +// FileNameSet is a list of file names to match. +type FileNameSet struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Set []string `protobuf:"bytes,1,rep,name=set,proto3" json:"set,omitempty"` +} + +func (x *FileNameSet) Reset() { + *x = FileNameSet{} + if protoimpl.UnsafeEnabled { + mi := &file_query_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FileNameSet) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FileNameSet) ProtoMessage() {} + +func (x *FileNameSet) ProtoReflect() protoreflect.Message { + mi := &file_query_proto_msgTypes[11] + 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 FileNameSet.ProtoReflect.Descriptor instead. +func (*FileNameSet) Descriptor() ([]byte, []int) { + return file_query_proto_rawDescGZIP(), []int{11} +} + +func (x *FileNameSet) GetSet() []string { + if x != nil { + return x.Set + } + return nil +} + +// Type changes the result type returned. +type Type struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Child *Q `protobuf:"bytes,1,opt,name=child,proto3" json:"child,omitempty"` + // TODO: type constants + Type Type_Kind `protobuf:"varint,2,opt,name=type,proto3,enum=grpc.v1.Type_Kind" json:"type,omitempty"` +} + +func (x *Type) Reset() { + *x = Type{} + if protoimpl.UnsafeEnabled { + mi := &file_query_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Type) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Type) ProtoMessage() {} + +func (x *Type) ProtoReflect() protoreflect.Message { + mi := &file_query_proto_msgTypes[12] + 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 Type.ProtoReflect.Descriptor instead. +func (*Type) Descriptor() ([]byte, []int) { + return file_query_proto_rawDescGZIP(), []int{12} +} + +func (x *Type) GetChild() *Q { + if x != nil { + return x.Child + } + return nil +} + +func (x *Type) GetType() Type_Kind { + if x != nil { + return x.Type + } + return Type_UNKNOWN +} + +type Substring struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Pattern string `protobuf:"bytes,1,opt,name=pattern,proto3" json:"pattern,omitempty"` + CaseSensitive bool `protobuf:"varint,2,opt,name=case_sensitive,json=caseSensitive,proto3" json:"case_sensitive,omitempty"` + // Match only filename + FileName bool `protobuf:"varint,3,opt,name=file_name,json=fileName,proto3" json:"file_name,omitempty"` + // Match only content + Content bool `protobuf:"varint,4,opt,name=content,proto3" json:"content,omitempty"` +} + +func (x *Substring) Reset() { + *x = Substring{} + if protoimpl.UnsafeEnabled { + mi := &file_query_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Substring) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Substring) ProtoMessage() {} + +func (x *Substring) ProtoReflect() protoreflect.Message { + mi := &file_query_proto_msgTypes[13] + 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 Substring.ProtoReflect.Descriptor instead. +func (*Substring) Descriptor() ([]byte, []int) { + return file_query_proto_rawDescGZIP(), []int{13} +} + +func (x *Substring) GetPattern() string { + if x != nil { + return x.Pattern + } + return "" +} + +func (x *Substring) GetCaseSensitive() bool { + if x != nil { + return x.CaseSensitive + } + return false +} + +func (x *Substring) GetFileName() bool { + if x != nil { + return x.FileName + } + return false +} + +func (x *Substring) GetContent() bool { + if x != nil { + return x.Content + } + return false +} + +// And is matched when all its children are. +type And struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Children []*Q `protobuf:"bytes,1,rep,name=children,proto3" json:"children,omitempty"` +} + +func (x *And) Reset() { + *x = And{} + if protoimpl.UnsafeEnabled { + mi := &file_query_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *And) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*And) ProtoMessage() {} + +func (x *And) ProtoReflect() protoreflect.Message { + mi := &file_query_proto_msgTypes[14] + 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 And.ProtoReflect.Descriptor instead. +func (*And) Descriptor() ([]byte, []int) { + return file_query_proto_rawDescGZIP(), []int{14} +} + +func (x *And) GetChildren() []*Q { + if x != nil { + return x.Children + } + return nil +} + +// Or is matched when any of its children is matched. +type Or struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Children []*Q `protobuf:"bytes,1,rep,name=children,proto3" json:"children,omitempty"` +} + +func (x *Or) Reset() { + *x = Or{} + if protoimpl.UnsafeEnabled { + mi := &file_query_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Or) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Or) ProtoMessage() {} + +func (x *Or) ProtoReflect() protoreflect.Message { + mi := &file_query_proto_msgTypes[15] + 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 Or.ProtoReflect.Descriptor instead. +func (*Or) Descriptor() ([]byte, []int) { + return file_query_proto_rawDescGZIP(), []int{15} +} + +func (x *Or) GetChildren() []*Q { + if x != nil { + return x.Children + } + return nil +} + +// Not inverts the meaning of its child. +type Not struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Child *Q `protobuf:"bytes,1,opt,name=child,proto3" json:"child,omitempty"` +} + +func (x *Not) Reset() { + *x = Not{} + if protoimpl.UnsafeEnabled { + mi := &file_query_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Not) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Not) ProtoMessage() {} + +func (x *Not) ProtoReflect() protoreflect.Message { + mi := &file_query_proto_msgTypes[16] + 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 Not.ProtoReflect.Descriptor instead. +func (*Not) Descriptor() ([]byte, []int) { + return file_query_proto_rawDescGZIP(), []int{16} +} + +func (x *Not) GetChild() *Q { + if x != nil { + return x.Child + } + return nil +} + +// Branch limits search to a specific branch. +type Branch struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Pattern string `protobuf:"bytes,1,opt,name=pattern,proto3" json:"pattern,omitempty"` + // exact is true if we want to Pattern to equal branch. + Exact bool `protobuf:"varint,2,opt,name=exact,proto3" json:"exact,omitempty"` +} + +func (x *Branch) Reset() { + *x = Branch{} + if protoimpl.UnsafeEnabled { + mi := &file_query_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Branch) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Branch) ProtoMessage() {} + +func (x *Branch) ProtoReflect() protoreflect.Message { + mi := &file_query_proto_msgTypes[17] + 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 Branch.ProtoReflect.Descriptor instead. +func (*Branch) Descriptor() ([]byte, []int) { + return file_query_proto_rawDescGZIP(), []int{17} +} + +func (x *Branch) GetPattern() string { + if x != nil { + return x.Pattern + } + return "" +} + +func (x *Branch) GetExact() bool { + if x != nil { + return x.Exact + } + return false +} + +var File_query_proto protoreflect.FileDescriptor + +var file_query_proto_rawDesc = []byte{ + 0x0a, 0x0b, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x67, + 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 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, 0xff, 0x05, 0x0a, 0x01, 0x51, 0x12, 0x33, 0x0a, 0x0a, 0x72, 0x61, + 0x77, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, + 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x61, 0x77, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x48, 0x00, 0x52, 0x09, 0x72, 0x61, 0x77, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, + 0x29, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x65, 0x78, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0f, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x65, 0x78, 0x70, + 0x48, 0x00, 0x52, 0x06, 0x72, 0x65, 0x67, 0x65, 0x78, 0x70, 0x12, 0x29, 0x0a, 0x06, 0x73, 0x79, + 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x67, 0x72, 0x70, + 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x48, 0x00, 0x52, 0x06, 0x73, + 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x12, 0x2f, 0x0a, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, + 0x31, 0x2e, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x08, 0x6c, 0x61, + 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x12, 0x16, 0x0a, 0x05, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x05, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x12, 0x23, + 0x0a, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x67, + 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x48, 0x00, 0x52, 0x04, 0x72, + 0x65, 0x70, 0x6f, 0x12, 0x36, 0x0a, 0x0b, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x72, 0x65, 0x67, 0x65, + 0x78, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, + 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x52, 0x65, 0x67, 0x65, 0x78, 0x70, 0x48, 0x00, 0x52, + 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x52, 0x65, 0x67, 0x65, 0x78, 0x70, 0x12, 0x3f, 0x0a, 0x0e, 0x62, + 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x72, + 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x48, 0x00, 0x52, 0x0d, 0x62, + 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x12, 0x2d, 0x0a, 0x08, + 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, + 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x49, 0x64, 0x73, + 0x48, 0x00, 0x52, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x49, 0x64, 0x73, 0x12, 0x2d, 0x0a, 0x08, 0x72, + 0x65, 0x70, 0x6f, 0x5f, 0x73, 0x65, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, + 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x53, 0x65, 0x74, 0x48, + 0x00, 0x52, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x53, 0x65, 0x74, 0x12, 0x3a, 0x0a, 0x0d, 0x66, 0x69, + 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x73, 0x65, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x6c, 0x65, + 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x74, 0x48, 0x00, 0x52, 0x0b, 0x66, 0x69, 0x6c, 0x65, 0x4e, + 0x61, 0x6d, 0x65, 0x53, 0x65, 0x74, 0x12, 0x23, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0c, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x54, + 0x79, 0x70, 0x65, 0x48, 0x00, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x32, 0x0a, 0x09, 0x73, + 0x75, 0x62, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, + 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x48, 0x00, 0x52, 0x09, 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, + 0x20, 0x0a, 0x03, 0x61, 0x6e, 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x67, + 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x64, 0x48, 0x00, 0x52, 0x03, 0x61, 0x6e, + 0x64, 0x12, 0x1d, 0x0a, 0x02, 0x6f, 0x72, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, + 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x72, 0x48, 0x00, 0x52, 0x02, 0x6f, 0x72, + 0x12, 0x20, 0x0a, 0x03, 0x6e, 0x6f, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, + 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x74, 0x48, 0x00, 0x52, 0x03, 0x6e, + 0x6f, 0x74, 0x12, 0x29, 0x0a, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, 0x11, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x72, 0x61, + 0x6e, 0x63, 0x68, 0x48, 0x00, 0x52, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x42, 0x07, 0x0a, + 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0xb4, 0x01, 0x0a, 0x09, 0x52, 0x61, 0x77, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2d, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x61, + 0x77, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x05, 0x66, 0x6c, + 0x61, 0x67, 0x73, 0x22, 0x78, 0x0a, 0x04, 0x46, 0x6c, 0x61, 0x67, 0x12, 0x0b, 0x0a, 0x07, 0x55, + 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x4f, 0x4e, 0x4c, 0x59, + 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x4f, 0x4e, 0x4c, + 0x59, 0x5f, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x4f, + 0x4e, 0x4c, 0x59, 0x5f, 0x46, 0x4f, 0x52, 0x4b, 0x53, 0x10, 0x04, 0x12, 0x0c, 0x0a, 0x08, 0x4e, + 0x4f, 0x5f, 0x46, 0x4f, 0x52, 0x4b, 0x53, 0x10, 0x08, 0x12, 0x11, 0x0a, 0x0d, 0x4f, 0x4e, 0x4c, + 0x59, 0x5f, 0x41, 0x52, 0x43, 0x48, 0x49, 0x56, 0x45, 0x44, 0x10, 0x10, 0x12, 0x0f, 0x0a, 0x0b, + 0x4e, 0x4f, 0x5f, 0x41, 0x52, 0x43, 0x48, 0x49, 0x56, 0x45, 0x44, 0x10, 0x20, 0x22, 0x7e, 0x0a, + 0x06, 0x52, 0x65, 0x67, 0x65, 0x78, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x65, 0x78, + 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, 0x65, 0x78, 0x70, 0x12, + 0x1b, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x61, 0x73, 0x65, 0x5f, 0x73, + 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, + 0x63, 0x61, 0x73, 0x65, 0x53, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x22, 0x28, 0x0a, + 0x06, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x12, 0x1e, 0x0a, 0x04, 0x65, 0x78, 0x70, 0x72, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, + 0x51, 0x52, 0x04, 0x65, 0x78, 0x70, 0x72, 0x22, 0x26, 0x0a, 0x08, 0x4c, 0x61, 0x6e, 0x67, 0x75, + 0x61, 0x67, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x22, + 0x1e, 0x0a, 0x04, 0x52, 0x65, 0x70, 0x6f, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x65, 0x78, + 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, 0x65, 0x78, 0x70, 0x22, + 0x24, 0x0a, 0x0a, 0x52, 0x65, 0x70, 0x6f, 0x52, 0x65, 0x67, 0x65, 0x78, 0x70, 0x12, 0x16, 0x0a, + 0x06, 0x72, 0x65, 0x67, 0x65, 0x78, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, + 0x65, 0x67, 0x65, 0x78, 0x70, 0x22, 0x39, 0x0a, 0x0d, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, + 0x73, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x12, 0x28, 0x0a, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x42, + 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x52, 0x04, 0x6c, 0x69, 0x73, 0x74, + 0x22, 0x3b, 0x0a, 0x0b, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x12, + 0x16, 0x0a, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x65, 0x70, 0x6f, 0x73, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x22, 0x1f, 0x0a, + 0x07, 0x52, 0x65, 0x70, 0x6f, 0x49, 0x64, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x65, 0x70, 0x6f, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x22, 0x6e, + 0x0a, 0x07, 0x52, 0x65, 0x70, 0x6f, 0x53, 0x65, 0x74, 0x12, 0x2b, 0x0a, 0x03, 0x73, 0x65, 0x74, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, + 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x53, 0x65, 0x74, 0x2e, 0x53, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x03, 0x73, 0x65, 0x74, 0x1a, 0x36, 0x0a, 0x08, 0x53, 0x65, 0x74, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x1f, + 0x0a, 0x0b, 0x46, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x74, 0x12, 0x10, 0x0a, + 0x03, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x73, 0x65, 0x74, 0x22, + 0x8e, 0x01, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x05, 0x63, 0x68, 0x69, 0x6c, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, + 0x31, 0x2e, 0x51, 0x52, 0x05, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x12, 0x26, 0x0a, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, + 0x76, 0x31, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x2e, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x22, 0x3c, 0x0a, 0x04, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, + 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x46, 0x49, 0x4c, 0x45, 0x5f, + 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x46, 0x49, 0x4c, 0x45, 0x5f, + 0x4e, 0x41, 0x4d, 0x45, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x52, 0x45, 0x50, 0x4f, 0x10, 0x03, + 0x22, 0x83, 0x01, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x18, + 0x0a, 0x07, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x61, 0x73, 0x65, + 0x5f, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0d, 0x63, 0x61, 0x73, 0x65, 0x53, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x12, + 0x1b, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x2d, 0x0a, 0x03, 0x41, 0x6e, 0x64, 0x12, 0x26, 0x0a, + 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x0a, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x52, 0x08, 0x63, 0x68, 0x69, + 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x22, 0x2c, 0x0a, 0x02, 0x4f, 0x72, 0x12, 0x26, 0x0a, 0x08, 0x63, + 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, + 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x52, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, + 0x72, 0x65, 0x6e, 0x22, 0x27, 0x0a, 0x03, 0x4e, 0x6f, 0x74, 0x12, 0x20, 0x0a, 0x05, 0x63, 0x68, + 0x69, 0x6c, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x67, 0x72, 0x70, 0x63, + 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x52, 0x05, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x22, 0x38, 0x0a, 0x06, + 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, + 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, + 0x12, 0x14, 0x0a, 0x05, 0x65, 0x78, 0x61, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x05, 0x65, 0x78, 0x61, 0x63, 0x74, 0x42, 0x26, 0x5a, 0x24, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x67, 0x72, 0x61, 0x70, 0x68, + 0x2f, 0x7a, 0x6f, 0x65, 0x6b, 0x74, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x76, 0x31, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_query_proto_rawDescOnce sync.Once + file_query_proto_rawDescData = file_query_proto_rawDesc +) + +func file_query_proto_rawDescGZIP() []byte { + file_query_proto_rawDescOnce.Do(func() { + file_query_proto_rawDescData = protoimpl.X.CompressGZIP(file_query_proto_rawDescData) + }) + return file_query_proto_rawDescData +} + +var file_query_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_query_proto_msgTypes = make([]protoimpl.MessageInfo, 19) +var file_query_proto_goTypes = []interface{}{ + (RawConfig_Flag)(0), // 0: grpc.v1.RawConfig.Flag + (Type_Kind)(0), // 1: grpc.v1.Type.Kind + (*Q)(nil), // 2: grpc.v1.Q + (*RawConfig)(nil), // 3: grpc.v1.RawConfig + (*Regexp)(nil), // 4: grpc.v1.Regexp + (*Symbol)(nil), // 5: grpc.v1.Symbol + (*Language)(nil), // 6: grpc.v1.Language + (*Repo)(nil), // 7: grpc.v1.Repo + (*RepoRegexp)(nil), // 8: grpc.v1.RepoRegexp + (*BranchesRepos)(nil), // 9: grpc.v1.BranchesRepos + (*BranchRepos)(nil), // 10: grpc.v1.BranchRepos + (*RepoIds)(nil), // 11: grpc.v1.RepoIds + (*RepoSet)(nil), // 12: grpc.v1.RepoSet + (*FileNameSet)(nil), // 13: grpc.v1.FileNameSet + (*Type)(nil), // 14: grpc.v1.Type + (*Substring)(nil), // 15: grpc.v1.Substring + (*And)(nil), // 16: grpc.v1.And + (*Or)(nil), // 17: grpc.v1.Or + (*Not)(nil), // 18: grpc.v1.Not + (*Branch)(nil), // 19: grpc.v1.Branch + nil, // 20: grpc.v1.RepoSet.SetEntry +} +var file_query_proto_depIdxs = []int32{ + 3, // 0: grpc.v1.Q.raw_config:type_name -> grpc.v1.RawConfig + 4, // 1: grpc.v1.Q.regexp:type_name -> grpc.v1.Regexp + 5, // 2: grpc.v1.Q.symbol:type_name -> grpc.v1.Symbol + 6, // 3: grpc.v1.Q.language:type_name -> grpc.v1.Language + 7, // 4: grpc.v1.Q.repo:type_name -> grpc.v1.Repo + 8, // 5: grpc.v1.Q.repo_regexp:type_name -> grpc.v1.RepoRegexp + 9, // 6: grpc.v1.Q.branches_repos:type_name -> grpc.v1.BranchesRepos + 11, // 7: grpc.v1.Q.repo_ids:type_name -> grpc.v1.RepoIds + 12, // 8: grpc.v1.Q.repo_set:type_name -> grpc.v1.RepoSet + 13, // 9: grpc.v1.Q.file_name_set:type_name -> grpc.v1.FileNameSet + 14, // 10: grpc.v1.Q.type:type_name -> grpc.v1.Type + 15, // 11: grpc.v1.Q.substring:type_name -> grpc.v1.Substring + 16, // 12: grpc.v1.Q.and:type_name -> grpc.v1.And + 17, // 13: grpc.v1.Q.or:type_name -> grpc.v1.Or + 18, // 14: grpc.v1.Q.not:type_name -> grpc.v1.Not + 19, // 15: grpc.v1.Q.branch:type_name -> grpc.v1.Branch + 0, // 16: grpc.v1.RawConfig.flags:type_name -> grpc.v1.RawConfig.Flag + 2, // 17: grpc.v1.Symbol.expr:type_name -> grpc.v1.Q + 10, // 18: grpc.v1.BranchesRepos.list:type_name -> grpc.v1.BranchRepos + 20, // 19: grpc.v1.RepoSet.set:type_name -> grpc.v1.RepoSet.SetEntry + 2, // 20: grpc.v1.Type.child:type_name -> grpc.v1.Q + 1, // 21: grpc.v1.Type.type:type_name -> grpc.v1.Type.Kind + 2, // 22: grpc.v1.And.children:type_name -> grpc.v1.Q + 2, // 23: grpc.v1.Or.children:type_name -> grpc.v1.Q + 2, // 24: grpc.v1.Not.child:type_name -> grpc.v1.Q + 25, // [25:25] is the sub-list for method output_type + 25, // [25:25] is the sub-list for method input_type + 25, // [25:25] is the sub-list for extension type_name + 25, // [25:25] is the sub-list for extension extendee + 0, // [0:25] is the sub-list for field type_name +} + +func init() { file_query_proto_init() } +func file_query_proto_init() { + if File_query_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_query_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Q); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_query_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RawConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_query_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Regexp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_query_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Symbol); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_query_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Language); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_query_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Repo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_query_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RepoRegexp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_query_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BranchesRepos); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_query_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BranchRepos); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_query_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RepoIds); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_query_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RepoSet); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_query_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FileNameSet); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_query_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Type); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_query_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Substring); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_query_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*And); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_query_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Or); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_query_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Not); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_query_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Branch); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_query_proto_msgTypes[0].OneofWrappers = []interface{}{ + (*Q_RawConfig)(nil), + (*Q_Regexp)(nil), + (*Q_Symbol)(nil), + (*Q_Language)(nil), + (*Q_Const)(nil), + (*Q_Repo)(nil), + (*Q_RepoRegexp)(nil), + (*Q_BranchesRepos)(nil), + (*Q_RepoIds)(nil), + (*Q_RepoSet)(nil), + (*Q_FileNameSet)(nil), + (*Q_Type)(nil), + (*Q_Substring)(nil), + (*Q_And)(nil), + (*Q_Or)(nil), + (*Q_Not)(nil), + (*Q_Branch)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_query_proto_rawDesc, + NumEnums: 2, + NumMessages: 19, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_query_proto_goTypes, + DependencyIndexes: file_query_proto_depIdxs, + EnumInfos: file_query_proto_enumTypes, + MessageInfos: file_query_proto_msgTypes, + }.Build() + File_query_proto = out.File + file_query_proto_rawDesc = nil + file_query_proto_goTypes = nil + file_query_proto_depIdxs = nil +} diff --git a/grpc/v1/query.proto b/grpc/v1/query.proto new file mode 100644 index 000000000..0ca08c5de --- /dev/null +++ b/grpc/v1/query.proto @@ -0,0 +1,147 @@ +syntax = "proto3"; + +package grpc.v1; + +import "google/protobuf/duration.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/timestamp.proto"; + +option go_package = "github.com/sourcegraph/zoekt/grpc/v1"; + +message Q { + oneof query { + RawConfig raw_config = 1; + Regexp regexp = 2; + Symbol symbol = 3; + Language language = 4; + bool const = 5; + Repo repo = 6; + RepoRegexp repo_regexp = 7; + BranchesRepos branches_repos = 8; + RepoIds repo_ids = 9; + RepoSet repo_set = 10; + FileNameSet file_name_set = 11; + Type type = 12; + Substring substring = 13; + And and = 14; + Or or = 15; + Not not = 16; + Branch branch = 17; + } +} + +// RawConfig filters repositories based on their encoded RawConfig map. +message RawConfig { + enum Flag { + UNKNOWN = 0x00; + ONLY_PUBLIC = 0x01; + ONLY_PRIVATE = 0x02; + ONLY_FORKS = 0x04; + NO_FORKS = 0x08; + ONLY_ARCHIVED = 0x10; + NO_ARCHIVED = 0x20; + } + + repeated Flag flags = 1; +} + +// Regexp is a query looking for regular expressions matches. +message Regexp { + string regexp = 1; + bool file_name = 2; + bool content = 3; + bool case_sensitive = 4; +} + +message Symbol { + Q expr = 1; +} + +message Language { + string language = 1; +} + +message Repo { + string regexp = 1; +} + +message RepoRegexp { + string regexp = 1; +} + +// BranchesRepos is a slice of BranchRepos to match. +message BranchesRepos { + repeated BranchRepos list = 1; +} + +// BranchRepos is a (branch, sourcegraph repo ids bitmap) tuple. It is a +// Sourcegraph addition. +message BranchRepos { + string branch = 1; + // a serialized roaring bitmap of the target repo ids + bytes repos = 2; +} + +// Similar to BranchRepos but will be used to match only by repoid and +// therefore matches all branches +message RepoIds { + // a serialized roaring bitmap of the target repo ids + bytes repos = 1; +} + +// RepoSet is a list of repos to match. +message RepoSet { + map set = 1; +} + +// FileNameSet is a list of file names to match. +message FileNameSet { + repeated string set = 1; +} + +// Type changes the result type returned. +message Type { + enum Kind { + UNKNOWN = 0; + FILE_MATCH = 1; + FILE_NAME = 2; + REPO = 3; + } + + Q child = 1; + // TODO: type constants + Kind type = 2; +} + +message Substring { + string pattern = 1; + bool case_sensitive = 2; + + // Match only filename + bool file_name = 3; + + // Match only content + bool content = 4; +} + +// And is matched when all its children are. +message And { + repeated Q children = 1; +} + +// Or is matched when any of its children is matched. +message Or { + repeated Q children = 1; +} + +// Not inverts the meaning of its child. +message Not { + Q child = 1; +} + +// Branch limits search to a specific branch. +message Branch { + string pattern = 1; + // exact is true if we want to Pattern to equal branch. + bool exact = 2; +} diff --git a/grpc/v1/webserver.pb.go b/grpc/v1/webserver.pb.go new file mode 100644 index 000000000..3c7ec11b9 --- /dev/null +++ b/grpc/v1/webserver.pb.go @@ -0,0 +1,3020 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.29.1 +// protoc (unknown) +// source: webserver.proto + +package v1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + durationpb "google.golang.org/protobuf/types/known/durationpb" + _ "google.golang.org/protobuf/types/known/emptypb" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type FlushReason int32 + +const ( + FlushReason_UNKNOWN FlushReason = 0 + FlushReason_TIMER_EXPIRED FlushReason = 1 + FlushReason_FINAL_FLUSH FlushReason = 2 + FlushReason_MAX_SIZE FlushReason = 3 +) + +// Enum value maps for FlushReason. +var ( + FlushReason_name = map[int32]string{ + 0: "UNKNOWN", + 1: "TIMER_EXPIRED", + 2: "FINAL_FLUSH", + 3: "MAX_SIZE", + } + FlushReason_value = map[string]int32{ + "UNKNOWN": 0, + "TIMER_EXPIRED": 1, + "FINAL_FLUSH": 2, + "MAX_SIZE": 3, + } +) + +func (x FlushReason) Enum() *FlushReason { + p := new(FlushReason) + *p = x + return p +} + +func (x FlushReason) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (FlushReason) Descriptor() protoreflect.EnumDescriptor { + return file_webserver_proto_enumTypes[0].Descriptor() +} + +func (FlushReason) Type() protoreflect.EnumType { + return &file_webserver_proto_enumTypes[0] +} + +func (x FlushReason) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use FlushReason.Descriptor instead. +func (FlushReason) EnumDescriptor() ([]byte, []int) { + return file_webserver_proto_rawDescGZIP(), []int{0} +} + +type ListOptions_RepoListField int32 + +const ( + ListOptions_REPO_LIST_FIELD_UNKNOWN ListOptions_RepoListField = 0 + ListOptions_REPO_LIST_FIELD_REPOS ListOptions_RepoListField = 1 + ListOptions_REPO_LIST_FIELD_MINIMAL ListOptions_RepoListField = 2 + ListOptions_REPO_LIST_FIELD_REPOS_MAP ListOptions_RepoListField = 3 +) + +// Enum value maps for ListOptions_RepoListField. +var ( + ListOptions_RepoListField_name = map[int32]string{ + 0: "REPO_LIST_FIELD_UNKNOWN", + 1: "REPO_LIST_FIELD_REPOS", + 2: "REPO_LIST_FIELD_MINIMAL", + 3: "REPO_LIST_FIELD_REPOS_MAP", + } + ListOptions_RepoListField_value = map[string]int32{ + "REPO_LIST_FIELD_UNKNOWN": 0, + "REPO_LIST_FIELD_REPOS": 1, + "REPO_LIST_FIELD_MINIMAL": 2, + "REPO_LIST_FIELD_REPOS_MAP": 3, + } +) + +func (x ListOptions_RepoListField) Enum() *ListOptions_RepoListField { + p := new(ListOptions_RepoListField) + *p = x + return p +} + +func (x ListOptions_RepoListField) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ListOptions_RepoListField) Descriptor() protoreflect.EnumDescriptor { + return file_webserver_proto_enumTypes[1].Descriptor() +} + +func (ListOptions_RepoListField) Type() protoreflect.EnumType { + return &file_webserver_proto_enumTypes[1] +} + +func (x ListOptions_RepoListField) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ListOptions_RepoListField.Descriptor instead. +func (ListOptions_RepoListField) EnumDescriptor() ([]byte, []int) { + return file_webserver_proto_rawDescGZIP(), []int{4, 0} +} + +type SearchRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Query *Q `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"` + Opts *SearchOptions `protobuf:"bytes,2,opt,name=opts,proto3" json:"opts,omitempty"` +} + +func (x *SearchRequest) Reset() { + *x = SearchRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_webserver_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SearchRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SearchRequest) ProtoMessage() {} + +func (x *SearchRequest) ProtoReflect() protoreflect.Message { + mi := &file_webserver_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 SearchRequest.ProtoReflect.Descriptor instead. +func (*SearchRequest) Descriptor() ([]byte, []int) { + return file_webserver_proto_rawDescGZIP(), []int{0} +} + +func (x *SearchRequest) GetQuery() *Q { + if x != nil { + return x.Query + } + return nil +} + +func (x *SearchRequest) GetOpts() *SearchOptions { + if x != nil { + return x.Opts + } + return nil +} + +type SearchResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Stats *Stats `protobuf:"bytes,1,opt,name=stats,proto3" json:"stats,omitempty"` + Progress *Progress `protobuf:"bytes,2,opt,name=progress,proto3" json:"progress,omitempty"` + Files []*FileMatch `protobuf:"bytes,3,rep,name=files,proto3" json:"files,omitempty"` + // RepoURLs holds a repo => template string map. + RepoUrls map[string]string `protobuf:"bytes,4,rep,name=repo_urls,json=repoUrls,proto3" json:"repo_urls,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // FragmentNames holds a repo => template string map, for + // the line number fragment. + LineFragments map[string]string `protobuf:"bytes,5,rep,name=line_fragments,json=lineFragments,proto3" json:"line_fragments,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *SearchResponse) Reset() { + *x = SearchResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_webserver_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SearchResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SearchResponse) ProtoMessage() {} + +func (x *SearchResponse) ProtoReflect() protoreflect.Message { + mi := &file_webserver_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 SearchResponse.ProtoReflect.Descriptor instead. +func (*SearchResponse) Descriptor() ([]byte, []int) { + return file_webserver_proto_rawDescGZIP(), []int{1} +} + +func (x *SearchResponse) GetStats() *Stats { + if x != nil { + return x.Stats + } + return nil +} + +func (x *SearchResponse) GetProgress() *Progress { + if x != nil { + return x.Progress + } + return nil +} + +func (x *SearchResponse) GetFiles() []*FileMatch { + if x != nil { + return x.Files + } + return nil +} + +func (x *SearchResponse) GetRepoUrls() map[string]string { + if x != nil { + return x.RepoUrls + } + return nil +} + +func (x *SearchResponse) GetLineFragments() map[string]string { + if x != nil { + return x.LineFragments + } + return nil +} + +type SearchOptions struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Return an upper-bound estimate of eligible documents in + // stats.ShardFilesConsidered. + EstimateDocCount bool `protobuf:"varint,1,opt,name=estimate_doc_count,json=estimateDocCount,proto3" json:"estimate_doc_count,omitempty"` + // Return the whole file. + Whole bool `protobuf:"varint,2,opt,name=whole,proto3" json:"whole,omitempty"` + // Maximum number of matches: skip all processing an index + // shard after we found this many non-overlapping matches. + ShardMaxMatchCount int64 `protobuf:"varint,3,opt,name=shard_max_match_count,json=shardMaxMatchCount,proto3" json:"shard_max_match_count,omitempty"` + // Maximum number of matches: stop looking for more matches + // once we have this many matches across shards. + TotalMaxMatchCount int64 `protobuf:"varint,4,opt,name=total_max_match_count,json=totalMaxMatchCount,proto3" json:"total_max_match_count,omitempty"` + // Maximum number of matches: skip processing documents for a repository in + // a shard once we have found ShardRepoMaxMatchCount. + // + // A compound shard may contain multiple repositories. This will most often + // be set to 1 to find all repositories containing a result. + ShardRepoMaxMatchCount int64 `protobuf:"varint,5,opt,name=shard_repo_max_match_count,json=shardRepoMaxMatchCount,proto3" json:"shard_repo_max_match_count,omitempty"` + // Abort the search after this much time has passed. + MaxWallTime *durationpb.Duration `protobuf:"bytes,6,opt,name=max_wall_time,json=maxWallTime,proto3" json:"max_wall_time,omitempty"` + // FlushWallTime if non-zero will stop streaming behaviour at first and + // instead will collate and sort results. At FlushWallTime the results will + // be sent and then the behaviour will revert to the normal streaming. + FlushWallTime *durationpb.Duration `protobuf:"bytes,7,opt,name=flush_wall_time,json=flushWallTime,proto3" json:"flush_wall_time,omitempty"` + // Trim the number of results after collating and sorting the + // results + MaxDocDisplayCount int64 `protobuf:"varint,8,opt,name=max_doc_display_count,json=maxDocDisplayCount,proto3" json:"max_doc_display_count,omitempty"` + // If set to a number greater than zero then up to this many number + // of context lines will be added before and after each matched line. + // Note that the included context lines might contain matches and + // it's up to the consumer of the result to remove those lines. + NumContextLines int64 `protobuf:"varint,9,opt,name=num_context_lines,json=numContextLines,proto3" json:"num_context_lines,omitempty"` + // If true, ChunkMatches will be returned in each FileMatch rather than LineMatches + // EXPERIMENTAL: the behavior of this flag may be changed in future versions. + ChunkMatches bool `protobuf:"varint,10,opt,name=chunk_matches,json=chunkMatches,proto3" json:"chunk_matches,omitempty"` + // EXPERIMENTAL. If true, document ranks are used as additional input for + // sorting matches. + UseDocumentRanks bool `protobuf:"varint,11,opt,name=use_document_ranks,json=useDocumentRanks,proto3" json:"use_document_ranks,omitempty"` + // EXPERIMENTAL. When UseDocumentRanks is enabled, this can be optionally set to adjust + // their weight in the file match score. If the value is <= 0.0, the default weight value + // will be used. This option is temporary and is only exposed for testing/ tuning purposes. + DocumentRanksWeight float64 `protobuf:"fixed64,12,opt,name=document_ranks_weight,json=documentRanksWeight,proto3" json:"document_ranks_weight,omitempty"` + // Trace turns on opentracing for this request if true and if the Jaeger address was provided as + // a command-line flag + Trace bool `protobuf:"varint,13,opt,name=trace,proto3" json:"trace,omitempty"` + // If set, the search results will contain debug information for scoring. + DebugScore bool `protobuf:"varint,14,opt,name=debug_score,json=debugScore,proto3" json:"debug_score,omitempty"` + // EXPERIMENTAL. If true, use keyword-style scoring instead of the default scoring formula. + // Currently, this treats each match in a file as a term and computes an approximation to BM25. + // When enabled, all other scoring signals are ignored, including document ranks. + UseKeywordScoring bool `protobuf:"varint,15,opt,name=use_keyword_scoring,json=useKeywordScoring,proto3" json:"use_keyword_scoring,omitempty"` +} + +func (x *SearchOptions) Reset() { + *x = SearchOptions{} + if protoimpl.UnsafeEnabled { + mi := &file_webserver_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SearchOptions) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SearchOptions) ProtoMessage() {} + +func (x *SearchOptions) ProtoReflect() protoreflect.Message { + mi := &file_webserver_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 SearchOptions.ProtoReflect.Descriptor instead. +func (*SearchOptions) Descriptor() ([]byte, []int) { + return file_webserver_proto_rawDescGZIP(), []int{2} +} + +func (x *SearchOptions) GetEstimateDocCount() bool { + if x != nil { + return x.EstimateDocCount + } + return false +} + +func (x *SearchOptions) GetWhole() bool { + if x != nil { + return x.Whole + } + return false +} + +func (x *SearchOptions) GetShardMaxMatchCount() int64 { + if x != nil { + return x.ShardMaxMatchCount + } + return 0 +} + +func (x *SearchOptions) GetTotalMaxMatchCount() int64 { + if x != nil { + return x.TotalMaxMatchCount + } + return 0 +} + +func (x *SearchOptions) GetShardRepoMaxMatchCount() int64 { + if x != nil { + return x.ShardRepoMaxMatchCount + } + return 0 +} + +func (x *SearchOptions) GetMaxWallTime() *durationpb.Duration { + if x != nil { + return x.MaxWallTime + } + return nil +} + +func (x *SearchOptions) GetFlushWallTime() *durationpb.Duration { + if x != nil { + return x.FlushWallTime + } + return nil +} + +func (x *SearchOptions) GetMaxDocDisplayCount() int64 { + if x != nil { + return x.MaxDocDisplayCount + } + return 0 +} + +func (x *SearchOptions) GetNumContextLines() int64 { + if x != nil { + return x.NumContextLines + } + return 0 +} + +func (x *SearchOptions) GetChunkMatches() bool { + if x != nil { + return x.ChunkMatches + } + return false +} + +func (x *SearchOptions) GetUseDocumentRanks() bool { + if x != nil { + return x.UseDocumentRanks + } + return false +} + +func (x *SearchOptions) GetDocumentRanksWeight() float64 { + if x != nil { + return x.DocumentRanksWeight + } + return 0 +} + +func (x *SearchOptions) GetTrace() bool { + if x != nil { + return x.Trace + } + return false +} + +func (x *SearchOptions) GetDebugScore() bool { + if x != nil { + return x.DebugScore + } + return false +} + +func (x *SearchOptions) GetUseKeywordScoring() bool { + if x != nil { + return x.UseKeywordScoring + } + return false +} + +type ListRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Query *Q `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"` + Opts *ListOptions `protobuf:"bytes,2,opt,name=opts,proto3" json:"opts,omitempty"` +} + +func (x *ListRequest) Reset() { + *x = ListRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_webserver_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListRequest) ProtoMessage() {} + +func (x *ListRequest) ProtoReflect() protoreflect.Message { + mi := &file_webserver_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 ListRequest.ProtoReflect.Descriptor instead. +func (*ListRequest) Descriptor() ([]byte, []int) { + return file_webserver_proto_rawDescGZIP(), []int{3} +} + +func (x *ListRequest) GetQuery() *Q { + if x != nil { + return x.Query + } + return nil +} + +func (x *ListRequest) GetOpts() *ListOptions { + if x != nil { + return x.Opts + } + return nil +} + +type ListOptions struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Field decides which field to populate in RepoList response. + Field ListOptions_RepoListField `protobuf:"varint,1,opt,name=field,proto3,enum=grpc.v1.ListOptions_RepoListField" json:"field,omitempty"` + // Return only Minimal data per repo that Sourcegraph frontend needs. + // + // Deprecated: use Field + Minimal bool `protobuf:"varint,16,opt,name=minimal,proto3" json:"minimal,omitempty"` +} + +func (x *ListOptions) Reset() { + *x = ListOptions{} + if protoimpl.UnsafeEnabled { + mi := &file_webserver_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListOptions) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListOptions) ProtoMessage() {} + +func (x *ListOptions) ProtoReflect() protoreflect.Message { + mi := &file_webserver_proto_msgTypes[4] + 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 ListOptions.ProtoReflect.Descriptor instead. +func (*ListOptions) Descriptor() ([]byte, []int) { + return file_webserver_proto_rawDescGZIP(), []int{4} +} + +func (x *ListOptions) GetField() ListOptions_RepoListField { + if x != nil { + return x.Field + } + return ListOptions_REPO_LIST_FIELD_UNKNOWN +} + +func (x *ListOptions) GetMinimal() bool { + if x != nil { + return x.Minimal + } + return false +} + +type ListResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Returned when ListOptions.Field is RepoListFieldRepos. + Repos []*RepoListEntry `protobuf:"bytes,1,rep,name=repos,proto3" json:"repos,omitempty"` + // ReposMap is set when ListOptions.Field is RepoListFieldReposMap. + ReposMap map[uint32]*MinimalRepoListEntry `protobuf:"bytes,2,rep,name=repos_map,json=reposMap,proto3" json:"repos_map,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Crashes int64 `protobuf:"varint,3,opt,name=crashes,proto3" json:"crashes,omitempty"` + // Stats response to a List request. + // This is the aggregate RepoStats of all repos matching the input query. + Stats *RepoStats `protobuf:"bytes,4,opt,name=stats,proto3" json:"stats,omitempty"` + // Returned when ListOptions.Field is RepoListFieldMinimal. + // + // Deprecated: use ReposMap. + Minimal map[uint32]*MinimalRepoListEntry `protobuf:"bytes,5,rep,name=minimal,proto3" json:"minimal,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *ListResponse) Reset() { + *x = ListResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_webserver_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListResponse) ProtoMessage() {} + +func (x *ListResponse) ProtoReflect() protoreflect.Message { + mi := &file_webserver_proto_msgTypes[5] + 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 ListResponse.ProtoReflect.Descriptor instead. +func (*ListResponse) Descriptor() ([]byte, []int) { + return file_webserver_proto_rawDescGZIP(), []int{5} +} + +func (x *ListResponse) GetRepos() []*RepoListEntry { + if x != nil { + return x.Repos + } + return nil +} + +func (x *ListResponse) GetReposMap() map[uint32]*MinimalRepoListEntry { + if x != nil { + return x.ReposMap + } + return nil +} + +func (x *ListResponse) GetCrashes() int64 { + if x != nil { + return x.Crashes + } + return 0 +} + +func (x *ListResponse) GetStats() *RepoStats { + if x != nil { + return x.Stats + } + return nil +} + +func (x *ListResponse) GetMinimal() map[uint32]*MinimalRepoListEntry { + if x != nil { + return x.Minimal + } + return nil +} + +type RepoListEntry struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Repository *Repository `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` + IndexMetadata *IndexMetadata `protobuf:"bytes,2,opt,name=index_metadata,json=indexMetadata,proto3" json:"index_metadata,omitempty"` + Stats *RepoStats `protobuf:"bytes,3,opt,name=stats,proto3" json:"stats,omitempty"` +} + +func (x *RepoListEntry) Reset() { + *x = RepoListEntry{} + if protoimpl.UnsafeEnabled { + mi := &file_webserver_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RepoListEntry) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RepoListEntry) ProtoMessage() {} + +func (x *RepoListEntry) ProtoReflect() protoreflect.Message { + mi := &file_webserver_proto_msgTypes[6] + 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 RepoListEntry.ProtoReflect.Descriptor instead. +func (*RepoListEntry) Descriptor() ([]byte, []int) { + return file_webserver_proto_rawDescGZIP(), []int{6} +} + +func (x *RepoListEntry) GetRepository() *Repository { + if x != nil { + return x.Repository + } + return nil +} + +func (x *RepoListEntry) GetIndexMetadata() *IndexMetadata { + if x != nil { + return x.IndexMetadata + } + return nil +} + +func (x *RepoListEntry) GetStats() *RepoStats { + if x != nil { + return x.Stats + } + return nil +} + +type Repository struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Sourcegraph's repository ID + Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + // The repository name + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + // The repository URL. + Url string `protobuf:"bytes,3,opt,name=url,proto3" json:"url,omitempty"` + // The physical source where this repo came from, eg. full + // path to the zip filename or git repository directory. This + // will not be exposed in the UI, but can be used to detect + // orphaned index shards. + Source string `protobuf:"bytes,4,opt,name=source,proto3" json:"source,omitempty"` + // The branches indexed in this repo. + Branches []*RepositoryBranch `protobuf:"bytes,5,rep,name=branches,proto3" json:"branches,omitempty"` + // Nil if this is not the super project. + SubRepoMap map[string]*Repository `protobuf:"bytes,6,rep,name=sub_repo_map,json=subRepoMap,proto3" json:"sub_repo_map,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // URL template to link to the commit of a branch + CommitUrlTemplate string `protobuf:"bytes,7,opt,name=commit_url_template,json=commitUrlTemplate,proto3" json:"commit_url_template,omitempty"` + // The repository URL for getting to a file. Has access to + // {{Branch}}, {{Path}} + FileUrlTemplate string `protobuf:"bytes,8,opt,name=file_url_template,json=fileUrlTemplate,proto3" json:"file_url_template,omitempty"` + // The URL fragment to add to a file URL for line numbers. has + // access to {{LineNumber}}. The fragment should include the + // separator, generally '#' or ';'. + LineFragmentTemplate string `protobuf:"bytes,9,opt,name=line_fragment_template,json=lineFragmentTemplate,proto3" json:"line_fragment_template,omitempty"` + // Perf optimization: priority is set when we load the shard. It corresponds to + // the value of "priority" stored in RawConfig. + Priority float64 `protobuf:"fixed64,10,opt,name=priority,proto3" json:"priority,omitempty"` + // All zoekt.* configuration settings. + RawConfig map[string]string `protobuf:"bytes,11,rep,name=raw_config,json=rawConfig,proto3" json:"raw_config,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // Importance of the repository, bigger is more important + Rank uint32 `protobuf:"varint,12,opt,name=rank,proto3" json:"rank,omitempty"` + // index_options is a hash of the options used to create the index for the + // repo. + IndexOptions string `protobuf:"bytes,13,opt,name=index_options,json=indexOptions,proto3" json:"index_options,omitempty"` + // has_symbols is true if this repository has indexed ctags + // output. Sourcegraph specific: This field is more appropriate for + // IndexMetadata. However, we store it here since the Sourcegraph frontend + // can read this structure but not IndexMetadata. + HasSymbols bool `protobuf:"varint,14,opt,name=has_symbols,json=hasSymbols,proto3" json:"has_symbols,omitempty"` + // tombstone is true if we are not allowed to search this repo. + Tombstone bool `protobuf:"varint,15,opt,name=tombstone,proto3" json:"tombstone,omitempty"` + // latest_commit_date is the date of the latest commit among all indexed Branches. + // The date might be time.Time's 0-value if the repository was last indexed + // before this field was added. + LatestCommitDate *timestamppb.Timestamp `protobuf:"bytes,16,opt,name=latest_commit_date,json=latestCommitDate,proto3" json:"latest_commit_date,omitempty"` + // file_tombstones is a set of file paths that should be ignored across all branches + // in this shard. + FileTombstones []string `protobuf:"bytes,17,rep,name=FileTombstones,proto3" json:"FileTombstones,omitempty"` +} + +func (x *Repository) Reset() { + *x = Repository{} + if protoimpl.UnsafeEnabled { + mi := &file_webserver_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Repository) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Repository) ProtoMessage() {} + +func (x *Repository) ProtoReflect() protoreflect.Message { + mi := &file_webserver_proto_msgTypes[7] + 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 Repository.ProtoReflect.Descriptor instead. +func (*Repository) Descriptor() ([]byte, []int) { + return file_webserver_proto_rawDescGZIP(), []int{7} +} + +func (x *Repository) GetId() uint32 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *Repository) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Repository) GetUrl() string { + if x != nil { + return x.Url + } + return "" +} + +func (x *Repository) GetSource() string { + if x != nil { + return x.Source + } + return "" +} + +func (x *Repository) GetBranches() []*RepositoryBranch { + if x != nil { + return x.Branches + } + return nil +} + +func (x *Repository) GetSubRepoMap() map[string]*Repository { + if x != nil { + return x.SubRepoMap + } + return nil +} + +func (x *Repository) GetCommitUrlTemplate() string { + if x != nil { + return x.CommitUrlTemplate + } + return "" +} + +func (x *Repository) GetFileUrlTemplate() string { + if x != nil { + return x.FileUrlTemplate + } + return "" +} + +func (x *Repository) GetLineFragmentTemplate() string { + if x != nil { + return x.LineFragmentTemplate + } + return "" +} + +func (x *Repository) GetPriority() float64 { + if x != nil { + return x.Priority + } + return 0 +} + +func (x *Repository) GetRawConfig() map[string]string { + if x != nil { + return x.RawConfig + } + return nil +} + +func (x *Repository) GetRank() uint32 { + if x != nil { + return x.Rank + } + return 0 +} + +func (x *Repository) GetIndexOptions() string { + if x != nil { + return x.IndexOptions + } + return "" +} + +func (x *Repository) GetHasSymbols() bool { + if x != nil { + return x.HasSymbols + } + return false +} + +func (x *Repository) GetTombstone() bool { + if x != nil { + return x.Tombstone + } + return false +} + +func (x *Repository) GetLatestCommitDate() *timestamppb.Timestamp { + if x != nil { + return x.LatestCommitDate + } + return nil +} + +func (x *Repository) GetFileTombstones() []string { + if x != nil { + return x.FileTombstones + } + return nil +} + +type IndexMetadata struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + IndexFormatVersion int64 `protobuf:"varint,1,opt,name=index_format_version,json=indexFormatVersion,proto3" json:"index_format_version,omitempty"` + IndexFeatureVersion int64 `protobuf:"varint,2,opt,name=index_feature_version,json=indexFeatureVersion,proto3" json:"index_feature_version,omitempty"` + IndexMinReaderVersion int64 `protobuf:"varint,3,opt,name=index_min_reader_version,json=indexMinReaderVersion,proto3" json:"index_min_reader_version,omitempty"` + IndexTime *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=index_time,json=indexTime,proto3" json:"index_time,omitempty"` + PlainAscii bool `protobuf:"varint,5,opt,name=plain_ascii,json=plainAscii,proto3" json:"plain_ascii,omitempty"` + LanguageMap map[string]uint32 `protobuf:"bytes,6,rep,name=language_map,json=languageMap,proto3" json:"language_map,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + ZoektVersion string `protobuf:"bytes,7,opt,name=zoekt_version,json=zoektVersion,proto3" json:"zoekt_version,omitempty"` + Id string `protobuf:"bytes,8,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *IndexMetadata) Reset() { + *x = IndexMetadata{} + if protoimpl.UnsafeEnabled { + mi := &file_webserver_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *IndexMetadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*IndexMetadata) ProtoMessage() {} + +func (x *IndexMetadata) ProtoReflect() protoreflect.Message { + mi := &file_webserver_proto_msgTypes[8] + 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 IndexMetadata.ProtoReflect.Descriptor instead. +func (*IndexMetadata) Descriptor() ([]byte, []int) { + return file_webserver_proto_rawDescGZIP(), []int{8} +} + +func (x *IndexMetadata) GetIndexFormatVersion() int64 { + if x != nil { + return x.IndexFormatVersion + } + return 0 +} + +func (x *IndexMetadata) GetIndexFeatureVersion() int64 { + if x != nil { + return x.IndexFeatureVersion + } + return 0 +} + +func (x *IndexMetadata) GetIndexMinReaderVersion() int64 { + if x != nil { + return x.IndexMinReaderVersion + } + return 0 +} + +func (x *IndexMetadata) GetIndexTime() *timestamppb.Timestamp { + if x != nil { + return x.IndexTime + } + return nil +} + +func (x *IndexMetadata) GetPlainAscii() bool { + if x != nil { + return x.PlainAscii + } + return false +} + +func (x *IndexMetadata) GetLanguageMap() map[string]uint32 { + if x != nil { + return x.LanguageMap + } + return nil +} + +func (x *IndexMetadata) GetZoektVersion() string { + if x != nil { + return x.ZoektVersion + } + return "" +} + +func (x *IndexMetadata) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +type MinimalRepoListEntry struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + HasSymbols bool `protobuf:"varint,1,opt,name=has_symbols,json=hasSymbols,proto3" json:"has_symbols,omitempty"` + Branches []*RepositoryBranch `protobuf:"bytes,2,rep,name=branches,proto3" json:"branches,omitempty"` +} + +func (x *MinimalRepoListEntry) Reset() { + *x = MinimalRepoListEntry{} + if protoimpl.UnsafeEnabled { + mi := &file_webserver_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MinimalRepoListEntry) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MinimalRepoListEntry) ProtoMessage() {} + +func (x *MinimalRepoListEntry) ProtoReflect() protoreflect.Message { + mi := &file_webserver_proto_msgTypes[9] + 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 MinimalRepoListEntry.ProtoReflect.Descriptor instead. +func (*MinimalRepoListEntry) Descriptor() ([]byte, []int) { + return file_webserver_proto_rawDescGZIP(), []int{9} +} + +func (x *MinimalRepoListEntry) GetHasSymbols() bool { + if x != nil { + return x.HasSymbols + } + return false +} + +func (x *MinimalRepoListEntry) GetBranches() []*RepositoryBranch { + if x != nil { + return x.Branches + } + return nil +} + +// RepositoryBranch describes an indexed branch, which is a name +// combined with a version. +type RepositoryBranch struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` +} + +func (x *RepositoryBranch) Reset() { + *x = RepositoryBranch{} + if protoimpl.UnsafeEnabled { + mi := &file_webserver_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RepositoryBranch) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RepositoryBranch) ProtoMessage() {} + +func (x *RepositoryBranch) ProtoReflect() protoreflect.Message { + mi := &file_webserver_proto_msgTypes[10] + 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 RepositoryBranch.ProtoReflect.Descriptor instead. +func (*RepositoryBranch) Descriptor() ([]byte, []int) { + return file_webserver_proto_rawDescGZIP(), []int{10} +} + +func (x *RepositoryBranch) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *RepositoryBranch) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +// RepoStats is a collection of statistics for a set of repositories. +type RepoStats struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // repos is used for aggregrating the number of repositories. + Repos int64 `protobuf:"varint,1,opt,name=repos,proto3" json:"repos,omitempty"` + // shards is the total number of search shards. + Shards int64 `protobuf:"varint,2,opt,name=shards,proto3" json:"shards,omitempty"` + // documents holds the number of documents or files. + Documents int64 `protobuf:"varint,3,opt,name=documents,proto3" json:"documents,omitempty"` + // index_bytes is the amount of RAM used for index overhead. + IndexBytes int64 `protobuf:"varint,4,opt,name=index_bytes,json=indexBytes,proto3" json:"index_bytes,omitempty"` + // content_bytes is the amount of RAM used for raw content. + ContentBytes int64 `protobuf:"varint,5,opt,name=content_bytes,json=contentBytes,proto3" json:"content_bytes,omitempty"` + // new_lines_count is the number of newlines "\n" that appear in the zoekt + // indexed documents. This is not exactly the same as line count, since it + // will not include lines not terminated by "\n" (eg a file with no "\n", or + // a final line without "\n"). Note: Zoekt deduplicates documents across + // branches, so if a path has the same contents on multiple branches, there + // is only one document for it. As such that document's newlines is only + // counted once. See DefaultBranchNewLinesCount and AllBranchesNewLinesCount + // for counts which do not deduplicate. + NewLinesCount uint64 `protobuf:"varint,6,opt,name=new_lines_count,json=newLinesCount,proto3" json:"new_lines_count,omitempty"` + // default_branch_new_lines_count is the number of newlines "\n" in the default + // branch. + DefaultBranchNewLinesCount uint64 `protobuf:"varint,7,opt,name=default_branch_new_lines_count,json=defaultBranchNewLinesCount,proto3" json:"default_branch_new_lines_count,omitempty"` + // other_branches_new_lines_count is the number of newlines "\n" in all branches + // except the default branch. + OtherBranchesNewLinesCount uint64 `protobuf:"varint,8,opt,name=other_branches_new_lines_count,json=otherBranchesNewLinesCount,proto3" json:"other_branches_new_lines_count,omitempty"` +} + +func (x *RepoStats) Reset() { + *x = RepoStats{} + if protoimpl.UnsafeEnabled { + mi := &file_webserver_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RepoStats) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RepoStats) ProtoMessage() {} + +func (x *RepoStats) ProtoReflect() protoreflect.Message { + mi := &file_webserver_proto_msgTypes[11] + 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 RepoStats.ProtoReflect.Descriptor instead. +func (*RepoStats) Descriptor() ([]byte, []int) { + return file_webserver_proto_rawDescGZIP(), []int{11} +} + +func (x *RepoStats) GetRepos() int64 { + if x != nil { + return x.Repos + } + return 0 +} + +func (x *RepoStats) GetShards() int64 { + if x != nil { + return x.Shards + } + return 0 +} + +func (x *RepoStats) GetDocuments() int64 { + if x != nil { + return x.Documents + } + return 0 +} + +func (x *RepoStats) GetIndexBytes() int64 { + if x != nil { + return x.IndexBytes + } + return 0 +} + +func (x *RepoStats) GetContentBytes() int64 { + if x != nil { + return x.ContentBytes + } + return 0 +} + +func (x *RepoStats) GetNewLinesCount() uint64 { + if x != nil { + return x.NewLinesCount + } + return 0 +} + +func (x *RepoStats) GetDefaultBranchNewLinesCount() uint64 { + if x != nil { + return x.DefaultBranchNewLinesCount + } + return 0 +} + +func (x *RepoStats) GetOtherBranchesNewLinesCount() uint64 { + if x != nil { + return x.OtherBranchesNewLinesCount + } + return 0 +} + +type Stats struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Amount of I/O for reading contents. + ContentBytesLoaded int64 `protobuf:"varint,1,opt,name=content_bytes_loaded,json=contentBytesLoaded,proto3" json:"content_bytes_loaded,omitempty"` + // Amount of I/O for reading from index. + IndexBytesLoaded int64 `protobuf:"varint,2,opt,name=index_bytes_loaded,json=indexBytesLoaded,proto3" json:"index_bytes_loaded,omitempty"` + // Number of search shards that had a crash. + Crashes int64 `protobuf:"varint,3,opt,name=crashes,proto3" json:"crashes,omitempty"` + // Wall clock time for this search + Duration *durationpb.Duration `protobuf:"bytes,4,opt,name=duration,proto3" json:"duration,omitempty"` + // Number of files containing a match. + FileCount int64 `protobuf:"varint,5,opt,name=file_count,json=fileCount,proto3" json:"file_count,omitempty"` + // Number of files in shards that we considered. + ShardFilesConsidered int64 `protobuf:"varint,6,opt,name=shard_files_considered,json=shardFilesConsidered,proto3" json:"shard_files_considered,omitempty"` + // Files that we evaluated. Equivalent to files for which all + // atom matches (including negations) evaluated to true. + FilesConsidered int64 `protobuf:"varint,7,opt,name=files_considered,json=filesConsidered,proto3" json:"files_considered,omitempty"` + // Files for which we loaded file content to verify substring matches + FilesLoaded int64 `protobuf:"varint,8,opt,name=files_loaded,json=filesLoaded,proto3" json:"files_loaded,omitempty"` + // Candidate files whose contents weren't examined because we + // gathered enough matches. + FilesSkipped int64 `protobuf:"varint,9,opt,name=files_skipped,json=filesSkipped,proto3" json:"files_skipped,omitempty"` + // Shards that we scanned to find matches. + ShardsScanned int64 `protobuf:"varint,10,opt,name=shards_scanned,json=shardsScanned,proto3" json:"shards_scanned,omitempty"` + // Shards that we did not process because a query was canceled. + ShardsSkipped int64 `protobuf:"varint,11,opt,name=shards_skipped,json=shardsSkipped,proto3" json:"shards_skipped,omitempty"` + // Shards that we did not process because the query was rejected by the + // ngram filter indicating it had no matches. + ShardsSkippedFilter int64 `protobuf:"varint,12,opt,name=shards_skipped_filter,json=shardsSkippedFilter,proto3" json:"shards_skipped_filter,omitempty"` + // Number of non-overlapping matches + MatchCount int64 `protobuf:"varint,13,opt,name=match_count,json=matchCount,proto3" json:"match_count,omitempty"` + // Number of candidate matches as a result of searching ngrams. + NgramMatches int64 `protobuf:"varint,14,opt,name=ngram_matches,json=ngramMatches,proto3" json:"ngram_matches,omitempty"` + // Wall clock time for queued search. + Wait *durationpb.Duration `protobuf:"bytes,15,opt,name=wait,proto3" json:"wait,omitempty"` + // Number of times regexp was called on files that we evaluated. + RegexpsConsidered int64 `protobuf:"varint,16,opt,name=regexps_considered,json=regexpsConsidered,proto3" json:"regexps_considered,omitempty"` + // FlushReason explains why results were flushed. + FlushReason FlushReason `protobuf:"varint,17,opt,name=flush_reason,json=flushReason,proto3,enum=grpc.v1.FlushReason" json:"flush_reason,omitempty"` +} + +func (x *Stats) Reset() { + *x = Stats{} + if protoimpl.UnsafeEnabled { + mi := &file_webserver_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Stats) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Stats) ProtoMessage() {} + +func (x *Stats) ProtoReflect() protoreflect.Message { + mi := &file_webserver_proto_msgTypes[12] + 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 Stats.ProtoReflect.Descriptor instead. +func (*Stats) Descriptor() ([]byte, []int) { + return file_webserver_proto_rawDescGZIP(), []int{12} +} + +func (x *Stats) GetContentBytesLoaded() int64 { + if x != nil { + return x.ContentBytesLoaded + } + return 0 +} + +func (x *Stats) GetIndexBytesLoaded() int64 { + if x != nil { + return x.IndexBytesLoaded + } + return 0 +} + +func (x *Stats) GetCrashes() int64 { + if x != nil { + return x.Crashes + } + return 0 +} + +func (x *Stats) GetDuration() *durationpb.Duration { + if x != nil { + return x.Duration + } + return nil +} + +func (x *Stats) GetFileCount() int64 { + if x != nil { + return x.FileCount + } + return 0 +} + +func (x *Stats) GetShardFilesConsidered() int64 { + if x != nil { + return x.ShardFilesConsidered + } + return 0 +} + +func (x *Stats) GetFilesConsidered() int64 { + if x != nil { + return x.FilesConsidered + } + return 0 +} + +func (x *Stats) GetFilesLoaded() int64 { + if x != nil { + return x.FilesLoaded + } + return 0 +} + +func (x *Stats) GetFilesSkipped() int64 { + if x != nil { + return x.FilesSkipped + } + return 0 +} + +func (x *Stats) GetShardsScanned() int64 { + if x != nil { + return x.ShardsScanned + } + return 0 +} + +func (x *Stats) GetShardsSkipped() int64 { + if x != nil { + return x.ShardsSkipped + } + return 0 +} + +func (x *Stats) GetShardsSkippedFilter() int64 { + if x != nil { + return x.ShardsSkippedFilter + } + return 0 +} + +func (x *Stats) GetMatchCount() int64 { + if x != nil { + return x.MatchCount + } + return 0 +} + +func (x *Stats) GetNgramMatches() int64 { + if x != nil { + return x.NgramMatches + } + return 0 +} + +func (x *Stats) GetWait() *durationpb.Duration { + if x != nil { + return x.Wait + } + return nil +} + +func (x *Stats) GetRegexpsConsidered() int64 { + if x != nil { + return x.RegexpsConsidered + } + return 0 +} + +func (x *Stats) GetFlushReason() FlushReason { + if x != nil { + return x.FlushReason + } + return FlushReason_UNKNOWN +} + +// Progress contains information about the global progress of the running search query. +// This is used by the frontend to reorder results and emit them when stable. +// Sourcegraph specific: this is used when querying multiple zoekt-webserver instances. +type Progress struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Priority of the shard that was searched. + Priority float64 `protobuf:"fixed64,1,opt,name=priority,proto3" json:"priority,omitempty"` + // max_pending_priority is the maximum priority of pending result that is being searched in parallel. + // This is used to reorder results when the result set is known to be stable-- that is, when a result's + // Priority is greater than the max(MaxPendingPriority) from the latest results of each backend, it can be returned to the user. + // + // max_pending_priority decreases monotonically in each SearchResult. + MaxPendingPriority float64 `protobuf:"fixed64,2,opt,name=max_pending_priority,json=maxPendingPriority,proto3" json:"max_pending_priority,omitempty"` +} + +func (x *Progress) Reset() { + *x = Progress{} + if protoimpl.UnsafeEnabled { + mi := &file_webserver_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Progress) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Progress) ProtoMessage() {} + +func (x *Progress) ProtoReflect() protoreflect.Message { + mi := &file_webserver_proto_msgTypes[13] + 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 Progress.ProtoReflect.Descriptor instead. +func (*Progress) Descriptor() ([]byte, []int) { + return file_webserver_proto_rawDescGZIP(), []int{13} +} + +func (x *Progress) GetPriority() float64 { + if x != nil { + return x.Priority + } + return 0 +} + +func (x *Progress) GetMaxPendingPriority() float64 { + if x != nil { + return x.MaxPendingPriority + } + return 0 +} + +// FileMatch contains all the matches within a file. +type FileMatch struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Ranking; the higher, the better. + Score float64 `protobuf:"fixed64,1,opt,name=score,proto3" json:"score,omitempty"` + // For debugging. Needs DebugScore set, but public so tests in + // other packages can print some diagnostics. + Debug string `protobuf:"bytes,2,opt,name=debug,proto3" json:"debug,omitempty"` + FileName string `protobuf:"bytes,3,opt,name=file_name,json=fileName,proto3" json:"file_name,omitempty"` + // Repository is the globally unique name of the repo of the + // match + Repository string `protobuf:"bytes,4,opt,name=repository,proto3" json:"repository,omitempty"` + Branches []string `protobuf:"bytes,5,rep,name=branches,proto3" json:"branches,omitempty"` + // One of line_matches or chunk_matches will be returned depending on whether + // the SearchOptions.ChunkMatches is set. + LineMatches []*LineMatch `protobuf:"bytes,6,rep,name=line_matches,json=lineMatches,proto3" json:"line_matches,omitempty"` + ChunkMatches []*ChunkMatch `protobuf:"bytes,7,rep,name=chunk_matches,json=chunkMatches,proto3" json:"chunk_matches,omitempty"` + // repository_id is a Sourcegraph extension. This is the ID of Repository in + // Sourcegraph. + RepositoryId uint32 `protobuf:"varint,8,opt,name=repository_id,json=repositoryId,proto3" json:"repository_id,omitempty"` + RepositoryPriority float64 `protobuf:"fixed64,9,opt,name=repository_priority,json=repositoryPriority,proto3" json:"repository_priority,omitempty"` + // Only set if requested + Content []byte `protobuf:"bytes,10,opt,name=content,proto3" json:"content,omitempty"` + // Checksum of the content. + Checksum []byte `protobuf:"bytes,11,opt,name=checksum,proto3" json:"checksum,omitempty"` + // Detected language of the result. + Language string `protobuf:"bytes,12,opt,name=language,proto3" json:"language,omitempty"` + // sub_repository_name is the globally unique name of the repo, + // if it came from a subrepository + SubRepositoryName string `protobuf:"bytes,13,opt,name=sub_repository_name,json=subRepositoryName,proto3" json:"sub_repository_name,omitempty"` + // sub_repository_path holds the prefix where the subrepository + // was mounted. + SubRepositoryPath string `protobuf:"bytes,14,opt,name=sub_repository_path,json=subRepositoryPath,proto3" json:"sub_repository_path,omitempty"` + // Commit SHA1 (hex) of the (sub)repo holding the file. + Version string `protobuf:"bytes,15,opt,name=version,proto3" json:"version,omitempty"` +} + +func (x *FileMatch) Reset() { + *x = FileMatch{} + if protoimpl.UnsafeEnabled { + mi := &file_webserver_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FileMatch) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FileMatch) ProtoMessage() {} + +func (x *FileMatch) ProtoReflect() protoreflect.Message { + mi := &file_webserver_proto_msgTypes[14] + 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 FileMatch.ProtoReflect.Descriptor instead. +func (*FileMatch) Descriptor() ([]byte, []int) { + return file_webserver_proto_rawDescGZIP(), []int{14} +} + +func (x *FileMatch) GetScore() float64 { + if x != nil { + return x.Score + } + return 0 +} + +func (x *FileMatch) GetDebug() string { + if x != nil { + return x.Debug + } + return "" +} + +func (x *FileMatch) GetFileName() string { + if x != nil { + return x.FileName + } + return "" +} + +func (x *FileMatch) GetRepository() string { + if x != nil { + return x.Repository + } + return "" +} + +func (x *FileMatch) GetBranches() []string { + if x != nil { + return x.Branches + } + return nil +} + +func (x *FileMatch) GetLineMatches() []*LineMatch { + if x != nil { + return x.LineMatches + } + return nil +} + +func (x *FileMatch) GetChunkMatches() []*ChunkMatch { + if x != nil { + return x.ChunkMatches + } + return nil +} + +func (x *FileMatch) GetRepositoryId() uint32 { + if x != nil { + return x.RepositoryId + } + return 0 +} + +func (x *FileMatch) GetRepositoryPriority() float64 { + if x != nil { + return x.RepositoryPriority + } + return 0 +} + +func (x *FileMatch) GetContent() []byte { + if x != nil { + return x.Content + } + return nil +} + +func (x *FileMatch) GetChecksum() []byte { + if x != nil { + return x.Checksum + } + return nil +} + +func (x *FileMatch) GetLanguage() string { + if x != nil { + return x.Language + } + return "" +} + +func (x *FileMatch) GetSubRepositoryName() string { + if x != nil { + return x.SubRepositoryName + } + return "" +} + +func (x *FileMatch) GetSubRepositoryPath() string { + if x != nil { + return x.SubRepositoryPath + } + return "" +} + +func (x *FileMatch) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +type LineMatch struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Line []byte `protobuf:"bytes,1,opt,name=line,proto3" json:"line,omitempty"` + LineStart int64 `protobuf:"varint,2,opt,name=line_start,json=lineStart,proto3" json:"line_start,omitempty"` + LineEnd int64 `protobuf:"varint,3,opt,name=line_end,json=lineEnd,proto3" json:"line_end,omitempty"` + LineNumber int64 `protobuf:"varint,4,opt,name=line_number,json=lineNumber,proto3" json:"line_number,omitempty"` + // before and after are only set when SearchOptions.NumContextLines is > 0 + Before []byte `protobuf:"bytes,5,opt,name=before,proto3" json:"before,omitempty"` + After []byte `protobuf:"bytes,6,opt,name=after,proto3" json:"after,omitempty"` + // If set, this was a match on the filename. + FileName bool `protobuf:"varint,7,opt,name=file_name,json=fileName,proto3" json:"file_name,omitempty"` + // The higher the better. Only ranks the quality of the match + // within the file, does not take rank of file into account + Score float64 `protobuf:"fixed64,8,opt,name=score,proto3" json:"score,omitempty"` + DebugScore string `protobuf:"bytes,9,opt,name=debug_score,json=debugScore,proto3" json:"debug_score,omitempty"` + LineFragments []*LineFragmentMatch `protobuf:"bytes,10,rep,name=line_fragments,json=lineFragments,proto3" json:"line_fragments,omitempty"` +} + +func (x *LineMatch) Reset() { + *x = LineMatch{} + if protoimpl.UnsafeEnabled { + mi := &file_webserver_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LineMatch) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LineMatch) ProtoMessage() {} + +func (x *LineMatch) ProtoReflect() protoreflect.Message { + mi := &file_webserver_proto_msgTypes[15] + 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 LineMatch.ProtoReflect.Descriptor instead. +func (*LineMatch) Descriptor() ([]byte, []int) { + return file_webserver_proto_rawDescGZIP(), []int{15} +} + +func (x *LineMatch) GetLine() []byte { + if x != nil { + return x.Line + } + return nil +} + +func (x *LineMatch) GetLineStart() int64 { + if x != nil { + return x.LineStart + } + return 0 +} + +func (x *LineMatch) GetLineEnd() int64 { + if x != nil { + return x.LineEnd + } + return 0 +} + +func (x *LineMatch) GetLineNumber() int64 { + if x != nil { + return x.LineNumber + } + return 0 +} + +func (x *LineMatch) GetBefore() []byte { + if x != nil { + return x.Before + } + return nil +} + +func (x *LineMatch) GetAfter() []byte { + if x != nil { + return x.After + } + return nil +} + +func (x *LineMatch) GetFileName() bool { + if x != nil { + return x.FileName + } + return false +} + +func (x *LineMatch) GetScore() float64 { + if x != nil { + return x.Score + } + return 0 +} + +func (x *LineMatch) GetDebugScore() string { + if x != nil { + return x.DebugScore + } + return "" +} + +func (x *LineMatch) GetLineFragments() []*LineFragmentMatch { + if x != nil { + return x.LineFragments + } + return nil +} + +type LineFragmentMatch struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Offset within the line, in bytes. + LineOffset int64 `protobuf:"varint,1,opt,name=line_offset,json=lineOffset,proto3" json:"line_offset,omitempty"` + // Offset from file start, in bytes. + Offset uint32 `protobuf:"varint,2,opt,name=offset,proto3" json:"offset,omitempty"` + // Number bytes that match. + MatchLength int64 `protobuf:"varint,3,opt,name=match_length,json=matchLength,proto3" json:"match_length,omitempty"` + SymbolInfo *SymbolInfo `protobuf:"bytes,4,opt,name=symbol_info,json=symbolInfo,proto3,oneof" json:"symbol_info,omitempty"` +} + +func (x *LineFragmentMatch) Reset() { + *x = LineFragmentMatch{} + if protoimpl.UnsafeEnabled { + mi := &file_webserver_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LineFragmentMatch) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LineFragmentMatch) ProtoMessage() {} + +func (x *LineFragmentMatch) ProtoReflect() protoreflect.Message { + mi := &file_webserver_proto_msgTypes[16] + 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 LineFragmentMatch.ProtoReflect.Descriptor instead. +func (*LineFragmentMatch) Descriptor() ([]byte, []int) { + return file_webserver_proto_rawDescGZIP(), []int{16} +} + +func (x *LineFragmentMatch) GetLineOffset() int64 { + if x != nil { + return x.LineOffset + } + return 0 +} + +func (x *LineFragmentMatch) GetOffset() uint32 { + if x != nil { + return x.Offset + } + return 0 +} + +func (x *LineFragmentMatch) GetMatchLength() int64 { + if x != nil { + return x.MatchLength + } + return 0 +} + +func (x *LineFragmentMatch) GetSymbolInfo() *SymbolInfo { + if x != nil { + return x.SymbolInfo + } + return nil +} + +type SymbolInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Sym string `protobuf:"bytes,1,opt,name=sym,proto3" json:"sym,omitempty"` + Kind string `protobuf:"bytes,2,opt,name=kind,proto3" json:"kind,omitempty"` + Parent string `protobuf:"bytes,3,opt,name=parent,proto3" json:"parent,omitempty"` + ParentKind string `protobuf:"bytes,4,opt,name=parent_kind,json=parentKind,proto3" json:"parent_kind,omitempty"` +} + +func (x *SymbolInfo) Reset() { + *x = SymbolInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_webserver_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SymbolInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SymbolInfo) ProtoMessage() {} + +func (x *SymbolInfo) ProtoReflect() protoreflect.Message { + mi := &file_webserver_proto_msgTypes[17] + 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 SymbolInfo.ProtoReflect.Descriptor instead. +func (*SymbolInfo) Descriptor() ([]byte, []int) { + return file_webserver_proto_rawDescGZIP(), []int{17} +} + +func (x *SymbolInfo) GetSym() string { + if x != nil { + return x.Sym + } + return "" +} + +func (x *SymbolInfo) GetKind() string { + if x != nil { + return x.Kind + } + return "" +} + +func (x *SymbolInfo) GetParent() string { + if x != nil { + return x.Parent + } + return "" +} + +func (x *SymbolInfo) GetParentKind() string { + if x != nil { + return x.ParentKind + } + return "" +} + +type ChunkMatch struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // A contiguous range of complete lines that fully contains Ranges. + Content []byte `protobuf:"bytes,1,opt,name=content,proto3" json:"content,omitempty"` + // The location (inclusive) of the beginning of content + // relative to the beginning of the file. It will always be at the + // beginning of a line (Column will always be 1). + ContentStart *Location `protobuf:"bytes,2,opt,name=content_start,json=contentStart,proto3" json:"content_start,omitempty"` + // True if this match is a match on the file name, in + // which case Content will contain the file name. + FileName bool `protobuf:"varint,3,opt,name=file_name,json=fileName,proto3" json:"file_name,omitempty"` + // A set of matching ranges within this chunk. Each range is relative + // to the beginning of the file (not the beginning of Content). + Ranges []*Range `protobuf:"bytes,4,rep,name=ranges,proto3" json:"ranges,omitempty"` + // The symbol information associated with Ranges. If it is non-nil, + // its length will equal that of Ranges. Any of its elements may be nil. + SymbolInfo []*SymbolInfo `protobuf:"bytes,5,rep,name=symbol_info,json=symbolInfo,proto3" json:"symbol_info,omitempty"` + Score float64 `protobuf:"fixed64,6,opt,name=score,proto3" json:"score,omitempty"` + DebugScore string `protobuf:"bytes,7,opt,name=debug_score,json=debugScore,proto3" json:"debug_score,omitempty"` +} + +func (x *ChunkMatch) Reset() { + *x = ChunkMatch{} + if protoimpl.UnsafeEnabled { + mi := &file_webserver_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ChunkMatch) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ChunkMatch) ProtoMessage() {} + +func (x *ChunkMatch) ProtoReflect() protoreflect.Message { + mi := &file_webserver_proto_msgTypes[18] + 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 ChunkMatch.ProtoReflect.Descriptor instead. +func (*ChunkMatch) Descriptor() ([]byte, []int) { + return file_webserver_proto_rawDescGZIP(), []int{18} +} + +func (x *ChunkMatch) GetContent() []byte { + if x != nil { + return x.Content + } + return nil +} + +func (x *ChunkMatch) GetContentStart() *Location { + if x != nil { + return x.ContentStart + } + return nil +} + +func (x *ChunkMatch) GetFileName() bool { + if x != nil { + return x.FileName + } + return false +} + +func (x *ChunkMatch) GetRanges() []*Range { + if x != nil { + return x.Ranges + } + return nil +} + +func (x *ChunkMatch) GetSymbolInfo() []*SymbolInfo { + if x != nil { + return x.SymbolInfo + } + return nil +} + +func (x *ChunkMatch) GetScore() float64 { + if x != nil { + return x.Score + } + return 0 +} + +func (x *ChunkMatch) GetDebugScore() string { + if x != nil { + return x.DebugScore + } + return "" +} + +type Range struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The inclusive beginning of the range. + Start *Location `protobuf:"bytes,1,opt,name=start,proto3" json:"start,omitempty"` + // The exclusive end of the range. + End *Location `protobuf:"bytes,2,opt,name=end,proto3" json:"end,omitempty"` +} + +func (x *Range) Reset() { + *x = Range{} + if protoimpl.UnsafeEnabled { + mi := &file_webserver_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Range) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Range) ProtoMessage() {} + +func (x *Range) ProtoReflect() protoreflect.Message { + mi := &file_webserver_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 Range.ProtoReflect.Descriptor instead. +func (*Range) Descriptor() ([]byte, []int) { + return file_webserver_proto_rawDescGZIP(), []int{19} +} + +func (x *Range) GetStart() *Location { + if x != nil { + return x.Start + } + return nil +} + +func (x *Range) GetEnd() *Location { + if x != nil { + return x.End + } + return nil +} + +type Location struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // 0-based byte offset from the beginning of the file + ByteOffset uint32 `protobuf:"varint,1,opt,name=byte_offset,json=byteOffset,proto3" json:"byte_offset,omitempty"` + // 1-based line number from the beginning of the file + LineNumber uint32 `protobuf:"varint,2,opt,name=line_number,json=lineNumber,proto3" json:"line_number,omitempty"` + // 1-based column number (in runes) from the beginning of line + Column uint32 `protobuf:"varint,3,opt,name=column,proto3" json:"column,omitempty"` +} + +func (x *Location) Reset() { + *x = Location{} + if protoimpl.UnsafeEnabled { + mi := &file_webserver_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Location) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Location) ProtoMessage() {} + +func (x *Location) ProtoReflect() protoreflect.Message { + mi := &file_webserver_proto_msgTypes[20] + 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 Location.ProtoReflect.Descriptor instead. +func (*Location) Descriptor() ([]byte, []int) { + return file_webserver_proto_rawDescGZIP(), []int{20} +} + +func (x *Location) GetByteOffset() uint32 { + if x != nil { + return x.ByteOffset + } + return 0 +} + +func (x *Location) GetLineNumber() uint32 { + if x != nil { + return x.LineNumber + } + return 0 +} + +func (x *Location) GetColumn() uint32 { + if x != nil { + return x.Column + } + return 0 +} + +var File_webserver_proto protoreflect.FileDescriptor + +var file_webserver_proto_rawDesc = []byte{ + 0x0a, 0x0f, 0x77, 0x65, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x07, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, + 0x79, 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, 0x1a, 0x0b, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x5d, 0x0a, 0x0d, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, + 0x51, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2a, 0x0a, 0x04, 0x6f, 0x70, 0x74, 0x73, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, + 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x04, + 0x6f, 0x70, 0x74, 0x73, 0x22, 0xa5, 0x03, 0x0a, 0x0e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, + 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x12, 0x2d, 0x0a, + 0x08, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x11, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, + 0x73, 0x73, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x28, 0x0a, 0x05, + 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x72, + 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, + 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x42, 0x0a, 0x09, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x75, + 0x72, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x72, 0x70, 0x63, + 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x55, 0x72, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x08, 0x72, 0x65, 0x70, 0x6f, 0x55, 0x72, 0x6c, 0x73, 0x12, 0x51, 0x0a, 0x0e, 0x6c, 0x69, + 0x6e, 0x65, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x61, + 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4c, 0x69, 0x6e, 0x65, + 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0d, + 0x6c, 0x69, 0x6e, 0x65, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x1a, 0x3b, 0x0a, + 0x0d, 0x52, 0x65, 0x70, 0x6f, 0x55, 0x72, 0x6c, 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, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x40, 0x0a, 0x12, 0x4c, 0x69, + 0x6e, 0x65, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 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, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xc4, 0x05, 0x0a, + 0x0d, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2c, + 0x0a, 0x12, 0x65, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x5f, 0x64, 0x6f, 0x63, 0x5f, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x65, 0x73, 0x74, 0x69, + 0x6d, 0x61, 0x74, 0x65, 0x44, 0x6f, 0x63, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, + 0x77, 0x68, 0x6f, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x77, 0x68, 0x6f, + 0x6c, 0x65, 0x12, 0x31, 0x0a, 0x15, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x6d, 0x61, 0x78, 0x5f, + 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x12, 0x73, 0x68, 0x61, 0x72, 0x64, 0x4d, 0x61, 0x78, 0x4d, 0x61, 0x74, 0x63, 0x68, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x31, 0x0a, 0x15, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x6d, + 0x61, 0x78, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x12, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x4d, 0x61, 0x78, 0x4d, 0x61, + 0x74, 0x63, 0x68, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x3a, 0x0a, 0x1a, 0x73, 0x68, 0x61, 0x72, + 0x64, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, + 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x16, 0x73, 0x68, + 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x4d, 0x61, 0x78, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x3d, 0x0a, 0x0d, 0x6d, 0x61, 0x78, 0x5f, 0x77, 0x61, 0x6c, 0x6c, + 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 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, 0x0b, 0x6d, 0x61, 0x78, 0x57, 0x61, 0x6c, 0x6c, 0x54, + 0x69, 0x6d, 0x65, 0x12, 0x41, 0x0a, 0x0f, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x5f, 0x77, 0x61, 0x6c, + 0x6c, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x07, 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, 0x0d, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x57, 0x61, + 0x6c, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x31, 0x0a, 0x15, 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x6f, + 0x63, 0x5f, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x12, 0x6d, 0x61, 0x78, 0x44, 0x6f, 0x63, 0x44, 0x69, 0x73, + 0x70, 0x6c, 0x61, 0x79, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x6e, 0x75, 0x6d, + 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x6e, 0x75, 0x6d, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x4c, 0x69, 0x6e, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x5f, 0x6d, + 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x63, 0x68, + 0x75, 0x6e, 0x6b, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x75, 0x73, + 0x65, 0x5f, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x72, 0x61, 0x6e, 0x6b, 0x73, + 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x75, 0x73, 0x65, 0x44, 0x6f, 0x63, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x52, 0x61, 0x6e, 0x6b, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x64, 0x6f, 0x63, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x72, 0x61, 0x6e, 0x6b, 0x73, 0x5f, 0x77, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x01, 0x52, 0x13, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x52, 0x61, 0x6e, 0x6b, 0x73, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x14, 0x0a, 0x05, + 0x74, 0x72, 0x61, 0x63, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x74, 0x72, 0x61, + 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x62, 0x75, 0x67, 0x5f, 0x73, 0x63, 0x6f, 0x72, + 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x64, 0x65, 0x62, 0x75, 0x67, 0x53, 0x63, + 0x6f, 0x72, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x75, 0x73, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x77, 0x6f, + 0x72, 0x64, 0x5f, 0x73, 0x63, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x11, 0x75, 0x73, 0x65, 0x4b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x53, 0x63, 0x6f, 0x72, + 0x69, 0x6e, 0x67, 0x22, 0x59, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x20, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0a, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x52, 0x05, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x12, 0x28, 0x0a, 0x04, 0x6f, 0x70, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x04, 0x6f, 0x70, 0x74, 0x73, 0x22, 0xe7, + 0x01, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x38, + 0x0a, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, + 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x65, 0x6c, + 0x64, 0x52, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x69, 0x6e, 0x69, + 0x6d, 0x61, 0x6c, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x6d, 0x69, 0x6e, 0x69, 0x6d, + 0x61, 0x6c, 0x22, 0x83, 0x01, 0x0a, 0x0d, 0x52, 0x65, 0x70, 0x6f, 0x4c, 0x69, 0x73, 0x74, 0x46, + 0x69, 0x65, 0x6c, 0x64, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x45, 0x50, 0x4f, 0x5f, 0x4c, 0x49, 0x53, + 0x54, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, + 0x00, 0x12, 0x19, 0x0a, 0x15, 0x52, 0x45, 0x50, 0x4f, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x5f, 0x46, + 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x52, 0x45, 0x50, 0x4f, 0x53, 0x10, 0x01, 0x12, 0x1b, 0x0a, 0x17, + 0x52, 0x45, 0x50, 0x4f, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, + 0x4d, 0x49, 0x4e, 0x49, 0x4d, 0x41, 0x4c, 0x10, 0x02, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x45, 0x50, + 0x4f, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x52, 0x45, 0x50, + 0x4f, 0x53, 0x5f, 0x4d, 0x41, 0x50, 0x10, 0x03, 0x22, 0xb7, 0x03, 0x0a, 0x0c, 0x4c, 0x69, 0x73, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x05, 0x72, 0x65, 0x70, + 0x6f, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, + 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x05, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x12, 0x40, 0x0a, 0x09, 0x72, 0x65, 0x70, 0x6f, 0x73, + 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x67, 0x72, 0x70, + 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, + 0x08, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x4d, 0x61, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x72, 0x61, + 0x73, 0x68, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x63, 0x72, 0x61, 0x73, + 0x68, 0x65, 0x73, 0x12, 0x28, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, + 0x6f, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x12, 0x3c, 0x0a, + 0x07, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, + 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x07, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x1a, 0x5a, 0x0a, 0x0d, 0x52, + 0x65, 0x70, 0x6f, 0x73, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x33, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, + 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x52, + 0x65, 0x70, 0x6f, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x59, 0x0a, 0x0c, 0x4d, 0x69, 0x6e, 0x69, 0x6d, + 0x61, 0x6c, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x33, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, + 0x76, 0x31, 0x2e, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x52, 0x65, 0x70, 0x6f, 0x4c, 0x69, + 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, + 0x38, 0x01, 0x22, 0xad, 0x01, 0x0a, 0x0d, 0x52, 0x65, 0x70, 0x6f, 0x4c, 0x69, 0x73, 0x74, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x33, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, + 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x0a, 0x72, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x3d, 0x0a, 0x0e, 0x69, 0x6e, 0x64, + 0x65, 0x78, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x64, 0x65, + 0x78, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x0d, 0x69, 0x6e, 0x64, 0x65, 0x78, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x28, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, + 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, + 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x05, 0x73, 0x74, 0x61, + 0x74, 0x73, 0x22, 0xc5, 0x06, 0x0a, 0x0a, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, + 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, + 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, + 0x35, 0x0a, 0x08, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x08, 0x62, 0x72, + 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x12, 0x45, 0x0a, 0x0c, 0x73, 0x75, 0x62, 0x5f, 0x72, 0x65, + 0x70, 0x6f, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x67, + 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, + 0x79, 0x2e, 0x53, 0x75, 0x62, 0x52, 0x65, 0x70, 0x6f, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x0a, 0x73, 0x75, 0x62, 0x52, 0x65, 0x70, 0x6f, 0x4d, 0x61, 0x70, 0x12, 0x2e, 0x0a, + 0x13, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x75, 0x72, 0x6c, 0x5f, 0x74, 0x65, 0x6d, 0x70, + 0x6c, 0x61, 0x74, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x63, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x55, 0x72, 0x6c, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x2a, 0x0a, + 0x11, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, + 0x74, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x66, 0x69, 0x6c, 0x65, 0x55, 0x72, + 0x6c, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x34, 0x0a, 0x16, 0x6c, 0x69, 0x6e, + 0x65, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, + 0x61, 0x74, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x6c, 0x69, 0x6e, 0x65, 0x46, + 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, + 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x01, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x41, 0x0a, 0x0a, 0x72, + 0x61, 0x77, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x22, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x52, 0x61, 0x77, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x09, 0x72, 0x61, 0x77, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, + 0x0a, 0x04, 0x72, 0x61, 0x6e, 0x6b, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x72, 0x61, + 0x6e, 0x6b, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x6f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x69, 0x6e, 0x64, 0x65, 0x78, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x68, 0x61, 0x73, 0x5f, 0x73, + 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x68, 0x61, + 0x73, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x6f, 0x6d, 0x62, + 0x73, 0x74, 0x6f, 0x6e, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x74, 0x6f, 0x6d, + 0x62, 0x73, 0x74, 0x6f, 0x6e, 0x65, 0x12, 0x48, 0x0a, 0x12, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, + 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x10, 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, 0x10, + 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x44, 0x61, 0x74, 0x65, + 0x12, 0x26, 0x0a, 0x0e, 0x46, 0x69, 0x6c, 0x65, 0x54, 0x6f, 0x6d, 0x62, 0x73, 0x74, 0x6f, 0x6e, + 0x65, 0x73, 0x18, 0x11, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x46, 0x69, 0x6c, 0x65, 0x54, 0x6f, + 0x6d, 0x62, 0x73, 0x74, 0x6f, 0x6e, 0x65, 0x73, 0x1a, 0x52, 0x0a, 0x0f, 0x53, 0x75, 0x62, 0x52, + 0x65, 0x70, 0x6f, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x67, + 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, + 0x79, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3c, 0x0a, 0x0e, + 0x52, 0x61, 0x77, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xcb, 0x03, 0x0a, 0x0d, 0x49, + 0x6e, 0x64, 0x65, 0x78, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x30, 0x0a, 0x14, + 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x5f, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x12, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x32, + 0x0a, 0x15, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x13, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x37, 0x0a, 0x18, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x6d, 0x69, 0x6e, 0x5f, + 0x72, 0x65, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x4d, 0x69, 0x6e, 0x52, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x39, 0x0a, 0x0a, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 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, 0x69, 0x6e, 0x64, + 0x65, 0x78, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x5f, + 0x61, 0x73, 0x63, 0x69, 0x69, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x70, 0x6c, 0x61, + 0x69, 0x6e, 0x41, 0x73, 0x63, 0x69, 0x69, 0x12, 0x4a, 0x0a, 0x0c, 0x6c, 0x61, 0x6e, 0x67, 0x75, + 0x61, 0x67, 0x65, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, + 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x4d, 0x61, + 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, + 0x4d, 0x61, 0x70, 0x12, 0x23, 0x0a, 0x0d, 0x7a, 0x6f, 0x65, 0x6b, 0x74, 0x5f, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x7a, 0x6f, 0x65, 0x6b, + 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x1a, 0x3e, 0x0a, 0x10, 0x4c, 0x61, 0x6e, 0x67, + 0x75, 0x61, 0x67, 0x65, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x6e, 0x0a, 0x14, 0x4d, 0x69, 0x6e, 0x69, + 0x6d, 0x61, 0x6c, 0x52, 0x65, 0x70, 0x6f, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x12, 0x1f, 0x0a, 0x0b, 0x68, 0x61, 0x73, 0x5f, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x68, 0x61, 0x73, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, + 0x73, 0x12, 0x35, 0x0a, 0x08, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x08, + 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x22, 0x40, 0x0a, 0x10, 0x52, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xcd, 0x02, 0x0a, 0x09, 0x52, + 0x65, 0x70, 0x6f, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x65, 0x70, 0x6f, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x12, 0x16, + 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, + 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x64, 0x6f, 0x63, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x62, 0x79, + 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x69, 0x6e, 0x64, 0x65, 0x78, + 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, + 0x77, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x0d, 0x6e, 0x65, 0x77, 0x4c, 0x69, 0x6e, 0x65, 0x73, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x42, 0x0a, 0x1e, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x62, 0x72, + 0x61, 0x6e, 0x63, 0x68, 0x5f, 0x6e, 0x65, 0x77, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x5f, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x1a, 0x64, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x4e, 0x65, 0x77, 0x4c, 0x69, 0x6e, 0x65, + 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x42, 0x0a, 0x1e, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, + 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x5f, 0x6e, 0x65, 0x77, 0x5f, 0x6c, 0x69, 0x6e, + 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x1a, + 0x6f, 0x74, 0x68, 0x65, 0x72, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x4e, 0x65, 0x77, + 0x4c, 0x69, 0x6e, 0x65, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xdf, 0x05, 0x0a, 0x05, 0x53, + 0x74, 0x61, 0x74, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, + 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x74, 0x65, 0x73, + 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, + 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x10, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x42, 0x79, 0x74, 0x65, 0x73, 0x4c, 0x6f, + 0x61, 0x64, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x72, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x63, 0x72, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x35, + 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 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, 0x08, 0x64, 0x75, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x34, 0x0a, 0x16, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x66, 0x69, + 0x6c, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 0x65, 0x64, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x14, 0x73, 0x68, 0x61, 0x72, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x73, + 0x43, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 0x65, 0x64, 0x12, 0x29, 0x0a, 0x10, 0x66, 0x69, + 0x6c, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 0x65, 0x64, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x73, 0x69, + 0x64, 0x65, 0x72, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x6c, + 0x6f, 0x61, 0x64, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x66, 0x69, 0x6c, + 0x65, 0x73, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x69, 0x6c, 0x65, + 0x73, 0x5f, 0x73, 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x0c, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x53, 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64, 0x12, 0x25, 0x0a, + 0x0e, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x5f, 0x73, 0x63, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x53, 0x63, 0x61, + 0x6e, 0x6e, 0x65, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x5f, 0x73, + 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x73, 0x68, + 0x61, 0x72, 0x64, 0x73, 0x53, 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64, 0x12, 0x32, 0x0a, 0x15, 0x73, + 0x68, 0x61, 0x72, 0x64, 0x73, 0x5f, 0x73, 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x66, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x03, 0x52, 0x13, 0x73, 0x68, 0x61, 0x72, + 0x64, 0x73, 0x53, 0x6b, 0x69, 0x70, 0x70, 0x65, 0x64, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, + 0x1f, 0x0a, 0x0b, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0d, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x12, 0x23, 0x0a, 0x0d, 0x6e, 0x67, 0x72, 0x61, 0x6d, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, + 0x73, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x6e, 0x67, 0x72, 0x61, 0x6d, 0x4d, 0x61, + 0x74, 0x63, 0x68, 0x65, 0x73, 0x12, 0x2d, 0x0a, 0x04, 0x77, 0x61, 0x69, 0x74, 0x18, 0x0f, 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, 0x04, + 0x77, 0x61, 0x69, 0x74, 0x12, 0x2d, 0x0a, 0x12, 0x72, 0x65, 0x67, 0x65, 0x78, 0x70, 0x73, 0x5f, + 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 0x65, 0x64, 0x18, 0x10, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x11, 0x72, 0x65, 0x67, 0x65, 0x78, 0x70, 0x73, 0x43, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, + 0x72, 0x65, 0x64, 0x12, 0x37, 0x0a, 0x0c, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x5f, 0x72, 0x65, 0x61, + 0x73, 0x6f, 0x6e, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x67, 0x72, 0x70, 0x63, + 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x6c, 0x75, 0x73, 0x68, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x52, + 0x0b, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x58, 0x0a, 0x08, + 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, + 0x72, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, + 0x72, 0x69, 0x74, 0x79, 0x12, 0x30, 0x0a, 0x14, 0x6d, 0x61, 0x78, 0x5f, 0x70, 0x65, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x01, 0x52, 0x12, 0x6d, 0x61, 0x78, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x50, 0x72, + 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0xa3, 0x04, 0x0a, 0x09, 0x46, 0x69, 0x6c, 0x65, 0x4d, + 0x61, 0x74, 0x63, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x01, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x65, + 0x62, 0x75, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x64, 0x65, 0x62, 0x75, 0x67, + 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, + 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1a, 0x0a, + 0x08, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x08, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x12, 0x35, 0x0a, 0x0c, 0x6c, 0x69, 0x6e, + 0x65, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x6e, 0x65, 0x4d, 0x61, + 0x74, 0x63, 0x68, 0x52, 0x0b, 0x6c, 0x69, 0x6e, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, + 0x12, 0x38, 0x0a, 0x0d, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, + 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, + 0x31, 0x2e, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x0c, 0x63, 0x68, + 0x75, 0x6e, 0x6b, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x0c, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x49, 0x64, 0x12, + 0x2f, 0x0a, 0x13, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x70, 0x72, + 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x01, 0x52, 0x12, 0x72, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, + 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x68, + 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x63, 0x68, + 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, + 0x67, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, + 0x67, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x73, 0x75, 0x62, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x11, 0x73, 0x75, 0x62, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x4e, 0x61, + 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x73, 0x75, 0x62, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x11, 0x73, 0x75, 0x62, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x50, 0x61, + 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0f, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xbf, 0x02, 0x0a, + 0x09, 0x4c, 0x69, 0x6e, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, + 0x6e, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x1d, + 0x0a, 0x0a, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x09, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x19, 0x0a, + 0x08, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x65, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x07, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x6c, 0x69, 0x6e, 0x65, + 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x6c, + 0x69, 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x65, 0x66, + 0x6f, 0x72, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x01, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, + 0x62, 0x75, 0x67, 0x5f, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x64, 0x65, 0x62, 0x75, 0x67, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x12, 0x41, 0x0a, 0x0e, 0x6c, + 0x69, 0x6e, 0x65, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x0a, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, + 0x6e, 0x65, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, + 0x0d, 0x6c, 0x69, 0x6e, 0x65, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0xba, + 0x01, 0x0a, 0x11, 0x4c, 0x69, 0x6e, 0x65, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x4d, + 0x61, 0x74, 0x63, 0x68, 0x12, 0x1f, 0x0a, 0x0b, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x6f, 0x66, 0x66, + 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x6c, 0x69, 0x6e, 0x65, 0x4f, + 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x21, 0x0a, + 0x0c, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x0b, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x12, 0x39, 0x0a, 0x0b, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, + 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x48, 0x00, 0x52, 0x0a, 0x73, 0x79, + 0x6d, 0x62, 0x6f, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x88, 0x01, 0x01, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, + 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x22, 0x6b, 0x0a, 0x0a, 0x53, + 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x79, 0x6d, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x79, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x6b, + 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, + 0x16, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x61, + 0x72, 0x65, 0x6e, 0x74, 0x4b, 0x69, 0x6e, 0x64, 0x22, 0x90, 0x02, 0x0a, 0x0a, 0x43, 0x68, 0x75, + 0x6e, 0x6b, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, + 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x12, 0x36, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, + 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x69, 0x6c, + 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x66, 0x69, + 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x06, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, + 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, + 0x2e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x06, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x34, + 0x0a, 0x0b, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x05, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, + 0x6d, 0x62, 0x6f, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, + 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x01, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, + 0x62, 0x75, 0x67, 0x5f, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x64, 0x65, 0x62, 0x75, 0x67, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x22, 0x55, 0x0a, 0x05, 0x52, + 0x61, 0x6e, 0x67, 0x65, 0x12, 0x27, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x23, 0x0a, + 0x03, 0x65, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x72, 0x70, + 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x03, 0x65, + 0x6e, 0x64, 0x22, 0x64, 0x0a, 0x08, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, + 0x0a, 0x0b, 0x62, 0x79, 0x74, 0x65, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x62, 0x79, 0x74, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, + 0x1f, 0x0a, 0x0b, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x6c, 0x69, 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x06, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x2a, 0x4c, 0x0a, 0x0b, 0x46, 0x6c, 0x75, 0x73, + 0x68, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, + 0x57, 0x4e, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x49, 0x4d, 0x45, 0x52, 0x5f, 0x45, 0x58, + 0x50, 0x49, 0x52, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x46, 0x49, 0x4e, 0x41, 0x4c, + 0x5f, 0x46, 0x4c, 0x55, 0x53, 0x48, 0x10, 0x02, 0x12, 0x0c, 0x0a, 0x08, 0x4d, 0x41, 0x58, 0x5f, + 0x53, 0x49, 0x5a, 0x45, 0x10, 0x03, 0x32, 0xcb, 0x01, 0x0a, 0x10, 0x57, 0x65, 0x62, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x3b, 0x0a, 0x06, 0x53, + 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x16, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, + 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, + 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0c, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x16, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, + 0x76, 0x31, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x17, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, + 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x35, 0x0a, + 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x14, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x67, 0x72, + 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x42, 0x26, 0x5a, 0x24, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x7a, + 0x6f, 0x65, 0x6b, 0x74, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_webserver_proto_rawDescOnce sync.Once + file_webserver_proto_rawDescData = file_webserver_proto_rawDesc +) + +func file_webserver_proto_rawDescGZIP() []byte { + file_webserver_proto_rawDescOnce.Do(func() { + file_webserver_proto_rawDescData = protoimpl.X.CompressGZIP(file_webserver_proto_rawDescData) + }) + return file_webserver_proto_rawDescData +} + +var file_webserver_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_webserver_proto_msgTypes = make([]protoimpl.MessageInfo, 28) +var file_webserver_proto_goTypes = []interface{}{ + (FlushReason)(0), // 0: grpc.v1.FlushReason + (ListOptions_RepoListField)(0), // 1: grpc.v1.ListOptions.RepoListField + (*SearchRequest)(nil), // 2: grpc.v1.SearchRequest + (*SearchResponse)(nil), // 3: grpc.v1.SearchResponse + (*SearchOptions)(nil), // 4: grpc.v1.SearchOptions + (*ListRequest)(nil), // 5: grpc.v1.ListRequest + (*ListOptions)(nil), // 6: grpc.v1.ListOptions + (*ListResponse)(nil), // 7: grpc.v1.ListResponse + (*RepoListEntry)(nil), // 8: grpc.v1.RepoListEntry + (*Repository)(nil), // 9: grpc.v1.Repository + (*IndexMetadata)(nil), // 10: grpc.v1.IndexMetadata + (*MinimalRepoListEntry)(nil), // 11: grpc.v1.MinimalRepoListEntry + (*RepositoryBranch)(nil), // 12: grpc.v1.RepositoryBranch + (*RepoStats)(nil), // 13: grpc.v1.RepoStats + (*Stats)(nil), // 14: grpc.v1.Stats + (*Progress)(nil), // 15: grpc.v1.Progress + (*FileMatch)(nil), // 16: grpc.v1.FileMatch + (*LineMatch)(nil), // 17: grpc.v1.LineMatch + (*LineFragmentMatch)(nil), // 18: grpc.v1.LineFragmentMatch + (*SymbolInfo)(nil), // 19: grpc.v1.SymbolInfo + (*ChunkMatch)(nil), // 20: grpc.v1.ChunkMatch + (*Range)(nil), // 21: grpc.v1.Range + (*Location)(nil), // 22: grpc.v1.Location + nil, // 23: grpc.v1.SearchResponse.RepoUrlsEntry + nil, // 24: grpc.v1.SearchResponse.LineFragmentsEntry + nil, // 25: grpc.v1.ListResponse.ReposMapEntry + nil, // 26: grpc.v1.ListResponse.MinimalEntry + nil, // 27: grpc.v1.Repository.SubRepoMapEntry + nil, // 28: grpc.v1.Repository.RawConfigEntry + nil, // 29: grpc.v1.IndexMetadata.LanguageMapEntry + (*Q)(nil), // 30: grpc.v1.Q + (*durationpb.Duration)(nil), // 31: google.protobuf.Duration + (*timestamppb.Timestamp)(nil), // 32: google.protobuf.Timestamp +} +var file_webserver_proto_depIdxs = []int32{ + 30, // 0: grpc.v1.SearchRequest.query:type_name -> grpc.v1.Q + 4, // 1: grpc.v1.SearchRequest.opts:type_name -> grpc.v1.SearchOptions + 14, // 2: grpc.v1.SearchResponse.stats:type_name -> grpc.v1.Stats + 15, // 3: grpc.v1.SearchResponse.progress:type_name -> grpc.v1.Progress + 16, // 4: grpc.v1.SearchResponse.files:type_name -> grpc.v1.FileMatch + 23, // 5: grpc.v1.SearchResponse.repo_urls:type_name -> grpc.v1.SearchResponse.RepoUrlsEntry + 24, // 6: grpc.v1.SearchResponse.line_fragments:type_name -> grpc.v1.SearchResponse.LineFragmentsEntry + 31, // 7: grpc.v1.SearchOptions.max_wall_time:type_name -> google.protobuf.Duration + 31, // 8: grpc.v1.SearchOptions.flush_wall_time:type_name -> google.protobuf.Duration + 30, // 9: grpc.v1.ListRequest.query:type_name -> grpc.v1.Q + 6, // 10: grpc.v1.ListRequest.opts:type_name -> grpc.v1.ListOptions + 1, // 11: grpc.v1.ListOptions.field:type_name -> grpc.v1.ListOptions.RepoListField + 8, // 12: grpc.v1.ListResponse.repos:type_name -> grpc.v1.RepoListEntry + 25, // 13: grpc.v1.ListResponse.repos_map:type_name -> grpc.v1.ListResponse.ReposMapEntry + 13, // 14: grpc.v1.ListResponse.stats:type_name -> grpc.v1.RepoStats + 26, // 15: grpc.v1.ListResponse.minimal:type_name -> grpc.v1.ListResponse.MinimalEntry + 9, // 16: grpc.v1.RepoListEntry.repository:type_name -> grpc.v1.Repository + 10, // 17: grpc.v1.RepoListEntry.index_metadata:type_name -> grpc.v1.IndexMetadata + 13, // 18: grpc.v1.RepoListEntry.stats:type_name -> grpc.v1.RepoStats + 12, // 19: grpc.v1.Repository.branches:type_name -> grpc.v1.RepositoryBranch + 27, // 20: grpc.v1.Repository.sub_repo_map:type_name -> grpc.v1.Repository.SubRepoMapEntry + 28, // 21: grpc.v1.Repository.raw_config:type_name -> grpc.v1.Repository.RawConfigEntry + 32, // 22: grpc.v1.Repository.latest_commit_date:type_name -> google.protobuf.Timestamp + 32, // 23: grpc.v1.IndexMetadata.index_time:type_name -> google.protobuf.Timestamp + 29, // 24: grpc.v1.IndexMetadata.language_map:type_name -> grpc.v1.IndexMetadata.LanguageMapEntry + 12, // 25: grpc.v1.MinimalRepoListEntry.branches:type_name -> grpc.v1.RepositoryBranch + 31, // 26: grpc.v1.Stats.duration:type_name -> google.protobuf.Duration + 31, // 27: grpc.v1.Stats.wait:type_name -> google.protobuf.Duration + 0, // 28: grpc.v1.Stats.flush_reason:type_name -> grpc.v1.FlushReason + 17, // 29: grpc.v1.FileMatch.line_matches:type_name -> grpc.v1.LineMatch + 20, // 30: grpc.v1.FileMatch.chunk_matches:type_name -> grpc.v1.ChunkMatch + 18, // 31: grpc.v1.LineMatch.line_fragments:type_name -> grpc.v1.LineFragmentMatch + 19, // 32: grpc.v1.LineFragmentMatch.symbol_info:type_name -> grpc.v1.SymbolInfo + 22, // 33: grpc.v1.ChunkMatch.content_start:type_name -> grpc.v1.Location + 21, // 34: grpc.v1.ChunkMatch.ranges:type_name -> grpc.v1.Range + 19, // 35: grpc.v1.ChunkMatch.symbol_info:type_name -> grpc.v1.SymbolInfo + 22, // 36: grpc.v1.Range.start:type_name -> grpc.v1.Location + 22, // 37: grpc.v1.Range.end:type_name -> grpc.v1.Location + 11, // 38: grpc.v1.ListResponse.ReposMapEntry.value:type_name -> grpc.v1.MinimalRepoListEntry + 11, // 39: grpc.v1.ListResponse.MinimalEntry.value:type_name -> grpc.v1.MinimalRepoListEntry + 9, // 40: grpc.v1.Repository.SubRepoMapEntry.value:type_name -> grpc.v1.Repository + 2, // 41: grpc.v1.WebserverService.Search:input_type -> grpc.v1.SearchRequest + 2, // 42: grpc.v1.WebserverService.StreamSearch:input_type -> grpc.v1.SearchRequest + 5, // 43: grpc.v1.WebserverService.List:input_type -> grpc.v1.ListRequest + 3, // 44: grpc.v1.WebserverService.Search:output_type -> grpc.v1.SearchResponse + 3, // 45: grpc.v1.WebserverService.StreamSearch:output_type -> grpc.v1.SearchResponse + 7, // 46: grpc.v1.WebserverService.List:output_type -> grpc.v1.ListResponse + 44, // [44:47] is the sub-list for method output_type + 41, // [41:44] is the sub-list for method input_type + 41, // [41:41] is the sub-list for extension type_name + 41, // [41:41] is the sub-list for extension extendee + 0, // [0:41] is the sub-list for field type_name +} + +func init() { file_webserver_proto_init() } +func file_webserver_proto_init() { + if File_webserver_proto != nil { + return + } + file_query_proto_init() + if !protoimpl.UnsafeEnabled { + file_webserver_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SearchRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_webserver_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SearchResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_webserver_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SearchOptions); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_webserver_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_webserver_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListOptions); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_webserver_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_webserver_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RepoListEntry); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_webserver_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Repository); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_webserver_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*IndexMetadata); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_webserver_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MinimalRepoListEntry); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_webserver_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RepositoryBranch); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_webserver_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RepoStats); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_webserver_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Stats); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_webserver_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Progress); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_webserver_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FileMatch); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_webserver_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LineMatch); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_webserver_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LineFragmentMatch); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_webserver_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SymbolInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_webserver_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ChunkMatch); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_webserver_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Range); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_webserver_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Location); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_webserver_proto_msgTypes[16].OneofWrappers = []interface{}{} + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_webserver_proto_rawDesc, + NumEnums: 2, + NumMessages: 28, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_webserver_proto_goTypes, + DependencyIndexes: file_webserver_proto_depIdxs, + EnumInfos: file_webserver_proto_enumTypes, + MessageInfos: file_webserver_proto_msgTypes, + }.Build() + File_webserver_proto = out.File + file_webserver_proto_rawDesc = nil + file_webserver_proto_goTypes = nil + file_webserver_proto_depIdxs = nil +} diff --git a/grpc/v1/webserver.proto b/grpc/v1/webserver.proto new file mode 100644 index 000000000..6f37ecc43 --- /dev/null +++ b/grpc/v1/webserver.proto @@ -0,0 +1,491 @@ +syntax = "proto3"; + +package grpc.v1; + +import "google/protobuf/duration.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/timestamp.proto"; +import "query.proto"; + +option go_package = "github.com/sourcegraph/zoekt/grpc/v1"; + +service WebserverService { + rpc Search(SearchRequest) returns (SearchResponse) {} + + rpc StreamSearch(SearchRequest) returns (stream SearchResponse) {} + + // List lists repositories. The query `q` can only contain + // query.Repo atoms. + rpc List(ListRequest) returns (ListResponse) {} +} + +message SearchRequest { + Q query = 1; + SearchOptions opts = 2; +} + +message SearchResponse { + Stats stats = 1; + Progress progress = 2; + + repeated FileMatch files = 3; + + // RepoURLs holds a repo => template string map. + map repo_urls = 4; + + // FragmentNames holds a repo => template string map, for + // the line number fragment. + map line_fragments = 5; +} + +message SearchOptions { + // Return an upper-bound estimate of eligible documents in + // stats.ShardFilesConsidered. + bool estimate_doc_count = 1; + + // Return the whole file. + bool whole = 2; + + // Maximum number of matches: skip all processing an index + // shard after we found this many non-overlapping matches. + int64 shard_max_match_count = 3; + + // Maximum number of matches: stop looking for more matches + // once we have this many matches across shards. + int64 total_max_match_count = 4; + + // Maximum number of matches: skip processing documents for a repository in + // a shard once we have found ShardRepoMaxMatchCount. + // + // A compound shard may contain multiple repositories. This will most often + // be set to 1 to find all repositories containing a result. + int64 shard_repo_max_match_count = 5; + + // Abort the search after this much time has passed. + google.protobuf.Duration max_wall_time = 6; + + // FlushWallTime if non-zero will stop streaming behaviour at first and + // instead will collate and sort results. At FlushWallTime the results will + // be sent and then the behaviour will revert to the normal streaming. + google.protobuf.Duration flush_wall_time = 7; + + // Trim the number of results after collating and sorting the + // results + int64 max_doc_display_count = 8; + + // If set to a number greater than zero then up to this many number + // of context lines will be added before and after each matched line. + // Note that the included context lines might contain matches and + // it's up to the consumer of the result to remove those lines. + int64 num_context_lines = 9; + + // If true, ChunkMatches will be returned in each FileMatch rather than LineMatches + // EXPERIMENTAL: the behavior of this flag may be changed in future versions. + bool chunk_matches = 10; + + // EXPERIMENTAL. If true, document ranks are used as additional input for + // sorting matches. + bool use_document_ranks = 11; + + // EXPERIMENTAL. When UseDocumentRanks is enabled, this can be optionally set to adjust + // their weight in the file match score. If the value is <= 0.0, the default weight value + // will be used. This option is temporary and is only exposed for testing/ tuning purposes. + double document_ranks_weight = 12; + + // Trace turns on opentracing for this request if true and if the Jaeger address was provided as + // a command-line flag + bool trace = 13; + + // If set, the search results will contain debug information for scoring. + bool debug_score = 14; + + // EXPERIMENTAL. If true, use keyword-style scoring instead of the default scoring formula. + // Currently, this treats each match in a file as a term and computes an approximation to BM25. + // When enabled, all other scoring signals are ignored, including document ranks. + bool use_keyword_scoring = 15; +} + +message ListRequest { + Q query = 1; + ListOptions opts = 2; +} + +message ListOptions { + enum RepoListField { + REPO_LIST_FIELD_UNKNOWN = 0; + REPO_LIST_FIELD_REPOS = 1; + REPO_LIST_FIELD_MINIMAL = 2; + REPO_LIST_FIELD_REPOS_MAP = 3; + } + + // Field decides which field to populate in RepoList response. + RepoListField field = 1; + + // Return only Minimal data per repo that Sourcegraph frontend needs. + // + // Deprecated: use Field + bool minimal = 16; +} + +message ListResponse { + // Returned when ListOptions.Field is RepoListFieldRepos. + repeated RepoListEntry repos = 1; + + // ReposMap is set when ListOptions.Field is RepoListFieldReposMap. + map repos_map = 2; + + int64 crashes = 3; + + // Stats response to a List request. + // This is the aggregate RepoStats of all repos matching the input query. + RepoStats stats = 4; + + // Returned when ListOptions.Field is RepoListFieldMinimal. + // + // Deprecated: use ReposMap. + map minimal = 5; +} + +message RepoListEntry { + Repository repository = 1; + IndexMetadata index_metadata = 2; + RepoStats stats = 3; +} + +message Repository { + // Sourcegraph's repository ID + uint32 id = 1; + + // The repository name + string name = 2; + + // The repository URL. + string url = 3; + + // The physical source where this repo came from, eg. full + // path to the zip filename or git repository directory. This + // will not be exposed in the UI, but can be used to detect + // orphaned index shards. + string source = 4; + + // The branches indexed in this repo. + repeated RepositoryBranch branches = 5; + + // Nil if this is not the super project. + map sub_repo_map = 6; + + // URL template to link to the commit of a branch + string commit_url_template = 7; + + // The repository URL for getting to a file. Has access to + // {{Branch}}, {{Path}} + string file_url_template = 8; + + // The URL fragment to add to a file URL for line numbers. has + // access to {{LineNumber}}. The fragment should include the + // separator, generally '#' or ';'. + string line_fragment_template = 9; + + // Perf optimization: priority is set when we load the shard. It corresponds to + // the value of "priority" stored in RawConfig. + double priority = 10; + + // All zoekt.* configuration settings. + map raw_config = 11; + + // Importance of the repository, bigger is more important + uint32 rank = 12; + + // index_options is a hash of the options used to create the index for the + // repo. + string index_options = 13; + + // has_symbols is true if this repository has indexed ctags + // output. Sourcegraph specific: This field is more appropriate for + // IndexMetadata. However, we store it here since the Sourcegraph frontend + // can read this structure but not IndexMetadata. + bool has_symbols = 14; + + // tombstone is true if we are not allowed to search this repo. + bool tombstone = 15; + + // latest_commit_date is the date of the latest commit among all indexed Branches. + // The date might be time.Time's 0-value if the repository was last indexed + // before this field was added. + google.protobuf.Timestamp latest_commit_date = 16; + + // file_tombstones is a set of file paths that should be ignored across all branches + // in this shard. + repeated string FileTombstones = 17; +} + +message IndexMetadata { + int64 index_format_version = 1; + int64 index_feature_version = 2; + int64 index_min_reader_version = 3; + google.protobuf.Timestamp index_time = 4; + bool plain_ascii = 5; + map language_map = 6; + string zoekt_version = 7; + string id = 8; +} + +message MinimalRepoListEntry { + bool has_symbols = 1; + repeated RepositoryBranch branches = 2; +} + +// RepositoryBranch describes an indexed branch, which is a name +// combined with a version. +message RepositoryBranch { + string name = 1; + string version = 2; +} + +// RepoStats is a collection of statistics for a set of repositories. +message RepoStats { + // repos is used for aggregrating the number of repositories. + int64 repos = 1; + + // shards is the total number of search shards. + int64 shards = 2; + + // documents holds the number of documents or files. + int64 documents = 3; + + // index_bytes is the amount of RAM used for index overhead. + int64 index_bytes = 4; + + // content_bytes is the amount of RAM used for raw content. + int64 content_bytes = 5; + + // Sourcegraph specific stats below. These are not as efficient to calculate + // as the above statistics. We experimentally measured about a 10% slower + // shard load time. However, we find these values very useful to track and + // computing them outside of load time introduces a lot of complexity. + + // new_lines_count is the number of newlines "\n" that appear in the zoekt + // indexed documents. This is not exactly the same as line count, since it + // will not include lines not terminated by "\n" (eg a file with no "\n", or + // a final line without "\n"). Note: Zoekt deduplicates documents across + // branches, so if a path has the same contents on multiple branches, there + // is only one document for it. As such that document's newlines is only + // counted once. See DefaultBranchNewLinesCount and AllBranchesNewLinesCount + // for counts which do not deduplicate. + uint64 new_lines_count = 6; + + // default_branch_new_lines_count is the number of newlines "\n" in the default + // branch. + uint64 default_branch_new_lines_count = 7; + + // other_branches_new_lines_count is the number of newlines "\n" in all branches + // except the default branch. + uint64 other_branches_new_lines_count = 8; +} + +message Stats { + // Amount of I/O for reading contents. + int64 content_bytes_loaded = 1; + + // Amount of I/O for reading from index. + int64 index_bytes_loaded = 2; + + // Number of search shards that had a crash. + int64 crashes = 3; + + // Wall clock time for this search + google.protobuf.Duration duration = 4; + + // Number of files containing a match. + int64 file_count = 5; + + // Number of files in shards that we considered. + int64 shard_files_considered = 6; + + // Files that we evaluated. Equivalent to files for which all + // atom matches (including negations) evaluated to true. + int64 files_considered = 7; + + // Files for which we loaded file content to verify substring matches + int64 files_loaded = 8; + + // Candidate files whose contents weren't examined because we + // gathered enough matches. + int64 files_skipped = 9; + + // Shards that we scanned to find matches. + int64 shards_scanned = 10; + + // Shards that we did not process because a query was canceled. + int64 shards_skipped = 11; + + // Shards that we did not process because the query was rejected by the + // ngram filter indicating it had no matches. + int64 shards_skipped_filter = 12; + + // Number of non-overlapping matches + int64 match_count = 13; + + // Number of candidate matches as a result of searching ngrams. + int64 ngram_matches = 14; + + // Wall clock time for queued search. + google.protobuf.Duration wait = 15; + + // Number of times regexp was called on files that we evaluated. + int64 regexps_considered = 16; + + // FlushReason explains why results were flushed. + FlushReason flush_reason = 17; +} + +enum FlushReason { + UNKNOWN = 0; + TIMER_EXPIRED = 1; + FINAL_FLUSH = 2; + MAX_SIZE = 3; +} + +// Progress contains information about the global progress of the running search query. +// This is used by the frontend to reorder results and emit them when stable. +// Sourcegraph specific: this is used when querying multiple zoekt-webserver instances. +message Progress { + // Priority of the shard that was searched. + double priority = 1; + + // max_pending_priority is the maximum priority of pending result that is being searched in parallel. + // This is used to reorder results when the result set is known to be stable-- that is, when a result's + // Priority is greater than the max(MaxPendingPriority) from the latest results of each backend, it can be returned to the user. + // + // max_pending_priority decreases monotonically in each SearchResult. + double max_pending_priority = 2; +} + +// FileMatch contains all the matches within a file. +message FileMatch { + // Ranking; the higher, the better. + double score = 1; + + // For debugging. Needs DebugScore set, but public so tests in + // other packages can print some diagnostics. + string debug = 2; + + string file_name = 3; + + // Repository is the globally unique name of the repo of the + // match + string repository = 4; + repeated string branches = 5; + + // One of line_matches or chunk_matches will be returned depending on whether + // the SearchOptions.ChunkMatches is set. + repeated LineMatch line_matches = 6; + repeated ChunkMatch chunk_matches = 7; + + // repository_id is a Sourcegraph extension. This is the ID of Repository in + // Sourcegraph. + uint32 repository_id = 8; + + double repository_priority = 9; + + // Only set if requested + bytes content = 10; + + // Checksum of the content. + bytes checksum = 11; + + // Detected language of the result. + string language = 12; + + // sub_repository_name is the globally unique name of the repo, + // if it came from a subrepository + string sub_repository_name = 13; + + // sub_repository_path holds the prefix where the subrepository + // was mounted. + string sub_repository_path = 14; + + // Commit SHA1 (hex) of the (sub)repo holding the file. + string version = 15; +} + +message LineMatch { + bytes line = 1; + int64 line_start = 2; + int64 line_end = 3; + int64 line_number = 4; + + // before and after are only set when SearchOptions.NumContextLines is > 0 + bytes before = 5; + bytes after = 6; + + // If set, this was a match on the filename. + bool file_name = 7; + + // The higher the better. Only ranks the quality of the match + // within the file, does not take rank of file into account + double score = 8; + string debug_score = 9; + + repeated LineFragmentMatch line_fragments = 10; +} + +message LineFragmentMatch { + // Offset within the line, in bytes. + int64 line_offset = 1; + + // Offset from file start, in bytes. + uint32 offset = 2; + + // Number bytes that match. + int64 match_length = 3; + + optional SymbolInfo symbol_info = 4; +} + +message SymbolInfo { + string sym = 1; + string kind = 2; + string parent = 3; + string parent_kind = 4; +} + +message ChunkMatch { + // A contiguous range of complete lines that fully contains Ranges. + bytes content = 1; + // The location (inclusive) of the beginning of content + // relative to the beginning of the file. It will always be at the + // beginning of a line (Column will always be 1). + Location content_start = 2; + + // True if this match is a match on the file name, in + // which case Content will contain the file name. + bool file_name = 3; + + // A set of matching ranges within this chunk. Each range is relative + // to the beginning of the file (not the beginning of Content). + repeated Range ranges = 4; + + // The symbol information associated with Ranges. If it is non-nil, + // its length will equal that of Ranges. Any of its elements may be nil. + repeated SymbolInfo symbol_info = 5; + + double score = 6; + string debug_score = 7; +} + +message Range { + // The inclusive beginning of the range. + Location start = 1; + // The exclusive end of the range. + Location end = 2; +} + +message Location { + // 0-based byte offset from the beginning of the file + uint32 byte_offset = 1; + // 1-based line number from the beginning of the file + uint32 line_number = 2; + // 1-based column number (in runes) from the beginning of line + uint32 column = 3; +} diff --git a/grpc/v1/webserver_grpc.pb.go b/grpc/v1/webserver_grpc.pb.go new file mode 100644 index 000000000..417519afc --- /dev/null +++ b/grpc/v1/webserver_grpc.pb.go @@ -0,0 +1,215 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc (unknown) +// source: webserver.proto + +package v1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + WebserverService_Search_FullMethodName = "/grpc.v1.WebserverService/Search" + WebserverService_StreamSearch_FullMethodName = "/grpc.v1.WebserverService/StreamSearch" + WebserverService_List_FullMethodName = "/grpc.v1.WebserverService/List" +) + +// WebserverServiceClient is the client API for WebserverService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type WebserverServiceClient interface { + Search(ctx context.Context, in *SearchRequest, opts ...grpc.CallOption) (*SearchResponse, error) + StreamSearch(ctx context.Context, in *SearchRequest, opts ...grpc.CallOption) (WebserverService_StreamSearchClient, error) + // List lists repositories. The query `q` can only contain + // query.Repo atoms. + List(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListResponse, error) +} + +type webserverServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewWebserverServiceClient(cc grpc.ClientConnInterface) WebserverServiceClient { + return &webserverServiceClient{cc} +} + +func (c *webserverServiceClient) Search(ctx context.Context, in *SearchRequest, opts ...grpc.CallOption) (*SearchResponse, error) { + out := new(SearchResponse) + err := c.cc.Invoke(ctx, WebserverService_Search_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *webserverServiceClient) StreamSearch(ctx context.Context, in *SearchRequest, opts ...grpc.CallOption) (WebserverService_StreamSearchClient, error) { + stream, err := c.cc.NewStream(ctx, &WebserverService_ServiceDesc.Streams[0], WebserverService_StreamSearch_FullMethodName, opts...) + if err != nil { + return nil, err + } + x := &webserverServiceStreamSearchClient{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 WebserverService_StreamSearchClient interface { + Recv() (*SearchResponse, error) + grpc.ClientStream +} + +type webserverServiceStreamSearchClient struct { + grpc.ClientStream +} + +func (x *webserverServiceStreamSearchClient) Recv() (*SearchResponse, error) { + m := new(SearchResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *webserverServiceClient) List(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListResponse, error) { + out := new(ListResponse) + err := c.cc.Invoke(ctx, WebserverService_List_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// WebserverServiceServer is the server API for WebserverService service. +// All implementations must embed UnimplementedWebserverServiceServer +// for forward compatibility +type WebserverServiceServer interface { + Search(context.Context, *SearchRequest) (*SearchResponse, error) + StreamSearch(*SearchRequest, WebserverService_StreamSearchServer) error + // List lists repositories. The query `q` can only contain + // query.Repo atoms. + List(context.Context, *ListRequest) (*ListResponse, error) + mustEmbedUnimplementedWebserverServiceServer() +} + +// UnimplementedWebserverServiceServer must be embedded to have forward compatible implementations. +type UnimplementedWebserverServiceServer struct { +} + +func (UnimplementedWebserverServiceServer) Search(context.Context, *SearchRequest) (*SearchResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Search not implemented") +} +func (UnimplementedWebserverServiceServer) StreamSearch(*SearchRequest, WebserverService_StreamSearchServer) error { + return status.Errorf(codes.Unimplemented, "method StreamSearch not implemented") +} +func (UnimplementedWebserverServiceServer) List(context.Context, *ListRequest) (*ListResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method List not implemented") +} +func (UnimplementedWebserverServiceServer) mustEmbedUnimplementedWebserverServiceServer() {} + +// UnsafeWebserverServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to WebserverServiceServer will +// result in compilation errors. +type UnsafeWebserverServiceServer interface { + mustEmbedUnimplementedWebserverServiceServer() +} + +func RegisterWebserverServiceServer(s grpc.ServiceRegistrar, srv WebserverServiceServer) { + s.RegisterService(&WebserverService_ServiceDesc, srv) +} + +func _WebserverService_Search_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SearchRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(WebserverServiceServer).Search(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: WebserverService_Search_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(WebserverServiceServer).Search(ctx, req.(*SearchRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _WebserverService_StreamSearch_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(SearchRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(WebserverServiceServer).StreamSearch(m, &webserverServiceStreamSearchServer{stream}) +} + +type WebserverService_StreamSearchServer interface { + Send(*SearchResponse) error + grpc.ServerStream +} + +type webserverServiceStreamSearchServer struct { + grpc.ServerStream +} + +func (x *webserverServiceStreamSearchServer) Send(m *SearchResponse) error { + return x.ServerStream.SendMsg(m) +} + +func _WebserverService_List_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(WebserverServiceServer).List(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: WebserverService_List_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(WebserverServiceServer).List(ctx, req.(*ListRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// WebserverService_ServiceDesc is the grpc.ServiceDesc for WebserverService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var WebserverService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "grpc.v1.WebserverService", + HandlerType: (*WebserverServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Search", + Handler: _WebserverService_Search_Handler, + }, + { + MethodName: "List", + Handler: _WebserverService_List_Handler, + }, + }, + Streams: []grpc.StreamDesc{ + { + StreamName: "StreamSearch", + Handler: _WebserverService_StreamSearch_Handler, + ServerStreams: true, + }, + }, + Metadata: "webserver.proto", +} diff --git a/query/BUILD.bazel b/query/BUILD.bazel index fc8776b30..3f577886f 100644 --- a/query/BUILD.bazel +++ b/query/BUILD.bazel @@ -7,11 +7,13 @@ go_library( "marshal.go", "parse.go", "query.go", + "query_proto.go", "regexp.go", ], importpath = "github.com/sourcegraph/zoekt/query", visibility = ["//visibility:public"], deps = [ + "//grpc/v1:grpc", "@com_github_go_enry_go_enry_v2//:go-enry", "@com_github_grafana_regexp//:regexp", "@com_github_roaringbitmap_roaring//:roaring", @@ -23,6 +25,7 @@ go_test( srcs = [ "marshal_test.go", "parse_test.go", + "query_proto_test.go", "query_test.go", "regexp_test.go", ], diff --git a/query/query_proto.go b/query/query_proto.go new file mode 100644 index 000000000..b5433863d --- /dev/null +++ b/query/query_proto.go @@ -0,0 +1,458 @@ +package query + +import ( + "fmt" + "regexp/syntax" + + "github.com/RoaringBitmap/roaring" + "github.com/grafana/regexp" + v1 "github.com/sourcegraph/zoekt/grpc/v1" +) + +func QToProto(q Q) *v1.Q { + switch v := q.(type) { + case RawConfig: + return &v1.Q{Query: &v1.Q_RawConfig{RawConfig: v.ToProto()}} + case *Regexp: + return &v1.Q{Query: &v1.Q_Regexp{Regexp: v.ToProto()}} + case *Symbol: + return &v1.Q{Query: &v1.Q_Symbol{Symbol: v.ToProto()}} + case *Language: + return &v1.Q{Query: &v1.Q_Language{Language: v.ToProto()}} + case *Const: + return &v1.Q{Query: &v1.Q_Const{Const: v.Value}} + case *Repo: + return &v1.Q{Query: &v1.Q_Repo{Repo: v.ToProto()}} + case *RepoRegexp: + return &v1.Q{Query: &v1.Q_RepoRegexp{RepoRegexp: v.ToProto()}} + case *BranchesRepos: + return &v1.Q{Query: &v1.Q_BranchesRepos{BranchesRepos: v.ToProto()}} + case *RepoIDs: + return &v1.Q{Query: &v1.Q_RepoIds{RepoIds: v.ToProto()}} + case *RepoSet: + return &v1.Q{Query: &v1.Q_RepoSet{RepoSet: v.ToProto()}} + case *FileNameSet: + return &v1.Q{Query: &v1.Q_FileNameSet{FileNameSet: v.ToProto()}} + case *Type: + return &v1.Q{Query: &v1.Q_Type{Type: v.ToProto()}} + case *Substring: + return &v1.Q{Query: &v1.Q_Substring{Substring: v.ToProto()}} + case *And: + return &v1.Q{Query: &v1.Q_And{And: v.ToProto()}} + case *Or: + return &v1.Q{Query: &v1.Q_Or{Or: v.ToProto()}} + case *Not: + return &v1.Q{Query: &v1.Q_Not{Not: v.ToProto()}} + case *Branch: + return &v1.Q{Query: &v1.Q_Branch{Branch: v.ToProto()}} + default: + // The following nodes do not have a proto representation: + // - GobCache: only needed for Gob encoding + // - caseQ: only used internally, not by the RPC layer + panic(fmt.Sprintf("unknown query node %T", v)) + } +} + +func QFromProto(p *v1.Q) (Q, error) { + switch v := p.Query.(type) { + case *v1.Q_RawConfig: + return RawConfigFromProto(v.RawConfig), nil + case *v1.Q_Regexp: + return RegexpFromProto(v.Regexp) + case *v1.Q_Symbol: + return SymbolFromProto(v.Symbol) + case *v1.Q_Language: + return LanguageFromProto(v.Language), nil + case *v1.Q_Const: + return &Const{Value: v.Const}, nil + case *v1.Q_Repo: + return RepoFromProto(v.Repo) + case *v1.Q_RepoRegexp: + return RepoRegexpFromProto(v.RepoRegexp) + case *v1.Q_BranchesRepos: + return BranchesReposFromProto(v.BranchesRepos) + case *v1.Q_RepoIds: + return RepoIDsFromProto(v.RepoIds) + case *v1.Q_RepoSet: + return RepoSetFromProto(v.RepoSet), nil + case *v1.Q_FileNameSet: + return FileNameSetFromProto(v.FileNameSet), nil + case *v1.Q_Type: + return TypeFromProto(v.Type) + case *v1.Q_Substring: + return SubstringFromProto(v.Substring), nil + case *v1.Q_And: + return AndFromProto(v.And) + case *v1.Q_Or: + return OrFromProto(v.Or) + case *v1.Q_Not: + return NotFromProto(v.Not) + case *v1.Q_Branch: + return BranchFromProto(v.Branch), nil + default: + panic(fmt.Sprintf("unknown query node %T", p.Query)) + } +} + +func RegexpFromProto(p *v1.Regexp) (*Regexp, error) { + parsed, err := syntax.Parse(p.GetRegexp(), regexpFlags) + if err != nil { + return nil, err + } + return &Regexp{ + Regexp: parsed, + FileName: p.GetFileName(), + Content: p.GetContent(), + CaseSensitive: p.GetCaseSensitive(), + }, nil +} + +func (r *Regexp) ToProto() *v1.Regexp { + return &v1.Regexp{ + Regexp: r.Regexp.String(), + FileName: r.FileName, + Content: r.Content, + CaseSensitive: r.CaseSensitive, + } +} + +func SymbolFromProto(p *v1.Symbol) (*Symbol, error) { + expr, err := QFromProto(p.GetExpr()) + if err != nil { + return nil, err + } + + return &Symbol{ + Expr: expr, + }, nil +} + +func (s *Symbol) ToProto() *v1.Symbol { + return &v1.Symbol{ + Expr: QToProto(s.Expr), + } +} + +func LanguageFromProto(p *v1.Language) *Language { + return &Language{ + Language: p.GetLanguage(), + } +} + +func (l *Language) ToProto() *v1.Language { + return &v1.Language{Language: l.Language} +} + +func RepoFromProto(p *v1.Repo) (*Repo, error) { + r, err := regexp.Compile(p.GetRegexp()) + if err != nil { + return nil, err + } + return &Repo{ + Regexp: r, + }, nil +} + +func (q *Repo) ToProto() *v1.Repo { + return &v1.Repo{ + Regexp: q.Regexp.String(), + } +} + +func RepoRegexpFromProto(p *v1.RepoRegexp) (*RepoRegexp, error) { + r, err := regexp.Compile(p.GetRegexp()) + if err != nil { + return nil, err + } + return &RepoRegexp{ + Regexp: r, + }, nil +} + +func (q *RepoRegexp) ToProto() *v1.RepoRegexp { + return &v1.RepoRegexp{ + Regexp: q.Regexp.String(), + } +} + +func BranchesReposFromProto(p *v1.BranchesRepos) (*BranchesRepos, error) { + brs := make([]BranchRepos, len(p.GetList())) + for i, br := range p.GetList() { + branchRepos, err := BranchReposFromProto(br) + if err != nil { + return nil, err + } + brs[i] = branchRepos + } + return &BranchesRepos{ + List: brs, + }, nil +} + +func (br *BranchesRepos) ToProto() *v1.BranchesRepos { + list := make([]*v1.BranchRepos, len(br.List)) + for i, branchRepo := range br.List { + list[i] = branchRepo.ToProto() + } + + return &v1.BranchesRepos{ + List: list, + } +} + +func RepoIDsFromProto(p *v1.RepoIds) (*RepoIDs, error) { + bm := roaring.NewBitmap() + err := bm.UnmarshalBinary(p.GetRepos()) + if err != nil { + return nil, err + } + + return &RepoIDs{ + Repos: bm, + }, nil +} + +func (q *RepoIDs) ToProto() *v1.RepoIds { + b, err := q.Repos.ToBytes() + if err != nil { + panic("unexpected error marshalling bitmap: " + err.Error()) + } + return &v1.RepoIds{ + Repos: b, + } +} + +func BranchReposFromProto(p *v1.BranchRepos) (BranchRepos, error) { + bm := roaring.NewBitmap() + err := bm.UnmarshalBinary(p.GetRepos()) + if err != nil { + return BranchRepos{}, err + } + return BranchRepos{ + Branch: p.GetBranch(), + Repos: bm, + }, nil +} + +func (br *BranchRepos) ToProto() *v1.BranchRepos { + b, err := br.Repos.ToBytes() + if err != nil { + panic("unexpected error marshalling bitmap: " + err.Error()) + } + + return &v1.BranchRepos{ + Branch: br.Branch, + Repos: b, + } +} + +func RepoSetFromProto(p *v1.RepoSet) *RepoSet { + return &RepoSet{ + Set: p.GetSet(), + } +} + +func (q *RepoSet) ToProto() *v1.RepoSet { + return &v1.RepoSet{ + Set: q.Set, + } +} + +func FileNameSetFromProto(p *v1.FileNameSet) *FileNameSet { + m := make(map[string]struct{}, len(p.GetSet())) + for _, name := range p.GetSet() { + m[name] = struct{}{} + } + return &FileNameSet{ + Set: m, + } +} + +func (q *FileNameSet) ToProto() *v1.FileNameSet { + s := make([]string, 0, len(q.Set)) + for name := range q.Set { + s = append(s, name) + } + return &v1.FileNameSet{ + Set: s, + } +} + +func TypeFromProto(p *v1.Type) (*Type, error) { + child, err := QFromProto(p.GetChild()) + if err != nil { + return nil, err + } + + var kind uint8 + switch p.GetType() { + case v1.Type_FILE_MATCH: + kind = TypeFileMatch + case v1.Type_FILE_NAME: + kind = TypeFileName + case v1.Type_REPO: + kind = TypeRepo + } + + return &Type{ + Child: child, + // TODO: make proper enum types + Type: kind, + }, nil +} + +func (q *Type) ToProto() *v1.Type { + var kind v1.Type_Kind + switch q.Type { + case TypeFileMatch: + kind = v1.Type_FILE_MATCH + case TypeFileName: + kind = v1.Type_FILE_NAME + case TypeRepo: + kind = v1.Type_REPO + } + + return &v1.Type{ + Child: QToProto(q.Child), + Type: kind, + } +} + +func SubstringFromProto(p *v1.Substring) *Substring { + return &Substring{ + Pattern: p.GetPattern(), + CaseSensitive: p.GetCaseSensitive(), + FileName: p.GetFileName(), + Content: p.GetContent(), + } +} + +func (q *Substring) ToProto() *v1.Substring { + return &v1.Substring{ + Pattern: q.Pattern, + CaseSensitive: q.CaseSensitive, + FileName: q.FileName, + Content: q.Content, + } +} + +func OrFromProto(p *v1.Or) (*Or, error) { + children := make([]Q, len(p.GetChildren())) + for i, child := range p.GetChildren() { + c, err := QFromProto(child) + if err != nil { + return nil, err + } + children[i] = c + } + return &Or{ + Children: children, + }, nil +} + +func (q *Or) ToProto() *v1.Or { + children := make([]*v1.Q, len(q.Children)) + for i, child := range q.Children { + children[i] = QToProto(child) + } + return &v1.Or{ + Children: children, + } +} + +func NotFromProto(p *v1.Not) (*Not, error) { + child, err := QFromProto(p.GetChild()) + if err != nil { + return nil, err + } + return &Not{ + Child: child, + }, nil +} + +func (q *Not) ToProto() *v1.Not { + return &v1.Not{ + Child: QToProto(q.Child), + } +} + +func AndFromProto(p *v1.And) (*And, error) { + children := make([]Q, len(p.GetChildren())) + for i, child := range p.GetChildren() { + c, err := QFromProto(child) + if err != nil { + return nil, err + } + children[i] = c + } + return &And{ + Children: children, + }, nil +} + +func (q *And) ToProto() *v1.And { + children := make([]*v1.Q, len(q.Children)) + for i, child := range q.Children { + children[i] = QToProto(child) + } + return &v1.And{ + Children: children, + } +} + +func BranchFromProto(p *v1.Branch) *Branch { + return &Branch{ + Pattern: p.GetPattern(), + Exact: p.GetExact(), + } +} + +func (q *Branch) ToProto() *v1.Branch { + return &v1.Branch{ + Pattern: q.Pattern, + Exact: q.Exact, + } +} + +func RawConfigFromProto(p *v1.RawConfig) (res RawConfig) { + for _, protoFlag := range p.Flags { + switch protoFlag { + case v1.RawConfig_ONLY_PUBLIC: + res |= RcOnlyPublic + case v1.RawConfig_ONLY_PRIVATE: + res |= RcOnlyPrivate + case v1.RawConfig_ONLY_FORKS: + res |= RcOnlyForks + case v1.RawConfig_NO_FORKS: + res |= RcNoForks + case v1.RawConfig_ONLY_ARCHIVED: + res |= RcOnlyArchived + case v1.RawConfig_NO_ARCHIVED: + res |= RcNoArchived + } + } + return res +} + +func (r RawConfig) ToProto() *v1.RawConfig { + var flags []v1.RawConfig_Flag + for _, flag := range flagNames { + if r&flag.Mask != 0 { + switch flag.Mask { + case RcOnlyPublic: + flags = append(flags, v1.RawConfig_ONLY_PUBLIC) + case RcOnlyPrivate: + flags = append(flags, v1.RawConfig_ONLY_PRIVATE) + case RcOnlyForks: + flags = append(flags, v1.RawConfig_ONLY_FORKS) + case RcNoForks: + flags = append(flags, v1.RawConfig_NO_FORKS) + case RcOnlyArchived: + flags = append(flags, v1.RawConfig_ONLY_ARCHIVED) + case RcNoArchived: + flags = append(flags, v1.RawConfig_NO_ARCHIVED) + } + } + } + return &v1.RawConfig{Flags: flags} +} diff --git a/query/query_proto_test.go b/query/query_proto_test.go new file mode 100644 index 000000000..c5f0065fe --- /dev/null +++ b/query/query_proto_test.go @@ -0,0 +1,99 @@ +package query + +import ( + "regexp/syntax" + "testing" + + "github.com/RoaringBitmap/roaring" + "github.com/google/go-cmp/cmp" + "github.com/grafana/regexp" +) + +func TestQueryRoundtrip(t *testing.T) { + testCases := []Q{ + &Regexp{ + Regexp: regexpMustParse("foo"), + FileName: true, + Content: true, + CaseSensitive: true, + }, + &Symbol{ + Expr: &Language{ + Language: "go", + }, + }, + &Language{ + Language: "typescript", + }, + &Const{ + Value: true, + }, + &Repo{ + Regexp: regexp.MustCompile("github.com/foo/bar"), + }, + &RepoRegexp{ + Regexp: regexp.MustCompile("github.com/foo.*"), + }, + &BranchesRepos{ + List: []BranchRepos{{ + Branch: "test", + Repos: func() *roaring.Bitmap { + bm := roaring.New() + bm.Add(3) + bm.Add(34) + return bm + }(), + }}, + }, + NewRepoIDs(3, 4, 5), + &Branch{ + Pattern: "master", + Exact: true, + }, + NewRepoSet("test1", "test2"), + NewFileNameSet("test3", "test4"), + &And{ + Children: []Q{ + &Language{Language: "go"}, + &Type{ + Child: &Substring{Pattern: "interface"}, + Type: TypeFileMatch, + }, + }, + }, + &Or{ + Children: []Q{ + &Language{Language: "go"}, + &Type{ + Child: &Substring{Pattern: "interface"}, + Type: TypeFileMatch, + }, + }, + }, + &Not{ + Child: &Language{Language: "go"}, + }, + } + + for _, q := range testCases { + t.Run("", func(t *testing.T) { + protoQ := QToProto(q) + q2, err := QFromProto(protoQ) + if err != nil { + t.Fatal(err) + } + if diff := cmp.Diff(q.String(), q2.String()); diff != "" { + t.Fatalf("unexpected diff: %s", diff) + } + }) + } + +} + +func regexpMustParse(s string) *syntax.Regexp { + re, err := syntax.Parse(s, syntax.Perl) + if err != nil { + panic(err) + } + return re +} diff --git a/testdata/search_result_1.pb b/testdata/search_result_1.pb new file mode 100755 index 0000000000000000000000000000000000000000..0d3006d1ae454973beb3ec7102300433d292b4c0 GIT binary patch literal 7252 zcmdT}dvH|M8E2Ou*;VVZT0khB(;Zp^hTQ~2AWdRI2u&m*NJ3RQnmK#-?Cxdn-m~6E zmXJE4))_ilwb(ixkhY2sS`;hOv8C-4tgYJC$M_gqd`%x}9Z&?V*g6*b`_8?)d6Y+X z{Hr?yeD~aY&pG$^{l4G#osaOe>NoCQ7q)lW^4**hAvFUPS}=~aD?q7*6{(JkX9za3tY>JM2@F( zJfX>aUYZG8Xs)F@g9*u9Cz}-95>`St9buW=uoJGS9uTQSPb=;(RrlAF2D@ZNH`};j zB)OLB;AYAYRv(s((~_}i8Qsac$v9RTwe;Moj`r4N4TIrJ7=8seY3Ldoka~*cbyLrC zqfh39Su=+@SxXje*4fj(UK0gJmu4-)+HRpBEk~qE3zzS*q3Go5m(GoJO%KGP;mOqp z$ee<)BV+|ISCK{O19+vIPYSCi zO)J=!W`()R5(Bz)ZDX)CiO1TADIi6wnOZ4|ZHiE>sgy{;DMQgv^<8@ck=d1^RR z{VVTcCdME2%$SGtcOM#!^qP6w+xOh@MxkP)KM98F&$wja=l-y%WyYB)so4oxu;W=L zZ=8x_8-w9z0t82+p*I`c$_QOHu)eHrGoDTh&9Ol;!3vg03(FEI)|u#Gw!T3yOL!z> z$wBpq?Qn-_pn9BLn$-<~K}@1?lVMC2Sz1~wt7o#pVg+I0D$h+#FljQiti@8gonu9W zny_n`ZemTY!Oeo{4$JZ~_Zj9fB@=3Q^!kX|;*AM>25{cG>$J%8VcxcguKaIf0pvq! zZi;0rJ=Nb2{m%FIYd~A(h1K7m61HaP9vEUhbfv%FhH8jdb0cS25{v6%%%NQ6G{yRp1~+rD=C00_?aZ~ooK{uD zd4y_A@MZ>iN)@p{Eq2E(EsMB?k0?Be-t+}9xG`w!cATjXHv~dSZNrPBUeCGo6_zk`P#1bj zl1_P7&63s)3I|6Pbj|kIO$*q7#veoU+b&$_C2{0iU8A}gGx>LFA*9?as$_4GXH>2b z+#W>Op+d$V4yaHjQCyojg|Uu`!j=Wp21=y>%%FfGdu119PC=fyEs)6z&C%-W13i&# z0bgkL^^yIjD#Xv@%6zS=EHtAk)}?2Bw6%TzzcyAJCHsP*dk-!QedjlblID@e1p1zn z9}^Vr%U#E{#JGz4TLa;&ilMn|s6~DDh{C<6Bo^h${c5CB@{g+c%{Z!jLx-|)7W1Kt zm8NNvq|y$lmA9R%Yf<3uo*gj&BNhE0lDQmX$H?eDK7^P3>V=vQhjWp_|Dn8rabfQZ|$rYpXY+1 z`w!V0*>2#o5*kTSdn#;7j}4zXNeo*H1r$>~mJZPz7fzc4;dMUc`jGT72jglEROxw2 ze3o=GSqMe}=S?r?r!ASs4LmGR%R&a#$pG~h9x$K;l#F$VUkPQ@q&oBo0LKB~i<2YM zeNZ2$hItvreo99F@k!UQ*L~`U`P}y}|z!^6C3a4~|NL@PUl;-h@6+*EDlMTs39zh+Nm3XOKpZQ0r zUQ7kehd!r~DC4ZxJJ3`7_jUD>d;`e6!{EL}=3I=uOGf?i!QC;tbwS-9AG)PtaDOy0 zbp5@xD_+?NaC^rKuHRzuGsVbL{Av`V=zyrB&A1TGhFg5rQuZSlshJ|vIFAr?6dYc9 zrPNYF7z+=VuEfP{XGJdbx%fDl=VRemx`qGT%@AgWeuac5>ng!Rn6i1y7HRB3F4JX`jMa`TB z)Bre;H>sZ9b!SDE_yoI&%+o=z+sKF>AD0!YhGxFMZf8|;QZIc?1&xlICxs5(!`AHB z3}BXyWSGL{q@C0eC6dBsJU!5Dfv_AyrM9flaw;y{mNS*0hEJ@1@q_#WeaR4ggl(Qj zeJRx7s4i7$guA4^6xmW`PaF$I>l-@BNN@xOTH`DIWW?hAzZ$o+LI zNiWM#6Z@ZXEUr#VaU5Qj37F6>@12@bB{$|9VspNXmG6Bu5P7$>qdnfmIT+vPnKM;b z9P%zYG5&#PuBzYpWBe|@rlkP|XL96D$1Kx`BLgI>nc+0h#A;4(cMj6h0GbCqRv)#V zYkaw_C1}&Gqqe%~wLs)>X{-Cai`4|4XI@^vhJNj1PPRMmjK2R|^h@h1j?_cJ(B>!J z+&%Yt5b}yr`5IQ!;Uc?(xl+h&;JHcqXYm{;EK zJe(nO2=|ZAjx6>i;Kg%behp)a*XT@L z>g(5lp_8j$pBCxyp}KK8%o>bsCL?itsBS(wZT8;zo!3nCopzh5cnv6