1use crate::call_type::{CallType, InstanceCreationType};
16use crate::generic_type_parameter::GenericTypeParameter;
17use crate::inferred_type::{DefaultType, TypeOrigin};
18use crate::parser::block::block;
19use crate::parser::type_name::TypeName;
20use crate::rib_source_span::SourceSpan;
21use crate::rib_type_error::RibTypeErrorInternal;
22use crate::{
23 from_string, text, type_checker, type_inference, ComponentDependencies, ComponentDependencyKey,
24 CustomInstanceSpec, DynamicParsedFunctionName, ExprVisitor, GlobalVariableTypeSpec,
25 InferredType, InstanceIdentifier, ParsedFunctionName, VariableId,
26};
27use bigdecimal::{BigDecimal, FromPrimitive, ToPrimitive};
28use combine::parser::char::spaces;
29use combine::stream::position;
30use combine::Parser;
31use combine::{eof, EasyParser};
32use golem_api_grpc::proto::golem::rib::range_expr::RangeExpr;
33use golem_wasm_ast::analysis::AnalysedType;
34use golem_wasm_rpc::{IntoValueAndType, ValueAndType};
35use serde::{Deserialize, Serialize, Serializer};
36use serde_json::Value;
37use std::collections::VecDeque;
38use std::fmt::Display;
39use std::ops::Deref;
40use std::str::FromStr;
41
42#[derive(Debug, Hash, Clone, PartialEq, Eq, PartialOrd, Ord)]
43pub enum Expr {
44 Let {
45 variable_id: VariableId,
46 type_annotation: Option<TypeName>,
47 expr: Box<Expr>,
48 inferred_type: InferredType,
49 source_span: SourceSpan,
50 },
51 SelectField {
52 expr: Box<Expr>,
53 field: String,
54 type_annotation: Option<TypeName>,
55 inferred_type: InferredType,
56 source_span: SourceSpan,
57 },
58 SelectIndex {
59 expr: Box<Expr>,
60 index: Box<Expr>,
61 type_annotation: Option<TypeName>,
62 inferred_type: InferredType,
63 source_span: SourceSpan,
64 },
65 Sequence {
66 exprs: Vec<Expr>,
67 type_annotation: Option<TypeName>,
68 inferred_type: InferredType,
69 source_span: SourceSpan,
70 },
71 Range {
72 range: Range,
73 type_annotation: Option<TypeName>,
74 inferred_type: InferredType,
75 source_span: SourceSpan,
76 },
77 Record {
78 exprs: Vec<(String, Box<Expr>)>,
79 type_annotation: Option<TypeName>,
80 inferred_type: InferredType,
81 source_span: SourceSpan,
82 },
83 Tuple {
84 exprs: Vec<Expr>,
85 type_annotation: Option<TypeName>,
86 inferred_type: InferredType,
87 source_span: SourceSpan,
88 },
89 Literal {
90 value: String,
91 type_annotation: Option<TypeName>,
92 inferred_type: InferredType,
93 source_span: SourceSpan,
94 },
95 Number {
96 number: Number,
97 type_annotation: Option<TypeName>,
98 inferred_type: InferredType,
99 source_span: SourceSpan,
100 },
101 Flags {
102 flags: Vec<String>,
103 type_annotation: Option<TypeName>,
104 inferred_type: InferredType,
105 source_span: SourceSpan,
106 },
107 Identifier {
108 variable_id: VariableId,
109 type_annotation: Option<TypeName>,
110 inferred_type: InferredType,
111 source_span: SourceSpan,
112 },
113 Boolean {
114 value: bool,
115 type_annotation: Option<TypeName>,
116 inferred_type: InferredType,
117 source_span: SourceSpan,
118 },
119 Concat {
120 exprs: Vec<Expr>,
121 type_annotation: Option<TypeName>,
122 inferred_type: InferredType,
123 source_span: SourceSpan,
124 },
125 ExprBlock {
126 exprs: Vec<Expr>,
127 type_annotation: Option<TypeName>,
128 inferred_type: InferredType,
129 source_span: SourceSpan,
130 },
131 Not {
132 expr: Box<Expr>,
133 inferred_type: InferredType,
134 type_annotation: Option<TypeName>,
135 source_span: SourceSpan,
136 },
137 GreaterThan {
138 lhs: Box<Expr>,
139 rhs: Box<Expr>,
140 type_annotation: Option<TypeName>,
141 inferred_type: InferredType,
142 source_span: SourceSpan,
143 },
144 And {
145 lhs: Box<Expr>,
146 rhs: Box<Expr>,
147 type_annotation: Option<TypeName>,
148 inferred_type: InferredType,
149 source_span: SourceSpan,
150 },
151 Or {
152 lhs: Box<Expr>,
153 rhs: Box<Expr>,
154 type_annotation: Option<TypeName>,
155 inferred_type: InferredType,
156 source_span: SourceSpan,
157 },
158 GreaterThanOrEqualTo {
159 lhs: Box<Expr>,
160 rhs: Box<Expr>,
161 type_annotation: Option<TypeName>,
162 inferred_type: InferredType,
163 source_span: SourceSpan,
164 },
165 LessThanOrEqualTo {
166 lhs: Box<Expr>,
167 rhs: Box<Expr>,
168 type_annotation: Option<TypeName>,
169 inferred_type: InferredType,
170 source_span: SourceSpan,
171 },
172 Plus {
173 lhs: Box<Expr>,
174 rhs: Box<Expr>,
175 type_annotation: Option<TypeName>,
176 inferred_type: InferredType,
177 source_span: SourceSpan,
178 },
179 Multiply {
180 lhs: Box<Expr>,
181 rhs: Box<Expr>,
182 type_annotation: Option<TypeName>,
183 inferred_type: InferredType,
184 source_span: SourceSpan,
185 },
186 Minus {
187 lhs: Box<Expr>,
188 rhs: Box<Expr>,
189 type_annotation: Option<TypeName>,
190 inferred_type: InferredType,
191 source_span: SourceSpan,
192 },
193 Divide {
194 lhs: Box<Expr>,
195 rhs: Box<Expr>,
196 type_annotation: Option<TypeName>,
197 inferred_type: InferredType,
198 source_span: SourceSpan,
199 },
200 EqualTo {
201 lhs: Box<Expr>,
202 rhs: Box<Expr>,
203 type_annotation: Option<TypeName>,
204 inferred_type: InferredType,
205 source_span: SourceSpan,
206 },
207 LessThan {
208 lhs: Box<Expr>,
209 rhs: Box<Expr>,
210 type_annotation: Option<TypeName>,
211 inferred_type: InferredType,
212 source_span: SourceSpan,
213 },
214 Cond {
215 cond: Box<Expr>,
216 lhs: Box<Expr>,
217 rhs: Box<Expr>,
218 type_annotation: Option<TypeName>,
219 inferred_type: InferredType,
220 source_span: SourceSpan,
221 },
222 PatternMatch {
223 predicate: Box<Expr>,
224 match_arms: Vec<MatchArm>,
225 type_annotation: Option<TypeName>,
226 inferred_type: InferredType,
227 source_span: SourceSpan,
228 },
229 Option {
230 expr: Option<Box<Expr>>,
231 type_annotation: Option<TypeName>,
232 inferred_type: InferredType,
233 source_span: SourceSpan,
234 },
235 Result {
236 expr: Result<Box<Expr>, Box<Expr>>,
237 type_annotation: Option<TypeName>,
238 inferred_type: InferredType,
239 source_span: SourceSpan,
240 },
241 Call {
247 call_type: CallType,
248 generic_type_parameter: Option<GenericTypeParameter>,
249 args: Vec<Expr>,
250 type_annotation: Option<TypeName>,
251 inferred_type: InferredType,
252 source_span: SourceSpan,
253 },
254 InvokeMethodLazy {
260 lhs: Box<Expr>,
261 method: String,
262 generic_type_parameter: Option<GenericTypeParameter>,
263 args: Vec<Expr>,
264 type_annotation: Option<TypeName>,
265 inferred_type: InferredType,
266 source_span: SourceSpan,
267 },
268 Unwrap {
269 expr: Box<Expr>,
270 inferred_type: InferredType,
271 type_annotation: Option<TypeName>,
272 source_span: SourceSpan,
273 },
274 Throw {
275 message: String,
276 inferred_type: InferredType,
277 type_annotation: Option<TypeName>,
278 source_span: SourceSpan,
279 },
280 GetTag {
281 expr: Box<Expr>,
282 inferred_type: InferredType,
283 type_annotation: Option<TypeName>,
284 source_span: SourceSpan,
285 },
286 ListComprehension {
287 iterated_variable: VariableId,
288 iterable_expr: Box<Expr>,
289 yield_expr: Box<Expr>,
290 type_annotation: Option<TypeName>,
291 inferred_type: InferredType,
292 source_span: SourceSpan,
293 },
294 ListReduce {
295 reduce_variable: VariableId,
296 iterated_variable: VariableId,
297 iterable_expr: Box<Expr>,
298 type_annotation: Option<TypeName>,
299 yield_expr: Box<Expr>,
300 init_value_expr: Box<Expr>,
301 inferred_type: InferredType,
302 source_span: SourceSpan,
303 },
304 Length {
305 expr: Box<Expr>,
306 inferred_type: InferredType,
307 type_annotation: Option<TypeName>,
308 source_span: SourceSpan,
309 },
310
311 GenerateWorkerName {
312 inferred_type: InferredType,
313 type_annotation: Option<TypeName>,
314 source_span: SourceSpan,
315 variable_id: Option<VariableId>,
316 },
317}
318
319impl Expr {
320 pub fn as_record(&self) -> Option<Vec<(String, Expr)>> {
321 match self {
322 Expr::Record { exprs: fields, .. } => Some(
323 fields
324 .iter()
325 .map(|(k, v)| (k.clone(), v.deref().clone()))
326 .collect::<Vec<_>>(),
327 ),
328 _ => None,
329 }
330 }
331 pub fn from_text(input: &str) -> Result<Expr, String> {
348 if input.trim().ends_with(';') {
349 return Err("unexpected `;` at the end of rib expression. \nnote: `;` is used to separate expressions, but it should not appear after the last expression (which is the return value)".to_string());
350 }
351
352 spaces()
353 .with(block().skip(eof()))
354 .easy_parse(position::Stream::new(input))
355 .map(|t| t.0)
356 .map_err(|err| format!("{err}"))
357 }
358
359 pub fn lookup(&self, source_span: &SourceSpan) -> Option<Expr> {
360 let mut expr = self.clone();
361 find_expr(&mut expr, source_span)
362 }
363
364 pub fn is_literal(&self) -> bool {
365 matches!(self, Expr::Literal { .. })
366 }
367
368 pub fn is_block(&self) -> bool {
369 matches!(self, Expr::ExprBlock { .. })
370 }
371
372 pub fn is_number(&self) -> bool {
373 matches!(self, Expr::Number { .. })
374 }
375
376 pub fn is_record(&self) -> bool {
377 matches!(self, Expr::Record { .. })
378 }
379
380 pub fn is_result(&self) -> bool {
381 matches!(self, Expr::Result { .. })
382 }
383
384 pub fn is_option(&self) -> bool {
385 matches!(self, Expr::Option { .. })
386 }
387
388 pub fn is_tuple(&self) -> bool {
389 matches!(self, Expr::Tuple { .. })
390 }
391
392 pub fn is_list(&self) -> bool {
393 matches!(self, Expr::Sequence { .. })
394 }
395
396 pub fn is_flags(&self) -> bool {
397 matches!(self, Expr::Flags { .. })
398 }
399
400 pub fn is_identifier(&self) -> bool {
401 matches!(self, Expr::Identifier { .. })
402 }
403
404 pub fn is_select_field(&self) -> bool {
405 matches!(self, Expr::SelectField { .. })
406 }
407
408 pub fn is_if_else(&self) -> bool {
409 matches!(self, Expr::Cond { .. })
410 }
411
412 pub fn is_function_call(&self) -> bool {
413 matches!(self, Expr::Call { .. })
414 }
415
416 pub fn is_match_expr(&self) -> bool {
417 matches!(self, Expr::PatternMatch { .. })
418 }
419
420 pub fn is_boolean(&self) -> bool {
421 matches!(self, Expr::Boolean { .. })
422 }
423
424 pub fn is_comparison(&self) -> bool {
425 matches!(
426 self,
427 Expr::GreaterThan { .. }
428 | Expr::GreaterThanOrEqualTo { .. }
429 | Expr::LessThanOrEqualTo { .. }
430 | Expr::EqualTo { .. }
431 | Expr::LessThan { .. }
432 )
433 }
434
435 pub fn is_concat(&self) -> bool {
436 matches!(self, Expr::Concat { .. })
437 }
438
439 pub fn is_multiple(&self) -> bool {
440 matches!(self, Expr::ExprBlock { .. })
441 }
442
443 pub fn inbuilt_variant(&self) -> Option<(String, Option<Expr>)> {
444 match self {
445 Expr::Option {
446 expr: Some(expr), ..
447 } => Some(("some".to_string(), Some(expr.deref().clone()))),
448 Expr::Option { expr: None, .. } => Some(("some".to_string(), None)),
449 Expr::Result { expr: Ok(expr), .. } => {
450 Some(("ok".to_string(), Some(expr.deref().clone())))
451 }
452 Expr::Result {
453 expr: Err(expr), ..
454 } => Some(("err".to_string(), Some(expr.deref().clone()))),
455 _ => None,
456 }
457 }
458 pub fn unwrap(&self) -> Self {
459 Expr::Unwrap {
460 expr: Box::new(self.clone()),
461 inferred_type: InferredType::unknown(),
462 source_span: SourceSpan::default(),
463 type_annotation: None,
464 }
465 }
466
467 pub fn length(expr: Expr) -> Self {
468 Expr::Length {
469 expr: Box::new(expr),
470 inferred_type: InferredType::u64(),
471 source_span: SourceSpan::default(),
472 type_annotation: None,
473 }
474 }
475
476 pub fn boolean(value: bool) -> Self {
477 Expr::Boolean {
478 value,
479 inferred_type: InferredType::bool(),
480 source_span: SourceSpan::default(),
481 type_annotation: None,
482 }
483 }
484
485 pub fn and(left: Expr, right: Expr) -> Self {
486 Expr::And {
487 lhs: Box::new(left),
488 rhs: Box::new(right),
489 inferred_type: InferredType::bool(),
490 source_span: SourceSpan::default(),
491 type_annotation: None,
492 }
493 }
494
495 pub fn throw(message: impl AsRef<str>) -> Self {
496 Expr::Throw {
497 message: message.as_ref().to_string(),
498 inferred_type: InferredType::unknown(),
499 source_span: SourceSpan::default(),
500 type_annotation: None,
501 }
502 }
503
504 pub fn generate_worker_name(variable_id: Option<VariableId>) -> Self {
505 Expr::GenerateWorkerName {
506 inferred_type: InferredType::string(),
507 type_annotation: None,
508 source_span: SourceSpan::default(),
509 variable_id,
510 }
511 }
512
513 pub fn plus(left: Expr, right: Expr) -> Self {
514 Expr::Plus {
515 lhs: Box::new(left),
516 rhs: Box::new(right),
517 inferred_type: InferredType::unknown(),
518 source_span: SourceSpan::default(),
519 type_annotation: None,
520 }
521 }
522
523 pub fn minus(left: Expr, right: Expr) -> Self {
524 Expr::Minus {
525 lhs: Box::new(left),
526 rhs: Box::new(right),
527 inferred_type: InferredType::unknown(),
528 source_span: SourceSpan::default(),
529 type_annotation: None,
530 }
531 }
532
533 pub fn divide(left: Expr, right: Expr) -> Self {
534 Expr::Divide {
535 lhs: Box::new(left),
536 rhs: Box::new(right),
537 inferred_type: InferredType::unknown(),
538 source_span: SourceSpan::default(),
539 type_annotation: None,
540 }
541 }
542
543 pub fn multiply(left: Expr, right: Expr) -> Self {
544 Expr::Multiply {
545 lhs: Box::new(left),
546 rhs: Box::new(right),
547 inferred_type: InferredType::unknown(),
548 source_span: SourceSpan::default(),
549 type_annotation: None,
550 }
551 }
552
553 pub fn and_combine(conditions: Vec<Expr>) -> Option<Expr> {
554 let mut cond: Option<Expr> = None;
555
556 for i in conditions {
557 let left = Box::new(cond.clone().unwrap_or(Expr::boolean(true)));
558 cond = Some(Expr::And {
559 lhs: left,
560 rhs: Box::new(i),
561 inferred_type: InferredType::bool(),
562 source_span: SourceSpan::default(),
563 type_annotation: None,
564 });
565 }
566
567 cond
568 }
569
570 pub fn call_worker_function(
571 dynamic_parsed_fn_name: DynamicParsedFunctionName,
572 generic_type_parameter: Option<GenericTypeParameter>,
573 module_identifier: Option<InstanceIdentifier>,
574 args: Vec<Expr>,
575 component_info: Option<ComponentDependencyKey>,
576 ) -> Self {
577 Expr::Call {
578 call_type: CallType::Function {
579 function_name: dynamic_parsed_fn_name,
580 instance_identifier: module_identifier.map(Box::new),
581 component_info,
582 },
583 generic_type_parameter,
584 args,
585 inferred_type: InferredType::unknown(),
586 source_span: SourceSpan::default(),
587 type_annotation: None,
588 }
589 }
590
591 pub fn call(
592 call_type: CallType,
593 generic_type_parameter: Option<GenericTypeParameter>,
594 args: Vec<Expr>,
595 ) -> Self {
596 Expr::Call {
597 call_type,
598 generic_type_parameter,
599 args,
600 inferred_type: InferredType::unknown(),
601 source_span: SourceSpan::default(),
602 type_annotation: None,
603 }
604 }
605
606 pub fn invoke_worker_function(
607 lhs: Expr,
608 function_name: String,
609 generic_type_parameter: Option<GenericTypeParameter>,
610 args: Vec<Expr>,
611 ) -> Self {
612 Expr::InvokeMethodLazy {
613 lhs: Box::new(lhs),
614 method: function_name,
615 generic_type_parameter,
616 args,
617 inferred_type: InferredType::unknown(),
618 source_span: SourceSpan::default(),
619 type_annotation: None,
620 }
621 }
622
623 pub fn concat(expressions: Vec<Expr>) -> Self {
624 Expr::Concat {
625 exprs: expressions,
626 inferred_type: InferredType::string(),
627 source_span: SourceSpan::default(),
628 type_annotation: None,
629 }
630 }
631
632 pub fn cond(cond: Expr, lhs: Expr, rhs: Expr) -> Self {
633 Expr::Cond {
634 cond: Box::new(cond),
635 lhs: Box::new(lhs),
636 rhs: Box::new(rhs),
637 inferred_type: InferredType::unknown(),
638 source_span: SourceSpan::default(),
639 type_annotation: None,
640 }
641 }
642
643 pub fn equal_to(left: Expr, right: Expr) -> Self {
644 Expr::EqualTo {
645 lhs: Box::new(left),
646 rhs: Box::new(right),
647 inferred_type: InferredType::bool(),
648 source_span: SourceSpan::default(),
649 type_annotation: None,
650 }
651 }
652
653 pub fn err(expr: Expr, type_annotation: Option<TypeName>) -> Self {
654 let inferred_type = expr.inferred_type();
655 Expr::Result {
656 expr: Err(Box::new(expr)),
657 type_annotation,
658 inferred_type: InferredType::result(Some(InferredType::unknown()), Some(inferred_type)),
659 source_span: SourceSpan::default(),
660 }
661 }
662
663 pub fn flags(flags: Vec<String>) -> Self {
664 Expr::Flags {
665 flags: flags.clone(),
666 inferred_type: InferredType::flags(flags),
667 source_span: SourceSpan::default(),
668 type_annotation: None,
669 }
670 }
671
672 pub fn greater_than(left: Expr, right: Expr) -> Self {
673 Expr::GreaterThan {
674 lhs: Box::new(left),
675 rhs: Box::new(right),
676 inferred_type: InferredType::bool(),
677 source_span: SourceSpan::default(),
678 type_annotation: None,
679 }
680 }
681
682 pub fn greater_than_or_equal_to(left: Expr, right: Expr) -> Self {
683 Expr::GreaterThanOrEqualTo {
684 lhs: Box::new(left),
685 rhs: Box::new(right),
686 inferred_type: InferredType::bool(),
687 source_span: SourceSpan::default(),
688 type_annotation: None,
689 }
690 }
691
692 pub fn identifier_global(name: impl AsRef<str>, type_annotation: Option<TypeName>) -> Self {
694 Expr::Identifier {
695 variable_id: VariableId::global(name.as_ref().to_string()),
696 type_annotation,
697 inferred_type: InferredType::unknown(),
698 source_span: SourceSpan::default(),
699 }
700 }
701
702 pub fn identifier_local(
703 name: impl AsRef<str>,
704 id: u32,
705 type_annotation: Option<TypeName>,
706 ) -> Self {
707 Expr::Identifier {
708 variable_id: VariableId::local(name.as_ref(), id),
709 type_annotation,
710 inferred_type: InferredType::unknown(),
711 source_span: SourceSpan::default(),
712 }
713 }
714
715 pub fn identifier_with_variable_id(
716 variable_id: VariableId,
717 type_annotation: Option<TypeName>,
718 ) -> Self {
719 Expr::Identifier {
720 variable_id,
721 type_annotation,
722 inferred_type: InferredType::unknown(),
723 source_span: SourceSpan::default(),
724 }
725 }
726
727 pub fn less_than(left: Expr, right: Expr) -> Self {
728 Expr::LessThan {
729 lhs: Box::new(left),
730 rhs: Box::new(right),
731 inferred_type: InferredType::bool(),
732 source_span: SourceSpan::default(),
733 type_annotation: None,
734 }
735 }
736
737 pub fn less_than_or_equal_to(left: Expr, right: Expr) -> Self {
738 Expr::LessThanOrEqualTo {
739 lhs: Box::new(left),
740 rhs: Box::new(right),
741 inferred_type: InferredType::bool(),
742 source_span: SourceSpan::default(),
743 type_annotation: None,
744 }
745 }
746
747 pub fn range(from: Expr, to: Expr) -> Self {
748 Expr::Range {
749 range: Range::Range {
750 from: Box::new(from.clone()),
751 to: Box::new(to.clone()),
752 },
753 inferred_type: InferredType::range(from.inferred_type(), Some(to.inferred_type())),
754 source_span: SourceSpan::default(),
755 type_annotation: None,
756 }
757 }
758
759 pub fn range_from(from: Expr) -> Self {
760 Expr::Range {
761 range: Range::RangeFrom {
762 from: Box::new(from.clone()),
763 },
764 inferred_type: InferredType::range(from.inferred_type(), None),
765 source_span: SourceSpan::default(),
766 type_annotation: None,
767 }
768 }
769
770 pub fn range_inclusive(from: Expr, to: Expr) -> Self {
771 Expr::Range {
772 range: Range::RangeInclusive {
773 from: Box::new(from.clone()),
774 to: Box::new(to.clone()),
775 },
776 inferred_type: InferredType::range(from.inferred_type(), Some(to.inferred_type())),
777 source_span: SourceSpan::default(),
778 type_annotation: None,
779 }
780 }
781
782 pub fn let_binding(
783 name: impl AsRef<str>,
784 expr: Expr,
785 type_annotation: Option<TypeName>,
786 ) -> Self {
787 Expr::Let {
788 variable_id: VariableId::global(name.as_ref().to_string()),
789 type_annotation,
790 expr: Box::new(expr),
791 source_span: SourceSpan::default(),
792 inferred_type: InferredType::tuple(vec![]),
793 }
794 }
795
796 pub fn let_binding_with_variable_id(
797 variable_id: VariableId,
798 expr: Expr,
799 type_annotation: Option<TypeName>,
800 ) -> Self {
801 Expr::Let {
802 variable_id,
803 type_annotation,
804 expr: Box::new(expr),
805 source_span: SourceSpan::default(),
806 inferred_type: InferredType::tuple(vec![]),
807 }
808 }
809
810 pub fn typed_list_reduce(
811 reduce_variable: VariableId,
812 iterated_variable: VariableId,
813 iterable_expr: Expr,
814 init_value_expr: Expr,
815 yield_expr: Expr,
816 inferred_type: InferredType,
817 ) -> Self {
818 Expr::ListReduce {
819 reduce_variable,
820 iterated_variable,
821 iterable_expr: Box::new(iterable_expr),
822 yield_expr: Box::new(yield_expr),
823 init_value_expr: Box::new(init_value_expr),
824 inferred_type,
825 source_span: SourceSpan::default(),
826 type_annotation: None,
827 }
828 }
829
830 pub fn list_reduce(
831 reduce_variable: VariableId,
832 iterated_variable: VariableId,
833 iterable_expr: Expr,
834 init_value_expr: Expr,
835 yield_expr: Expr,
836 ) -> Self {
837 Expr::typed_list_reduce(
838 reduce_variable,
839 iterated_variable,
840 iterable_expr,
841 init_value_expr,
842 yield_expr,
843 InferredType::unknown(),
844 )
845 }
846
847 pub fn list_comprehension_typed(
848 iterated_variable: VariableId,
849 iterable_expr: Expr,
850 yield_expr: Expr,
851 inferred_type: InferredType,
852 ) -> Self {
853 Expr::ListComprehension {
854 iterated_variable,
855 iterable_expr: Box::new(iterable_expr),
856 yield_expr: Box::new(yield_expr),
857 inferred_type,
858 source_span: SourceSpan::default(),
859 type_annotation: None,
860 }
861 }
862
863 pub fn list_comprehension(
864 variable_id: VariableId,
865 iterable_expr: Expr,
866 yield_expr: Expr,
867 ) -> Self {
868 Expr::list_comprehension_typed(
869 variable_id,
870 iterable_expr,
871 yield_expr,
872 InferredType::list(InferredType::unknown()),
873 )
874 }
875
876 pub fn bind_global_variable_types(&mut self, type_spec: &Vec<GlobalVariableTypeSpec>) {
877 type_inference::bind_global_variable_types(self, type_spec)
878 }
879
880 pub fn bind_instance_types(&mut self) {
881 type_inference::bind_instance_types(self)
882 }
883
884 pub fn literal(value: impl AsRef<str>) -> Self {
885 let default_type = DefaultType::String;
886
887 Expr::Literal {
888 value: value.as_ref().to_string(),
889 inferred_type: InferredType::from(&default_type),
890 source_span: SourceSpan::default(),
891 type_annotation: None,
892 }
893 }
894
895 pub fn empty_expr() -> Self {
896 Expr::literal("")
897 }
898
899 pub fn expr_block(expressions: Vec<Expr>) -> Self {
900 let inferred_type = expressions
901 .last()
902 .map_or(InferredType::unknown(), |e| e.inferred_type());
903
904 Expr::ExprBlock {
905 exprs: expressions,
906 inferred_type,
907 source_span: SourceSpan::default(),
908 type_annotation: None,
909 }
910 }
911
912 #[allow(clippy::should_implement_trait)]
913 pub fn not(expr: Expr) -> Self {
914 Expr::Not {
915 expr: Box::new(expr),
916 inferred_type: InferredType::bool(),
917 source_span: SourceSpan::default(),
918 type_annotation: None,
919 }
920 }
921
922 pub fn ok(expr: Expr, type_annotation: Option<TypeName>) -> Self {
923 let inferred_type = expr.inferred_type();
924
925 Expr::Result {
926 expr: Ok(Box::new(expr)),
927 type_annotation,
928 inferred_type: InferredType::result(Some(inferred_type), Some(InferredType::unknown())),
929 source_span: SourceSpan::default(),
930 }
931 }
932
933 pub fn option(expr: Option<Expr>) -> Self {
934 let inferred_type = match &expr {
935 Some(expr) => expr.inferred_type(),
936 None => InferredType::unknown(),
937 };
938
939 Expr::Option {
940 expr: expr.map(Box::new),
941 type_annotation: None,
942 inferred_type: InferredType::option(inferred_type),
943 source_span: SourceSpan::default(),
944 }
945 }
946
947 pub fn or(left: Expr, right: Expr) -> Self {
948 Expr::Or {
949 lhs: Box::new(left),
950 rhs: Box::new(right),
951 inferred_type: InferredType::bool(),
952 source_span: SourceSpan::default(),
953 type_annotation: None,
954 }
955 }
956
957 pub fn pattern_match(expr: Expr, match_arms: Vec<MatchArm>) -> Self {
958 Expr::PatternMatch {
959 predicate: Box::new(expr),
960 match_arms,
961 inferred_type: InferredType::unknown(),
962 source_span: SourceSpan::default(),
963 type_annotation: None,
964 }
965 }
966
967 pub fn record(expressions: Vec<(String, Expr)>) -> Self {
968 let inferred_type = InferredType::record(
969 expressions
970 .iter()
971 .map(|(field_name, expr)| (field_name.to_string(), expr.inferred_type()))
972 .collect(),
973 );
974
975 Expr::Record {
976 exprs: expressions
977 .into_iter()
978 .map(|(field_name, expr)| (field_name, Box::new(expr)))
979 .collect(),
980 inferred_type,
981 source_span: SourceSpan::default(),
982 type_annotation: None,
983 }
984 }
985
986 pub fn select_field(
987 expr: Expr,
988 field: impl AsRef<str>,
989 type_annotation: Option<TypeName>,
990 ) -> Self {
991 Expr::SelectField {
992 expr: Box::new(expr),
993 field: field.as_ref().to_string(),
994 type_annotation,
995 inferred_type: InferredType::unknown(),
996 source_span: SourceSpan::default(),
997 }
998 }
999
1000 pub fn select_index(expr: Expr, index: Expr) -> Self {
1001 Expr::SelectIndex {
1002 expr: Box::new(expr),
1003 index: Box::new(index),
1004 type_annotation: None,
1005 inferred_type: InferredType::unknown(),
1006 source_span: SourceSpan::default(),
1007 }
1008 }
1009
1010 pub fn get_tag(expr: Expr) -> Self {
1011 Expr::GetTag {
1012 expr: Box::new(expr),
1013 inferred_type: InferredType::unknown(),
1014 source_span: SourceSpan::default(),
1015 type_annotation: None,
1016 }
1017 }
1018
1019 pub fn tuple(expressions: Vec<Expr>) -> Self {
1020 let inferred_type = InferredType::tuple(
1021 expressions
1022 .iter()
1023 .map(|expr| expr.inferred_type())
1024 .collect(),
1025 );
1026
1027 Expr::Tuple {
1028 exprs: expressions,
1029 inferred_type,
1030 source_span: SourceSpan::default(),
1031 type_annotation: None,
1032 }
1033 }
1034
1035 pub fn sequence(expressions: Vec<Expr>, type_annotation: Option<TypeName>) -> Self {
1036 let inferred_type = InferredType::list(
1037 expressions
1038 .first()
1039 .map_or(InferredType::unknown(), |x| x.inferred_type()),
1040 );
1041
1042 Expr::Sequence {
1043 exprs: expressions,
1044 type_annotation,
1045 inferred_type,
1046 source_span: SourceSpan::default(),
1047 }
1048 }
1049
1050 pub fn inferred_type_mut(&mut self) -> &mut InferredType {
1051 match self {
1052 Expr::Let { inferred_type, .. }
1053 | Expr::SelectField { inferred_type, .. }
1054 | Expr::SelectIndex { inferred_type, .. }
1055 | Expr::Sequence { inferred_type, .. }
1056 | Expr::Record { inferred_type, .. }
1057 | Expr::Tuple { inferred_type, .. }
1058 | Expr::Literal { inferred_type, .. }
1059 | Expr::Number { inferred_type, .. }
1060 | Expr::Flags { inferred_type, .. }
1061 | Expr::Identifier { inferred_type, .. }
1062 | Expr::Boolean { inferred_type, .. }
1063 | Expr::Concat { inferred_type, .. }
1064 | Expr::ExprBlock { inferred_type, .. }
1065 | Expr::Not { inferred_type, .. }
1066 | Expr::GreaterThan { inferred_type, .. }
1067 | Expr::GreaterThanOrEqualTo { inferred_type, .. }
1068 | Expr::LessThanOrEqualTo { inferred_type, .. }
1069 | Expr::EqualTo { inferred_type, .. }
1070 | Expr::Plus { inferred_type, .. }
1071 | Expr::Minus { inferred_type, .. }
1072 | Expr::Divide { inferred_type, .. }
1073 | Expr::Multiply { inferred_type, .. }
1074 | Expr::LessThan { inferred_type, .. }
1075 | Expr::Cond { inferred_type, .. }
1076 | Expr::PatternMatch { inferred_type, .. }
1077 | Expr::Option { inferred_type, .. }
1078 | Expr::Result { inferred_type, .. }
1079 | Expr::Unwrap { inferred_type, .. }
1080 | Expr::Throw { inferred_type, .. }
1081 | Expr::GetTag { inferred_type, .. }
1082 | Expr::And { inferred_type, .. }
1083 | Expr::Or { inferred_type, .. }
1084 | Expr::ListComprehension { inferred_type, .. }
1085 | Expr::ListReduce { inferred_type, .. }
1086 | Expr::Call { inferred_type, .. }
1087 | Expr::Range { inferred_type, .. }
1088 | Expr::InvokeMethodLazy { inferred_type, .. }
1089 | Expr::Length { inferred_type, .. }
1090 | Expr::GenerateWorkerName { inferred_type, .. } => &mut *inferred_type,
1091 }
1092 }
1093
1094 pub fn inferred_type(&self) -> InferredType {
1095 match self {
1096 Expr::Let { inferred_type, .. }
1097 | Expr::SelectField { inferred_type, .. }
1098 | Expr::SelectIndex { inferred_type, .. }
1099 | Expr::Sequence { inferred_type, .. }
1100 | Expr::Record { inferred_type, .. }
1101 | Expr::Tuple { inferred_type, .. }
1102 | Expr::Literal { inferred_type, .. }
1103 | Expr::Number { inferred_type, .. }
1104 | Expr::Flags { inferred_type, .. }
1105 | Expr::Identifier { inferred_type, .. }
1106 | Expr::Boolean { inferred_type, .. }
1107 | Expr::Concat { inferred_type, .. }
1108 | Expr::ExprBlock { inferred_type, .. }
1109 | Expr::Not { inferred_type, .. }
1110 | Expr::GreaterThan { inferred_type, .. }
1111 | Expr::GreaterThanOrEqualTo { inferred_type, .. }
1112 | Expr::LessThanOrEqualTo { inferred_type, .. }
1113 | Expr::EqualTo { inferred_type, .. }
1114 | Expr::Plus { inferred_type, .. }
1115 | Expr::Minus { inferred_type, .. }
1116 | Expr::Divide { inferred_type, .. }
1117 | Expr::Multiply { inferred_type, .. }
1118 | Expr::LessThan { inferred_type, .. }
1119 | Expr::Cond { inferred_type, .. }
1120 | Expr::PatternMatch { inferred_type, .. }
1121 | Expr::Option { inferred_type, .. }
1122 | Expr::Result { inferred_type, .. }
1123 | Expr::Unwrap { inferred_type, .. }
1124 | Expr::Throw { inferred_type, .. }
1125 | Expr::GetTag { inferred_type, .. }
1126 | Expr::And { inferred_type, .. }
1127 | Expr::Or { inferred_type, .. }
1128 | Expr::ListComprehension { inferred_type, .. }
1129 | Expr::ListReduce { inferred_type, .. }
1130 | Expr::Call { inferred_type, .. }
1131 | Expr::Range { inferred_type, .. }
1132 | Expr::InvokeMethodLazy { inferred_type, .. }
1133 | Expr::Length { inferred_type, .. }
1134 | Expr::GenerateWorkerName { inferred_type, .. } => inferred_type.clone(),
1135 }
1136 }
1137
1138 pub fn infer_types(
1139 &mut self,
1140 component_dependency: &ComponentDependencies,
1141 global_variable_type_spec: &Vec<GlobalVariableTypeSpec>,
1142 custom_instance_spec: &[CustomInstanceSpec],
1143 ) -> Result<(), RibTypeErrorInternal> {
1144 self.infer_types_initial_phase(
1145 component_dependency,
1146 global_variable_type_spec,
1147 custom_instance_spec,
1148 )?;
1149 self.bind_instance_types();
1150 type_inference::type_inference_fix_point(Self::resolve_method_calls, self)?;
1155 self.infer_function_call_types(component_dependency, custom_instance_spec)?;
1156 type_inference::type_inference_fix_point(
1157 |x| Self::inference_scan(x, component_dependency, custom_instance_spec),
1158 self,
1159 )?;
1160 self.check_types(component_dependency)?;
1161 self.unify_types()?;
1162 Ok(())
1163 }
1164
1165 pub fn infer_types_initial_phase(
1166 &mut self,
1167 component_dependency: &ComponentDependencies,
1168 global_variable_type_spec: &Vec<GlobalVariableTypeSpec>,
1169 custom_instance_spec: &[CustomInstanceSpec],
1170 ) -> Result<(), RibTypeErrorInternal> {
1171 self.set_origin();
1172 self.bind_global_variable_types(global_variable_type_spec);
1173 self.bind_type_annotations();
1174 self.bind_variables_of_list_comprehension();
1175 self.bind_variables_of_list_reduce();
1176 self.bind_variables_of_pattern_match();
1177 self.bind_variables_of_let_assignment();
1178 self.identify_instance_creation(component_dependency, custom_instance_spec)?;
1179 self.ensure_stateful_instance();
1180 self.infer_variants(component_dependency);
1181 self.infer_enums(component_dependency);
1182 Ok(())
1183 }
1184
1185 pub fn resolve_method_calls(&mut self) -> Result<(), RibTypeErrorInternal> {
1186 self.bind_instance_types();
1187 self.infer_worker_function_invokes()?;
1188 Ok(())
1189 }
1190
1191 pub fn set_origin(&mut self) {
1192 let mut visitor = ExprVisitor::bottom_up(self);
1193
1194 while let Some(expr) = visitor.pop_front() {
1195 let source_location = expr.source_span();
1196 let origin = TypeOrigin::OriginatedAt(source_location.clone());
1197 let inferred_type = expr.inferred_type();
1198 let origin = inferred_type.add_origin(origin);
1199 expr.with_inferred_type_mut(origin);
1200 }
1201 }
1202
1203 pub fn inference_scan(
1207 &mut self,
1208 component_dependencies: &ComponentDependencies,
1209 custom_instance_spec: &[CustomInstanceSpec],
1210 ) -> Result<(), RibTypeErrorInternal> {
1211 self.infer_all_identifiers();
1212 self.push_types_down()?;
1213 self.infer_all_identifiers();
1214 self.pull_types_up(component_dependencies)?;
1215 self.infer_global_inputs();
1216 self.infer_function_call_types(component_dependencies, custom_instance_spec)?;
1217 Ok(())
1218 }
1219
1220 pub fn infer_worker_function_invokes(&mut self) -> Result<(), RibTypeErrorInternal> {
1221 type_inference::infer_worker_function_invokes(self)
1222 }
1223
1224 pub fn bind_variables_of_pattern_match(&mut self) {
1228 type_inference::bind_variables_of_pattern_match(self);
1229 }
1230
1231 pub fn bind_variables_of_let_assignment(&mut self) {
1235 type_inference::bind_variables_of_let_assignment(self);
1236 }
1237
1238 pub fn bind_variables_of_list_comprehension(&mut self) {
1239 type_inference::bind_variables_of_list_comprehension(self);
1240 }
1241
1242 pub fn bind_variables_of_list_reduce(&mut self) {
1243 type_inference::bind_variables_of_list_reduce(self);
1244 }
1245
1246 pub fn identify_instance_creation(
1247 &mut self,
1248 component_dependency: &ComponentDependencies,
1249 custom_instance_spec: &[CustomInstanceSpec],
1250 ) -> Result<(), RibTypeErrorInternal> {
1251 type_inference::identify_instance_creation(self, component_dependency, custom_instance_spec)
1252 }
1253
1254 pub fn ensure_stateful_instance(&mut self) {
1255 type_inference::ensure_stateful_instance(self)
1256 }
1257
1258 pub fn infer_function_call_types(
1259 &mut self,
1260 component_dependency: &ComponentDependencies,
1261 custom_instance_spec: &[CustomInstanceSpec],
1262 ) -> Result<(), RibTypeErrorInternal> {
1263 type_inference::infer_function_call_types(
1264 self,
1265 component_dependency,
1266 custom_instance_spec,
1267 )?;
1268 Ok(())
1269 }
1270
1271 pub fn push_types_down(&mut self) -> Result<(), RibTypeErrorInternal> {
1272 type_inference::push_types_down(self)
1273 }
1274
1275 pub fn infer_all_identifiers(&mut self) {
1276 type_inference::infer_all_identifiers(self)
1277 }
1278
1279 pub fn pull_types_up(
1280 &mut self,
1281 component_dependencies: &ComponentDependencies,
1282 ) -> Result<(), RibTypeErrorInternal> {
1283 type_inference::type_pull_up(self, component_dependencies)
1284 }
1285
1286 pub fn infer_global_inputs(&mut self) {
1287 type_inference::infer_global_inputs(self);
1288 }
1289
1290 pub fn bind_type_annotations(&mut self) {
1291 type_inference::bind_type_annotations(self);
1292 }
1293
1294 pub fn check_types(
1295 &mut self,
1296 component_dependency: &ComponentDependencies,
1297 ) -> Result<(), RibTypeErrorInternal> {
1298 type_checker::type_check(self, component_dependency)
1299 }
1300
1301 pub fn unify_types(&mut self) -> Result<(), RibTypeErrorInternal> {
1302 type_inference::unify_types(self)?;
1303 Ok(())
1304 }
1305
1306 pub fn merge_inferred_type(&self, new_inferred_type: InferredType) -> Expr {
1307 let mut expr_copied = self.clone();
1308 expr_copied.add_infer_type_mut(new_inferred_type);
1309 expr_copied
1310 }
1311
1312 pub fn add_infer_type_mut(&mut self, new_inferred_type: InferredType) {
1313 match self {
1314 Expr::Identifier { inferred_type, .. }
1315 | Expr::Let { inferred_type, .. }
1316 | Expr::SelectField { inferred_type, .. }
1317 | Expr::SelectIndex { inferred_type, .. }
1318 | Expr::Sequence { inferred_type, .. }
1319 | Expr::Record { inferred_type, .. }
1320 | Expr::Tuple { inferred_type, .. }
1321 | Expr::Literal { inferred_type, .. }
1322 | Expr::Number { inferred_type, .. }
1323 | Expr::Flags { inferred_type, .. }
1324 | Expr::Boolean { inferred_type, .. }
1325 | Expr::Concat { inferred_type, .. }
1326 | Expr::ExprBlock { inferred_type, .. }
1327 | Expr::Not { inferred_type, .. }
1328 | Expr::GreaterThan { inferred_type, .. }
1329 | Expr::GreaterThanOrEqualTo { inferred_type, .. }
1330 | Expr::LessThanOrEqualTo { inferred_type, .. }
1331 | Expr::EqualTo { inferred_type, .. }
1332 | Expr::Plus { inferred_type, .. }
1333 | Expr::Minus { inferred_type, .. }
1334 | Expr::Divide { inferred_type, .. }
1335 | Expr::Multiply { inferred_type, .. }
1336 | Expr::LessThan { inferred_type, .. }
1337 | Expr::Cond { inferred_type, .. }
1338 | Expr::PatternMatch { inferred_type, .. }
1339 | Expr::Option { inferred_type, .. }
1340 | Expr::Result { inferred_type, .. }
1341 | Expr::Unwrap { inferred_type, .. }
1342 | Expr::Throw { inferred_type, .. }
1343 | Expr::GetTag { inferred_type, .. }
1344 | Expr::And { inferred_type, .. }
1345 | Expr::Or { inferred_type, .. }
1346 | Expr::ListComprehension { inferred_type, .. }
1347 | Expr::ListReduce { inferred_type, .. }
1348 | Expr::InvokeMethodLazy { inferred_type, .. }
1349 | Expr::Range { inferred_type, .. }
1350 | Expr::Length { inferred_type, .. }
1351 | Expr::GenerateWorkerName { inferred_type, .. }
1352 | Expr::Call { inferred_type, .. } => {
1353 if !new_inferred_type.is_unknown() {
1354 *inferred_type = inferred_type.merge(new_inferred_type);
1355 }
1356 }
1357 }
1358 }
1359
1360 pub fn reset_type(&mut self) {
1361 type_inference::reset_type_info(self);
1362 }
1363
1364 pub fn source_span(&self) -> SourceSpan {
1365 match self {
1366 Expr::Identifier { source_span, .. }
1367 | Expr::Let { source_span, .. }
1368 | Expr::SelectField { source_span, .. }
1369 | Expr::SelectIndex { source_span, .. }
1370 | Expr::Sequence { source_span, .. }
1371 | Expr::Record { source_span, .. }
1372 | Expr::Tuple { source_span, .. }
1373 | Expr::Literal { source_span, .. }
1374 | Expr::Number { source_span, .. }
1375 | Expr::Flags { source_span, .. }
1376 | Expr::Boolean { source_span, .. }
1377 | Expr::Concat { source_span, .. }
1378 | Expr::ExprBlock { source_span, .. }
1379 | Expr::Not { source_span, .. }
1380 | Expr::GreaterThan { source_span, .. }
1381 | Expr::GreaterThanOrEqualTo { source_span, .. }
1382 | Expr::LessThanOrEqualTo { source_span, .. }
1383 | Expr::EqualTo { source_span, .. }
1384 | Expr::LessThan { source_span, .. }
1385 | Expr::Plus { source_span, .. }
1386 | Expr::Minus { source_span, .. }
1387 | Expr::Divide { source_span, .. }
1388 | Expr::Multiply { source_span, .. }
1389 | Expr::Cond { source_span, .. }
1390 | Expr::PatternMatch { source_span, .. }
1391 | Expr::Option { source_span, .. }
1392 | Expr::Result { source_span, .. }
1393 | Expr::Unwrap { source_span, .. }
1394 | Expr::Throw { source_span, .. }
1395 | Expr::And { source_span, .. }
1396 | Expr::Or { source_span, .. }
1397 | Expr::GetTag { source_span, .. }
1398 | Expr::ListComprehension { source_span, .. }
1399 | Expr::ListReduce { source_span, .. }
1400 | Expr::InvokeMethodLazy { source_span, .. }
1401 | Expr::Range { source_span, .. }
1402 | Expr::Length { source_span, .. }
1403 | Expr::Call { source_span, .. }
1404 | Expr::GenerateWorkerName { source_span, .. } => source_span.clone(),
1405 }
1406 }
1407
1408 pub fn type_annotation(&self) -> &Option<TypeName> {
1409 match self {
1410 Expr::Identifier {
1411 type_annotation, ..
1412 }
1413 | Expr::Let {
1414 type_annotation, ..
1415 }
1416 | Expr::SelectField {
1417 type_annotation, ..
1418 }
1419 | Expr::SelectIndex {
1420 type_annotation, ..
1421 }
1422 | Expr::Sequence {
1423 type_annotation, ..
1424 }
1425 | Expr::Record {
1426 type_annotation, ..
1427 }
1428 | Expr::Tuple {
1429 type_annotation, ..
1430 }
1431 | Expr::Literal {
1432 type_annotation, ..
1433 }
1434 | Expr::Number {
1435 type_annotation, ..
1436 }
1437 | Expr::Flags {
1438 type_annotation, ..
1439 }
1440 | Expr::Boolean {
1441 type_annotation, ..
1442 }
1443 | Expr::Concat {
1444 type_annotation, ..
1445 }
1446 | Expr::ExprBlock {
1447 type_annotation, ..
1448 }
1449 | Expr::Not {
1450 type_annotation, ..
1451 }
1452 | Expr::GreaterThan {
1453 type_annotation, ..
1454 }
1455 | Expr::GreaterThanOrEqualTo {
1456 type_annotation, ..
1457 }
1458 | Expr::LessThanOrEqualTo {
1459 type_annotation, ..
1460 }
1461 | Expr::EqualTo {
1462 type_annotation, ..
1463 }
1464 | Expr::LessThan {
1465 type_annotation, ..
1466 }
1467 | Expr::Plus {
1468 type_annotation, ..
1469 }
1470 | Expr::Minus {
1471 type_annotation, ..
1472 }
1473 | Expr::Divide {
1474 type_annotation, ..
1475 }
1476 | Expr::Multiply {
1477 type_annotation, ..
1478 }
1479 | Expr::Cond {
1480 type_annotation, ..
1481 }
1482 | Expr::PatternMatch {
1483 type_annotation, ..
1484 }
1485 | Expr::Option {
1486 type_annotation, ..
1487 }
1488 | Expr::Result {
1489 type_annotation, ..
1490 }
1491 | Expr::Unwrap {
1492 type_annotation, ..
1493 }
1494 | Expr::Throw {
1495 type_annotation, ..
1496 }
1497 | Expr::And {
1498 type_annotation, ..
1499 }
1500 | Expr::Or {
1501 type_annotation, ..
1502 }
1503 | Expr::GetTag {
1504 type_annotation, ..
1505 }
1506 | Expr::ListComprehension {
1507 type_annotation, ..
1508 }
1509 | Expr::ListReduce {
1510 type_annotation, ..
1511 }
1512 | Expr::InvokeMethodLazy {
1513 type_annotation, ..
1514 }
1515 | Expr::Range {
1516 type_annotation, ..
1517 }
1518 | Expr::Length {
1519 type_annotation, ..
1520 }
1521 | Expr::GenerateWorkerName {
1522 type_annotation, ..
1523 }
1524 | Expr::Call {
1525 type_annotation, ..
1526 } => type_annotation,
1527 }
1528 }
1529
1530 pub fn with_type_annotation_opt(&self, type_annotation: Option<TypeName>) -> Expr {
1531 if let Some(type_annotation) = type_annotation {
1532 self.with_type_annotation(type_annotation)
1533 } else {
1534 self.clone()
1535 }
1536 }
1537
1538 pub fn with_type_annotation(&self, type_annotation: TypeName) -> Expr {
1539 let mut expr_copied = self.clone();
1540 expr_copied.with_type_annotation_mut(type_annotation);
1541 expr_copied
1542 }
1543
1544 pub fn with_type_annotation_mut(&mut self, type_annotation: TypeName) {
1545 let new_type_annotation = type_annotation;
1546
1547 match self {
1548 Expr::Identifier {
1549 type_annotation, ..
1550 }
1551 | Expr::Let {
1552 type_annotation, ..
1553 }
1554 | Expr::SelectField {
1555 type_annotation, ..
1556 }
1557 | Expr::SelectIndex {
1558 type_annotation, ..
1559 }
1560 | Expr::Sequence {
1561 type_annotation, ..
1562 }
1563 | Expr::Record {
1564 type_annotation, ..
1565 }
1566 | Expr::Tuple {
1567 type_annotation, ..
1568 }
1569 | Expr::Literal {
1570 type_annotation, ..
1571 }
1572 | Expr::Number {
1573 type_annotation, ..
1574 }
1575 | Expr::Flags {
1576 type_annotation, ..
1577 }
1578 | Expr::Boolean {
1579 type_annotation, ..
1580 }
1581 | Expr::Concat {
1582 type_annotation, ..
1583 }
1584 | Expr::ExprBlock {
1585 type_annotation, ..
1586 }
1587 | Expr::Not {
1588 type_annotation, ..
1589 }
1590 | Expr::GreaterThan {
1591 type_annotation, ..
1592 }
1593 | Expr::GreaterThanOrEqualTo {
1594 type_annotation, ..
1595 }
1596 | Expr::LessThanOrEqualTo {
1597 type_annotation, ..
1598 }
1599 | Expr::EqualTo {
1600 type_annotation, ..
1601 }
1602 | Expr::LessThan {
1603 type_annotation, ..
1604 }
1605 | Expr::Plus {
1606 type_annotation, ..
1607 }
1608 | Expr::Minus {
1609 type_annotation, ..
1610 }
1611 | Expr::Divide {
1612 type_annotation, ..
1613 }
1614 | Expr::Multiply {
1615 type_annotation, ..
1616 }
1617 | Expr::Cond {
1618 type_annotation, ..
1619 }
1620 | Expr::PatternMatch {
1621 type_annotation, ..
1622 }
1623 | Expr::Option {
1624 type_annotation, ..
1625 }
1626 | Expr::Result {
1627 type_annotation, ..
1628 }
1629 | Expr::Unwrap {
1630 type_annotation, ..
1631 }
1632 | Expr::Throw {
1633 type_annotation, ..
1634 }
1635 | Expr::And {
1636 type_annotation, ..
1637 }
1638 | Expr::Or {
1639 type_annotation, ..
1640 }
1641 | Expr::GetTag {
1642 type_annotation, ..
1643 }
1644 | Expr::Range {
1645 type_annotation, ..
1646 }
1647 | Expr::ListComprehension {
1648 type_annotation, ..
1649 }
1650 | Expr::ListReduce {
1651 type_annotation, ..
1652 }
1653 | Expr::InvokeMethodLazy {
1654 type_annotation, ..
1655 }
1656 | Expr::Length {
1657 type_annotation, ..
1658 }
1659 | Expr::GenerateWorkerName {
1660 type_annotation, ..
1661 }
1662 | Expr::Call {
1663 type_annotation, ..
1664 } => {
1665 *type_annotation = Some(new_type_annotation);
1666 }
1667 }
1668 }
1669
1670 pub fn with_source_span(&self, new_source_span: SourceSpan) -> Expr {
1671 let mut expr_copied = self.clone();
1672 expr_copied.with_source_span_mut(new_source_span);
1673 expr_copied
1674 }
1675
1676 pub fn with_source_span_mut(&mut self, new_source_span: SourceSpan) {
1677 match self {
1678 Expr::Identifier { source_span, .. }
1679 | Expr::Let { source_span, .. }
1680 | Expr::SelectField { source_span, .. }
1681 | Expr::SelectIndex { source_span, .. }
1682 | Expr::Sequence { source_span, .. }
1683 | Expr::Number { source_span, .. }
1684 | Expr::Record { source_span, .. }
1685 | Expr::Tuple { source_span, .. }
1686 | Expr::Literal { source_span, .. }
1687 | Expr::Flags { source_span, .. }
1688 | Expr::Boolean { source_span, .. }
1689 | Expr::Concat { source_span, .. }
1690 | Expr::ExprBlock { source_span, .. }
1691 | Expr::Not { source_span, .. }
1692 | Expr::GreaterThan { source_span, .. }
1693 | Expr::GreaterThanOrEqualTo { source_span, .. }
1694 | Expr::LessThanOrEqualTo { source_span, .. }
1695 | Expr::EqualTo { source_span, .. }
1696 | Expr::LessThan { source_span, .. }
1697 | Expr::Plus { source_span, .. }
1698 | Expr::Minus { source_span, .. }
1699 | Expr::Divide { source_span, .. }
1700 | Expr::Multiply { source_span, .. }
1701 | Expr::Cond { source_span, .. }
1702 | Expr::PatternMatch { source_span, .. }
1703 | Expr::Option { source_span, .. }
1704 | Expr::Result { source_span, .. }
1705 | Expr::Unwrap { source_span, .. }
1706 | Expr::Throw { source_span, .. }
1707 | Expr::And { source_span, .. }
1708 | Expr::Or { source_span, .. }
1709 | Expr::GetTag { source_span, .. }
1710 | Expr::Range { source_span, .. }
1711 | Expr::ListComprehension { source_span, .. }
1712 | Expr::ListReduce { source_span, .. }
1713 | Expr::InvokeMethodLazy { source_span, .. }
1714 | Expr::Length { source_span, .. }
1715 | Expr::GenerateWorkerName { source_span, .. }
1716 | Expr::Call { source_span, .. } => {
1717 *source_span = new_source_span;
1718 }
1719 }
1720 }
1721
1722 pub fn with_inferred_type(&self, new_inferred_type: InferredType) -> Expr {
1723 let mut expr_copied = self.clone();
1724 expr_copied.with_inferred_type_mut(new_inferred_type);
1725 expr_copied
1726 }
1727
1728 pub fn with_inferred_type_mut(&mut self, new_inferred_type: InferredType) {
1731 match self {
1732 Expr::Identifier { inferred_type, .. }
1733 | Expr::Let { inferred_type, .. }
1734 | Expr::SelectField { inferred_type, .. }
1735 | Expr::SelectIndex { inferred_type, .. }
1736 | Expr::Sequence { inferred_type, .. }
1737 | Expr::Record { inferred_type, .. }
1738 | Expr::Tuple { inferred_type, .. }
1739 | Expr::Literal { inferred_type, .. }
1740 | Expr::Number { inferred_type, .. }
1741 | Expr::Flags { inferred_type, .. }
1742 | Expr::Boolean { inferred_type, .. }
1743 | Expr::Concat { inferred_type, .. }
1744 | Expr::ExprBlock { inferred_type, .. }
1745 | Expr::Not { inferred_type, .. }
1746 | Expr::GreaterThan { inferred_type, .. }
1747 | Expr::GreaterThanOrEqualTo { inferred_type, .. }
1748 | Expr::LessThanOrEqualTo { inferred_type, .. }
1749 | Expr::EqualTo { inferred_type, .. }
1750 | Expr::LessThan { inferred_type, .. }
1751 | Expr::Plus { inferred_type, .. }
1752 | Expr::Minus { inferred_type, .. }
1753 | Expr::Divide { inferred_type, .. }
1754 | Expr::Multiply { inferred_type, .. }
1755 | Expr::Cond { inferred_type, .. }
1756 | Expr::PatternMatch { inferred_type, .. }
1757 | Expr::Option { inferred_type, .. }
1758 | Expr::Result { inferred_type, .. }
1759 | Expr::Unwrap { inferred_type, .. }
1760 | Expr::Throw { inferred_type, .. }
1761 | Expr::And { inferred_type, .. }
1762 | Expr::Or { inferred_type, .. }
1763 | Expr::GetTag { inferred_type, .. }
1764 | Expr::ListComprehension { inferred_type, .. }
1765 | Expr::ListReduce { inferred_type, .. }
1766 | Expr::InvokeMethodLazy { inferred_type, .. }
1767 | Expr::Range { inferred_type, .. }
1768 | Expr::Length { inferred_type, .. }
1769 | Expr::GenerateWorkerName { inferred_type, .. }
1770 | Expr::Call { inferred_type, .. } => {
1771 *inferred_type = new_inferred_type;
1772 }
1773 }
1774 }
1775
1776 pub fn infer_enums(&mut self, component_dependency: &ComponentDependencies) {
1777 type_inference::infer_enums(self, component_dependency);
1778 }
1779
1780 pub fn infer_variants(&mut self, component_dependency: &ComponentDependencies) {
1781 type_inference::infer_variants(self, component_dependency);
1782 }
1783
1784 pub fn visit_expr_nodes_lazy<'a>(&'a mut self, queue: &mut VecDeque<&'a mut Expr>) {
1785 type_inference::visit_expr_nodes_lazy(self, queue);
1786 }
1787
1788 pub fn number_inferred(
1789 big_decimal: BigDecimal,
1790 type_annotation: Option<TypeName>,
1791 inferred_type: InferredType,
1792 ) -> Expr {
1793 Expr::Number {
1794 number: Number { value: big_decimal },
1795 type_annotation,
1796 inferred_type,
1797 source_span: SourceSpan::default(),
1798 }
1799 }
1800
1801 pub fn number(big_decimal: BigDecimal) -> Expr {
1802 let default_type = DefaultType::from(&big_decimal);
1803 let inferred_type = InferredType::from(&default_type);
1804
1805 Expr::number_inferred(big_decimal, None, inferred_type)
1806 }
1807}
1808
1809#[derive(Debug, Hash, Clone, PartialEq, Eq, PartialOrd, Ord)]
1810pub enum Range {
1811 Range { from: Box<Expr>, to: Box<Expr> },
1812 RangeInclusive { from: Box<Expr>, to: Box<Expr> },
1813 RangeFrom { from: Box<Expr> },
1814}
1815
1816impl Range {
1817 pub fn from(&self) -> Option<&Expr> {
1818 match self {
1819 Range::Range { from, .. } => Some(from),
1820 Range::RangeInclusive { from, .. } => Some(from),
1821 Range::RangeFrom { from } => Some(from),
1822 }
1823 }
1824
1825 pub fn to(&self) -> Option<&Expr> {
1826 match self {
1827 Range::Range { to, .. } => Some(to),
1828 Range::RangeInclusive { to, .. } => Some(to),
1829 Range::RangeFrom { .. } => None,
1830 }
1831 }
1832
1833 pub fn inclusive(&self) -> bool {
1834 matches!(self, Range::RangeInclusive { .. })
1835 }
1836
1837 pub fn get_exprs_mut(&mut self) -> Vec<&mut Box<Expr>> {
1838 match self {
1839 Range::Range { from, to } => vec![from, to],
1840 Range::RangeInclusive { from, to } => vec![from, to],
1841 Range::RangeFrom { from } => vec![from],
1842 }
1843 }
1844
1845 pub fn get_exprs(&self) -> Vec<&Expr> {
1846 match self {
1847 Range::Range { from, to } => vec![from.as_ref(), to.as_ref()],
1848 Range::RangeInclusive { from, to } => vec![from.as_ref(), to.as_ref()],
1849 Range::RangeFrom { from } => vec![from.as_ref()],
1850 }
1851 }
1852}
1853
1854#[derive(Debug, Hash, Clone, PartialEq, Ord, PartialOrd)]
1855pub struct Number {
1856 pub value: BigDecimal,
1857}
1858
1859impl Eq for Number {}
1860
1861impl Number {
1862 pub fn to_val(&self, analysed_type: &AnalysedType) -> Option<ValueAndType> {
1863 match analysed_type {
1864 AnalysedType::F64(_) => self.value.to_f64().map(|v| v.into_value_and_type()),
1865 AnalysedType::U64(_) => self.value.to_u64().map(|v| v.into_value_and_type()),
1866 AnalysedType::F32(_) => self.value.to_f32().map(|v| v.into_value_and_type()),
1867 AnalysedType::U32(_) => self.value.to_u32().map(|v| v.into_value_and_type()),
1868 AnalysedType::S32(_) => self.value.to_i32().map(|v| v.into_value_and_type()),
1869 AnalysedType::S64(_) => self.value.to_i64().map(|v| v.into_value_and_type()),
1870 AnalysedType::U8(_) => self.value.to_u8().map(|v| v.into_value_and_type()),
1871 AnalysedType::S8(_) => self.value.to_i8().map(|v| v.into_value_and_type()),
1872 AnalysedType::U16(_) => self.value.to_u16().map(|v| v.into_value_and_type()),
1873 AnalysedType::S16(_) => self.value.to_i16().map(|v| v.into_value_and_type()),
1874 _ => None,
1875 }
1876 }
1877}
1878
1879impl Display for Number {
1880 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1881 write!(f, "{}", self.value)
1882 }
1883}
1884
1885#[derive(Debug, Hash, Clone, PartialEq, Eq, Ord, PartialOrd)]
1886pub struct MatchArm {
1887 pub arm_pattern: ArmPattern,
1888 pub arm_resolution_expr: Box<Expr>,
1889}
1890
1891impl MatchArm {
1892 pub fn new(arm_pattern: ArmPattern, arm_resolution: Expr) -> MatchArm {
1893 MatchArm {
1894 arm_pattern,
1895 arm_resolution_expr: Box::new(arm_resolution),
1896 }
1897 }
1898}
1899#[derive(Debug, Hash, Clone, PartialEq, Eq, Ord, PartialOrd)]
1900pub enum ArmPattern {
1901 WildCard,
1902 As(String, Box<ArmPattern>),
1903 Constructor(String, Vec<ArmPattern>),
1904 TupleConstructor(Vec<ArmPattern>),
1905 RecordConstructor(Vec<(String, ArmPattern)>),
1906 ListConstructor(Vec<ArmPattern>),
1907 Literal(Box<Expr>),
1908}
1909
1910impl ArmPattern {
1911 pub fn is_wildcard(&self) -> bool {
1912 matches!(self, ArmPattern::WildCard)
1913 }
1914
1915 pub fn is_literal_identifier(&self) -> bool {
1916 matches!(self, ArmPattern::Literal(expr) if expr.is_identifier())
1917 }
1918
1919 pub fn constructor(name: &str, patterns: Vec<ArmPattern>) -> ArmPattern {
1920 ArmPattern::Constructor(name.to_string(), patterns)
1921 }
1922
1923 pub fn literal(expr: Expr) -> ArmPattern {
1924 ArmPattern::Literal(Box::new(expr))
1925 }
1926
1927 pub fn get_expr_literals_mut(&mut self) -> Vec<&mut Box<Expr>> {
1928 match self {
1929 ArmPattern::Literal(expr) => vec![expr],
1930 ArmPattern::As(_, pattern) => pattern.get_expr_literals_mut(),
1931 ArmPattern::Constructor(_, patterns) => {
1932 let mut result = vec![];
1933 for pattern in patterns {
1934 result.extend(pattern.get_expr_literals_mut());
1935 }
1936 result
1937 }
1938 ArmPattern::TupleConstructor(patterns) => {
1939 let mut result = vec![];
1940 for pattern in patterns {
1941 result.extend(pattern.get_expr_literals_mut());
1942 }
1943 result
1944 }
1945 ArmPattern::RecordConstructor(patterns) => {
1946 let mut result = vec![];
1947 for (_, pattern) in patterns {
1948 result.extend(pattern.get_expr_literals_mut());
1949 }
1950 result
1951 }
1952 ArmPattern::ListConstructor(patterns) => {
1953 let mut result = vec![];
1954 for pattern in patterns {
1955 result.extend(pattern.get_expr_literals_mut());
1956 }
1957 result
1958 }
1959 ArmPattern::WildCard => vec![],
1960 }
1961 }
1962
1963 pub fn get_expr_literals(&self) -> Vec<&Expr> {
1964 match self {
1965 ArmPattern::Literal(expr) => vec![expr.as_ref()],
1966 ArmPattern::As(_, pattern) => pattern.get_expr_literals(),
1967 ArmPattern::Constructor(_, patterns) => {
1968 let mut result = vec![];
1969 for pattern in patterns {
1970 result.extend(pattern.get_expr_literals());
1971 }
1972 result
1973 }
1974 ArmPattern::TupleConstructor(patterns) => {
1975 let mut result = vec![];
1976 for pattern in patterns {
1977 result.extend(pattern.get_expr_literals());
1978 }
1979 result
1980 }
1981 ArmPattern::RecordConstructor(patterns) => {
1982 let mut result = vec![];
1983 for (_, pattern) in patterns {
1984 result.extend(pattern.get_expr_literals());
1985 }
1986 result
1987 }
1988 ArmPattern::ListConstructor(patterns) => {
1989 let mut result = vec![];
1990 for pattern in patterns {
1991 result.extend(pattern.get_expr_literals());
1992 }
1993 result
1994 }
1995 ArmPattern::WildCard => vec![],
1996 }
1997 }
1998 pub fn ok(binding_variable: &str) -> ArmPattern {
2000 ArmPattern::Literal(Box::new(Expr::Result {
2001 expr: Ok(Box::new(Expr::Identifier {
2002 variable_id: VariableId::global(binding_variable.to_string()),
2003 type_annotation: None,
2004 inferred_type: InferredType::unknown(),
2005 source_span: SourceSpan::default(),
2006 })),
2007 type_annotation: None,
2008 inferred_type: InferredType::result(
2009 Some(InferredType::unknown()),
2010 Some(InferredType::unknown()),
2011 ),
2012 source_span: SourceSpan::default(),
2013 }))
2014 }
2015
2016 pub fn err(binding_variable: &str) -> ArmPattern {
2018 ArmPattern::Literal(Box::new(Expr::Result {
2019 expr: Err(Box::new(Expr::Identifier {
2020 variable_id: VariableId::global(binding_variable.to_string()),
2021 type_annotation: None,
2022 inferred_type: InferredType::unknown(),
2023 source_span: SourceSpan::default(),
2024 })),
2025 type_annotation: None,
2026 inferred_type: InferredType::result(
2027 Some(InferredType::unknown()),
2028 Some(InferredType::unknown()),
2029 ),
2030 source_span: SourceSpan::default(),
2031 }))
2032 }
2033
2034 pub fn some(binding_variable: &str) -> ArmPattern {
2036 ArmPattern::Literal(Box::new(Expr::Option {
2037 expr: Some(Box::new(Expr::Identifier {
2038 variable_id: VariableId::local_with_no_id(binding_variable),
2039 type_annotation: None,
2040 inferred_type: InferredType::unknown(),
2041 source_span: SourceSpan::default(),
2042 })),
2043 type_annotation: None,
2044 inferred_type: InferredType::unknown(),
2045 source_span: SourceSpan::default(),
2046 }))
2047 }
2048
2049 pub fn none() -> ArmPattern {
2050 ArmPattern::Literal(Box::new(Expr::Option {
2051 expr: None,
2052 type_annotation: None,
2053 inferred_type: InferredType::unknown(),
2054 source_span: SourceSpan::default(),
2055 }))
2056 }
2057
2058 pub fn identifier(binding_variable: &str) -> ArmPattern {
2059 ArmPattern::Literal(Box::new(Expr::Identifier {
2060 variable_id: VariableId::global(binding_variable.to_string()),
2061 type_annotation: None,
2062 inferred_type: InferredType::unknown(),
2063 source_span: SourceSpan::default(),
2064 }))
2065 }
2066 pub fn custom_constructor(name: &str, args: Vec<ArmPattern>) -> ArmPattern {
2067 ArmPattern::Constructor(name.to_string(), args)
2068 }
2069}
2070
2071#[cfg(feature = "protobuf")]
2072impl TryFrom<golem_api_grpc::proto::golem::rib::Expr> for Expr {
2073 type Error = String;
2074
2075 fn try_from(value: golem_api_grpc::proto::golem::rib::Expr) -> Result<Self, Self::Error> {
2076 let expr = value.expr.ok_or("Missing expr")?;
2077
2078 let expr = match expr {
2079 golem_api_grpc::proto::golem::rib::expr::Expr::Let(expr) => {
2080 let name = expr.name;
2081 let type_annotation = expr.type_name.map(TypeName::try_from).transpose()?;
2082 let expr_: golem_api_grpc::proto::golem::rib::Expr =
2083 *expr.expr.ok_or("Missing expr")?;
2084 let expr: Expr = expr_.try_into()?;
2085 Expr::let_binding(name, expr, type_annotation)
2086 }
2087
2088 golem_api_grpc::proto::golem::rib::expr::Expr::SelectIndexV1(expr) => {
2089 let selection = *expr.expr.ok_or("Missing expr")?;
2090 let field = *expr.index.ok_or("Missing index")?;
2091 let type_annotation = expr.type_name.map(TypeName::try_from).transpose()?;
2092
2093 Expr::select_index(selection.try_into()?, field.try_into()?)
2094 .with_type_annotation_opt(type_annotation)
2095 }
2096
2097 golem_api_grpc::proto::golem::rib::expr::Expr::Length(expr) => {
2098 let expr = expr.expr.ok_or("Missing expr")?;
2099 Expr::Length {
2100 expr: Box::new((*expr).try_into()?),
2101 type_annotation: None,
2102 inferred_type: InferredType::unknown(),
2103 source_span: SourceSpan::default(),
2104 }
2105 }
2106
2107 golem_api_grpc::proto::golem::rib::expr::Expr::Range(range) => {
2108 let range_expr = range.range_expr.ok_or("Missing range expr")?;
2109
2110 match range_expr {
2111 RangeExpr::RangeFrom(range_from) => {
2112 let from = range_from.from.ok_or("Missing from expr")?;
2113 Expr::range_from((*from).try_into()?)
2114 }
2115 RangeExpr::Range(range) => {
2116 let from = range.from.ok_or("Missing from expr")?;
2117 let to = range.to.ok_or("Missing to expr")?;
2118 Expr::range((*from).try_into()?, (*to).try_into()?)
2119 }
2120 RangeExpr::RangeInclusive(range_inclusive) => {
2121 let from = range_inclusive.from.ok_or("Missing from expr")?;
2122 let to = range_inclusive.to.ok_or("Missing to expr")?;
2123 Expr::range_inclusive((*from).try_into()?, (*to).try_into()?)
2124 }
2125 }
2126 }
2127
2128 golem_api_grpc::proto::golem::rib::expr::Expr::Not(expr) => {
2129 let expr = expr.expr.ok_or("Missing expr")?;
2130 Expr::not((*expr).try_into()?)
2131 }
2132
2133 golem_api_grpc::proto::golem::rib::expr::Expr::GreaterThan(expr) => {
2134 let left = expr.left.ok_or("Missing left expr")?;
2135 let right = expr.right.ok_or("Missing right expr")?;
2136 Expr::greater_than((*left).try_into()?, (*right).try_into()?)
2137 }
2138
2139 golem_api_grpc::proto::golem::rib::expr::Expr::GreaterThanOrEqual(expr) => {
2140 let left = expr.left.ok_or("Missing left expr")?;
2141 let right = expr.right.ok_or("Missing right expr")?;
2142 Expr::greater_than_or_equal_to((*left).try_into()?, (*right).try_into()?)
2143 }
2144
2145 golem_api_grpc::proto::golem::rib::expr::Expr::LessThan(expr) => {
2146 let left = expr.left.ok_or("Missing left expr")?;
2147 let right = expr.right.ok_or("Missing right expr")?;
2148 Expr::less_than((*left).try_into()?, (*right).try_into()?)
2149 }
2150
2151 golem_api_grpc::proto::golem::rib::expr::Expr::LessThanOrEqual(expr) => {
2152 let left = expr.left.ok_or("Missing left expr")?;
2153 let right = expr.right.ok_or("Missing right expr")?;
2154 Expr::less_than_or_equal_to((*left).try_into()?, (*right).try_into()?)
2155 }
2156
2157 golem_api_grpc::proto::golem::rib::expr::Expr::EqualTo(expr) => {
2158 let left = expr.left.ok_or("Missing left expr")?;
2159 let right = expr.right.ok_or("Missing right expr")?;
2160 Expr::equal_to((*left).try_into()?, (*right).try_into()?)
2161 }
2162
2163 golem_api_grpc::proto::golem::rib::expr::Expr::Add(expr) => {
2164 let left = expr.left.ok_or("Missing left expr")?;
2165 let right = expr.right.ok_or("Missing right expr")?;
2166 Expr::plus((*left).try_into()?, (*right).try_into()?)
2167 }
2168
2169 golem_api_grpc::proto::golem::rib::expr::Expr::Subtract(expr) => {
2170 let left = expr.left.ok_or("Missing left expr")?;
2171 let right = expr.right.ok_or("Missing right expr")?;
2172 Expr::plus((*left).try_into()?, (*right).try_into()?)
2173 }
2174
2175 golem_api_grpc::proto::golem::rib::expr::Expr::Divide(expr) => {
2176 let left = expr.left.ok_or("Missing left expr")?;
2177 let right = expr.right.ok_or("Missing right expr")?;
2178 Expr::plus((*left).try_into()?, (*right).try_into()?)
2179 }
2180
2181 golem_api_grpc::proto::golem::rib::expr::Expr::Multiply(expr) => {
2182 let left = expr.left.ok_or("Missing left expr")?;
2183 let right = expr.right.ok_or("Missing right expr")?;
2184 Expr::plus((*left).try_into()?, (*right).try_into()?)
2185 }
2186
2187 golem_api_grpc::proto::golem::rib::expr::Expr::Cond(expr) => {
2188 let left = expr.left.ok_or("Missing left expr")?;
2189 let cond = expr.cond.ok_or("Missing cond expr")?;
2190 let right = expr.right.ok_or("Missing right expr")?;
2191 Expr::cond(
2192 (*left).try_into()?,
2193 (*cond).try_into()?,
2194 (*right).try_into()?,
2195 )
2196 }
2197
2198 golem_api_grpc::proto::golem::rib::expr::Expr::Concat(
2199 golem_api_grpc::proto::golem::rib::ConcatExpr { exprs },
2200 ) => {
2201 let exprs: Vec<Expr> = exprs
2202 .into_iter()
2203 .map(|expr| expr.try_into())
2204 .collect::<Result<Vec<_>, _>>()?;
2205 Expr::concat(exprs)
2206 }
2207
2208 golem_api_grpc::proto::golem::rib::expr::Expr::Multiple(
2209 golem_api_grpc::proto::golem::rib::MultipleExpr { exprs },
2210 ) => {
2211 let exprs: Vec<Expr> = exprs
2212 .into_iter()
2213 .map(|expr| expr.try_into())
2214 .collect::<Result<Vec<_>, _>>()?;
2215 Expr::expr_block(exprs)
2216 }
2217
2218 golem_api_grpc::proto::golem::rib::expr::Expr::Sequence(
2219 golem_api_grpc::proto::golem::rib::SequenceExpr { exprs, type_name },
2220 ) => {
2221 let type_annotation = type_name.map(TypeName::try_from).transpose()?;
2222
2223 let exprs: Vec<Expr> = exprs
2224 .into_iter()
2225 .map(|expr| expr.try_into())
2226 .collect::<Result<Vec<_>, _>>()?;
2227 Expr::sequence(exprs, type_annotation)
2228 }
2229
2230 golem_api_grpc::proto::golem::rib::expr::Expr::Tuple(
2231 golem_api_grpc::proto::golem::rib::TupleExpr { exprs },
2232 ) => {
2233 let exprs: Vec<Expr> = exprs
2234 .into_iter()
2235 .map(|expr| expr.try_into())
2236 .collect::<Result<Vec<_>, _>>()?;
2237 Expr::tuple(exprs)
2238 }
2239
2240 golem_api_grpc::proto::golem::rib::expr::Expr::Record(
2241 golem_api_grpc::proto::golem::rib::RecordExpr { fields },
2242 ) => {
2243 let mut values: Vec<(String, Expr)> = vec![];
2244 for record in fields.into_iter() {
2245 let name = record.name;
2246 let expr = record.expr.ok_or("Missing expr")?;
2247 values.push((name, expr.try_into()?));
2248 }
2249 Expr::record(values)
2250 }
2251
2252 golem_api_grpc::proto::golem::rib::expr::Expr::Flags(
2253 golem_api_grpc::proto::golem::rib::FlagsExpr { values },
2254 ) => Expr::flags(values),
2255
2256 golem_api_grpc::proto::golem::rib::expr::Expr::Literal(
2257 golem_api_grpc::proto::golem::rib::LiteralExpr { value },
2258 ) => Expr::literal(value),
2259
2260 golem_api_grpc::proto::golem::rib::expr::Expr::Identifier(
2261 golem_api_grpc::proto::golem::rib::IdentifierExpr { name, type_name },
2262 ) => {
2263 let type_name = type_name.map(TypeName::try_from).transpose()?;
2264
2265 Expr::identifier_global(name.as_str(), type_name)
2266 }
2267
2268 golem_api_grpc::proto::golem::rib::expr::Expr::Boolean(
2269 golem_api_grpc::proto::golem::rib::BooleanExpr { value },
2270 ) => Expr::boolean(value),
2271
2272 golem_api_grpc::proto::golem::rib::expr::Expr::Throw(
2273 golem_api_grpc::proto::golem::rib::ThrowExpr { message },
2274 ) => Expr::throw(message),
2275
2276 golem_api_grpc::proto::golem::rib::expr::Expr::GenerateWorkerName(
2277 golem_api_grpc::proto::golem::rib::GenerateWorkerNameExpr {},
2278 ) => Expr::generate_worker_name(None),
2279
2280 golem_api_grpc::proto::golem::rib::expr::Expr::And(expr) => {
2281 let left = expr.left.ok_or("Missing left expr")?;
2282 let right = expr.right.ok_or("Missing right expr")?;
2283 Expr::and((*left).try_into()?, (*right).try_into()?)
2284 }
2285
2286 golem_api_grpc::proto::golem::rib::expr::Expr::Or(expr) => {
2287 let left = expr.left.ok_or("Missing left expr")?;
2288 let right = expr.right.ok_or("Missing right expr")?;
2289 Expr::or((*left).try_into()?, (*right).try_into()?)
2290 }
2291
2292 golem_api_grpc::proto::golem::rib::expr::Expr::Tag(expr) => {
2293 let expr = expr.expr.ok_or("Missing expr in tag")?;
2294 Expr::get_tag((*expr).try_into()?)
2295 }
2296
2297 golem_api_grpc::proto::golem::rib::expr::Expr::Unwrap(expr) => {
2298 let expr = expr.expr.ok_or("Missing expr")?;
2299 let expr: Expr = (*expr).try_into()?;
2300 expr.unwrap()
2301 }
2302
2303 golem_api_grpc::proto::golem::rib::expr::Expr::Number(number) => {
2304 let type_name = number.type_name.map(TypeName::try_from).transpose()?;
2306 let big_decimal = if let Some(number) = number.number {
2307 BigDecimal::from_str(&number).map_err(|e| e.to_string())?
2308 } else if let Some(float) = number.float {
2309 BigDecimal::from_f64(float).ok_or("Invalid float")?
2310 } else {
2311 return Err("Missing number".to_string());
2312 };
2313
2314 Expr::number(big_decimal).with_type_annotation_opt(type_name)
2315 }
2316 golem_api_grpc::proto::golem::rib::expr::Expr::SelectField(expr) => {
2317 let expr = *expr;
2318 let field = expr.field;
2319 let type_name = expr.type_name.map(TypeName::try_from).transpose()?;
2320 let expr = *expr.expr.ok_or(
2321 "Mi\
2322 ssing expr",
2323 )?;
2324
2325 Expr::select_field(expr.try_into()?, field.as_str(), type_name)
2326 }
2327 golem_api_grpc::proto::golem::rib::expr::Expr::SelectIndex(expr) => {
2328 let expr = *expr;
2329 let type_name = expr.type_name.map(TypeName::try_from).transpose()?;
2330 let index = expr.index as usize;
2331 let expr = *expr.expr.ok_or("Missing expr")?;
2332
2333 let index_expr =
2334 Expr::number(BigDecimal::from_usize(index).ok_or("Invalid index")?);
2335
2336 Expr::select_index(expr.try_into()?, index_expr).with_type_annotation_opt(type_name)
2337 }
2338 golem_api_grpc::proto::golem::rib::expr::Expr::Option(expr) => {
2339 let type_name = expr.type_name;
2340 let type_name = type_name.map(TypeName::try_from).transpose()?;
2341
2342 match expr.expr {
2343 Some(expr) => {
2344 Expr::option(Some((*expr).try_into()?)).with_type_annotation_opt(type_name)
2345 }
2346 None => Expr::option(None).with_type_annotation_opt(type_name),
2347 }
2348 }
2349 golem_api_grpc::proto::golem::rib::expr::Expr::Result(expr) => {
2350 let type_name = expr.type_name;
2351 let type_name = type_name.map(TypeName::try_from).transpose()?;
2352 let result = expr.result.ok_or("Missing result")?;
2353 match result {
2354 golem_api_grpc::proto::golem::rib::result_expr::Result::Ok(expr) => {
2355 Expr::ok((*expr).try_into()?, type_name)
2356 }
2357 golem_api_grpc::proto::golem::rib::result_expr::Result::Err(expr) => {
2358 Expr::err((*expr).try_into()?, type_name)
2359 }
2360 }
2361 }
2362 golem_api_grpc::proto::golem::rib::expr::Expr::PatternMatch(expr) => {
2363 let patterns: Vec<MatchArm> = expr
2364 .patterns
2365 .into_iter()
2366 .map(|expr| expr.try_into())
2367 .collect::<Result<Vec<_>, _>>()?;
2368 let expr = expr.expr.ok_or("Missing expr")?;
2369 Expr::pattern_match((*expr).try_into()?, patterns)
2370 }
2371 golem_api_grpc::proto::golem::rib::expr::Expr::ListComprehension(
2372 list_comprehension,
2373 ) => {
2374 let iterable_expr = list_comprehension.iterable_expr.ok_or("Missing expr")?;
2375 let iterable_expr = (*iterable_expr).try_into()?;
2376 let yield_expr = list_comprehension.yield_expr.ok_or("Missing list")?;
2377 let yield_expr = (*yield_expr).try_into()?;
2378 let variable_id =
2379 VariableId::list_comprehension_identifier(list_comprehension.iterated_variable);
2380 Expr::list_comprehension(variable_id, iterable_expr, yield_expr)
2381 }
2382 golem_api_grpc::proto::golem::rib::expr::Expr::ListReduce(list_reduce) => {
2383 let init_value_expr = list_reduce.init_value_expr.ok_or("Missing initial expr")?;
2384 let init_value_expr = (*init_value_expr).try_into()?;
2385 let iterable_expr = list_reduce.iterable_expr.ok_or("Missing expr")?;
2386 let iterable_expr = (*iterable_expr).try_into()?;
2387 let yield_expr = list_reduce.yield_expr.ok_or("Missing list")?;
2388 let yield_expr = (*yield_expr).try_into()?;
2389 let iterated_variable_id =
2390 VariableId::list_comprehension_identifier(list_reduce.iterated_variable);
2391 let reduce_variable_id =
2392 VariableId::list_reduce_identifier(list_reduce.reduce_variable);
2393 Expr::list_reduce(
2394 reduce_variable_id,
2395 iterated_variable_id,
2396 iterable_expr,
2397 init_value_expr,
2398 yield_expr,
2399 )
2400 }
2401 golem_api_grpc::proto::golem::rib::expr::Expr::Call(expr) => {
2402 let params: Vec<Expr> = expr
2403 .params
2404 .into_iter()
2405 .map(|expr| expr.try_into())
2406 .collect::<Result<Vec<_>, _>>()?;
2407 let legacy_invocation_name = expr.name;
2409 let call_type = expr.call_type;
2410 let generic_type_parameter = expr
2411 .generic_type_parameter
2412 .map(|tp| GenericTypeParameter { value: tp });
2413
2414 match (legacy_invocation_name, call_type) {
2415 (Some(legacy), None) => {
2416 let name = legacy.name.ok_or("Missing function call name")?;
2417 match name {
2418 golem_api_grpc::proto::golem::rib::invocation_name::Name::Parsed(name) => {
2419 Expr::call_worker_function(DynamicParsedFunctionName::parse(
2421 ParsedFunctionName::try_from(name)?.to_string()
2422 )?, generic_type_parameter, None, params, None)
2423 }
2424 golem_api_grpc::proto::golem::rib::invocation_name::Name::VariantConstructor(
2425 name,
2426 ) => Expr::call_worker_function(DynamicParsedFunctionName::parse(name)?, generic_type_parameter, None, params, None),
2427 golem_api_grpc::proto::golem::rib::invocation_name::Name::EnumConstructor(
2428 name,
2429 ) => Expr::call_worker_function(DynamicParsedFunctionName::parse(name)?, generic_type_parameter, None, params, None),
2430 }
2431 }
2432 (_, Some(call_type)) => {
2433 let name = call_type.name.ok_or("Missing function call name")?;
2434 match name {
2435 golem_api_grpc::proto::golem::rib::call_type::Name::Parsed(name) => {
2436 Expr::call_worker_function(name.try_into()?, generic_type_parameter, None, params, None)
2437 }
2438 golem_api_grpc::proto::golem::rib::call_type::Name::VariantConstructor(
2439 name,
2440 ) => Expr::call_worker_function(DynamicParsedFunctionName::parse(name)?, generic_type_parameter, None, params, None),
2441 golem_api_grpc::proto::golem::rib::call_type::Name::EnumConstructor(
2442 name,
2443 ) => Expr::call_worker_function(DynamicParsedFunctionName::parse(name)?, generic_type_parameter, None, params, None),
2444 golem_api_grpc::proto::golem::rib::call_type::Name::InstanceCreation(instance_creation) => {
2445 let instance_creation_type = InstanceCreationType::try_from(*instance_creation)?;
2446 let call_type = CallType::InstanceCreation(instance_creation_type);
2447 Expr::Call {
2448 call_type,
2449 generic_type_parameter,
2450 args: vec![],
2451 inferred_type: InferredType::unknown(),
2452 source_span: SourceSpan::default(),
2453 type_annotation: None, }
2455 }
2456 }
2457 }
2458 (_, _) => Err("Missing both call type (and legacy invocation type)")?,
2459 }
2460 }
2461 golem_api_grpc::proto::golem::rib::expr::Expr::LazyInvokeMethod(lazy_invoke) => {
2462 let lhs_proto = lazy_invoke.lhs.ok_or("Missing lhs")?;
2463 let lhs = Box::new((*lhs_proto).try_into()?);
2464 let method = lazy_invoke.method;
2465 let generic_type_parameter = lazy_invoke.generic_type_parameter;
2466 let args: Vec<Expr> = lazy_invoke
2467 .args
2468 .into_iter()
2469 .map(Expr::try_from)
2470 .collect::<Result<Vec<_>, _>>()?;
2471
2472 Expr::InvokeMethodLazy {
2473 lhs,
2474 method,
2475 generic_type_parameter: generic_type_parameter
2476 .map(|value| GenericTypeParameter { value }),
2477 args,
2478 inferred_type: InferredType::unknown(),
2479 source_span: SourceSpan::default(),
2480 type_annotation: None, }
2482 }
2483 };
2484 Ok(expr)
2485 }
2486}
2487
2488impl Display for Expr {
2489 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2490 write!(f, "{}", text::to_string(self).unwrap())
2491 }
2492}
2493
2494impl Display for ArmPattern {
2495 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2496 write!(f, "{}", text::to_string_arm_pattern(self).unwrap())
2497 }
2498}
2499
2500impl<'de> Deserialize<'de> for Expr {
2501 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
2502 where
2503 D: serde::Deserializer<'de>,
2504 {
2505 let value = Value::deserialize(deserializer)?;
2506 match value {
2507 Value::String(expr_string) => match from_string(expr_string.as_str()) {
2508 Ok(expr) => Ok(expr),
2509 Err(message) => Err(serde::de::Error::custom(message.to_string())),
2510 },
2511
2512 e => Err(serde::de::Error::custom(format!(
2513 "Failed to deserialize expression {e}"
2514 ))),
2515 }
2516 }
2517}
2518
2519impl Serialize for Expr {
2520 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
2521 where
2522 S: Serializer,
2523 {
2524 match text::to_string(self) {
2525 Ok(value) => Value::serialize(&Value::String(value), serializer),
2526 Err(error) => Err(serde::ser::Error::custom(error.to_string())),
2527 }
2528 }
2529}
2530
2531#[cfg(feature = "protobuf")]
2532mod protobuf {
2533 use crate::{ArmPattern, Expr, MatchArm, Range};
2534 use golem_api_grpc::proto::golem::rib::range_expr::RangeExpr;
2535
2536 impl From<Expr> for golem_api_grpc::proto::golem::rib::Expr {
2554 fn from(value: Expr) -> Self {
2555 let expr = match value {
2556 Expr::GenerateWorkerName { .. } => Some(
2557 golem_api_grpc::proto::golem::rib::expr::Expr::GenerateWorkerName(
2558 golem_api_grpc::proto::golem::rib::GenerateWorkerNameExpr {},
2559 ),
2560 ),
2561 Expr::Let {
2562 variable_id,
2563 type_annotation,
2564 expr,
2565 ..
2566 } => Some(golem_api_grpc::proto::golem::rib::expr::Expr::Let(
2567 Box::new(golem_api_grpc::proto::golem::rib::LetExpr {
2568 name: variable_id.name().to_string(),
2569 expr: Some(Box::new((*expr).into())),
2570 type_name: type_annotation.map(|t| t.into()),
2571 }),
2572 )),
2573
2574 Expr::Length { expr, .. } => {
2575 Some(golem_api_grpc::proto::golem::rib::expr::Expr::Length(
2576 Box::new(golem_api_grpc::proto::golem::rib::LengthExpr {
2577 expr: Some(Box::new((*expr).into())),
2578 }),
2579 ))
2580 }
2581
2582 Expr::SelectField {
2583 expr,
2584 field,
2585 type_annotation,
2586 ..
2587 } => Some(golem_api_grpc::proto::golem::rib::expr::Expr::SelectField(
2588 Box::new(golem_api_grpc::proto::golem::rib::SelectFieldExpr {
2589 expr: Some(Box::new((*expr).into())),
2590 field,
2591 type_name: type_annotation.map(|t| t.into()),
2592 }),
2593 )),
2594
2595 Expr::Range { range, .. } => match range {
2596 Range::RangeFrom { from } => {
2597 Some(golem_api_grpc::proto::golem::rib::expr::Expr::Range(
2598 Box::new(golem_api_grpc::proto::golem::rib::RangeExpr {
2599 range_expr: Some(RangeExpr::RangeFrom(Box::new(
2600 golem_api_grpc::proto::golem::rib::RangeFrom {
2601 from: Some(Box::new((*from).into())),
2602 },
2603 ))),
2604 }),
2605 ))
2606 }
2607 Range::Range { from, to } => {
2608 Some(golem_api_grpc::proto::golem::rib::expr::Expr::Range(
2609 Box::new(golem_api_grpc::proto::golem::rib::RangeExpr {
2610 range_expr: Some(RangeExpr::Range(Box::new(
2611 golem_api_grpc::proto::golem::rib::Range {
2612 from: Some(Box::new((*from).into())),
2613 to: Some(Box::new((*to).into())),
2614 },
2615 ))),
2616 }),
2617 ))
2618 }
2619 Range::RangeInclusive { from, to } => {
2620 Some(golem_api_grpc::proto::golem::rib::expr::Expr::Range(
2621 Box::new(golem_api_grpc::proto::golem::rib::RangeExpr {
2622 range_expr: Some(RangeExpr::RangeInclusive(Box::new(
2623 golem_api_grpc::proto::golem::rib::RangeInclusive {
2624 from: Some(Box::new((*from).into())),
2625 to: Some(Box::new((*to).into())),
2626 },
2627 ))),
2628 }),
2629 ))
2630 }
2631 },
2632
2633 Expr::SelectIndex {
2634 expr,
2635 index,
2636 type_annotation,
2637 ..
2638 } => Some(
2639 golem_api_grpc::proto::golem::rib::expr::Expr::SelectIndexV1(Box::new(
2640 golem_api_grpc::proto::golem::rib::SelectIndexExprV1 {
2641 expr: Some(Box::new((*expr).into())),
2642 index: Some(Box::new((*index).into())),
2643 type_name: type_annotation.map(|t| t.into()),
2644 },
2645 )),
2646 ),
2647
2648 Expr::Sequence {
2649 exprs: expressions,
2650 type_annotation,
2651 ..
2652 } => Some(golem_api_grpc::proto::golem::rib::expr::Expr::Sequence(
2653 golem_api_grpc::proto::golem::rib::SequenceExpr {
2654 exprs: expressions.into_iter().map(|expr| expr.into()).collect(),
2655 type_name: type_annotation.map(|t| t.into()),
2656 },
2657 )),
2658 Expr::Record { exprs: fields, .. } => {
2659 Some(golem_api_grpc::proto::golem::rib::expr::Expr::Record(
2660 golem_api_grpc::proto::golem::rib::RecordExpr {
2661 fields: fields
2662 .into_iter()
2663 .map(|(name, expr)| {
2664 golem_api_grpc::proto::golem::rib::RecordFieldExpr {
2665 name,
2666 expr: Some((*expr).into()),
2667 }
2668 })
2669 .collect(),
2670 },
2671 ))
2672 }
2673 Expr::Tuple {
2674 exprs: expressions, ..
2675 } => Some(golem_api_grpc::proto::golem::rib::expr::Expr::Tuple(
2676 golem_api_grpc::proto::golem::rib::TupleExpr {
2677 exprs: expressions.into_iter().map(|expr| expr.into()).collect(),
2678 },
2679 )),
2680 Expr::Literal { value, .. } => {
2681 Some(golem_api_grpc::proto::golem::rib::expr::Expr::Literal(
2682 golem_api_grpc::proto::golem::rib::LiteralExpr { value },
2683 ))
2684 }
2685 Expr::Number {
2686 number,
2687 type_annotation,
2688 ..
2689 } => Some(golem_api_grpc::proto::golem::rib::expr::Expr::Number(
2690 golem_api_grpc::proto::golem::rib::NumberExpr {
2691 number: Some(number.value.to_string()),
2692 float: None,
2693 type_name: type_annotation.map(|t| t.into()),
2694 },
2695 )),
2696 Expr::Flags { flags, .. } => {
2697 Some(golem_api_grpc::proto::golem::rib::expr::Expr::Flags(
2698 golem_api_grpc::proto::golem::rib::FlagsExpr { values: flags },
2699 ))
2700 }
2701 Expr::Identifier {
2702 variable_id,
2703 type_annotation,
2704 ..
2705 } => Some(golem_api_grpc::proto::golem::rib::expr::Expr::Identifier(
2706 golem_api_grpc::proto::golem::rib::IdentifierExpr {
2707 name: variable_id.name(),
2708 type_name: type_annotation.map(|t| t.into()),
2709 },
2710 )),
2711 Expr::Boolean { value, .. } => {
2712 Some(golem_api_grpc::proto::golem::rib::expr::Expr::Boolean(
2713 golem_api_grpc::proto::golem::rib::BooleanExpr { value },
2714 ))
2715 }
2716 Expr::Concat {
2717 exprs: expressions, ..
2718 } => Some(golem_api_grpc::proto::golem::rib::expr::Expr::Concat(
2719 golem_api_grpc::proto::golem::rib::ConcatExpr {
2720 exprs: expressions.into_iter().map(|expr| expr.into()).collect(),
2721 },
2722 )),
2723 Expr::ExprBlock {
2724 exprs: expressions, ..
2725 } => Some(golem_api_grpc::proto::golem::rib::expr::Expr::Multiple(
2726 golem_api_grpc::proto::golem::rib::MultipleExpr {
2727 exprs: expressions.into_iter().map(|expr| expr.into()).collect(),
2728 },
2729 )),
2730 Expr::Not { expr, .. } => Some(golem_api_grpc::proto::golem::rib::expr::Expr::Not(
2731 Box::new(golem_api_grpc::proto::golem::rib::NotExpr {
2732 expr: Some(Box::new((*expr).into())),
2733 }),
2734 )),
2735 Expr::GreaterThan {
2736 lhs: left,
2737 rhs: right,
2738 ..
2739 } => Some(golem_api_grpc::proto::golem::rib::expr::Expr::GreaterThan(
2740 Box::new(golem_api_grpc::proto::golem::rib::GreaterThanExpr {
2741 left: Some(Box::new((*left).into())),
2742 right: Some(Box::new((*right).into())),
2743 }),
2744 )),
2745 Expr::GreaterThanOrEqualTo { lhs, rhs, .. } => Some(
2746 golem_api_grpc::proto::golem::rib::expr::Expr::GreaterThanOrEqual(Box::new(
2747 golem_api_grpc::proto::golem::rib::GreaterThanOrEqualToExpr {
2748 left: Some(Box::new((*lhs).into())),
2749 right: Some(Box::new((*rhs).into())),
2750 },
2751 )),
2752 ),
2753 Expr::LessThan {
2754 lhs: left,
2755 rhs: right,
2756 ..
2757 } => Some(golem_api_grpc::proto::golem::rib::expr::Expr::LessThan(
2758 Box::new(golem_api_grpc::proto::golem::rib::LessThanExpr {
2759 left: Some(Box::new((*left).into())),
2760 right: Some(Box::new((*right).into())),
2761 }),
2762 )),
2763 Expr::Plus {
2764 lhs: left,
2765 rhs: right,
2766 ..
2767 } => Some(golem_api_grpc::proto::golem::rib::expr::Expr::Add(
2768 Box::new(golem_api_grpc::proto::golem::rib::AddExpr {
2769 left: Some(Box::new((*left).into())),
2770 right: Some(Box::new((*right).into())),
2771 }),
2772 )),
2773 Expr::Minus {
2774 lhs: left,
2775 rhs: right,
2776 ..
2777 } => Some(golem_api_grpc::proto::golem::rib::expr::Expr::Subtract(
2778 Box::new(golem_api_grpc::proto::golem::rib::SubtractExpr {
2779 left: Some(Box::new((*left).into())),
2780 right: Some(Box::new((*right).into())),
2781 }),
2782 )),
2783 Expr::Divide { lhs, rhs, .. } => {
2784 Some(golem_api_grpc::proto::golem::rib::expr::Expr::Divide(
2785 Box::new(golem_api_grpc::proto::golem::rib::DivideExpr {
2786 left: Some(Box::new((*lhs).into())),
2787 right: Some(Box::new((*rhs).into())),
2788 }),
2789 ))
2790 }
2791 Expr::Multiply { lhs, rhs, .. } => {
2792 Some(golem_api_grpc::proto::golem::rib::expr::Expr::Multiply(
2793 Box::new(golem_api_grpc::proto::golem::rib::MultiplyExpr {
2794 left: Some(Box::new((*lhs).into())),
2795 right: Some(Box::new((*rhs).into())),
2796 }),
2797 ))
2798 }
2799 Expr::LessThanOrEqualTo { lhs, rhs, .. } => Some(
2800 golem_api_grpc::proto::golem::rib::expr::Expr::LessThanOrEqual(Box::new(
2801 golem_api_grpc::proto::golem::rib::LessThanOrEqualToExpr {
2802 left: Some(Box::new((*lhs).into())),
2803 right: Some(Box::new((*rhs).into())),
2804 },
2805 )),
2806 ),
2807 Expr::EqualTo { lhs, rhs, .. } => {
2808 Some(golem_api_grpc::proto::golem::rib::expr::Expr::EqualTo(
2809 Box::new(golem_api_grpc::proto::golem::rib::EqualToExpr {
2810 left: Some(Box::new((*lhs).into())),
2811 right: Some(Box::new((*rhs).into())),
2812 }),
2813 ))
2814 }
2815 Expr::Cond {
2821 cond: lhs,
2822 lhs: cond,
2823 rhs,
2824 ..
2825 } => Some(golem_api_grpc::proto::golem::rib::expr::Expr::Cond(
2826 Box::new(golem_api_grpc::proto::golem::rib::CondExpr {
2827 left: Some(Box::new((*lhs).into())),
2828 cond: Some(Box::new((*cond).into())),
2829 right: Some(Box::new((*rhs).into())),
2830 }),
2831 )),
2832 Expr::PatternMatch {
2833 predicate,
2834 match_arms,
2835 ..
2836 } => Some(golem_api_grpc::proto::golem::rib::expr::Expr::PatternMatch(
2837 Box::new(golem_api_grpc::proto::golem::rib::PatternMatchExpr {
2838 expr: Some(Box::new((*predicate).into())),
2839 patterns: match_arms.into_iter().map(|a| a.into()).collect(),
2840 }),
2841 )),
2842 Expr::Option {
2843 expr,
2844 type_annotation,
2845 ..
2846 } => Some(golem_api_grpc::proto::golem::rib::expr::Expr::Option(
2847 Box::new(golem_api_grpc::proto::golem::rib::OptionExpr {
2848 expr: expr.map(|expr| Box::new((*expr).into())),
2849 type_name: type_annotation.map(|t| t.into()),
2850 }),
2851 )),
2852 Expr::Result {
2853 expr,
2854 type_annotation,
2855 ..
2856 } => {
2857 let type_name = type_annotation.map(|t| t.into());
2858
2859 let result = match expr {
2860 Ok(expr) => golem_api_grpc::proto::golem::rib::result_expr::Result::Ok(
2861 Box::new((*expr).into()),
2862 ),
2863 Err(expr) => golem_api_grpc::proto::golem::rib::result_expr::Result::Err(
2864 Box::new((*expr).into()),
2865 ),
2866 };
2867
2868 Some(golem_api_grpc::proto::golem::rib::expr::Expr::Result(
2869 Box::new(golem_api_grpc::proto::golem::rib::ResultExpr {
2870 result: Some(result),
2871 type_name,
2872 }),
2873 ))
2874 }
2875 Expr::Call {
2876 call_type,
2877 generic_type_parameter,
2878 args,
2879 ..
2880 } => {
2881 Some(golem_api_grpc::proto::golem::rib::expr::Expr::Call(
2882 Box::new(golem_api_grpc::proto::golem::rib::CallExpr {
2883 name: None, params: args.into_iter().map(|expr| expr.into()).collect(),
2885 generic_type_parameter: generic_type_parameter.map(|t| t.value),
2886 call_type: Some(Box::new(
2887 golem_api_grpc::proto::golem::rib::CallType::from(call_type),
2888 )),
2889 }),
2890 ))
2891 }
2892 Expr::Unwrap { expr, .. } => {
2893 Some(golem_api_grpc::proto::golem::rib::expr::Expr::Unwrap(
2894 Box::new(golem_api_grpc::proto::golem::rib::UnwrapExpr {
2895 expr: Some(Box::new((*expr).into())),
2896 }),
2897 ))
2898 }
2899 Expr::Throw { message, .. } => {
2900 Some(golem_api_grpc::proto::golem::rib::expr::Expr::Throw(
2901 golem_api_grpc::proto::golem::rib::ThrowExpr { message },
2902 ))
2903 }
2904 Expr::GetTag { expr, .. } => {
2905 Some(golem_api_grpc::proto::golem::rib::expr::Expr::Tag(
2906 Box::new(golem_api_grpc::proto::golem::rib::GetTagExpr {
2907 expr: Some(Box::new((*expr).into())),
2908 }),
2909 ))
2910 }
2911 Expr::And { lhs, rhs, .. } => {
2912 Some(golem_api_grpc::proto::golem::rib::expr::Expr::And(
2913 Box::new(golem_api_grpc::proto::golem::rib::AndExpr {
2914 left: Some(Box::new((*lhs).into())),
2915 right: Some(Box::new((*rhs).into())),
2916 }),
2917 ))
2918 }
2919
2920 Expr::Or { lhs, rhs, .. } => {
2921 Some(golem_api_grpc::proto::golem::rib::expr::Expr::Or(Box::new(
2922 golem_api_grpc::proto::golem::rib::OrExpr {
2923 left: Some(Box::new((*lhs).into())),
2924 right: Some(Box::new((*rhs).into())),
2925 },
2926 )))
2927 }
2928 Expr::ListComprehension {
2929 iterated_variable,
2930 iterable_expr,
2931 yield_expr,
2932 ..
2933 } => Some(
2934 golem_api_grpc::proto::golem::rib::expr::Expr::ListComprehension(Box::new(
2935 golem_api_grpc::proto::golem::rib::ListComprehensionExpr {
2936 iterated_variable: iterated_variable.name(),
2937 iterable_expr: Some(Box::new((*iterable_expr).into())),
2938 yield_expr: Some(Box::new((*yield_expr).into())),
2939 },
2940 )),
2941 ),
2942
2943 Expr::ListReduce {
2944 reduce_variable,
2945 iterated_variable,
2946 iterable_expr,
2947 yield_expr,
2948 init_value_expr,
2949 ..
2950 } => Some(golem_api_grpc::proto::golem::rib::expr::Expr::ListReduce(
2951 Box::new(golem_api_grpc::proto::golem::rib::ListReduceExpr {
2952 reduce_variable: reduce_variable.name(),
2953 iterated_variable: iterated_variable.name(),
2954 iterable_expr: Some(Box::new((*iterable_expr).into())),
2955 init_value_expr: Some(Box::new((*init_value_expr).into())),
2956 yield_expr: Some(Box::new((*yield_expr).into())),
2957 }),
2958 )),
2959 Expr::InvokeMethodLazy {
2960 lhs,
2961 method,
2962 generic_type_parameter,
2963 args,
2964 ..
2965 } => Some(
2966 golem_api_grpc::proto::golem::rib::expr::Expr::LazyInvokeMethod(Box::new(
2967 golem_api_grpc::proto::golem::rib::LazyInvokeMethodExpr {
2968 lhs: Some(Box::new((*lhs).into())),
2969 method,
2970 generic_type_parameter: generic_type_parameter.map(|t| t.value),
2971 args: args.into_iter().map(|expr| expr.into()).collect(),
2972 },
2973 )),
2974 ),
2975 };
2976
2977 golem_api_grpc::proto::golem::rib::Expr { expr }
2978 }
2979 }
2980
2981 impl TryFrom<golem_api_grpc::proto::golem::rib::ArmPattern> for ArmPattern {
2982 type Error = String;
2983
2984 fn try_from(
2985 value: golem_api_grpc::proto::golem::rib::ArmPattern,
2986 ) -> Result<Self, Self::Error> {
2987 let pattern = value.pattern.ok_or("Missing pattern")?;
2988 match pattern {
2989 golem_api_grpc::proto::golem::rib::arm_pattern::Pattern::WildCard(_) => {
2990 Ok(ArmPattern::WildCard)
2991 }
2992 golem_api_grpc::proto::golem::rib::arm_pattern::Pattern::As(asp) => {
2993 let name = asp.name;
2994 let pattern = asp.pattern.ok_or("Missing pattern")?;
2995 Ok(ArmPattern::As(name, Box::new((*pattern).try_into()?)))
2996 }
2997 golem_api_grpc::proto::golem::rib::arm_pattern::Pattern::Constructor(
2998 golem_api_grpc::proto::golem::rib::ConstructorArmPattern { name, patterns },
2999 ) => {
3000 let patterns = patterns
3001 .into_iter()
3002 .map(ArmPattern::try_from)
3003 .collect::<Result<Vec<_>, _>>()?;
3004 Ok(ArmPattern::Constructor(name, patterns))
3005 }
3006 golem_api_grpc::proto::golem::rib::arm_pattern::Pattern::TupleConstructor(
3007 golem_api_grpc::proto::golem::rib::TupleConstructorArmPattern { patterns },
3008 ) => {
3009 let patterns = patterns
3010 .into_iter()
3011 .map(ArmPattern::try_from)
3012 .collect::<Result<Vec<_>, _>>()?;
3013 Ok(ArmPattern::TupleConstructor(patterns))
3014 }
3015 golem_api_grpc::proto::golem::rib::arm_pattern::Pattern::Literal(
3016 golem_api_grpc::proto::golem::rib::LiteralArmPattern { expr },
3017 ) => {
3018 let inner = expr.ok_or("Missing expr")?;
3019 Ok(ArmPattern::Literal(Box::new(inner.try_into()?)))
3020 }
3021 golem_api_grpc::proto::golem::rib::arm_pattern::Pattern::RecordConstructor(
3022 golem_api_grpc::proto::golem::rib::RecordConstructorArmPattern { fields },
3023 ) => {
3024 let fields = fields
3025 .into_iter()
3026 .map(|field| {
3027 let name = field.name;
3028 let proto_pattern = field.pattern.ok_or("Missing pattern")?;
3029 let arm_pattern = ArmPattern::try_from(proto_pattern)?;
3030 Ok((name, arm_pattern))
3031 })
3032 .collect::<Result<Vec<_>, String>>()?;
3033 Ok(ArmPattern::RecordConstructor(fields))
3034 }
3035 golem_api_grpc::proto::golem::rib::arm_pattern::Pattern::ListConstructor(
3036 golem_api_grpc::proto::golem::rib::ListConstructorArmPattern { patterns },
3037 ) => {
3038 let patterns = patterns
3039 .into_iter()
3040 .map(ArmPattern::try_from)
3041 .collect::<Result<Vec<_>, _>>()?;
3042 Ok(ArmPattern::ListConstructor(patterns))
3043 }
3044 }
3045 }
3046 }
3047
3048 impl From<ArmPattern> for golem_api_grpc::proto::golem::rib::ArmPattern {
3049 fn from(value: ArmPattern) -> Self {
3050 match value {
3051 ArmPattern::WildCard => golem_api_grpc::proto::golem::rib::ArmPattern {
3052 pattern: Some(
3053 golem_api_grpc::proto::golem::rib::arm_pattern::Pattern::WildCard(
3054 golem_api_grpc::proto::golem::rib::WildCardArmPattern {},
3055 ),
3056 ),
3057 },
3058 ArmPattern::As(name, pattern) => golem_api_grpc::proto::golem::rib::ArmPattern {
3059 pattern: Some(golem_api_grpc::proto::golem::rib::arm_pattern::Pattern::As(
3060 Box::new(golem_api_grpc::proto::golem::rib::AsArmPattern {
3061 name,
3062 pattern: Some(Box::new((*pattern).into())),
3063 }),
3064 )),
3065 },
3066 ArmPattern::Constructor(name, patterns) => {
3067 golem_api_grpc::proto::golem::rib::ArmPattern {
3068 pattern: Some(
3069 golem_api_grpc::proto::golem::rib::arm_pattern::Pattern::Constructor(
3070 golem_api_grpc::proto::golem::rib::ConstructorArmPattern {
3071 name,
3072 patterns: patterns
3073 .into_iter()
3074 .map(golem_api_grpc::proto::golem::rib::ArmPattern::from)
3075 .collect(),
3076 },
3077 ),
3078 ),
3079 }
3080 }
3081 ArmPattern::Literal(expr) => golem_api_grpc::proto::golem::rib::ArmPattern {
3082 pattern: Some(
3083 golem_api_grpc::proto::golem::rib::arm_pattern::Pattern::Literal(
3084 golem_api_grpc::proto::golem::rib::LiteralArmPattern {
3085 expr: Some((*expr).into()),
3086 },
3087 ),
3088 ),
3089 },
3090
3091 ArmPattern::TupleConstructor(patterns) => {
3092 golem_api_grpc::proto::golem::rib::ArmPattern {
3093 pattern: Some(
3094 golem_api_grpc::proto::golem::rib::arm_pattern::Pattern::TupleConstructor(
3095 golem_api_grpc::proto::golem::rib::TupleConstructorArmPattern {
3096 patterns: patterns
3097 .into_iter()
3098 .map(golem_api_grpc::proto::golem::rib::ArmPattern::from)
3099 .collect(),
3100 },
3101 ),
3102 ),
3103 }
3104 }
3105
3106 ArmPattern::RecordConstructor(fields) => {
3107 golem_api_grpc::proto::golem::rib::ArmPattern {
3108 pattern: Some(
3109 golem_api_grpc::proto::golem::rib::arm_pattern::Pattern::RecordConstructor(
3110 golem_api_grpc::proto::golem::rib::RecordConstructorArmPattern {
3111 fields: fields
3112 .into_iter()
3113 .map(|(name, pattern)| {
3114 golem_api_grpc::proto::golem::rib::RecordFieldArmPattern {
3115 name,
3116 pattern: Some(pattern.into()),
3117 }
3118 })
3119 .collect(),
3120 },
3121 ),
3122 ),
3123 }
3124 }
3125
3126 ArmPattern::ListConstructor(patterns) => {
3127 golem_api_grpc::proto::golem::rib::ArmPattern {
3128 pattern: Some(
3129 golem_api_grpc::proto::golem::rib::arm_pattern::Pattern::ListConstructor(
3130 golem_api_grpc::proto::golem::rib::ListConstructorArmPattern {
3131 patterns: patterns
3132 .into_iter()
3133 .map(golem_api_grpc::proto::golem::rib::ArmPattern::from)
3134 .collect(),
3135 },
3136 ),
3137 ),
3138 }
3139 }
3140 }
3141 }
3142 }
3143
3144 impl TryFrom<golem_api_grpc::proto::golem::rib::MatchArm> for MatchArm {
3145 type Error = String;
3146
3147 fn try_from(
3148 value: golem_api_grpc::proto::golem::rib::MatchArm,
3149 ) -> Result<Self, Self::Error> {
3150 let pattern = value.pattern.ok_or("Missing pattern")?;
3151 let expr = value.expr.ok_or("Missing expr")?;
3152 Ok(MatchArm::new(pattern.try_into()?, expr.try_into()?))
3153 }
3154 }
3155
3156 impl From<MatchArm> for golem_api_grpc::proto::golem::rib::MatchArm {
3157 fn from(value: MatchArm) -> Self {
3158 let MatchArm {
3159 arm_pattern,
3160 arm_resolution_expr,
3161 } = value;
3162 golem_api_grpc::proto::golem::rib::MatchArm {
3163 pattern: Some(arm_pattern.into()),
3164 expr: Some((*arm_resolution_expr).into()),
3165 }
3166 }
3167 }
3168}
3169
3170fn find_expr(expr: &mut Expr, source_span: &SourceSpan) -> Option<Expr> {
3171 let mut expr = expr.clone();
3172
3173 let mut visitor = ExprVisitor::bottom_up(&mut expr);
3174
3175 while let Some(current) = visitor.pop_back() {
3176 let span = current.source_span();
3177
3178 if source_span.eq(&span) {
3179 return Some(current.clone());
3180 }
3181 }
3182
3183 None
3184}