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