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  }