github.com/cloudwan/edgelq-sdk@v1.15.4/limits/resources/v1alpha2/plan/plan.pb.filter.go (about) 1 // Code generated by protoc-gen-goten-resource 2 // Resource: Plan 3 // DO NOT EDIT!!! 4 5 package plan 6 7 import ( 8 "fmt" 9 "math" 10 "strings" 11 12 "google.golang.org/grpc/codes" 13 "google.golang.org/grpc/status" 14 "google.golang.org/protobuf/proto" 15 16 gotenobject "github.com/cloudwan/goten-sdk/runtime/object" 17 gotenresource "github.com/cloudwan/goten-sdk/runtime/resource" 18 filterParser "github.com/cloudwan/goten-sdk/runtime/resource/filter" 19 utils "github.com/cloudwan/goten-sdk/runtime/utils" 20 ) 21 22 // proto imports 23 import ( 24 iam_iam_common "github.com/cloudwan/edgelq-sdk/iam/resources/v1alpha2/common" 25 common "github.com/cloudwan/edgelq-sdk/limits/resources/v1alpha2/common" 26 meta_service "github.com/cloudwan/edgelq-sdk/meta/resources/v1alpha2/service" 27 meta "github.com/cloudwan/goten-sdk/types/meta" 28 ) 29 30 var ( 31 _ = new(fmt.Stringer) 32 _ = strings.Builder{} 33 _ = math.IsNaN 34 35 _ = new(proto.Message) 36 37 _ = new(gotenobject.FieldPath) 38 _ = gotenresource.WildcardId 39 ) 40 41 // make sure we're using proto imports 42 var ( 43 _ = &iam_iam_common.PCR{} 44 _ = &common.Allowance{} 45 _ = &meta_service.Service{} 46 _ = &meta.Meta{} 47 ) 48 49 type FilterCondition interface { 50 gotenresource.FilterCondition 51 _IsFilterCondition() 52 _IsPlanFilterBuilderOrCondition() 53 And(...FilterCondition) FilterCondition 54 Evaluate(res *Plan) bool 55 56 // Whether this condition is at least as specific as other. 57 // When true, any Plan that passes this condition will also pass other condition. 58 Satisfies(other FilterCondition) bool 59 60 // Checks whether condition specifies given field path 61 // Useful for blacklisting protected paths in iam policy conditions 62 SpecifiesFieldPath(fp Plan_FieldPath) bool 63 } 64 65 func AndFilterConditions(conds ...FilterCondition) FilterCondition { 66 result := &FilterConditionComposite{ 67 Operator: filterParser.AND, 68 } 69 for _, condi := range conds { 70 switch cond := condi.(type) { 71 case *FilterConditionComposite: 72 if cond.Operator == filterParser.AND { 73 result.Conditions = append(result.Conditions, cond.Conditions...) 74 continue 75 } 76 default: 77 } 78 result.Conditions = append(result.Conditions, condi) 79 } 80 return result 81 } 82 83 type FilterConditionComposite struct { 84 Operator filterParser.CompositeOperator 85 Conditions []FilterCondition 86 } 87 88 func (cond *FilterConditionComposite) String() string { 89 substrs := make([]string, 0, len(cond.Conditions)) 90 for _, subcond := range cond.Conditions { 91 substrs = append(substrs, subcond.String()) 92 } 93 sep := fmt.Sprintf(" %s ", cond.Operator) 94 return "(" + strings.Join(substrs, sep) + ")" 95 } 96 97 func (cond *FilterConditionComposite) _IsFilterCondition() {} 98 99 func (cond *FilterConditionComposite) _IsPlanFilterBuilderOrCondition() {} 100 101 func (cond *FilterConditionComposite) And(conds ...FilterCondition) FilterCondition { 102 return AndFilterConditions(append([]FilterCondition{cond}, conds...)...) 103 } 104 105 func (cond *FilterConditionComposite) Evaluate(res *Plan) bool { 106 switch cond.Operator { 107 case filterParser.OR: 108 for _, subCond := range cond.Conditions { 109 if subCond.Evaluate(res) { 110 return true 111 } 112 } 113 return false 114 case filterParser.AND: 115 for _, subCond := range cond.Conditions { 116 if !subCond.Evaluate(res) { 117 return false 118 } 119 } 120 return true 121 default: 122 panic(fmt.Sprintf("Unsupported composite condition operator: %s", cond.Operator)) 123 } 124 } 125 126 func (cond *FilterConditionComposite) EvaluateRaw(res gotenresource.Resource) bool { 127 if typedRes, ok := res.(*Plan); !ok { 128 return false 129 } else { 130 return cond.Evaluate(typedRes) 131 } 132 } 133 134 func (cond *FilterConditionComposite) flattenConditions() (results []FilterCondition) { 135 for _, subcnd := range cond.Conditions { 136 switch tsubcnd := subcnd.(type) { 137 case *FilterConditionComposite: 138 if tsubcnd.Operator == cond.Operator { 139 results = append(results, tsubcnd.flattenConditions()...) 140 } else { 141 results = append(results, subcnd) // take it as it is 142 } 143 default: 144 results = append(results, subcnd) 145 } 146 } 147 return 148 } 149 150 func (cond *FilterConditionComposite) Satisfies(other FilterCondition) bool { 151 flattened := cond.flattenConditions() 152 switch cond.Operator { 153 case filterParser.AND: 154 switch tother := other.(type) { 155 case *FilterConditionComposite: 156 switch tother.Operator { 157 case filterParser.AND: 158 otherFlattened := tother.flattenConditions() 159 OtherSubcnds: 160 for _, otherSubcnd := range otherFlattened { 161 for _, subcnd := range flattened { 162 if subcnd.Satisfies(otherSubcnd) { 163 continue OtherSubcnds 164 } 165 } 166 return false 167 } 168 return true 169 case filterParser.OR: 170 otherFlattened := tother.flattenConditions() 171 for _, otherSubcnd := range otherFlattened { 172 if cond.Satisfies(otherSubcnd) { 173 return true 174 } 175 } 176 return false 177 default: 178 return false 179 } 180 default: 181 for _, subcnd := range flattened { 182 if subcnd.Satisfies(other) { 183 return true 184 } 185 } 186 return false 187 } 188 default: 189 panic(fmt.Errorf("unsupported condition type %s", cond.Operator)) 190 } 191 return false 192 } 193 194 func (cond *FilterConditionComposite) SatisfiesRaw(other gotenresource.FilterCondition) bool { 195 if typedCond, ok := other.(FilterCondition); !ok { 196 return false 197 } else { 198 return cond.Satisfies(typedCond) 199 } 200 } 201 202 func (cond *FilterConditionComposite) SpecifiesFieldPath(fp Plan_FieldPath) bool { 203 for _, subcnd := range cond.Conditions { 204 if subcnd.SpecifiesFieldPath(fp) { 205 return true 206 } 207 } 208 return false 209 } 210 211 func (cond *FilterConditionComposite) SpecifiesRawFieldPath(fp gotenobject.FieldPath) bool { 212 if typedFp, ok := fp.(Plan_FieldPath); !ok { 213 return false 214 } else { 215 return cond.SpecifiesFieldPath(typedFp) 216 } 217 } 218 219 func (cond *FilterConditionComposite) GetOperator() filterParser.CompositeOperator { 220 return cond.Operator 221 } 222 223 func (cond *FilterConditionComposite) GetSubConditions() []gotenresource.FilterCondition { 224 subConds := make([]gotenresource.FilterCondition, len(cond.Conditions)) 225 for idx, subCond := range cond.Conditions { 226 subConds[idx] = subCond 227 } 228 return subConds 229 } 230 231 func (cond *FilterConditionComposite) ConditionComposite() {} 232 233 type FilterConditionNot struct { 234 FilterCondition 235 } 236 237 func (cond *FilterConditionNot) String() string { 238 return "NOT " + cond.FilterCondition.String() 239 } 240 241 func (cond *FilterConditionNot) _IsFilterCondition() {} 242 243 func (cond *FilterConditionNot) _IsPlanFilterBuilderOrCondition() {} 244 245 func (cond *FilterConditionNot) And(conds ...FilterCondition) FilterCondition { 246 return AndFilterConditions(append([]FilterCondition{cond}, conds...)...) 247 } 248 249 func (cond *FilterConditionNot) Evaluate(res *Plan) bool { 250 return !cond.FilterCondition.Evaluate(res) 251 } 252 253 func (cond *FilterConditionNot) EvaluateRaw(res gotenresource.Resource) bool { 254 if typedRes, ok := res.(*Plan); !ok { 255 return false 256 } else { 257 return cond.Evaluate(typedRes) 258 } 259 } 260 261 func (cond *FilterConditionNot) Satisfies(other FilterCondition) bool { 262 switch tother := other.(type) { 263 case *FilterConditionNot: 264 return cond.FilterCondition.Satisfies(tother.FilterCondition) 265 default: 266 return !cond.FilterCondition.Satisfies(other) 267 } 268 } 269 270 func (cond *FilterConditionNot) SatisfiesRaw(other gotenresource.FilterCondition) bool { 271 if typedCond, ok := other.(FilterCondition); !ok { 272 return false 273 } else { 274 return cond.Satisfies(typedCond) 275 } 276 } 277 278 func (cond *FilterConditionNot) SpecifiesFieldPath(fp Plan_FieldPath) bool { 279 return cond.FilterCondition.SpecifiesFieldPath(fp) 280 } 281 282 func (cond *FilterConditionNot) SpecifiesRawFieldPath(fp gotenobject.FieldPath) bool { 283 if typedFp, ok := fp.(Plan_FieldPath); !ok { 284 return false 285 } else { 286 return cond.SpecifiesFieldPath(typedFp) 287 } 288 } 289 290 func (cond *FilterConditionNot) GetSubCondition() gotenresource.FilterCondition { 291 return cond.FilterCondition 292 } 293 294 func (cond *FilterConditionNot) ConditionNot() {} 295 296 type FilterConditionIsNull struct { 297 Not bool 298 FieldPath Plan_FieldPath 299 } 300 301 func (cond *FilterConditionIsNull) String() string { 302 if cond.Not { 303 return cond.FieldPath.String() + " IS NOT NULL" 304 } else { 305 return cond.FieldPath.String() + " IS NULL" 306 } 307 } 308 309 func (cond *FilterConditionIsNull) _IsFilterCondition() {} 310 311 func (cond *FilterConditionIsNull) _IsPlanFilterBuilderOrCondition() {} 312 313 func (cond *FilterConditionIsNull) And(conds ...FilterCondition) FilterCondition { 314 return AndFilterConditions(append([]FilterCondition{cond}, conds...)...) 315 } 316 317 func (cond *FilterConditionIsNull) Evaluate(res *Plan) bool { 318 if v, ok := cond.FieldPath.GetSingleRaw(res); !ok { 319 return !cond.Not 320 } else { 321 return cond.Not != utils.IsNil(v) 322 } 323 } 324 325 func (cond *FilterConditionIsNull) EvaluateRaw(res gotenresource.Resource) bool { 326 if typedRes, ok := res.(*Plan); !ok { 327 return false 328 } else { 329 return cond.Evaluate(typedRes) 330 } 331 } 332 333 func (cond *FilterConditionIsNull) asCompare() FilterCondition { 334 res := &FilterConditionCompare{ 335 Operator: filterParser.Eq, 336 Plan_FieldPathValue: cond.FieldPath.WithIValue(nil), 337 } 338 if cond.Not { 339 res.Operator = filterParser.Neq 340 } 341 return res 342 } 343 344 func (cond *FilterConditionIsNull) Satisfies(other FilterCondition) bool { 345 switch tother := other.(type) { 346 case *FilterConditionIsNull: 347 return cond.FieldPath.String() == tother.FieldPath.String() && cond.Not == tother.Not 348 case *FilterConditionCompare: 349 return cond.asCompare().Satisfies(tother) 350 default: 351 return false 352 } 353 } 354 355 func (cond *FilterConditionIsNull) SatisfiesRaw(other gotenresource.FilterCondition) bool { 356 if typedCond, ok := other.(FilterCondition); !ok { 357 return false 358 } else { 359 return cond.Satisfies(typedCond) 360 } 361 } 362 363 func (cond *FilterConditionIsNull) SpecifiesFieldPath(fp Plan_FieldPath) bool { 364 return cond.FieldPath.String() == fp.String() 365 } 366 367 func (cond *FilterConditionIsNull) SpecifiesRawFieldPath(fp gotenobject.FieldPath) bool { 368 if typedFp, ok := fp.(Plan_FieldPath); !ok { 369 return false 370 } else { 371 return cond.SpecifiesFieldPath(typedFp) 372 } 373 } 374 375 func (cond *FilterConditionIsNull) NotNull() bool { 376 return cond.Not 377 } 378 379 func (cond *FilterConditionIsNull) GetRawFieldPath() gotenobject.FieldPath { 380 return cond.FieldPath 381 } 382 383 func (cond *FilterConditionIsNull) ConditionIsNull() {} 384 385 type FilterConditionIsNaN struct { 386 Not bool 387 FieldPath Plan_FieldPath 388 } 389 390 func (cond *FilterConditionIsNaN) String() string { 391 if cond.Not { 392 return cond.FieldPath.String() + " IS NOT NaN" 393 } else { 394 return cond.FieldPath.String() + " IS NaN" 395 } 396 } 397 398 func (cond *FilterConditionIsNaN) _IsFilterCondition() {} 399 400 func (cond *FilterConditionIsNaN) _IsPlanFilterBuilderOrCondition() {} 401 402 func (cond *FilterConditionIsNaN) And(conds ...FilterCondition) FilterCondition { 403 return AndFilterConditions(append([]FilterCondition{cond}, conds...)...) 404 } 405 406 func (cond *FilterConditionIsNaN) Evaluate(res *Plan) bool { 407 v, ok := cond.FieldPath.GetSingleRaw(res) 408 if !ok { 409 return false 410 } 411 fv, ok := v.(float64) 412 if !ok { 413 return false 414 } 415 return math.IsNaN(fv) 416 } 417 418 func (cond *FilterConditionIsNaN) EvaluateRaw(res gotenresource.Resource) bool { 419 if typedRes, ok := res.(*Plan); !ok { 420 return false 421 } else { 422 return cond.Evaluate(typedRes) 423 } 424 } 425 426 func (cond *FilterConditionIsNaN) Satisfies(other FilterCondition) bool { 427 switch tother := other.(type) { 428 case *FilterConditionIsNaN: 429 return cond.FieldPath.String() == tother.FieldPath.String() && cond.Not == tother.Not 430 default: 431 return false 432 } 433 } 434 435 func (cond *FilterConditionIsNaN) SatisfiesRaw(other gotenresource.FilterCondition) bool { 436 if typedCond, ok := other.(FilterCondition); !ok { 437 return false 438 } else { 439 return cond.Satisfies(typedCond) 440 } 441 } 442 443 func (cond *FilterConditionIsNaN) SpecifiesFieldPath(fp Plan_FieldPath) bool { 444 return cond.FieldPath.String() == fp.String() 445 } 446 447 func (cond *FilterConditionIsNaN) SpecifiesRawFieldPath(fp gotenobject.FieldPath) bool { 448 if typedFp, ok := fp.(Plan_FieldPath); !ok { 449 return false 450 } else { 451 return cond.SpecifiesFieldPath(typedFp) 452 } 453 } 454 455 func (cond *FilterConditionIsNaN) GetRawFieldPath() gotenobject.FieldPath { 456 return cond.FieldPath 457 } 458 459 func (cond *FilterConditionIsNaN) ConditionIsNaN() {} 460 461 type FilterConditionCompare struct { 462 Operator filterParser.CompareOperator 463 Plan_FieldPathValue 464 } 465 466 func (cond *FilterConditionCompare) String() string { 467 jsonValue, err := utils.JsonMarshal(cond.Plan_FieldPathValue.GetRawValue()) 468 if err != nil { 469 panic(err) 470 } 471 return fmt.Sprintf("%s %s %s", cond.Plan_FieldPathValue, cond.Operator, jsonValue) 472 } 473 474 func (cond *FilterConditionCompare) _IsFilterCondition() {} 475 476 func (cond *FilterConditionCompare) _IsPlanFilterBuilderOrCondition() {} 477 478 func (cond *FilterConditionCompare) And(conds ...FilterCondition) FilterCondition { 479 return AndFilterConditions(append([]FilterCondition{cond}, conds...)...) 480 } 481 482 func (cond *FilterConditionCompare) Evaluate(res *Plan) bool { 483 // Special evaluation for name or reference - may include wildcards 484 if nameOrRefFPV, ok := cond.Plan_FieldPathValue.GetRawValue().(gotenresource.Name); ok { 485 if otherObj, ok := cond.Plan_FieldPathValue.GetSingleRaw(res); ok { 486 match := nameOrRefFPV.Matches(otherObj) 487 switch cond.Operator { 488 case filterParser.Eq: 489 return match 490 case filterParser.Neq: 491 return !match 492 default: 493 return false 494 } 495 } 496 } 497 // special evaluation for objects 498 if objValue, ok := cond.Plan_FieldPathValue.GetRawValue().(proto.Message); ok { 499 if otherObj, ok := cond.Plan_FieldPathValue.GetSingleRaw(res); ok { 500 switch cond.Operator { 501 case filterParser.Eq: 502 return proto.Equal(objValue, otherObj.(proto.Message)) 503 case filterParser.Neq: 504 return !proto.Equal(objValue, otherObj.(proto.Message)) 505 default: 506 return false 507 } 508 } 509 } 510 cmpResult, comparable := cond.Plan_FieldPathValue.CompareWith(res) 511 if !comparable { 512 return false 513 } 514 return cond.Operator.MatchCompareResult(cmpResult) 515 } 516 517 func (cond *FilterConditionCompare) EvaluateRaw(res gotenresource.Resource) bool { 518 if typedRes, ok := res.(*Plan); !ok { 519 return false 520 } else { 521 return cond.Evaluate(typedRes) 522 } 523 } 524 525 func (cond *FilterConditionCompare) Satisfies(other FilterCondition) bool { 526 switch tother := other.(type) { 527 case *FilterConditionCompare: 528 if cond.Plan_FieldPathValue.String() != tother.Plan_FieldPathValue.String() { 529 return false 530 } 531 othertmp := new(Plan) 532 tother.SetTo(&othertmp) 533 if cmp, comparable := cond.CompareWith(othertmp); !comparable { 534 return false 535 } else { 536 return filterParser.CompareSatisfies(tother.Operator, cond.Operator, cmp) 537 } 538 case *FilterConditionIn: 539 if cond.Operator != filterParser.Eq { 540 return false 541 } 542 if cond.Plan_FieldPathValue.String() != tother.Plan_FieldPathArrayOfValues.String() { 543 return false 544 } 545 for _, inv := range tother.GetRawValues() { 546 othertmp := new(Plan) 547 tother.WithIValue(inv).SetTo(&othertmp) 548 if cmp, comparable := cond.Plan_FieldPathValue.CompareWith(othertmp); comparable && cmp == 0 { 549 return true 550 } 551 } 552 return false 553 case *FilterConditionComposite: 554 if tother.Operator == filterParser.AND { 555 for _, othersubcnd := range tother.flattenConditions() { 556 if !cond.Satisfies(othersubcnd) { 557 return false 558 } 559 } 560 return true 561 } else { // OR 562 for _, othersubcnd := range tother.flattenConditions() { 563 if cond.Satisfies(othersubcnd) { 564 return true 565 } 566 } 567 return false 568 } 569 default: 570 return false 571 } 572 } 573 574 func (cond *FilterConditionCompare) SatisfiesRaw(other gotenresource.FilterCondition) bool { 575 if typedCond, ok := other.(FilterCondition); !ok { 576 return false 577 } else { 578 return cond.Satisfies(typedCond) 579 } 580 } 581 582 func (cond *FilterConditionCompare) SpecifiesFieldPath(fp Plan_FieldPath) bool { 583 return cond.Plan_FieldPathValue.String() == fp.String() 584 } 585 586 func (cond *FilterConditionCompare) SpecifiesRawFieldPath(fp gotenobject.FieldPath) bool { 587 if typedFp, ok := fp.(Plan_FieldPath); !ok { 588 return false 589 } else { 590 return cond.SpecifiesFieldPath(typedFp) 591 } 592 } 593 594 func (cond *FilterConditionCompare) GetOperator() filterParser.CompareOperator { 595 return cond.Operator 596 } 597 598 func (cond *FilterConditionCompare) GetRawFieldPath() gotenobject.FieldPath { 599 return cond.Plan_FieldPathValue 600 } 601 602 func (cond *FilterConditionCompare) GetRawFieldPathValue() gotenobject.FieldPathValue { 603 return cond.Plan_FieldPathValue 604 } 605 606 func (cond *FilterConditionCompare) ConditionCompare() {} 607 608 type FilterConditionContains struct { 609 Type gotenresource.ConditionContainsType 610 FieldPath Plan_FieldPath 611 612 Value Plan_FieldPathArrayItemValue 613 Values []Plan_FieldPathArrayItemValue 614 } 615 616 func (cond *FilterConditionContains) String() string { 617 switch cond.ConditionContainsType() { 618 case gotenresource.ConditionContainsTypeValue: 619 jsonValue, err := utils.JsonMarshal(cond.Value.GetRawItemValue()) 620 if err != nil { 621 panic(err) 622 } 623 return fmt.Sprintf("%s CONTAINS %s", cond.FieldPath, string(jsonValue)) 624 case gotenresource.ConditionContainsTypeAny, gotenresource.ConditionContainsTypeAll: 625 jsonValues := make([]string, len(cond.Values)) 626 for i, v := range cond.Values { 627 if jsonValue, err := utils.JsonMarshal(v.GetRawItemValue()); err != nil { 628 panic(err) 629 } else { 630 jsonValues[i] = string(jsonValue) 631 } 632 } 633 return fmt.Sprintf("%s CONTAINS %s %s", cond.FieldPath, cond.ConditionContainsType(), fmt.Sprintf("(%s)", strings.Join(jsonValues, ", "))) 634 default: 635 panic(gotenresource.NewUnknownConditionContainsType(cond.ConditionContainsType())) 636 } 637 } 638 639 func (cond *FilterConditionContains) ConditionContainsType() gotenresource.ConditionContainsType { 640 return cond.Type 641 } 642 643 func (cond *FilterConditionContains) _IsFilterCondition() {} 644 645 func (cond *FilterConditionContains) _IsPlanFilterBuilderOrCondition() {} 646 647 func (cond *FilterConditionContains) And(conds ...FilterCondition) FilterCondition { 648 return AndFilterConditions(append([]FilterCondition{cond}, conds...)...) 649 } 650 651 func (cond *FilterConditionContains) Evaluate(res *Plan) bool { 652 switch cond.ConditionContainsType() { 653 case gotenresource.ConditionContainsTypeValue: 654 return cond.Value.ContainsValue(res) 655 case gotenresource.ConditionContainsTypeAny: 656 for _, v := range cond.Values { 657 if v.ContainsValue(res) { 658 return true 659 } 660 } 661 return false 662 case gotenresource.ConditionContainsTypeAll: 663 for _, v := range cond.Values { 664 if !v.ContainsValue(res) { 665 return false 666 } 667 } 668 return true 669 default: 670 panic(gotenresource.NewUnknownConditionContainsType(cond.ConditionContainsType())) 671 } 672 } 673 674 func (cond *FilterConditionContains) EvaluateRaw(res gotenresource.Resource) bool { 675 if typedRes, ok := res.(*Plan); !ok { 676 return false 677 } else { 678 return cond.Evaluate(typedRes) 679 } 680 } 681 682 func (cond *FilterConditionContains) Satisfies(other FilterCondition) bool { 683 switch tother := other.(type) { 684 case *FilterConditionContains: 685 if cond.ConditionContainsType().IsValue() && tother.ConditionContainsType().IsValue() { 686 othertmp := new(Plan) 687 tother.Value.WithIValue(tother.GetRawFieldPathItemValue().GetRawItemValue()).SetTo(&othertmp) 688 return cond.Value.ContainsValue(othertmp) 689 } 690 return false 691 default: 692 return false 693 } 694 } 695 696 func (cond *FilterConditionContains) SatisfiesRaw(other gotenresource.FilterCondition) bool { 697 if typedCond, ok := other.(FilterCondition); !ok { 698 return false 699 } else { 700 return cond.Satisfies(typedCond) 701 } 702 } 703 704 func (cond *FilterConditionContains) SpecifiesFieldPath(fp Plan_FieldPath) bool { 705 return cond.FieldPath.String() == fp.String() 706 } 707 708 func (cond *FilterConditionContains) SpecifiesRawFieldPath(fp gotenobject.FieldPath) bool { 709 if typedFp, ok := fp.(Plan_FieldPath); !ok { 710 return false 711 } else { 712 return cond.SpecifiesFieldPath(typedFp) 713 } 714 } 715 716 func (cond *FilterConditionContains) GetFieldPath() Plan_FieldPath { 717 return cond.FieldPath 718 } 719 720 func (cond *FilterConditionContains) GetRawFieldPath() gotenobject.FieldPath { 721 return cond.FieldPath 722 } 723 724 func (cond *FilterConditionContains) GetRawFieldPathItemValue() gotenobject.FieldPathArrayItemValue { 725 switch cond.ConditionContainsType() { 726 case gotenresource.ConditionContainsTypeValue: 727 return cond.Value 728 default: 729 panic(fmt.Errorf("unable to get value for condition contains type %s", cond.ConditionContainsType())) 730 } 731 } 732 733 func (cond *FilterConditionContains) GetRawFieldPathItemValues() (res []gotenobject.FieldPathArrayItemValue) { 734 switch cond.ConditionContainsType() { 735 case gotenresource.ConditionContainsTypeAny, gotenresource.ConditionContainsTypeAll: 736 for _, fpaiv := range cond.Values { 737 res = append(res, fpaiv) 738 } 739 default: 740 panic(fmt.Errorf("unable to get values for condition contains type %s", cond.ConditionContainsType())) 741 } 742 return 743 } 744 745 func (cond *FilterConditionContains) ConditionContains() {} 746 747 type FilterConditionIn struct { 748 Plan_FieldPathArrayOfValues 749 } 750 751 func (cond *FilterConditionIn) String() string { 752 jsonValues, err := utils.JsonMarshal(cond.Plan_FieldPathArrayOfValues.GetRawValues()) 753 if err != nil { 754 panic(err) 755 } 756 return fmt.Sprintf("%s IN %s", cond.Plan_FieldPathArrayOfValues, jsonValues) 757 } 758 759 func (cond *FilterConditionIn) _IsFilterCondition() {} 760 761 func (cond *FilterConditionIn) _IsPlanFilterBuilderOrCondition() {} 762 763 func (cond *FilterConditionIn) And(conds ...FilterCondition) FilterCondition { 764 return AndFilterConditions(append([]FilterCondition{cond}, conds...)...) 765 } 766 767 func (cond *FilterConditionIn) Evaluate(res *Plan) bool { 768 for _, inValue := range cond.Plan_FieldPathArrayOfValues.GetRawValues() { 769 if cmp, ok := cond.Plan_FieldPathArrayOfValues.WithIValue(inValue).CompareWith(res); ok && cmp == 0 { 770 return true 771 } 772 } 773 return false 774 } 775 776 func (cond *FilterConditionIn) EvaluateRaw(res gotenresource.Resource) bool { 777 if typedRes, ok := res.(*Plan); !ok { 778 return false 779 } else { 780 return cond.Evaluate(typedRes) 781 } 782 } 783 784 func (cond *FilterConditionIn) Satisfies(other FilterCondition) bool { 785 switch tother := other.(type) { 786 case *FilterConditionIn: 787 outer: 788 for _, cval := range cond.Plan_FieldPathArrayOfValues.GetRawValues() { 789 for _, otherval := range tother.Plan_FieldPathArrayOfValues.GetRawValues() { 790 othertmp := new(Plan) 791 tother.Plan_FieldPathArrayOfValues.WithIValue(otherval).SetTo(&othertmp) 792 if cmp, comparable := cond.Plan_FieldPathArrayOfValues.WithIValue(cval).CompareWith(othertmp); comparable && cmp == 0 { 793 continue outer 794 } 795 } 796 return false 797 } 798 return true 799 default: 800 for _, cval := range cond.Plan_FieldPathArrayOfValues.GetRawValues() { 801 subcnd := &FilterConditionCompare{ 802 Operator: filterParser.Eq, 803 Plan_FieldPathValue: cond.Plan_FieldPathArrayOfValues.WithIValue(cval), 804 } 805 if !subcnd.Satisfies(tother) { 806 return false 807 } 808 } 809 return true 810 } 811 } 812 813 func (cond *FilterConditionIn) SatisfiesRaw(other gotenresource.FilterCondition) bool { 814 if typedCond, ok := other.(FilterCondition); !ok { 815 return false 816 } else { 817 return cond.Satisfies(typedCond) 818 } 819 } 820 821 func (cond *FilterConditionIn) SpecifiesFieldPath(fp Plan_FieldPath) bool { 822 return cond.Plan_FieldPathArrayOfValues.String() == fp.String() 823 } 824 825 func (cond *FilterConditionIn) SpecifiesRawFieldPath(fp gotenobject.FieldPath) bool { 826 if typedFp, ok := fp.(Plan_FieldPath); !ok { 827 return false 828 } else { 829 return cond.SpecifiesFieldPath(typedFp) 830 } 831 } 832 833 func (cond *FilterConditionIn) GetRawFieldPath() gotenobject.FieldPath { 834 return cond.Plan_FieldPathArrayOfValues 835 } 836 837 func (cond *FilterConditionIn) GetRawFieldPathArrayOfValues() gotenobject.FieldPathArrayOfValues { 838 return cond.Plan_FieldPathArrayOfValues 839 } 840 841 func (cond *FilterConditionIn) ConditionIn() {} 842 843 type FilterConditionNotIn struct { 844 Plan_FieldPathArrayOfValues 845 } 846 847 func (cond *FilterConditionNotIn) String() string { 848 jsonValues, err := utils.JsonMarshal(cond.Plan_FieldPathArrayOfValues.GetRawValues()) 849 if err != nil { 850 panic(err) 851 } 852 return fmt.Sprintf("%s NOT IN %s", cond.Plan_FieldPathArrayOfValues, jsonValues) 853 } 854 855 func (cond *FilterConditionNotIn) _IsFilterCondition() {} 856 857 func (cond *FilterConditionNotIn) _IsPlanFilterBuilderOrCondition() {} 858 859 func (cond *FilterConditionNotIn) And(conds ...FilterCondition) FilterCondition { 860 return AndFilterConditions(append([]FilterCondition{cond}, conds...)...) 861 } 862 863 func (cond *FilterConditionNotIn) Evaluate(res *Plan) bool { 864 for _, inValue := range cond.Plan_FieldPathArrayOfValues.GetRawValues() { 865 if cmp, ok := cond.Plan_FieldPathArrayOfValues.WithIValue(inValue).CompareWith(res); ok && cmp == 0 { 866 return false 867 } 868 } 869 return true 870 } 871 872 func (cond *FilterConditionNotIn) EvaluateRaw(res gotenresource.Resource) bool { 873 if typedRes, ok := res.(*Plan); !ok { 874 return false 875 } else { 876 return cond.Evaluate(typedRes) 877 } 878 } 879 880 func (cond *FilterConditionNotIn) Satisfies(other FilterCondition) bool { 881 return false 882 } 883 884 func (cond *FilterConditionNotIn) SatisfiesRaw(other gotenresource.FilterCondition) bool { 885 if typedCond, ok := other.(FilterCondition); !ok { 886 return false 887 } else { 888 return cond.Satisfies(typedCond) 889 } 890 } 891 892 func (cond *FilterConditionNotIn) SpecifiesFieldPath(fp Plan_FieldPath) bool { 893 return cond.Plan_FieldPathArrayOfValues.String() == fp.String() 894 } 895 896 func (cond *FilterConditionNotIn) SpecifiesRawFieldPath(fp gotenobject.FieldPath) bool { 897 if typedFp, ok := fp.(Plan_FieldPath); !ok { 898 return false 899 } else { 900 return cond.SpecifiesFieldPath(typedFp) 901 } 902 } 903 904 func (cond *FilterConditionNotIn) GetRawFieldPath() gotenobject.FieldPath { 905 return cond.Plan_FieldPathArrayOfValues 906 } 907 908 func (cond *FilterConditionNotIn) GetRawFieldPathArrayOfValues() gotenobject.FieldPathArrayOfValues { 909 return cond.Plan_FieldPathArrayOfValues 910 } 911 912 func (cond *FilterConditionNotIn) ConditionNotIn() {} 913 914 type Filter struct { 915 FilterCondition 916 } 917 918 func (filter *Filter) _IsPlanFilterBuilderOrCondition() {} 919 920 // GetCondition is a getter of FilterCondition, which also handles nil pointer 921 func (filter *Filter) GetCondition() FilterCondition { 922 if filter == nil { 923 return AndFilterConditions() 924 } else { 925 return filter.FilterCondition 926 } 927 } 928 929 // Evaluate is a wrapper on FilterCondition, which also handles nil pointer 930 func (filter *Filter) Evaluate(res *Plan) bool { 931 return filter.GetCondition().Evaluate(res) 932 } 933 934 func (filter *Filter) EvaluateRaw(res gotenresource.Resource) bool { 935 if typedRes, ok := res.(*Plan); !ok { 936 return false 937 } else { 938 return filter.Evaluate(typedRes) 939 } 940 } 941 942 func (filter *Filter) GetRawCondition() gotenresource.FilterCondition { 943 if filter == nil { 944 return nil 945 } 946 return filter.GetCondition() 947 } 948 949 // FilterSlice is a helper for filtering arrays 950 func (filter *Filter) FilterSlice(in []*Plan) (out []*Plan) { 951 for _, res := range in { 952 if filter.Evaluate(res) { 953 out = append(out, res) 954 } 955 } 956 return 957 } 958 959 // implement methods required by protobuf-go library for string-struct conversion 960 961 func (filter *Filter) ProtoString() (string, error) { 962 if filter == nil || filter.FilterCondition == nil { 963 return "", nil 964 } 965 return filter.FilterCondition.String(), nil 966 } 967 968 func (filter *Filter) ParseProtoString(data string) error { 969 expression, err := filterParser.Parse([]byte(data)) 970 if err != nil { 971 return status.Error(codes.InvalidArgument, err.Error()) 972 } 973 974 condition, err := makeFilterConditionFromOr(expression.And) 975 if err != nil { 976 return err 977 } 978 filter.FilterCondition = condition 979 return nil 980 } 981 982 func (filter *Filter) String() string { 983 if filter == nil || filter.FilterCondition == nil { 984 return "<nil>" 985 } 986 return filter.FilterCondition.String() 987 } 988 989 func (filter *Filter) SetFromCliFlag(raw string) error { 990 return filter.ParseProtoString(raw) 991 } 992 993 // helpers 994 995 func makeFilterConditionFromOperand(condition *filterParser.ConditionOperand) (FilterCondition, error) { 996 path, err := ParsePlan_FieldPath(condition.FieldPath) 997 if err != nil { 998 return nil, err 999 } 1000 rhs := condition.ConditionRHS 1001 valueJSON, err := rhs.JSONValue() 1002 if err != nil { 1003 return nil, status.Error(codes.Internal, err.Error()) 1004 } 1005 1006 if rhs.Compare != nil { 1007 cmp := rhs.Compare 1008 if !path.IsLeaf() && !(cmp.Operator == filterParser.Eq || cmp.Operator == filterParser.Neq) { 1009 return nil, status.Errorf(codes.InvalidArgument, "path '%s' is not comparable leaf value for operator %s", path, cmp.Operator) 1010 } 1011 1012 // translate null comparison to IS(NOT)NULL 1013 if cmp.Value.Null { 1014 switch cmp.Operator { 1015 case filterParser.Eq: 1016 return &FilterConditionIsNull{false, path}, nil 1017 case filterParser.Neq: 1018 return &FilterConditionIsNull{true, path}, nil 1019 default: 1020 return nil, status.Errorf(codes.InvalidArgument, "operator '%s' isn't valid when comparing null value", cmp.Operator) 1021 } 1022 } 1023 1024 pfv, err := ParsePlan_FieldPathValue(path.String(), string(valueJSON)) 1025 if err != nil { 1026 return nil, status.Errorf(codes.InvalidArgument, "error when parsing filter value for field path '%s': %s", path, err) 1027 } 1028 1029 return &FilterConditionCompare{ 1030 Operator: cmp.Operator, 1031 Plan_FieldPathValue: pfv, 1032 }, nil 1033 } else if rhs.Is != nil { 1034 if rhs.Is.Null { 1035 return &FilterConditionIsNull{rhs.Is.Not, path}, nil 1036 } else if rhs.Is.NaN { 1037 return &FilterConditionIsNaN{rhs.Is.Not, path}, nil 1038 } else { 1039 return nil, status.Error(codes.Internal, "unknown filter IS type - expected NULL or NaN") 1040 } 1041 } else if rhs.Contains != nil { 1042 ct := gotenresource.ConditionContainsTypeFromParser(rhs.Contains) 1043 fp, err := ParsePlan_FieldPath(path.String()) 1044 if err != nil { 1045 return nil, err 1046 } 1047 if rhs.Contains.Value != nil { 1048 pfav, err := ParsePlan_FieldPathArrayItemValue(path.String(), string(valueJSON)) 1049 if err != nil { 1050 return nil, err 1051 } 1052 return &FilterConditionContains{ct, fp, pfav, nil}, nil 1053 } else if rhs.Contains.Any != nil || rhs.Contains.All != nil { 1054 parrv := rhs.Contains.GetArray() 1055 vals := make([]Plan_FieldPathArrayItemValue, len(parrv)) 1056 for i, pv := range parrv { 1057 jsonv, err := utils.JsonMarshal(pv) 1058 if err != nil { 1059 return nil, err 1060 } 1061 if pfav, err := ParsePlan_FieldPathArrayItemValue(path.String(), string(jsonv)); err != nil { 1062 return nil, err 1063 } else { 1064 vals[i] = pfav 1065 } 1066 } 1067 return &FilterConditionContains{ct, fp, nil, vals}, nil 1068 } else { 1069 return nil, status.Error(codes.Internal, "unknown condition contains type") 1070 } 1071 } else if rhs.Like != nil { 1072 return nil, status.Errorf(codes.Unimplemented, "'LIKE' condition is not supported") 1073 } else if rhs.In != nil { 1074 if fpaov, err := ParsePlan_FieldPathArrayOfValues(path.String(), string(valueJSON)); err != nil { 1075 return nil, err 1076 } else { 1077 return &FilterConditionIn{fpaov}, nil 1078 } 1079 } else if rhs.NotIn != nil { 1080 if fpaov, err := ParsePlan_FieldPathArrayOfValues(path.String(), string(valueJSON)); err != nil { 1081 return nil, err 1082 } else { 1083 return &FilterConditionNotIn{fpaov}, nil 1084 } 1085 } 1086 return nil, status.Error(codes.Internal, "unknown filter RHS operand type") 1087 1088 } 1089 1090 func makeFilterConditionFromCondition(condition *filterParser.Condition) (FilterCondition, error) { 1091 if condition.SubExpression != nil { 1092 return makeFilterConditionFromOr(condition.SubExpression.And) 1093 } else if condition.Not != nil { 1094 not, err := makeFilterConditionFromCondition(condition.Not) 1095 if err != nil { 1096 return nil, err 1097 } 1098 return &FilterConditionNot{not}, nil 1099 } else if condition.Operand != nil { 1100 return makeFilterConditionFromOperand(condition.Operand) 1101 } else { 1102 return nil, status.Error(codes.Internal, "unknown condition type") 1103 } 1104 } 1105 1106 func makeFilterConditionFromAnd(conditions []filterParser.Condition) (FilterCondition, error) { 1107 if len(conditions) == 1 { 1108 return makeFilterConditionFromCondition(&conditions[0]) 1109 } else { 1110 cnds := make([]FilterCondition, 0, len(conditions)) 1111 for _, condition := range conditions { 1112 cnd, err := makeFilterConditionFromCondition(&condition) 1113 if err != nil { 1114 return nil, err 1115 } 1116 cnds = append(cnds, cnd) 1117 } 1118 return &FilterConditionComposite{Operator: filterParser.AND, Conditions: cnds}, nil 1119 } 1120 } 1121 1122 func makeFilterConditionFromOr(conditions []filterParser.AndCondition) (FilterCondition, error) { 1123 if len(conditions) == 1 { 1124 return makeFilterConditionFromAnd(conditions[0].Or) 1125 } else { 1126 cnds := make([]FilterCondition, 0, len(conditions)) 1127 for _, condition := range conditions { 1128 cnd, err := makeFilterConditionFromAnd(condition.Or) 1129 if err != nil { 1130 return nil, err 1131 } 1132 cnds = append(cnds, cnd) 1133 } 1134 return &FilterConditionComposite{Operator: filterParser.OR, Conditions: cnds}, nil 1135 } 1136 }