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  	_ = &timestamppb.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  }