fork of https://github.com/sourcegraph/zoekt
0

Configure Feed

Select the types of activity you want to include in your feed.

1package query 2 3import ( 4 "fmt" 5 "regexp/syntax" 6 7 "github.com/RoaringBitmap/roaring" 8 "github.com/grafana/regexp" 9 proto "github.com/sourcegraph/zoekt/grpc/protos/zoekt/webserver/v1" 10) 11 12func QToProto(q Q) *proto.Q { 13 switch v := q.(type) { 14 case RawConfig: 15 return &proto.Q{Query: &proto.Q_RawConfig{RawConfig: v.ToProto()}} 16 case *Regexp: 17 return &proto.Q{Query: &proto.Q_Regexp{Regexp: v.ToProto()}} 18 case *Symbol: 19 return &proto.Q{Query: &proto.Q_Symbol{Symbol: v.ToProto()}} 20 case *Language: 21 return &proto.Q{Query: &proto.Q_Language{Language: v.ToProto()}} 22 case *Const: 23 return &proto.Q{Query: &proto.Q_Const{Const: v.Value}} 24 case *Repo: 25 return &proto.Q{Query: &proto.Q_Repo{Repo: v.ToProto()}} 26 case *RepoRegexp: 27 return &proto.Q{Query: &proto.Q_RepoRegexp{RepoRegexp: v.ToProto()}} 28 case *BranchesRepos: 29 return &proto.Q{Query: &proto.Q_BranchesRepos{BranchesRepos: v.ToProto()}} 30 case *RepoIDs: 31 return &proto.Q{Query: &proto.Q_RepoIds{RepoIds: v.ToProto()}} 32 case *RepoSet: 33 return &proto.Q{Query: &proto.Q_RepoSet{RepoSet: v.ToProto()}} 34 case *FileNameSet: 35 return &proto.Q{Query: &proto.Q_FileNameSet{FileNameSet: v.ToProto()}} 36 case *Type: 37 return &proto.Q{Query: &proto.Q_Type{Type: v.ToProto()}} 38 case *Substring: 39 return &proto.Q{Query: &proto.Q_Substring{Substring: v.ToProto()}} 40 case *And: 41 return &proto.Q{Query: &proto.Q_And{And: v.ToProto()}} 42 case *Or: 43 return &proto.Q{Query: &proto.Q_Or{Or: v.ToProto()}} 44 case *Not: 45 return &proto.Q{Query: &proto.Q_Not{Not: v.ToProto()}} 46 case *Branch: 47 return &proto.Q{Query: &proto.Q_Branch{Branch: v.ToProto()}} 48 default: 49 // The following nodes do not have a proto representation: 50 // - GobCache: only needed for Gob encoding 51 // - caseQ: only used internally, not by the RPC layer 52 panic(fmt.Sprintf("unknown query node %T", v)) 53 } 54} 55 56func QFromProto(p *proto.Q) (Q, error) { 57 switch v := p.Query.(type) { 58 case *proto.Q_RawConfig: 59 return RawConfigFromProto(v.RawConfig), nil 60 case *proto.Q_Regexp: 61 return RegexpFromProto(v.Regexp) 62 case *proto.Q_Symbol: 63 return SymbolFromProto(v.Symbol) 64 case *proto.Q_Language: 65 return LanguageFromProto(v.Language), nil 66 case *proto.Q_Const: 67 return &Const{Value: v.Const}, nil 68 case *proto.Q_Repo: 69 return RepoFromProto(v.Repo) 70 case *proto.Q_RepoRegexp: 71 return RepoRegexpFromProto(v.RepoRegexp) 72 case *proto.Q_BranchesRepos: 73 return BranchesReposFromProto(v.BranchesRepos) 74 case *proto.Q_RepoIds: 75 return RepoIDsFromProto(v.RepoIds) 76 case *proto.Q_RepoSet: 77 return RepoSetFromProto(v.RepoSet), nil 78 case *proto.Q_FileNameSet: 79 return FileNameSetFromProto(v.FileNameSet), nil 80 case *proto.Q_Type: 81 return TypeFromProto(v.Type) 82 case *proto.Q_Substring: 83 return SubstringFromProto(v.Substring), nil 84 case *proto.Q_And: 85 return AndFromProto(v.And) 86 case *proto.Q_Or: 87 return OrFromProto(v.Or) 88 case *proto.Q_Not: 89 return NotFromProto(v.Not) 90 case *proto.Q_Branch: 91 return BranchFromProto(v.Branch), nil 92 default: 93 panic(fmt.Sprintf("unknown query node %T", p.Query)) 94 } 95} 96 97func RegexpFromProto(p *proto.Regexp) (*Regexp, error) { 98 parsed, err := syntax.Parse(p.GetRegexp(), regexpFlags) 99 if err != nil { 100 return nil, err 101 } 102 return &Regexp{ 103 Regexp: parsed, 104 FileName: p.GetFileName(), 105 Content: p.GetContent(), 106 CaseSensitive: p.GetCaseSensitive(), 107 }, nil 108} 109 110func (r *Regexp) ToProto() *proto.Regexp { 111 return &proto.Regexp{ 112 Regexp: r.Regexp.String(), 113 FileName: r.FileName, 114 Content: r.Content, 115 CaseSensitive: r.CaseSensitive, 116 } 117} 118 119func SymbolFromProto(p *proto.Symbol) (*Symbol, error) { 120 expr, err := QFromProto(p.GetExpr()) 121 if err != nil { 122 return nil, err 123 } 124 125 return &Symbol{ 126 Expr: expr, 127 }, nil 128} 129 130func (s *Symbol) ToProto() *proto.Symbol { 131 return &proto.Symbol{ 132 Expr: QToProto(s.Expr), 133 } 134} 135 136func LanguageFromProto(p *proto.Language) *Language { 137 return &Language{ 138 Language: p.GetLanguage(), 139 } 140} 141 142func (l *Language) ToProto() *proto.Language { 143 return &proto.Language{Language: l.Language} 144} 145 146func RepoFromProto(p *proto.Repo) (*Repo, error) { 147 r, err := regexp.Compile(p.GetRegexp()) 148 if err != nil { 149 return nil, err 150 } 151 return &Repo{ 152 Regexp: r, 153 }, nil 154} 155 156func (q *Repo) ToProto() *proto.Repo { 157 return &proto.Repo{ 158 Regexp: q.Regexp.String(), 159 } 160} 161 162func RepoRegexpFromProto(p *proto.RepoRegexp) (*RepoRegexp, error) { 163 r, err := regexp.Compile(p.GetRegexp()) 164 if err != nil { 165 return nil, err 166 } 167 return &RepoRegexp{ 168 Regexp: r, 169 }, nil 170} 171 172func (q *RepoRegexp) ToProto() *proto.RepoRegexp { 173 return &proto.RepoRegexp{ 174 Regexp: q.Regexp.String(), 175 } 176} 177 178func BranchesReposFromProto(p *proto.BranchesRepos) (*BranchesRepos, error) { 179 brs := make([]BranchRepos, len(p.GetList())) 180 for i, br := range p.GetList() { 181 branchRepos, err := BranchReposFromProto(br) 182 if err != nil { 183 return nil, err 184 } 185 brs[i] = branchRepos 186 } 187 return &BranchesRepos{ 188 List: brs, 189 }, nil 190} 191 192func (br *BranchesRepos) ToProto() *proto.BranchesRepos { 193 list := make([]*proto.BranchRepos, len(br.List)) 194 for i, branchRepo := range br.List { 195 list[i] = branchRepo.ToProto() 196 } 197 198 return &proto.BranchesRepos{ 199 List: list, 200 } 201} 202 203func RepoIDsFromProto(p *proto.RepoIds) (*RepoIDs, error) { 204 bm := roaring.NewBitmap() 205 err := bm.UnmarshalBinary(p.GetRepos()) 206 if err != nil { 207 return nil, err 208 } 209 210 return &RepoIDs{ 211 Repos: bm, 212 }, nil 213} 214 215func (q *RepoIDs) ToProto() *proto.RepoIds { 216 b, err := q.Repos.ToBytes() 217 if err != nil { 218 panic("unexpected error marshalling bitmap: " + err.Error()) 219 } 220 return &proto.RepoIds{ 221 Repos: b, 222 } 223} 224 225func BranchReposFromProto(p *proto.BranchRepos) (BranchRepos, error) { 226 bm := roaring.NewBitmap() 227 err := bm.UnmarshalBinary(p.GetRepos()) 228 if err != nil { 229 return BranchRepos{}, err 230 } 231 return BranchRepos{ 232 Branch: p.GetBranch(), 233 Repos: bm, 234 }, nil 235} 236 237func (br *BranchRepos) ToProto() *proto.BranchRepos { 238 b, err := br.Repos.ToBytes() 239 if err != nil { 240 panic("unexpected error marshalling bitmap: " + err.Error()) 241 } 242 243 return &proto.BranchRepos{ 244 Branch: br.Branch, 245 Repos: b, 246 } 247} 248 249func RepoSetFromProto(p *proto.RepoSet) *RepoSet { 250 return &RepoSet{ 251 Set: p.GetSet(), 252 } 253} 254 255func (q *RepoSet) ToProto() *proto.RepoSet { 256 return &proto.RepoSet{ 257 Set: q.Set, 258 } 259} 260 261func FileNameSetFromProto(p *proto.FileNameSet) *FileNameSet { 262 m := make(map[string]struct{}, len(p.GetSet())) 263 for _, name := range p.GetSet() { 264 m[name] = struct{}{} 265 } 266 return &FileNameSet{ 267 Set: m, 268 } 269} 270 271func (q *FileNameSet) ToProto() *proto.FileNameSet { 272 s := make([]string, 0, len(q.Set)) 273 for name := range q.Set { 274 s = append(s, name) 275 } 276 return &proto.FileNameSet{ 277 Set: s, 278 } 279} 280 281func TypeFromProto(p *proto.Type) (*Type, error) { 282 child, err := QFromProto(p.GetChild()) 283 if err != nil { 284 return nil, err 285 } 286 287 var kind uint8 288 switch p.GetType() { 289 case proto.Type_KIND_FILE_MATCH: 290 kind = TypeFileMatch 291 case proto.Type_KIND_FILE_NAME: 292 kind = TypeFileName 293 case proto.Type_KIND_REPO: 294 kind = TypeRepo 295 } 296 297 return &Type{ 298 Child: child, 299 // TODO: make proper enum types 300 Type: kind, 301 }, nil 302} 303 304func (q *Type) ToProto() *proto.Type { 305 var kind proto.Type_Kind 306 switch q.Type { 307 case TypeFileMatch: 308 kind = proto.Type_KIND_FILE_MATCH 309 case TypeFileName: 310 kind = proto.Type_KIND_FILE_NAME 311 case TypeRepo: 312 kind = proto.Type_KIND_REPO 313 } 314 315 return &proto.Type{ 316 Child: QToProto(q.Child), 317 Type: kind, 318 } 319} 320 321func SubstringFromProto(p *proto.Substring) *Substring { 322 return &Substring{ 323 Pattern: p.GetPattern(), 324 CaseSensitive: p.GetCaseSensitive(), 325 FileName: p.GetFileName(), 326 Content: p.GetContent(), 327 } 328} 329 330func (q *Substring) ToProto() *proto.Substring { 331 return &proto.Substring{ 332 Pattern: q.Pattern, 333 CaseSensitive: q.CaseSensitive, 334 FileName: q.FileName, 335 Content: q.Content, 336 } 337} 338 339func OrFromProto(p *proto.Or) (*Or, error) { 340 children := make([]Q, len(p.GetChildren())) 341 for i, child := range p.GetChildren() { 342 c, err := QFromProto(child) 343 if err != nil { 344 return nil, err 345 } 346 children[i] = c 347 } 348 return &Or{ 349 Children: children, 350 }, nil 351} 352 353func (q *Or) ToProto() *proto.Or { 354 children := make([]*proto.Q, len(q.Children)) 355 for i, child := range q.Children { 356 children[i] = QToProto(child) 357 } 358 return &proto.Or{ 359 Children: children, 360 } 361} 362 363func NotFromProto(p *proto.Not) (*Not, error) { 364 child, err := QFromProto(p.GetChild()) 365 if err != nil { 366 return nil, err 367 } 368 return &Not{ 369 Child: child, 370 }, nil 371} 372 373func (q *Not) ToProto() *proto.Not { 374 return &proto.Not{ 375 Child: QToProto(q.Child), 376 } 377} 378 379func AndFromProto(p *proto.And) (*And, error) { 380 children := make([]Q, len(p.GetChildren())) 381 for i, child := range p.GetChildren() { 382 c, err := QFromProto(child) 383 if err != nil { 384 return nil, err 385 } 386 children[i] = c 387 } 388 return &And{ 389 Children: children, 390 }, nil 391} 392 393func (q *And) ToProto() *proto.And { 394 children := make([]*proto.Q, len(q.Children)) 395 for i, child := range q.Children { 396 children[i] = QToProto(child) 397 } 398 return &proto.And{ 399 Children: children, 400 } 401} 402 403func BranchFromProto(p *proto.Branch) *Branch { 404 return &Branch{ 405 Pattern: p.GetPattern(), 406 Exact: p.GetExact(), 407 } 408} 409 410func (q *Branch) ToProto() *proto.Branch { 411 return &proto.Branch{ 412 Pattern: q.Pattern, 413 Exact: q.Exact, 414 } 415} 416 417func RawConfigFromProto(p *proto.RawConfig) (res RawConfig) { 418 for _, protoFlag := range p.Flags { 419 switch protoFlag { 420 case proto.RawConfig_FLAG_ONLY_PUBLIC: 421 res |= RcOnlyPublic 422 case proto.RawConfig_FLAG_ONLY_PRIVATE: 423 res |= RcOnlyPrivate 424 case proto.RawConfig_FLAG_ONLY_FORKS: 425 res |= RcOnlyForks 426 case proto.RawConfig_FLAG_NO_FORKS: 427 res |= RcNoForks 428 case proto.RawConfig_FLAG_ONLY_ARCHIVED: 429 res |= RcOnlyArchived 430 case proto.RawConfig_FLAG_NO_ARCHIVED: 431 res |= RcNoArchived 432 } 433 } 434 return res 435} 436 437func (r RawConfig) ToProto() *proto.RawConfig { 438 var flags []proto.RawConfig_Flag 439 for _, flag := range flagNames { 440 if r&flag.Mask != 0 { 441 switch flag.Mask { 442 case RcOnlyPublic: 443 flags = append(flags, proto.RawConfig_FLAG_ONLY_PUBLIC) 444 case RcOnlyPrivate: 445 flags = append(flags, proto.RawConfig_FLAG_ONLY_PRIVATE) 446 case RcOnlyForks: 447 flags = append(flags, proto.RawConfig_FLAG_ONLY_FORKS) 448 case RcNoForks: 449 flags = append(flags, proto.RawConfig_FLAG_NO_FORKS) 450 case RcOnlyArchived: 451 flags = append(flags, proto.RawConfig_FLAG_ONLY_ARCHIVED) 452 case RcNoArchived: 453 flags = append(flags, proto.RawConfig_FLAG_NO_ARCHIVED) 454 } 455 } 456 } 457 return &proto.RawConfig{Flags: flags} 458}