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