1use super::annotation::Annotations;
4use super::{MessageType, NonEmptyVec, ProgressAttachment, Role, ValidationError};
5use proc_macro2::{Ident, TokenStream};
6
7#[path = "protocol_validation.rs"]
8mod validation;
9use validation::{ensure_declared_role, validate_choice_branches};
10
11fn annotation_has_key(annotation: &super::annotation::ProtocolAnnotation, key: &str) -> bool {
12 annotation
13 .dsl_entries()
14 .iter()
15 .any(|(entry_key, _)| entry_key == key)
16}
17
18fn annotation_has_value(
19 annotation: &super::annotation::ProtocolAnnotation,
20 key: &str,
21 value: &str,
22) -> bool {
23 annotation
24 .dsl_entries()
25 .iter()
26 .any(|(entry_key, entry_value)| entry_key == key && entry_value.eq_ignore_ascii_case(value))
27}
28
29#[derive(Debug)]
31pub enum Protocol {
32 Begin {
34 operation: String,
35 args: Vec<String>,
36 progress: Option<ProgressAttachment>,
37 continuation: Box<Protocol>,
38 },
39
40 Await {
42 operation: String,
43 continuation: Box<Protocol>,
44 },
45
46 Resolve {
48 operation: String,
49 outcome: CommitmentOutcome,
50 continuation: Box<Protocol>,
51 },
52
53 Invalidate {
55 operation: String,
56 continuation: Box<Protocol>,
57 },
58
59 Send {
61 from: Role,
62 to: Role,
63 message: MessageType,
64 continuation: Box<Protocol>,
65 annotations: Annotations,
67 from_annotations: Annotations,
69 to_annotations: Annotations,
71 },
72
73 Broadcast {
75 from: Role,
76 to_all: NonEmptyVec<Role>,
77 message: MessageType,
78 continuation: Box<Protocol>,
79 annotations: Annotations,
81 from_annotations: Annotations,
83 },
84
85 Choice {
87 role: Role,
88 branches: NonEmptyVec<Branch>,
89 annotations: Annotations,
91 },
92
93 Let {
95 name: String,
97 mode: AuthorityBindingMode,
99 expr: AuthorityExpr,
101 linear: bool,
103 continuation: Box<Protocol>,
105 },
106
107 Case {
109 expr: AuthorityExpr,
111 branches: NonEmptyVec<CaseBranch>,
113 },
114
115 Timeout {
117 role: Role,
119 duration_ms: u64,
121 body: Box<Protocol>,
123 on_timeout: Box<Protocol>,
125 on_cancel: Option<Box<Protocol>>,
127 },
128
129 Loop {
131 condition: Option<Condition>,
132 body: Box<Protocol>,
133 },
134
135 Parallel { protocols: NonEmptyVec<Protocol> },
137
138 Rec { label: Ident, body: Box<Protocol> },
140
141 Var(Ident),
143
144 Publish {
146 event: String,
147 arg: Option<String>,
148 continuation: Box<Protocol>,
149 },
150
151 PublishAuthority {
153 witness: String,
154 publication_name: String,
155 continuation: Box<Protocol>,
156 },
157
158 Materialize {
160 proof: String,
161 publication: String,
162 continuation: Box<Protocol>,
163 },
164
165 Handoff {
167 operation: String,
168 target: Role,
169 receipt: String,
170 continuation: Box<Protocol>,
171 },
172
173 DependentWork {
175 name: String,
176 arg: Option<String>,
177 required_for: String,
178 continuation: Box<Protocol>,
179 },
180
181 Extension {
183 extension: Box<dyn crate::extensions::ProtocolExtension>,
185 continuation: Box<Protocol>,
187 annotations: Annotations,
189 },
190
191 End,
193}
194
195#[derive(Debug)]
197pub struct Branch {
198 pub label: Ident,
199 pub guard: Option<ChoiceGuard>,
200 pub protocol: Protocol,
201}
202
203#[derive(Debug)]
205pub struct CaseBranch {
206 pub pattern: CasePattern,
207 pub protocol: Protocol,
208}
209
210#[derive(Debug, Clone, PartialEq, Eq)]
212pub struct CasePattern {
213 pub constructor: String,
214 pub binders: Vec<String>,
215}
216
217#[derive(Debug, Clone, Copy, PartialEq, Eq)]
219pub enum AuthorityBindingMode {
220 Plain,
221 Authoritative,
222 Observe,
223}
224
225#[derive(Debug, Clone, PartialEq, Eq)]
227pub enum AuthorityExpr {
228 Var(String),
229 Check {
230 effect: String,
231 operation: String,
232 args: Vec<String>,
233 },
234 Observe {
235 effect: String,
236 operation: String,
237 args: Vec<String>,
238 },
239 Transfer {
240 subject: String,
241 from: String,
242 to: String,
243 },
244 Constructor {
245 name: String,
246 arg: Option<String>,
247 },
248 Call {
249 name: String,
250 args: Vec<String>,
251 },
252}
253
254#[derive(Debug, Clone, PartialEq, Eq)]
256pub enum CommitmentOutcome {
257 Success(Option<String>),
258 Failure(Option<String>),
259 Timeout(Option<String>),
260 Cancelled,
261}
262
263#[derive(Debug, Clone)]
265pub enum ChoiceGuard {
266 Predicate(TokenStream),
267 Evidence {
268 effect: String,
269 operation: String,
270 args: Vec<String>,
271 binding: String,
272 },
273}
274
275#[derive(Debug, Clone)]
277pub enum Condition {
278 RoleDecides(Role),
280 Count(usize),
282 Custom(TokenStream),
284 Fuel(usize),
286 YieldAfter(usize),
288 YieldWhen(String),
290}
291
292impl Protocol {
293 #[must_use]
294 pub fn mentions_role(&self, role: &Role) -> bool {
295 match self {
296 Protocol::Begin { continuation, .. }
297 | Protocol::Await { continuation, .. }
298 | Protocol::Resolve { continuation, .. }
299 | Protocol::Invalidate { continuation, .. } => continuation.mentions_role(role),
300 Protocol::Send {
301 from,
302 to,
303 continuation,
304 ..
305 } => {
306 from.matches_family(role)
307 || to.matches_family(role)
308 || continuation.mentions_role(role)
309 }
310 Protocol::Broadcast {
311 from,
312 to_all,
313 continuation,
314 ..
315 } => {
316 from.matches_family(role)
317 || to_all.iter().any(|r| r.matches_family(role))
318 || continuation.mentions_role(role)
319 }
320 Protocol::Choice {
321 role: r, branches, ..
322 } => r.matches_family(role) || branches.iter().any(|b| b.protocol.mentions_role(role)),
323 Protocol::Let { continuation, .. } => continuation.mentions_role(role),
324 Protocol::Case { branches, .. } => {
325 branches.iter().any(|b| b.protocol.mentions_role(role))
326 }
327 Protocol::Timeout {
328 role: timeout_role,
329 body,
330 on_timeout,
331 on_cancel,
332 ..
333 } => {
334 timeout_role.matches_family(role)
335 || body.mentions_role(role)
336 || on_timeout.mentions_role(role)
337 || on_cancel
338 .as_deref()
339 .is_some_and(|branch| branch.mentions_role(role))
340 }
341 Protocol::Loop { body, .. } => body.mentions_role(role),
342 Protocol::Parallel { protocols } => protocols.iter().any(|p| p.mentions_role(role)),
343 Protocol::Rec { body, .. } => body.mentions_role(role),
344 Protocol::Publish { continuation, .. }
345 | Protocol::PublishAuthority { continuation, .. }
346 | Protocol::Materialize { continuation, .. }
347 | Protocol::DependentWork { continuation, .. } => continuation.mentions_role(role),
348 Protocol::Handoff {
349 target,
350 continuation,
351 ..
352 } => target.matches_family(role) || continuation.mentions_role(role),
353 Protocol::Extension {
354 extension,
355 continuation,
356 ..
357 } => extension.mentions_role(role) || continuation.mentions_role(role),
358 Protocol::Var(_) | Protocol::End => false,
359 }
360 }
361
362 pub(crate) fn validate(&self, roles: &[Role]) -> Result<(), ValidationError> {
363 match self {
364 Protocol::Begin { continuation, .. }
365 | Protocol::Await { continuation, .. }
366 | Protocol::Resolve { continuation, .. }
367 | Protocol::Invalidate { continuation, .. } => continuation.validate(roles),
368 Protocol::Send {
369 from,
370 to,
371 continuation,
372 ..
373 } => {
374 ensure_declared_role(roles, from)?;
375 ensure_declared_role(roles, to)?;
376 continuation.validate(roles)
377 }
378 Protocol::Broadcast {
379 from,
380 to_all,
381 continuation,
382 ..
383 } => {
384 ensure_declared_role(roles, from)?;
385 for to in to_all {
386 ensure_declared_role(roles, to)?;
387 }
388 continuation.validate(roles)
389 }
390 Protocol::Choice { role, branches, .. } => {
391 ensure_declared_role(roles, role)?;
392 validate_choice_branches(role, branches)?;
393 Ok(())
394 }
395 Protocol::Let { continuation, .. } => continuation.validate(roles),
396 Protocol::Case { branches, .. } => {
397 for branch in branches {
398 branch.protocol.validate(roles)?;
399 }
400 Ok(())
401 }
402 Protocol::Timeout {
403 role,
404 body,
405 on_timeout,
406 on_cancel,
407 ..
408 } => {
409 ensure_declared_role(roles, role)?;
410 body.validate(roles)?;
411 on_timeout.validate(roles)?;
412 if let Some(on_cancel) = on_cancel.as_deref() {
413 on_cancel.validate(roles)?;
414 }
415 Ok(())
416 }
417 Protocol::Loop { body, .. } => body.validate(roles),
418 Protocol::Parallel { protocols } => {
419 for p in protocols {
420 p.validate(roles)?;
421 }
422 Ok(())
423 }
424 Protocol::Rec { body, .. } => body.validate(roles),
425 Protocol::Publish { continuation, .. }
426 | Protocol::PublishAuthority { continuation, .. }
427 | Protocol::Materialize { continuation, .. }
428 | Protocol::DependentWork { continuation, .. } => continuation.validate(roles),
429 Protocol::Handoff {
430 target,
431 continuation,
432 ..
433 } => {
434 ensure_declared_role(roles, target)?;
435 continuation.validate(roles)
436 }
437 Protocol::Extension {
438 extension,
439 continuation,
440 ..
441 } => {
442 extension.validate(roles).map_err(|e| {
444 ValidationError::ExtensionError(format!("Extension validation failed: {}", e))
445 })?;
446 continuation.validate(roles)
447 }
448 Protocol::Var(_) | Protocol::End => Ok(()),
449 }
450 }
451
452 pub fn get_annotations(&self) -> &Annotations {
454 match self {
455 Protocol::Send { annotations, .. } => annotations,
456 Protocol::Broadcast { annotations, .. } => annotations,
457 Protocol::Choice { annotations, .. } => annotations,
458 Protocol::Begin { .. }
459 | Protocol::Await { .. }
460 | Protocol::Resolve { .. }
461 | Protocol::Invalidate { .. }
462 | Protocol::Let { .. }
463 | Protocol::Case { .. }
464 | Protocol::Timeout { .. }
465 | Protocol::Publish { .. }
466 | Protocol::PublishAuthority { .. }
467 | Protocol::Materialize { .. }
468 | Protocol::Handoff { .. }
469 | Protocol::DependentWork { .. } => {
470 static EMPTY: std::sync::OnceLock<Annotations> = std::sync::OnceLock::new();
471 EMPTY.get_or_init(Annotations::new)
472 }
473 Protocol::Extension { annotations, .. } => annotations,
474 Protocol::Loop { .. }
475 | Protocol::Parallel { .. }
476 | Protocol::Rec { .. }
477 | Protocol::Var(_)
478 | Protocol::End => {
479 static EMPTY: std::sync::OnceLock<Annotations> = std::sync::OnceLock::new();
481 EMPTY.get_or_init(Annotations::new)
482 }
483 }
484 }
485
486 pub fn get_from_annotations(&self) -> Option<&Annotations> {
488 match self {
489 Protocol::Send {
490 from_annotations, ..
491 } => Some(from_annotations),
492 Protocol::Broadcast {
493 from_annotations, ..
494 } => Some(from_annotations),
495 _ => None,
496 }
497 }
498
499 pub fn get_to_annotations(&self) -> Option<&Annotations> {
501 match self {
502 Protocol::Send { to_annotations, .. } => Some(to_annotations),
503 _ => None,
504 }
505 }
506
507 pub fn get_annotations_mut(&mut self) -> Option<&mut Annotations> {
509 match self {
510 Protocol::Send { annotations, .. } => Some(annotations),
511 Protocol::Broadcast { annotations, .. } => Some(annotations),
512 Protocol::Choice { annotations, .. } => Some(annotations),
513 Protocol::Begin { .. }
514 | Protocol::Await { .. }
515 | Protocol::Resolve { .. }
516 | Protocol::Invalidate { .. }
517 | Protocol::Let { .. }
518 | Protocol::Case { .. }
519 | Protocol::Timeout { .. }
520 | Protocol::Publish { .. }
521 | Protocol::PublishAuthority { .. }
522 | Protocol::Materialize { .. }
523 | Protocol::Handoff { .. }
524 | Protocol::DependentWork { .. } => None,
525 Protocol::Extension { annotations, .. } => Some(annotations),
526 Protocol::Loop { .. }
527 | Protocol::Parallel { .. }
528 | Protocol::Rec { .. }
529 | Protocol::Var(_)
530 | Protocol::End => None,
531 }
532 }
533
534 pub fn get_from_annotations_mut(&mut self) -> Option<&mut Annotations> {
536 match self {
537 Protocol::Send {
538 from_annotations, ..
539 } => Some(from_annotations),
540 Protocol::Broadcast {
541 from_annotations, ..
542 } => Some(from_annotations),
543 _ => None,
544 }
545 }
546
547 pub fn get_to_annotations_mut(&mut self) -> Option<&mut Annotations> {
549 match self {
550 Protocol::Send { to_annotations, .. } => Some(to_annotations),
551 _ => None,
552 }
553 }
554
555 pub fn add_annotation(&mut self, annotation: super::annotation::ProtocolAnnotation) -> bool {
557 if let Some(annotations) = self.get_annotations_mut() {
558 annotations.push(annotation);
559 true
560 } else {
561 false
562 }
563 }
564
565 pub fn clear_annotations(&mut self) {
567 if let Some(annotations) = self.get_annotations_mut() {
568 annotations.clear();
569 }
570 if let Some(from_annotations) = self.get_from_annotations_mut() {
571 from_annotations.clear();
572 }
573 if let Some(to_annotations) = self.get_to_annotations_mut() {
574 to_annotations.clear();
575 }
576 }
577
578 pub fn has_any_annotations(&self) -> bool {
580 !self.get_annotations().is_empty()
581 || self.get_from_annotations().is_some_and(|a| !a.is_empty())
582 || self.get_to_annotations().is_some_and(|a| !a.is_empty())
583 }
584
585 pub fn annotation_count(&self) -> usize {
587 self.get_annotations().len()
588 + self.get_from_annotations().map_or(0, |a| a.len())
589 + self.get_to_annotations().map_or(0, |a| a.len())
590 }
591
592 pub fn merge_annotations_from(&mut self, other: &Protocol) {
594 if let Some(self_annotations) = self.get_annotations_mut() {
596 self_annotations.merge(other.get_annotations());
597 }
598
599 if let (Some(self_from), Some(other_from)) = (
601 self.get_from_annotations_mut(),
602 other.get_from_annotations(),
603 ) {
604 self_from.merge(other_from);
605 }
606
607 if let (Some(self_to), Some(other_to)) =
609 (self.get_to_annotations_mut(), other.get_to_annotations())
610 {
611 self_to.merge(other_to);
612 }
613 }
614
615 pub fn validate_required_annotations(&self, required_keys: &[&str]) -> Result<(), Vec<String>> {
617 let missing: Vec<String> = required_keys
618 .iter()
619 .filter(|&key| {
620 !self
621 .get_annotations()
622 .iter()
623 .any(|annotation| annotation_has_key(annotation, key))
624 })
625 .map(|&key| key.to_string())
626 .collect();
627
628 if missing.is_empty() {
629 Ok(())
630 } else {
631 Err(missing)
632 }
633 }
634
635 pub fn collect_nodes_with_annotation<'a>(&'a self, key: &str, nodes: &mut Vec<&'a Protocol>) {
637 if self
638 .get_annotations()
639 .iter()
640 .any(|annotation| annotation_has_key(annotation, key))
641 {
642 nodes.push(self);
643 }
644
645 match self {
647 Protocol::Begin { continuation, .. }
648 | Protocol::Await { continuation, .. }
649 | Protocol::Resolve { continuation, .. }
650 | Protocol::Invalidate { continuation, .. } => {
651 continuation.collect_nodes_with_annotation(key, nodes);
652 }
653 Protocol::Send { continuation, .. } => {
654 continuation.collect_nodes_with_annotation(key, nodes);
655 }
656 Protocol::Broadcast { continuation, .. } => {
657 continuation.collect_nodes_with_annotation(key, nodes);
658 }
659 Protocol::Let { continuation, .. } => {
660 continuation.collect_nodes_with_annotation(key, nodes);
661 }
662 Protocol::Choice { branches, .. } => {
663 for branch in branches {
664 branch.protocol.collect_nodes_with_annotation(key, nodes);
665 }
666 }
667 Protocol::Case { branches, .. } => {
668 for branch in branches {
669 branch.protocol.collect_nodes_with_annotation(key, nodes);
670 }
671 }
672 Protocol::Timeout {
673 body,
674 on_timeout,
675 on_cancel,
676 ..
677 } => {
678 body.collect_nodes_with_annotation(key, nodes);
679 on_timeout.collect_nodes_with_annotation(key, nodes);
680 if let Some(on_cancel) = on_cancel.as_deref() {
681 on_cancel.collect_nodes_with_annotation(key, nodes);
682 }
683 }
684 Protocol::Loop { body, .. } => {
685 body.collect_nodes_with_annotation(key, nodes);
686 }
687 Protocol::Parallel { protocols } => {
688 for protocol in protocols {
689 protocol.collect_nodes_with_annotation(key, nodes);
690 }
691 }
692 Protocol::Rec { body, .. } => {
693 body.collect_nodes_with_annotation(key, nodes);
694 }
695 Protocol::Publish { continuation, .. }
696 | Protocol::PublishAuthority { continuation, .. }
697 | Protocol::Materialize { continuation, .. }
698 | Protocol::Handoff { continuation, .. }
699 | Protocol::DependentWork { continuation, .. } => {
700 continuation.collect_nodes_with_annotation(key, nodes);
701 }
702 Protocol::Extension { continuation, .. } => {
703 continuation.collect_nodes_with_annotation(key, nodes);
704 }
705 Protocol::Var(_) | Protocol::End => {
706 }
708 }
709 }
710
711 pub fn collect_nodes_with_annotation_value<'a>(
713 &'a self,
714 key: &str,
715 value: &str,
716 nodes: &mut Vec<&'a Protocol>,
717 ) {
718 if self
719 .get_annotations()
720 .iter()
721 .any(|annotation| annotation_has_value(annotation, key, value))
722 {
723 nodes.push(self);
724 }
725
726 match self {
728 Protocol::Begin { continuation, .. }
729 | Protocol::Await { continuation, .. }
730 | Protocol::Resolve { continuation, .. }
731 | Protocol::Invalidate { continuation, .. } => {
732 continuation.collect_nodes_with_annotation_value(key, value, nodes);
733 }
734 Protocol::Send { continuation, .. } => {
735 continuation.collect_nodes_with_annotation_value(key, value, nodes);
736 }
737 Protocol::Broadcast { continuation, .. } => {
738 continuation.collect_nodes_with_annotation_value(key, value, nodes);
739 }
740 Protocol::Let { continuation, .. } => {
741 continuation.collect_nodes_with_annotation_value(key, value, nodes);
742 }
743 Protocol::Choice { branches, .. } => {
744 for branch in branches {
745 branch
746 .protocol
747 .collect_nodes_with_annotation_value(key, value, nodes);
748 }
749 }
750 Protocol::Case { branches, .. } => {
751 for branch in branches {
752 branch
753 .protocol
754 .collect_nodes_with_annotation_value(key, value, nodes);
755 }
756 }
757 Protocol::Timeout {
758 body,
759 on_timeout,
760 on_cancel,
761 ..
762 } => {
763 body.collect_nodes_with_annotation_value(key, value, nodes);
764 on_timeout.collect_nodes_with_annotation_value(key, value, nodes);
765 if let Some(on_cancel) = on_cancel.as_deref() {
766 on_cancel.collect_nodes_with_annotation_value(key, value, nodes);
767 }
768 }
769 Protocol::Loop { body, .. } => {
770 body.collect_nodes_with_annotation_value(key, value, nodes);
771 }
772 Protocol::Parallel { protocols } => {
773 for protocol in protocols {
774 protocol.collect_nodes_with_annotation_value(key, value, nodes);
775 }
776 }
777 Protocol::Rec { body, .. } => {
778 body.collect_nodes_with_annotation_value(key, value, nodes);
779 }
780 Protocol::Publish { continuation, .. }
781 | Protocol::PublishAuthority { continuation, .. }
782 | Protocol::Materialize { continuation, .. }
783 | Protocol::Handoff { continuation, .. }
784 | Protocol::DependentWork { continuation, .. } => {
785 continuation.collect_nodes_with_annotation_value(key, value, nodes);
786 }
787 Protocol::Extension { continuation, .. } => {
788 continuation.collect_nodes_with_annotation_value(key, value, nodes);
789 }
790 Protocol::Var(_) | Protocol::End => {
791 }
793 }
794 }
795
796 pub fn deep_annotation_count(&self) -> usize {
798 let mut count = self.annotation_count();
799
800 match self {
801 Protocol::Begin { continuation, .. }
802 | Protocol::Await { continuation, .. }
803 | Protocol::Resolve { continuation, .. }
804 | Protocol::Invalidate { continuation, .. } => {
805 count += continuation.deep_annotation_count();
806 }
807 Protocol::Send { continuation, .. } => {
808 count += continuation.deep_annotation_count();
809 }
810 Protocol::Broadcast { continuation, .. } => {
811 count += continuation.deep_annotation_count();
812 }
813 Protocol::Let { continuation, .. } => {
814 count += continuation.deep_annotation_count();
815 }
816 Protocol::Choice { branches, .. } => {
817 for branch in branches {
818 count += branch.protocol.deep_annotation_count();
819 }
820 }
821 Protocol::Case { branches, .. } => {
822 for branch in branches {
823 count += branch.protocol.deep_annotation_count();
824 }
825 }
826 Protocol::Timeout {
827 body,
828 on_timeout,
829 on_cancel,
830 ..
831 } => {
832 count += body.deep_annotation_count();
833 count += on_timeout.deep_annotation_count();
834 if let Some(on_cancel) = on_cancel.as_deref() {
835 count += on_cancel.deep_annotation_count();
836 }
837 }
838 Protocol::Loop { body, .. } => {
839 count += body.deep_annotation_count();
840 }
841 Protocol::Parallel { protocols } => {
842 for protocol in protocols {
843 count += protocol.deep_annotation_count();
844 }
845 }
846 Protocol::Rec { body, .. } => {
847 count += body.deep_annotation_count();
848 }
849 Protocol::Publish { continuation, .. }
850 | Protocol::PublishAuthority { continuation, .. }
851 | Protocol::Materialize { continuation, .. }
852 | Protocol::Handoff { continuation, .. }
853 | Protocol::DependentWork { continuation, .. } => {
854 count += continuation.deep_annotation_count();
855 }
856 Protocol::Extension { continuation, .. } => {
857 count += continuation.deep_annotation_count();
858 }
859 Protocol::Var(_) | Protocol::End => {
860 }
862 }
863
864 count
865 }
866
867 pub fn visit_annotated_nodes<F>(&self, f: &mut F)
869 where
870 F: FnMut(&Protocol),
871 {
872 if self.has_any_annotations() {
873 f(self);
874 }
875
876 match self {
877 Protocol::Begin { continuation, .. }
878 | Protocol::Await { continuation, .. }
879 | Protocol::Resolve { continuation, .. }
880 | Protocol::Invalidate { continuation, .. } => {
881 continuation.visit_annotated_nodes(f);
882 }
883 Protocol::Send { continuation, .. } => {
884 continuation.visit_annotated_nodes(f);
885 }
886 Protocol::Broadcast { continuation, .. } => {
887 continuation.visit_annotated_nodes(f);
888 }
889 Protocol::Let { continuation, .. } => {
890 continuation.visit_annotated_nodes(f);
891 }
892 Protocol::Choice { branches, .. } => {
893 for branch in branches {
894 branch.protocol.visit_annotated_nodes(f);
895 }
896 }
897 Protocol::Case { branches, .. } => {
898 for branch in branches {
899 branch.protocol.visit_annotated_nodes(f);
900 }
901 }
902 Protocol::Timeout {
903 body,
904 on_timeout,
905 on_cancel,
906 ..
907 } => {
908 body.visit_annotated_nodes(f);
909 on_timeout.visit_annotated_nodes(f);
910 if let Some(on_cancel) = on_cancel.as_deref() {
911 on_cancel.visit_annotated_nodes(f);
912 }
913 }
914 Protocol::Loop { body, .. } => {
915 body.visit_annotated_nodes(f);
916 }
917 Protocol::Parallel { protocols } => {
918 for protocol in protocols {
919 protocol.visit_annotated_nodes(f);
920 }
921 }
922 Protocol::Rec { body, .. } => {
923 body.visit_annotated_nodes(f);
924 }
925 Protocol::Publish { continuation, .. }
926 | Protocol::PublishAuthority { continuation, .. }
927 | Protocol::Materialize { continuation, .. }
928 | Protocol::Handoff { continuation, .. }
929 | Protocol::DependentWork { continuation, .. } => {
930 continuation.visit_annotated_nodes(f);
931 }
932 Protocol::Extension { continuation, .. } => {
933 continuation.visit_annotated_nodes(f);
934 }
935 Protocol::Var(_) | Protocol::End => {
936 }
938 }
939 }
940
941 pub fn visit_annotated_nodes_mut<F>(&mut self, f: &mut F)
943 where
944 F: FnMut(&mut Protocol),
945 {
946 if self.has_any_annotations() {
947 f(self);
948 }
949
950 match self {
951 Protocol::Begin { continuation, .. }
952 | Protocol::Await { continuation, .. }
953 | Protocol::Resolve { continuation, .. }
954 | Protocol::Invalidate { continuation, .. } => {
955 continuation.visit_annotated_nodes_mut(f);
956 }
957 Protocol::Send { continuation, .. } => {
958 continuation.visit_annotated_nodes_mut(f);
959 }
960 Protocol::Broadcast { continuation, .. } => {
961 continuation.visit_annotated_nodes_mut(f);
962 }
963 Protocol::Let { continuation, .. } => {
964 continuation.visit_annotated_nodes_mut(f);
965 }
966 Protocol::Choice { branches, .. } => {
967 for branch in branches {
968 branch.protocol.visit_annotated_nodes_mut(f);
969 }
970 }
971 Protocol::Case { branches, .. } => {
972 for branch in branches {
973 branch.protocol.visit_annotated_nodes_mut(f);
974 }
975 }
976 Protocol::Timeout {
977 body,
978 on_timeout,
979 on_cancel,
980 ..
981 } => {
982 body.visit_annotated_nodes_mut(f);
983 on_timeout.visit_annotated_nodes_mut(f);
984 if let Some(on_cancel) = on_cancel.as_deref_mut() {
985 on_cancel.visit_annotated_nodes_mut(f);
986 }
987 }
988 Protocol::Loop { body, .. } => {
989 body.visit_annotated_nodes_mut(f);
990 }
991 Protocol::Parallel { protocols } => {
992 for protocol in protocols {
993 protocol.visit_annotated_nodes_mut(f);
994 }
995 }
996 Protocol::Rec { body, .. } => {
997 body.visit_annotated_nodes_mut(f);
998 }
999 Protocol::Publish { continuation, .. }
1000 | Protocol::PublishAuthority { continuation, .. }
1001 | Protocol::Materialize { continuation, .. }
1002 | Protocol::Handoff { continuation, .. }
1003 | Protocol::DependentWork { continuation, .. } => {
1004 continuation.visit_annotated_nodes_mut(f);
1005 }
1006 Protocol::Extension { continuation, .. } => {
1007 continuation.visit_annotated_nodes_mut(f);
1008 }
1009 Protocol::Var(_) | Protocol::End => {
1010 }
1012 }
1013 }
1014}