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