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