@@ -64,139 +64,177 @@ void AppendEscaped(std::string* result, std::string_view str, bool escape_dot) {
6464 }
6565}
6666
67- absl::Status AppendTypeParameters (std::string* result, const Type& type );
67+ absl::Status AppendTypeDesc (std::string* result, const TypeSpec& type_spec );
6868
69- // Recursively appends a string representation of the given `type` to `result`.
70- // Type parameters are enclosed in angle brackets and separated by commas.
71- //
72- // Grammar:
73- // TypeDesc = NamespaceIdentifier [ "<" TypeList ">" ] ;
74- // NamespaceIdentifier = [ "." ] Identifier { "." Identifier } ;
75- // TypeList = TypeElem { "," TypeElem } ;
76- // TypeElem = TypeDesc | TypeParam
77- // TypeParam = "~" Alpha ;
78- // Identifier = ( Alpha | "_" ) { AlphaNumeric | "_" } ;
79- // (* Terminals *)
80- // Alpha = "a"..."z" | "A"..."Z" ;
81- // Digit = "0"..."9" ;
82- // AlphaNumeric = Alpha | Digit ;
83- //
84- // For compatibility, the implementation allows unexpected characters in
85- // type names and parameters and escapes them with a backslash.
86- absl::Status AppendTypeDesc (std::string* result, const Type& type) {
87- switch (type.kind ()) {
88- case TypeKind::kNull :
89- absl::StrAppend (result, " null" );
90- break ;
91- case TypeKind::kBool :
92- absl::StrAppend (result, " bool" );
93- break ;
94- case TypeKind::kInt :
95- absl::StrAppend (result, " int" );
96- break ;
97- case TypeKind::kUint :
98- absl::StrAppend (result, " uint" );
99- break ;
100- case TypeKind::kDouble :
101- absl::StrAppend (result, " double" );
102- break ;
103- case TypeKind::kString :
104- absl::StrAppend (result, " string" );
105- break ;
106- case TypeKind::kBytes :
107- absl::StrAppend (result, " bytes" );
108- break ;
109- case TypeKind::kDuration :
110- absl::StrAppend (result, " duration" );
111- break ;
112- case TypeKind::kTimestamp :
113- absl::StrAppend (result, " timestamp" );
114- break ;
115- case TypeKind::kAny :
116- absl::StrAppend (result, " any" );
117- break ;
118- case TypeKind::kDyn :
119- absl::StrAppend (result, " dyn" );
120- break ;
121- case TypeKind::kBoolWrapper :
122- absl::StrAppend (result, " bool_wrapper" );
123- break ;
124- case TypeKind::kIntWrapper :
125- absl::StrAppend (result, " int_wrapper" );
126- break ;
127- case TypeKind::kUintWrapper :
128- absl::StrAppend (result, " uint_wrapper" );
129- break ;
130- case TypeKind::kDoubleWrapper :
131- absl::StrAppend (result, " double_wrapper" );
132- break ;
133- case TypeKind::kStringWrapper :
134- absl::StrAppend (result, " string_wrapper" );
135- break ;
136- case TypeKind::kBytesWrapper :
137- absl::StrAppend (result, " bytes_wrapper" );
138- break ;
139- case TypeKind::kList :
140- absl::StrAppend (result, " list" );
141- CEL_RETURN_IF_ERROR (AppendTypeParameters (result, type));
142- break ;
143- case TypeKind::kMap :
144- absl::StrAppend (result, " map" );
145- CEL_RETURN_IF_ERROR (AppendTypeParameters (result, type));
146- break ;
147- case TypeKind::kFunction :
148- absl::StrAppend (result, " function" );
149- CEL_RETURN_IF_ERROR (AppendTypeParameters (result, type));
150- break ;
151- case TypeKind::kType :
152- absl::StrAppend (result, " type" );
153- CEL_RETURN_IF_ERROR (AppendTypeParameters (result, type));
154- break ;
155- case TypeKind::kTypeParam :
156- absl::StrAppend (result, " ~" );
157- AppendEscaped (result, type.GetTypeParam ().name (), /* escape_dot=*/ true );
158- break ;
159- case TypeKind::kOpaque :
160- AppendEscaped (result, type.name (), /* escape_dot=*/ false );
161- CEL_RETURN_IF_ERROR (AppendTypeParameters (result, type));
162- break ;
163- case TypeKind::kStruct :
164- AppendEscaped (result, type.name (), /* escape_dot=*/ false );
165- CEL_RETURN_IF_ERROR (AppendTypeParameters (result, type));
166- break ;
167- default :
168- return absl::InvalidArgumentError (
169- absl::StrFormat (" Type kind: %s is not supported in CEL declarations" ,
170- type.DebugString ()));
69+ absl::Status AppendTypeSpecList (std::string* result,
70+ const std::vector<TypeSpec>& params) {
71+ if (!params.empty ()) {
72+ result->push_back (' <' );
73+ for (size_t i = 0 ; i < params.size (); ++i) {
74+ CEL_RETURN_IF_ERROR (AppendTypeDesc (result, params[i]));
75+ if (i < params.size () - 1 ) {
76+ result->push_back (' ,' );
77+ }
78+ }
79+ result->push_back (' >' );
17180 }
17281 return absl::OkStatus ();
17382}
17483
175- absl::Status AppendTypeParameters (std::string* result, const Type& type) {
176- const auto & parameters = type.GetParameters ();
177- if (!parameters.empty ()) {
178- result->push_back (' <' );
179- for (size_t i = 0 ; i < parameters.size (); ++i) {
180- CEL_RETURN_IF_ERROR (AppendTypeDesc (result, parameters[i]));
181- if (i < parameters.size () - 1 ) {
84+ absl::Status AppendTypeDesc (std::string* result, const TypeSpec& type_spec) {
85+ if (type_spec.has_null ()) {
86+ absl::StrAppend (result, " null" );
87+ } else if (type_spec.has_dyn ()) {
88+ absl::StrAppend (result, " dyn" );
89+ } else if (type_spec.has_primitive ()) {
90+ switch (type_spec.primitive ()) {
91+ case PrimitiveType::kBool :
92+ absl::StrAppend (result, " bool" );
93+ break ;
94+ case PrimitiveType::kInt64 :
95+ absl::StrAppend (result, " int" );
96+ break ;
97+ case PrimitiveType::kUint64 :
98+ absl::StrAppend (result, " uint" );
99+ break ;
100+ case PrimitiveType::kDouble :
101+ absl::StrAppend (result, " double" );
102+ break ;
103+ case PrimitiveType::kString :
104+ absl::StrAppend (result, " string" );
105+ break ;
106+ case PrimitiveType::kBytes :
107+ absl::StrAppend (result, " bytes" );
108+ break ;
109+ default :
110+ return absl::InvalidArgumentError (" Unsupported primitive type" );
111+ }
112+ } else if (type_spec.has_well_known ()) {
113+ switch (type_spec.well_known ()) {
114+ case WellKnownTypeSpec::kAny :
115+ absl::StrAppend (result, " any" );
116+ break ;
117+ case WellKnownTypeSpec::kTimestamp :
118+ absl::StrAppend (result, " timestamp" );
119+ break ;
120+ case WellKnownTypeSpec::kDuration :
121+ absl::StrAppend (result, " duration" );
122+ break ;
123+ default :
124+ return absl::InvalidArgumentError (" Unsupported well-known type" );
125+ }
126+ } else if (type_spec.has_wrapper ()) {
127+ switch (type_spec.wrapper ()) {
128+ case PrimitiveType::kBool :
129+ absl::StrAppend (result, " bool_wrapper" );
130+ break ;
131+ case PrimitiveType::kInt64 :
132+ absl::StrAppend (result, " int_wrapper" );
133+ break ;
134+ case PrimitiveType::kUint64 :
135+ absl::StrAppend (result, " uint_wrapper" );
136+ break ;
137+ case PrimitiveType::kDouble :
138+ absl::StrAppend (result, " double_wrapper" );
139+ break ;
140+ case PrimitiveType::kString :
141+ absl::StrAppend (result, " string_wrapper" );
142+ break ;
143+ case PrimitiveType::kBytes :
144+ absl::StrAppend (result, " bytes_wrapper" );
145+ break ;
146+ default :
147+ return absl::InvalidArgumentError (" Unsupported wrapper type" );
148+ }
149+ } else if (type_spec.has_list_type ()) {
150+ absl::StrAppend (result, " list" );
151+ if (type_spec.list_type ().has_elem_type ()) {
152+ result->push_back (' <' );
153+ CEL_RETURN_IF_ERROR (
154+ AppendTypeDesc (result, type_spec.list_type ().elem_type ()));
155+ result->push_back (' >' );
156+ }
157+ } else if (type_spec.has_map_type ()) {
158+ absl::StrAppend (result, " map" );
159+ if (type_spec.map_type ().has_key_type () &&
160+ type_spec.map_type ().has_value_type ()) {
161+ result->push_back (' <' );
162+ CEL_RETURN_IF_ERROR (
163+ AppendTypeDesc (result, type_spec.map_type ().key_type ()));
164+ result->push_back (' ,' );
165+ CEL_RETURN_IF_ERROR (
166+ AppendTypeDesc (result, type_spec.map_type ().value_type ()));
167+ result->push_back (' >' );
168+ }
169+ } else if (type_spec.has_function ()) {
170+ absl::StrAppend (result, " function" );
171+ if (type_spec.function ().has_result_type () ||
172+ !type_spec.function ().arg_types ().empty ()) {
173+ result->push_back (' <' );
174+ if (type_spec.function ().has_result_type ()) {
175+ CEL_RETURN_IF_ERROR (
176+ AppendTypeDesc (result, type_spec.function ().result_type ()));
177+ } else {
178+ absl::StrAppend (result, " dyn" );
179+ }
180+ for (const auto & arg : type_spec.function ().arg_types ()) {
182181 result->push_back (' ,' );
182+ CEL_RETURN_IF_ERROR (AppendTypeDesc (result, arg));
183183 }
184+ result->push_back (' >' );
184185 }
186+ } else if (type_spec.has_type ()) {
187+ absl::StrAppend (result, " type" );
188+ result->push_back (' <' );
189+ CEL_RETURN_IF_ERROR (AppendTypeDesc (result, type_spec.type ()));
185190 result->push_back (' >' );
191+ } else if (type_spec.has_type_param ()) {
192+ absl::StrAppend (result, " ~" );
193+ AppendEscaped (result, type_spec.type_param ().type (), /* escape_dot=*/ true );
194+ } else if (type_spec.has_abstract_type ()) {
195+ AppendEscaped (result, type_spec.abstract_type ().name (),
196+ /* escape_dot=*/ false );
197+ CEL_RETURN_IF_ERROR (AppendTypeSpecList (
198+ result, type_spec.abstract_type ().parameter_types ()));
199+ } else if (type_spec.has_message_type ()) {
200+ AppendEscaped (result, type_spec.message_type ().type (),
201+ /* escape_dot=*/ false );
202+ } else {
203+ return absl::InvalidArgumentError (absl::StrCat (
204+ " Unsupported type in signature: " , FormatTypeSpec (type_spec)));
186205 }
187206 return absl::OkStatus ();
188207}
189208} // namespace
190209
191210absl::StatusOr<std::string> MakeTypeSignature (const Type& type) {
192211 std::string result;
193- CEL_RETURN_IF_ERROR (AppendTypeDesc (&result, type));
212+ CEL_ASSIGN_OR_RETURN (TypeSpec type_spec, ConvertTypeToTypeSpec (type));
213+ CEL_RETURN_IF_ERROR (AppendTypeDesc (&result, type_spec));
214+ return result;
215+ }
216+
217+ absl::StatusOr<std::string> MakeTypeSpecSignature (const TypeSpec& type_spec) {
218+ std::string result;
219+ CEL_RETURN_IF_ERROR (AppendTypeDesc (&result, type_spec));
194220 return result;
195221}
196222
197223absl::StatusOr<std::string> MakeOverloadSignature (
198224 std::string_view function_name, const std::vector<Type>& args,
199225 bool is_member) {
226+ std::vector<TypeSpec> arg_type_specs;
227+ arg_type_specs.reserve (args.size ());
228+ for (const auto & arg : args) {
229+ CEL_ASSIGN_OR_RETURN (TypeSpec type_spec, ConvertTypeToTypeSpec (arg));
230+ arg_type_specs.push_back (type_spec);
231+ }
232+ return MakeOverloadSignature (function_name, arg_type_specs, is_member);
233+ }
234+
235+ absl::StatusOr<std::string> MakeOverloadSignature (
236+ std::string_view function_name, const std::vector<TypeSpec>& args,
237+ bool is_member) {
200238 std::string result;
201239 if (is_member) {
202240 if (!args.empty ()) {
@@ -589,10 +627,14 @@ absl::StatusOr<ParsedFunctionOverload> ParseFunctionSignature(
589627 return out;
590628}
591629
630+ absl::StatusOr<TypeSpec> ParseTypeSpec (std::string_view signature) {
631+ std::string stripped_sig = StripUnescapedWhitespace (signature);
632+ return ParseTypeSignature (stripped_sig);
633+ }
634+
592635absl::StatusOr<Type> ParseType (std::string_view signature, google::protobuf::Arena* arena,
593636 const google::protobuf::DescriptorPool& pool) {
594- std::string stripped_sig = StripUnescapedWhitespace (signature);
595- CEL_ASSIGN_OR_RETURN (auto type_spec, ParseTypeSignature (stripped_sig));
637+ CEL_ASSIGN_OR_RETURN (auto type_spec, ParseTypeSpec (signature));
596638 return cel::ConvertTypeSpecToType (type_spec, arena, pool);
597639}
598640
0 commit comments