1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
|
// Copyright 2018 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package types
import (
"fmt"
"reflect"
"google.golang.org/protobuf/proto"
"github.com/google/cel-go/common/types/ref"
anypb "google.golang.org/protobuf/types/known/anypb"
structpb "google.golang.org/protobuf/types/known/structpb"
)
// Null type implementation.
type Null structpb.NullValue
var (
// NullValue singleton.
NullValue = Null(structpb.NullValue_NULL_VALUE)
// golang reflect type for Null values.
nullReflectType = reflect.TypeOf(NullValue)
)
// ConvertToNative implements ref.Val.ConvertToNative.
func (n Null) ConvertToNative(typeDesc reflect.Type) (any, error) {
switch typeDesc.Kind() {
case reflect.Int32:
switch typeDesc {
case jsonNullType:
return structpb.NullValue_NULL_VALUE, nil
case nullReflectType:
return n, nil
}
case reflect.Ptr:
switch typeDesc {
case anyValueType:
// Convert to a JSON-null before packing to an Any field since the enum value for JSON
// null cannot be packed directly.
pb, err := n.ConvertToNative(jsonValueType)
if err != nil {
return nil, err
}
return anypb.New(pb.(proto.Message))
case jsonValueType:
return structpb.NewNullValue(), nil
case boolWrapperType, byteWrapperType, doubleWrapperType, floatWrapperType,
int32WrapperType, int64WrapperType, stringWrapperType, uint32WrapperType,
uint64WrapperType:
return nil, nil
}
case reflect.Interface:
nv := n.Value()
if reflect.TypeOf(nv).Implements(typeDesc) {
return nv, nil
}
if reflect.TypeOf(n).Implements(typeDesc) {
return n, nil
}
}
// If the type conversion isn't supported return an error.
return nil, fmt.Errorf("type conversion error from '%v' to '%v'", NullType, typeDesc)
}
// ConvertToType implements ref.Val.ConvertToType.
func (n Null) ConvertToType(typeVal ref.Type) ref.Val {
switch typeVal {
case StringType:
return String("null")
case NullType:
return n
case TypeType:
return NullType
}
return NewErr("type conversion error from '%s' to '%s'", NullType, typeVal)
}
// Equal implements ref.Val.Equal.
func (n Null) Equal(other ref.Val) ref.Val {
return Bool(NullType == other.Type())
}
// IsZeroValue returns true as null always represents an absent value.
func (n Null) IsZeroValue() bool {
return true
}
// Type implements ref.Val.Type.
func (n Null) Type() ref.Type {
return NullType
}
// Value implements ref.Val.Value.
func (n Null) Value() any {
return structpb.NullValue_NULL_VALUE
}
|