-
Notifications
You must be signed in to change notification settings - Fork 228
proposal 190
This is a fix for Issue 190.
Originally, CEL treated protocol buffer enum values as int
values, automatically coercing them when reading from or assigning to proto fields. Enum constants are available as int-valued constants in the environment. While this is simple and convenient, it does not catch basic errors, such as comparing an enum-valued field to a constant from a different enum.
In PR 157 we changed the spec and conformance tests to make each enum a distinct type, with conversion functions to and from int
. The constants are now of their distinct enum type. This catches all many errors, while uncommon uses such as arithmetic on enums or cross-enum comparisons or assignments can still be accomplished with explicit conversions.
Unfortunately, this would create a compatibility problem for existing programs. We are withdrawing the changes in PR 157.
Instead, we propose a hybrid plan:
- Enums are treated as distinct types at type-check time. The conversion functions mentioned in PR 157 are all available.
- Enums are treated as
int
at runtime. The above conversion functions are implemented asint
toint
identity functions. - For compatibility, we will add a new "identity" overload to all type conversion functions at both type check and runtime, so
int(MyEnum.MY_CONST)
will work with both old and new semantics. For consistency, we will add this for all type conversion functions, e.g.string("foo")
invokes an identity function and yields"foo"
. This will be deployed first.
All previously compiled ASTs will continue to run with no changes, as the runtime semantics do not change. Expressions which make use of enum arithmetic, assignments of ints or cross-enum comparisons and assignments will start to fail type-check, but we don't believe that we have such expressions in the field. If there are, we will make the identity conversion functions available and allow customers to update their expressions to use them before updating the type checker. E.g. msg.enum_field - MyEnum.BASE > 3
becomes int(msg.enum_field) - int(MyEnum.BASE) > 3
.