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