Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions cel-c/internal/runtime/instr.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ typedef enum CEL_ATTRIBUTE_CLOSED_ENUM {
_cel_InstrKind_kCallGetMinutes,
_cel_InstrKind_kCallGetSeconds,
_cel_InstrKind_kCallGetMilliseconds,
_cel_InstrKind_kCallGetFullYear,
_cel_InstrKind_kCallGetMonth,
_cel_InstrKind_kCallGetDate,
_cel_InstrKind_kCallGetDayOfMonth,
_cel_InstrKind_kCallGetDayOfWeek,
_cel_InstrKind_kCallGetDayOfYear,
_cel_InstrKind_kCallContainsString,
_cel_InstrKind_kCallStartsWithString,
_cel_InstrKind_kCallEndsWithString,
Expand Down
126 changes: 122 additions & 4 deletions cel-c/internal/runtime/interpretable.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2779,16 +2779,45 @@ static inline void _cel_Interpretable_CallSize(
}

typedef enum {
// Accessors supported by both durations and timestamps.
_cel_TimeAccessor_kHours,
_cel_TimeAccessor_kMinutes,
_cel_TimeAccessor_kSeconds,
_cel_TimeAccessor_kMilliseconds,
// Accessors supported only by timestamps.
_cel_TimeAccessor_kFullYear,
_cel_TimeAccessor_kMonth,
_cel_TimeAccessor_kDate,
_cel_TimeAccessor_kDayOfMonth,
_cel_TimeAccessor_kDayOfWeek,
_cel_TimeAccessor_kDayOfYear,
} _cel_TimeAccessor;

// Returns true if `accessor` has an overload for `google.protobuf.Duration`.
CEL_ATTRIBUTE_NODISCARD
static inline bool _cel_TimeAccessor_SupportsDuration(
_cel_TimeAccessor accessor) {
switch (accessor) {
case _cel_TimeAccessor_kHours:
case _cel_TimeAccessor_kMinutes:
case _cel_TimeAccessor_kSeconds:
case _cel_TimeAccessor_kMilliseconds:
return true;
case _cel_TimeAccessor_kFullYear:
case _cel_TimeAccessor_kMonth:
case _cel_TimeAccessor_kDate:
case _cel_TimeAccessor_kDayOfMonth:
case _cel_TimeAccessor_kDayOfWeek:
case _cel_TimeAccessor_kDayOfYear:
return false;
}
CEL_UNREACHABLE();
}

// Returns the requested component of a duration, matching cel-cpp. Hours,
// minutes and seconds are the total number of whole units in the duration,
// truncated towards zero. Milliseconds is the sub-second component, in the
// range [-999, 999].
// range [-999, 999]. `accessor` must support durations.
CEL_ATTRIBUTE_NODISCARD
static inline int64_t _cel_Interpretable_DurationComponent(
cel_Duration d, _cel_TimeAccessor accessor) {
Expand All @@ -2806,10 +2835,20 @@ static inline int64_t _cel_Interpretable_DurationComponent(
return sec;
case _cel_TimeAccessor_kMilliseconds:
return nsec / INT32_C(1000000);
case _cel_TimeAccessor_kFullYear:
case _cel_TimeAccessor_kMonth:
case _cel_TimeAccessor_kDate:
case _cel_TimeAccessor_kDayOfMonth:
case _cel_TimeAccessor_kDayOfWeek:
case _cel_TimeAccessor_kDayOfYear:
break;
}
CEL_UNREACHABLE();
}

// Returns the requested component of a civil time, matching the CEL
// specification. Note that `getMonth`, `getDayOfMonth` and `getDayOfYear` are
// zero-based, whereas `getDate` is one-based.
CEL_ATTRIBUTE_NODISCARD
static inline int64_t _cel_Interpretable_CivilTimeComponent(
const _cel_CivilTime* cel_nonnull civil_time, _cel_TimeAccessor accessor) {
Expand All @@ -2822,6 +2861,18 @@ static inline int64_t _cel_Interpretable_CivilTimeComponent(
return civil_time->second;
case _cel_TimeAccessor_kMilliseconds:
return civil_time->millisecond;
case _cel_TimeAccessor_kFullYear:
return civil_time->year;
case _cel_TimeAccessor_kMonth:
return civil_time->month - 1;
case _cel_TimeAccessor_kDate:
return civil_time->day;
case _cel_TimeAccessor_kDayOfMonth:
return civil_time->day - 1;
case _cel_TimeAccessor_kDayOfWeek:
return civil_time->day_of_week;
case _cel_TimeAccessor_kDayOfYear:
return civil_time->day_of_year - 1;
}
CEL_UNREACHABLE();
}
Expand All @@ -2832,6 +2883,12 @@ static inline int64_t _cel_Interpretable_CivilTimeComponent(
// (google.protobuf.Timestamp) -> int
// (google.protobuf.Timestamp, string) -> int
//
// And `getFullYear`, `getMonth`, `getDate`, `getDayOfMonth`, `getDayOfWeek` and
// `getDayOfYear`:
//
// (google.protobuf.Timestamp) -> int
// (google.protobuf.Timestamp, string) -> int
//
// For timestamps, the optional string is the time zone, otherwise UTC is used.
static inline void _cel_Interpretable_CallTimeAccessor(
_cel_Interpretable* cel_nonnull interp,
Expand All @@ -2848,9 +2905,10 @@ static inline void _cel_Interpretable_CallTimeAccessor(
case cel_ValueKind_kError:
break;
case cel_ValueKind_kDuration:
if (tz != cel_nullptr) {
// There is no time zone overload for durations.
if (cel_Value_IsError(tz)) {
if (tz != cel_nullptr || !_cel_TimeAccessor_SupportsDuration(accessor)) {
// There is no time zone overload for durations, and not all accessors
// support durations.
if (tz != cel_nullptr && cel_Value_IsError(tz)) {
*top = *tz;
} else {
cel_Value_SetError(top,
Expand Down Expand Up @@ -3252,6 +3310,12 @@ static inline void _cel_Interpretable_ComputedGoto(
&&INSTR_CALL_GET_MINUTES,
&&INSTR_CALL_GET_SECONDS,
&&INSTR_CALL_GET_MILLISECONDS,
&&INSTR_CALL_GET_FULL_YEAR,
&&INSTR_CALL_GET_MONTH,
&&INSTR_CALL_GET_DATE,
&&INSTR_CALL_GET_DAY_OF_MONTH,
&&INSTR_CALL_GET_DAY_OF_WEEK,
&&INSTR_CALL_GET_DAY_OF_YEAR,
&&INSTR_CALL_CONTAINS_STRING,
&&INSTR_CALL_STARTS_WITH_STRING,
&&INSTR_CALL_ENDS_WITH_STRING,
Expand Down Expand Up @@ -3438,6 +3502,30 @@ static inline void _cel_Interpretable_ComputedGoto(
_cel_Interpretable_CallTimeAccessor(interp, &instr->data,
_cel_TimeAccessor_kMilliseconds);
DISPATCH_NEXT_INSTR();
INSTR_CALL_GET_FULL_YEAR:
_cel_Interpretable_CallTimeAccessor(interp, &instr->data,
_cel_TimeAccessor_kFullYear);
DISPATCH_NEXT_INSTR();
INSTR_CALL_GET_MONTH:
_cel_Interpretable_CallTimeAccessor(interp, &instr->data,
_cel_TimeAccessor_kMonth);
DISPATCH_NEXT_INSTR();
INSTR_CALL_GET_DATE:
_cel_Interpretable_CallTimeAccessor(interp, &instr->data,
_cel_TimeAccessor_kDate);
DISPATCH_NEXT_INSTR();
INSTR_CALL_GET_DAY_OF_MONTH:
_cel_Interpretable_CallTimeAccessor(interp, &instr->data,
_cel_TimeAccessor_kDayOfMonth);
DISPATCH_NEXT_INSTR();
INSTR_CALL_GET_DAY_OF_WEEK:
_cel_Interpretable_CallTimeAccessor(interp, &instr->data,
_cel_TimeAccessor_kDayOfWeek);
DISPATCH_NEXT_INSTR();
INSTR_CALL_GET_DAY_OF_YEAR:
_cel_Interpretable_CallTimeAccessor(interp, &instr->data,
_cel_TimeAccessor_kDayOfYear);
DISPATCH_NEXT_INSTR();
INSTR_CALL_CONTAINS_STRING:
_cel_Interpretable_CallContainsString(interp, &instr->data);
DISPATCH_NEXT_INSTR();
Expand Down Expand Up @@ -3696,6 +3784,36 @@ static inline void _cel_Interpretable_Switch(
_cel_TimeAccessor_kMilliseconds);
++instr;
break;
case _cel_InstrKind_kCallGetFullYear:
_cel_Interpretable_CallTimeAccessor(interp, &instr->data,
_cel_TimeAccessor_kFullYear);
++instr;
break;
case _cel_InstrKind_kCallGetMonth:
_cel_Interpretable_CallTimeAccessor(interp, &instr->data,
_cel_TimeAccessor_kMonth);
++instr;
break;
case _cel_InstrKind_kCallGetDate:
_cel_Interpretable_CallTimeAccessor(interp, &instr->data,
_cel_TimeAccessor_kDate);
++instr;
break;
case _cel_InstrKind_kCallGetDayOfMonth:
_cel_Interpretable_CallTimeAccessor(interp, &instr->data,
_cel_TimeAccessor_kDayOfMonth);
++instr;
break;
case _cel_InstrKind_kCallGetDayOfWeek:
_cel_Interpretable_CallTimeAccessor(interp, &instr->data,
_cel_TimeAccessor_kDayOfWeek);
++instr;
break;
case _cel_InstrKind_kCallGetDayOfYear:
_cel_Interpretable_CallTimeAccessor(interp, &instr->data,
_cel_TimeAccessor_kDayOfYear);
++instr;
break;
case _cel_InstrKind_kCallContainsString:
_cel_Interpretable_CallContainsString(interp, &instr->data);
++instr;
Expand Down
22 changes: 20 additions & 2 deletions cel-c/internal/runtime/interpreter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1565,8 +1565,8 @@ static void _cel_Interpreter_PreVisitCallArgExpr(

// Returns the instruction kind for the duration/timestamp accessor `fn_name`,
// or `_cel_InstrKind_kUnreachable` if `fn_name` is not an accessor. Accessors
// accept (google.protobuf.Duration), (google.protobuf.Timestamp) or
// (google.protobuf.Timestamp, string).
// accept (google.protobuf.Timestamp) or (google.protobuf.Timestamp, string),
// and some additionally accept (google.protobuf.Duration).
CEL_ATTRIBUTE_NODISCARD
static _cel_InstrKind _cel_Interpreter_TimeAccessorKind(
cel_StringView fn_name) {
Expand All @@ -1582,6 +1582,24 @@ static _cel_InstrKind _cel_Interpreter_TimeAccessorKind(
if (cel_StringView_Equals(fn_name, cel_StringView_From("getMilliseconds"))) {
return _cel_InstrKind_kCallGetMilliseconds;
}
if (cel_StringView_Equals(fn_name, cel_StringView_From("getFullYear"))) {
return _cel_InstrKind_kCallGetFullYear;
}
if (cel_StringView_Equals(fn_name, cel_StringView_From("getMonth"))) {
return _cel_InstrKind_kCallGetMonth;
}
if (cel_StringView_Equals(fn_name, cel_StringView_From("getDate"))) {
return _cel_InstrKind_kCallGetDate;
}
if (cel_StringView_Equals(fn_name, cel_StringView_From("getDayOfMonth"))) {
return _cel_InstrKind_kCallGetDayOfMonth;
}
if (cel_StringView_Equals(fn_name, cel_StringView_From("getDayOfWeek"))) {
return _cel_InstrKind_kCallGetDayOfWeek;
}
if (cel_StringView_Equals(fn_name, cel_StringView_From("getDayOfYear"))) {
return _cel_InstrKind_kCallGetDayOfYear;
}
return _cel_InstrKind_kUnreachable;
}

Expand Down
Loading
Loading