Skip to content

Well-known types#

CEL provides special handling for a subset of the Protocol Buffer Well-Known Types. Only those listed on this page are automatically converted to CEL-native types during evaluation.

Examples on this page use this Protobuf definition:

syntax = "proto3";

package example.v1;

import "google/protobuf/struct.proto";
import "google/protobuf/wrappers.proto";

message User {
  string name = 1;
  google.protobuf.StringValue nickname = 2;
  google.protobuf.Int64Value age = 3;
  google.protobuf.Struct metadata = 4;
}

Wrapper types#

The following wrapper types automatically unwrap to their primitive types: BoolValue, BytesValue, DoubleValue, FloatValue, Int32Value, Int64Value, StringValue, UInt32Value, UInt64Value.

google.protobuf.BoolValue{value: true}
// result: true (bool)
google.protobuf.BytesValue{value: b"data"}
// result: b"data" (bytes)
google.protobuf.DoubleValue{value: 3.14}
// result: 3.14 (double)
google.protobuf.Int64Value{value: 42}
// result: 42 (int)
google.protobuf.StringValue{value: "hello"}
// result: "hello" (string)

Wrapper values can be compared directly to primitives.

google.protobuf.StringValue{value: "hello"} == "hello"
// result: true (bool)

Wrapper fields and null#

Unset wrapper type fields evaluate to null instead of a default value.

// input: user = example.v1.User{name: "Alice"}
user.nickname
// result: null (null_type)
// input: user = example.v1.User{name: "Alice"}
user.nickname == null
// result: true (bool)

When set, wrapper fields unwrap to their primitive value.

// input: user = example.v1.User{name: "Alice", nickname: google.protobuf.StringValue{value: "Ali"}}
user.nickname
// result: "Ali" (string)

Use has() to check whether a wrapper field is set.

// input: user = example.v1.User{name: "Alice"}
has(user.nickname)
// result: false (bool)
// input: user = example.v1.User{name: "Alice", nickname: google.protobuf.StringValue{value: "Ali"}}
has(user.nickname)
// result: true (bool)

Struct#

google.protobuf.Struct converts to a map with string keys and is the idiomatic way to represent arbitrary JSON objects in Protocol Buffers.

google.protobuf.Struct{fields: {"name": google.protobuf.Value{string_value: "Alice"}}}
// result: {"name": "Alice"} (map)

Access fields using dot notation or index syntax.

// input: data = google.protobuf.Struct{fields: {"name": google.protobuf.Value{string_value: "Alice"}}}
data.name
// result: "Alice" (string)
// input: data = google.protobuf.Struct{fields: {"name": google.protobuf.Value{string_value: "Alice"}}}
data["name"]
// result: "Alice" (string)

Use in to test for key existence.

// input: data = google.protobuf.Struct{fields: {"name": google.protobuf.Value{string_value: "Alice"}}}
"name" in data
// result: true (bool)

Value#

google.protobuf.Value converts to the type matching its content: null, bool, double, string, list, or map.

google.protobuf.Value{string_value: "hello"}
// result: "hello" (string)
google.protobuf.Value{number_value: 42.0}
// result: 42 (double)
google.protobuf.Value{bool_value: true}
// result: true (bool)
google.protobuf.Value{null_value: google.protobuf.NullValue.NULL_VALUE}
// result: null (null_type)
google.protobuf.Value{
  list_value: google.protobuf.ListValue{values: [
    google.protobuf.Value{string_value: "a"}
  ]}
}
// result: ["a"] (list)
google.protobuf.Value{
  struct_value: google.protobuf.Struct{fields: {
    "key": google.protobuf.Value{string_value: "value"}
  }}
}
// result: {"key": "value"} (map)

ListValue#

google.protobuf.ListValue converts to a list. Each list element is converted.

google.protobuf.ListValue{values: [google.protobuf.Value{string_value: "a"}]}
// result: ["a"] (list)

Any#

google.protobuf.Any is converted to its contained message type when evaluated. If the contained type is itself a Well-Known Type, it's further converted.

google.protobuf.Any{type_url: "type.googleapis.com/google.protobuf.StringValue", value: b"\n\x02hi"}
// result: "hi" (string)

The type URL must reference a message type known to the CEL runtime; unknown types produce a runtime error.

google.protobuf.Any{type_url: "type.googleapis.com/unknown.Type", value: b""}
// error: unknown type

NullValue#

google.protobuf.NullValue corresponds to the CEL null literal. See Null for details.

Timestamp and Duration#

google.protobuf.Timestamp and google.protobuf.Duration are also Well-Known Types with dedicated support in CEL. See Time for details on creating and manipulating these types.

See also#

  • Protocol Buffers - Protobuf messages and enumerations
  • Time - Timestamps and durations
  • Maps - Map operations that apply to Struct
  • Lists - List operations that apply to ListValue
  • Null - The null value and wrapper field semantics