radix_transactions/manifest/
parser.rs

1use crate::manifest::ast::ValueKind;
2use crate::manifest::ast::*;
3use crate::manifest::compiler::CompileErrorDiagnosticsStyle;
4use crate::manifest::diagnostic_snippets::create_snippet;
5use crate::manifest::manifest_enums::KNOWN_ENUM_DISCRIMINATORS;
6use crate::manifest::token::{Position, Span, Token, TokenWithSpan};
7use crate::manifest::*;
8use radix_common::data::manifest::MANIFEST_SBOR_V1_MAX_DEPTH;
9use sbor::prelude::*;
10
11// For values greater than below it is not possible to encode compiled manifest due to
12//   EncodeError::MaxDepthExceeded(MANIFEST_SBOR_V1_MAX_DEPTH)
13pub const PARSER_MAX_DEPTH: usize = MANIFEST_SBOR_V1_MAX_DEPTH - 4;
14
15#[derive(Debug, Clone, PartialEq, Eq)]
16pub enum ParserErrorKind {
17    UnexpectedEof,
18    UnexpectedToken { expected: TokenType, actual: Token },
19    InvalidArgument { expected: TokenType, actual: Token },
20    InvalidNumberOfValues { expected: usize, actual: usize },
21    InvalidNumberOfTypes { expected: usize, actual: usize },
22    UnknownEnumDiscriminator { actual: String },
23    MaxDepthExceeded { actual: usize, max: usize },
24}
25
26#[derive(Debug, Clone, PartialEq, Eq)]
27pub struct ParserError {
28    pub error_kind: ParserErrorKind,
29    pub span: Span,
30}
31
32impl ParserError {
33    fn unexpected_token(token: TokenWithSpan, expected: TokenType) -> Self {
34        Self {
35            error_kind: ParserErrorKind::UnexpectedToken {
36                expected,
37                actual: token.token,
38            },
39            span: token.span,
40        }
41    }
42}
43
44#[derive(Debug, Clone, PartialEq, Eq)]
45pub enum TokenType {
46    Instruction,
47    Value,
48    ValueKind,
49    EnumDiscriminator,
50    Exact(Token),
51}
52
53impl fmt::Display for TokenType {
54    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
55        match self {
56            TokenType::Instruction => write!(f, "an instruction"),
57            TokenType::Value => write!(f, "a manifest SBOR value"),
58            TokenType::ValueKind => write!(f, "a manifest SBOR value kind"),
59            TokenType::EnumDiscriminator => {
60                write!(f, "a u8 enum discriminator or valid discriminator alias")
61            }
62            TokenType::Exact(token) => write!(f, "exactly {}", token),
63        }
64    }
65}
66
67pub enum InstructionIdent {
68    // ==============
69    // Pseudo-instructions
70    // ==============
71    UsePreallocatedAddress,
72    UseChild,
73
74    // ==============
75    // Standard instructions (in canonical order)
76    // ==============
77
78    // Bucket Lifecycle
79    TakeFromWorktop,
80    TakeNonFungiblesFromWorktop,
81    TakeAllFromWorktop,
82    ReturnToWorktop,
83    BurnResource,
84
85    // Resource Assertions
86    AssertWorktopContainsAny,
87    AssertWorktopContains,
88    AssertWorktopContainsNonFungibles,
89    AssertWorktopIsEmpty, // An alias
90    AssertWorktopResourcesOnly,
91    AssertWorktopResourcesInclude,
92    AssertNextCallReturnsOnly,
93    AssertNextCallReturnsInclude,
94    AssertBucketContents,
95
96    // Proof Lifecycle
97    CreateProofFromBucketOfAmount,
98    CreateProofFromBucketOfNonFungibles,
99    CreateProofFromBucketOfAll,
100    CreateProofFromAuthZoneOfAmount,
101    CreateProofFromAuthZoneOfNonFungibles,
102    CreateProofFromAuthZoneOfAll,
103    CloneProof,
104    DropProof,
105    PushToAuthZone,
106    PopFromAuthZone,
107    DropAuthZoneProofs,
108    DropAuthZoneRegularProofs,
109    DropAuthZoneSignatureProofs,
110    DropNamedProofs,
111    DropAllProofs,
112
113    // Invocations
114    CallFunction,
115    CallMethod,
116    CallRoyaltyMethod,
117    CallMetadataMethod,
118    CallRoleAssignmentMethod,
119    CallDirectVaultMethod,
120
121    // Address Allocation
122    AllocateGlobalAddress,
123
124    // Interactions with other intents
125    YieldToParent,
126    YieldToChild,
127    VerifyParent,
128
129    // ==============
130    // Call direct vault method aliases
131    // ==============
132    RecallFromVault,
133    FreezeVault,
134    UnfreezeVault,
135    RecallNonFungiblesFromVault,
136
137    // ==============
138    // Call function aliases
139    // ==============
140    PublishPackage,
141    PublishPackageAdvanced,
142    CreateFungibleResource,
143    CreateFungibleResourceWithInitialSupply,
144    CreateNonFungibleResource,
145    CreateNonFungibleResourceWithInitialSupply,
146    CreateAccessController,
147    CreateIdentity,
148    CreateIdentityAdvanced,
149    CreateAccount,
150    CreateAccountAdvanced,
151
152    // ==============
153    // Call non-main-method aliases
154    // ==============
155    SetMetadata,
156    RemoveMetadata,
157    LockMetadata,
158    SetComponentRoyalty,
159    LockComponentRoyalty,
160    ClaimComponentRoyalties,
161    SetOwnerRole,
162    LockOwnerRole,
163    SetRole,
164
165    // ==============
166    // Call main-method aliases
167    // ==============
168    ClaimPackageRoyalties,
169    MintFungible,
170    MintNonFungible,
171    MintRuidNonFungible,
172    CreateValidator,
173}
174
175impl InstructionIdent {
176    pub fn from_ident(ident: &str) -> Option<Self> {
177        let value = match ident {
178            // ==============
179            // Pseudo-instructions
180            // ==============
181            "USE_CHILD" => InstructionIdent::UseChild,
182            "USE_PREALLOCATED_ADDRESS" => InstructionIdent::UsePreallocatedAddress,
183
184            // ==============
185            // Standard instructions (in canonical order)
186            // ==============
187
188            // Bucket Lifecycle
189            TakeFromWorktop::IDENT => InstructionIdent::TakeFromWorktop,
190            TakeNonFungiblesFromWorktop::IDENT => InstructionIdent::TakeNonFungiblesFromWorktop,
191            TakeAllFromWorktop::IDENT => InstructionIdent::TakeAllFromWorktop,
192            ReturnToWorktop::IDENT => InstructionIdent::ReturnToWorktop,
193            BurnResource::IDENT => InstructionIdent::BurnResource,
194
195            // Resource Assertions
196            AssertWorktopContains::IDENT => InstructionIdent::AssertWorktopContains,
197            AssertWorktopContainsNonFungibles::IDENT => {
198                InstructionIdent::AssertWorktopContainsNonFungibles
199            }
200            AssertWorktopContainsAny::IDENT => InstructionIdent::AssertWorktopContainsAny,
201            "ASSERT_WORKTOP_IS_EMPTY" => InstructionIdent::AssertWorktopIsEmpty,
202            AssertWorktopResourcesOnly::IDENT => InstructionIdent::AssertWorktopResourcesOnly,
203            AssertWorktopResourcesInclude::IDENT => InstructionIdent::AssertWorktopResourcesInclude,
204            AssertNextCallReturnsOnly::IDENT => InstructionIdent::AssertNextCallReturnsOnly,
205            AssertNextCallReturnsInclude::IDENT => InstructionIdent::AssertNextCallReturnsInclude,
206            AssertBucketContents::IDENT => InstructionIdent::AssertBucketContents,
207
208            // Proof Lifecycle
209            CreateProofFromBucketOfAmount::IDENT => InstructionIdent::CreateProofFromBucketOfAmount,
210            CreateProofFromBucketOfNonFungibles::IDENT => {
211                InstructionIdent::CreateProofFromBucketOfNonFungibles
212            }
213            CreateProofFromBucketOfAll::IDENT => InstructionIdent::CreateProofFromBucketOfAll,
214            CreateProofFromAuthZoneOfAmount::IDENT => {
215                InstructionIdent::CreateProofFromAuthZoneOfAmount
216            }
217            CreateProofFromAuthZoneOfNonFungibles::IDENT => {
218                InstructionIdent::CreateProofFromAuthZoneOfNonFungibles
219            }
220            CreateProofFromAuthZoneOfAll::IDENT => InstructionIdent::CreateProofFromAuthZoneOfAll,
221            CloneProof::IDENT => InstructionIdent::CloneProof,
222            DropProof::IDENT => InstructionIdent::DropProof,
223            PushToAuthZone::IDENT => InstructionIdent::PushToAuthZone,
224            PopFromAuthZone::IDENT => InstructionIdent::PopFromAuthZone,
225            DropAuthZoneProofs::IDENT => InstructionIdent::DropAuthZoneProofs,
226            DropAuthZoneSignatureProofs::IDENT => InstructionIdent::DropAuthZoneSignatureProofs,
227            DropAuthZoneRegularProofs::IDENT => InstructionIdent::DropAuthZoneRegularProofs,
228            DropNamedProofs::IDENT => InstructionIdent::DropNamedProofs,
229            DropAllProofs::IDENT => InstructionIdent::DropAllProofs,
230
231            // Invocation
232            CallFunction::IDENT => InstructionIdent::CallFunction,
233            CallMethod::IDENT => InstructionIdent::CallMethod,
234            CallRoyaltyMethod::IDENT => InstructionIdent::CallRoyaltyMethod,
235            CallMetadataMethod::IDENT => InstructionIdent::CallMetadataMethod,
236            CallRoleAssignmentMethod::IDENT => InstructionIdent::CallRoleAssignmentMethod,
237            CallDirectVaultMethod::IDENT => InstructionIdent::CallDirectVaultMethod,
238
239            // Address Allocation
240            AllocateGlobalAddress::IDENT => InstructionIdent::AllocateGlobalAddress,
241
242            // Interaction with other intents
243            YieldToParent::IDENT => InstructionIdent::YieldToParent,
244            YieldToChild::IDENT => InstructionIdent::YieldToChild,
245            VerifyParent::IDENT => InstructionIdent::VerifyParent,
246
247            // ==============
248            // Call direct vault method aliases
249            // ==============
250            "RECALL_FROM_VAULT" => InstructionIdent::RecallFromVault,
251            "FREEZE_VAULT" => InstructionIdent::FreezeVault,
252            "UNFREEZE_VAULT" => InstructionIdent::UnfreezeVault,
253            "RECALL_NON_FUNGIBLES_FROM_VAULT" => InstructionIdent::RecallNonFungiblesFromVault,
254
255            // ==============
256            // Call function aliases
257            // ==============
258            "PUBLISH_PACKAGE" => InstructionIdent::PublishPackage,
259            "PUBLISH_PACKAGE_ADVANCED" => InstructionIdent::PublishPackageAdvanced,
260            "CREATE_FUNGIBLE_RESOURCE" => InstructionIdent::CreateFungibleResource,
261            "CREATE_FUNGIBLE_RESOURCE_WITH_INITIAL_SUPPLY" => {
262                InstructionIdent::CreateFungibleResourceWithInitialSupply
263            }
264            "CREATE_NON_FUNGIBLE_RESOURCE" => InstructionIdent::CreateNonFungibleResource,
265            "CREATE_NON_FUNGIBLE_RESOURCE_WITH_INITIAL_SUPPLY" => {
266                InstructionIdent::CreateNonFungibleResourceWithInitialSupply
267            }
268            "CREATE_IDENTITY" => InstructionIdent::CreateIdentity,
269            "CREATE_IDENTITY_ADVANCED" => InstructionIdent::CreateIdentityAdvanced,
270            "CREATE_ACCOUNT" => InstructionIdent::CreateAccount,
271            "CREATE_ACCOUNT_ADVANCED" => InstructionIdent::CreateAccountAdvanced,
272            "CREATE_ACCESS_CONTROLLER" => InstructionIdent::CreateAccessController,
273
274            // ==============
275            // Call non-main-method aliases
276            // ==============
277            "SET_METADATA" => InstructionIdent::SetMetadata,
278            "REMOVE_METADATA" => InstructionIdent::RemoveMetadata,
279            "LOCK_METADATA" => InstructionIdent::LockMetadata,
280            "SET_COMPONENT_ROYALTY" => InstructionIdent::SetComponentRoyalty,
281            "LOCK_COMPONENT_ROYALTY" => InstructionIdent::LockComponentRoyalty,
282            "CLAIM_COMPONENT_ROYALTIES" => InstructionIdent::ClaimComponentRoyalties,
283            "SET_OWNER_ROLE" => InstructionIdent::SetOwnerRole,
284            "LOCK_OWNER_ROLE" => InstructionIdent::LockOwnerRole,
285            "SET_ROLE" => InstructionIdent::SetRole,
286
287            // ==============
288            // Call main-method aliases
289            // ==============
290            "MINT_FUNGIBLE" => InstructionIdent::MintFungible,
291            "MINT_NON_FUNGIBLE" => InstructionIdent::MintNonFungible,
292            "MINT_RUID_NON_FUNGIBLE" => InstructionIdent::MintRuidNonFungible,
293            "CLAIM_PACKAGE_ROYALTIES" => InstructionIdent::ClaimPackageRoyalties,
294            "CREATE_VALIDATOR" => InstructionIdent::CreateValidator,
295
296            _ => {
297                return None;
298            }
299        };
300        Some(value)
301    }
302}
303
304pub enum ManifestValueIdent {
305    // ==============
306    // SBOR composite value types
307    // ==============
308    Enum,
309    Array,
310    Tuple,
311    Map,
312    // ==============
313    // SBOR aliases
314    // ==============
315    Some,
316    None,
317    Ok,
318    Err,
319    Bytes,
320    NonFungibleGlobalId,
321    // ==============
322    // SBOR custom types
323    // ==============
324    Address,
325    Bucket,
326    Proof,
327    Expression,
328    Blob,
329    Decimal,
330    PreciseDecimal,
331    NonFungibleLocalId,
332    AddressReservation,
333    NamedAddress,
334    Intent,
335    NamedIntent,
336}
337
338impl ManifestValueIdent {
339    pub fn from_ident(ident: &str) -> Option<Self> {
340        let value = match ident {
341            // ==============
342            // SBOR composite value types
343            // ==============
344            "Enum" => Self::Enum,
345            "Array" => Self::Array,
346            "Tuple" => Self::Tuple,
347            "Map" => Self::Map,
348            // ==============
349            // SBOR aliases
350            // ==============
351            "Some" => Self::Some,
352            "None" => Self::None,
353            "Ok" => Self::Ok,
354            "Err" => Self::Err,
355            "Bytes" => Self::Bytes,
356            "NonFungibleGlobalId" => Self::NonFungibleGlobalId,
357            // ==============
358            // Custom types
359            // ==============
360            "Address" => Self::Address,
361            "Bucket" => Self::Bucket,
362            "Proof" => Self::Proof,
363            "Expression" => Self::Expression,
364            "Blob" => Self::Blob,
365            "Decimal" => Self::Decimal,
366            "PreciseDecimal" => Self::PreciseDecimal,
367            "NonFungibleLocalId" => Self::NonFungibleLocalId,
368            "AddressReservation" => Self::AddressReservation,
369            "NamedAddress" => Self::NamedAddress,
370            "Intent" => Self::Intent,
371            "NamedIntent" => Self::NamedIntent,
372            _ => {
373                return None;
374            }
375        };
376        Some(value)
377    }
378}
379
380pub struct Parser {
381    tokens: Vec<TokenWithSpan>,
382    current: usize,
383    max_depth: usize,
384    stack_depth: usize,
385}
386
387impl Parser {
388    pub fn new(tokens: Vec<TokenWithSpan>, max_depth: usize) -> Result<Self, ParserError> {
389        if tokens.is_empty() {
390            Err(ParserError {
391                error_kind: ParserErrorKind::UnexpectedEof,
392                span: Span {
393                    start: Position {
394                        full_index: 0,
395                        line_idx: 0,
396                        line_char_index: 0,
397                    },
398                    end: Position {
399                        full_index: 0,
400                        line_idx: 0,
401                        line_char_index: 0,
402                    },
403                },
404            })
405        } else {
406            Ok(Self {
407                tokens,
408                current: 0,
409                max_depth,
410                stack_depth: 0,
411            })
412        }
413    }
414
415    #[inline]
416    fn track_stack_depth_increase(&mut self) -> Result<(), ParserError> {
417        self.stack_depth += 1;
418        if self.stack_depth > self.max_depth {
419            let token = self.peek()?;
420
421            return Err(ParserError {
422                error_kind: ParserErrorKind::MaxDepthExceeded {
423                    actual: self.stack_depth,
424                    max: self.max_depth,
425                },
426                span: token.span,
427            });
428        }
429        Ok(())
430    }
431
432    #[inline]
433    fn track_stack_depth_decrease(&mut self) -> Result<(), ParserError> {
434        self.stack_depth -= 1;
435        Ok(())
436    }
437
438    pub fn is_eof(&self) -> bool {
439        self.current == self.tokens.len()
440    }
441
442    pub fn peek(&mut self) -> Result<TokenWithSpan, ParserError> {
443        match self.tokens.get(self.current) {
444            Some(token) => Ok(token.clone()),
445            None => Err(ParserError {
446                error_kind: ParserErrorKind::UnexpectedEof,
447                span: {
448                    let position = self.tokens[self.current - 1].span.end;
449                    Span {
450                        start: position,
451                        end: position,
452                    }
453                },
454            }),
455        }
456    }
457
458    pub fn advance(&mut self) -> Result<TokenWithSpan, ParserError> {
459        let token = self.peek()?;
460        self.current += 1;
461        Ok(token)
462    }
463
464    fn advance_exact(&mut self, expected: Token) -> Result<TokenWithSpan, ParserError> {
465        let token = self.advance()?;
466
467        if token.token != expected {
468            Err(ParserError::unexpected_token(
469                token,
470                TokenType::Exact(expected),
471            ))
472        } else {
473            Ok(token)
474        }
475    }
476
477    pub fn parse_manifest(&mut self) -> Result<Vec<InstructionWithSpan>, ParserError> {
478        let mut instructions = Vec::<InstructionWithSpan>::new();
479
480        while !self.is_eof() {
481            instructions.push(self.parse_instruction()?);
482        }
483
484        Ok(instructions)
485    }
486
487    fn parse_instruction_arguments(&mut self) -> Result<Vec<ValueWithSpan>, ParserError> {
488        let mut args = Vec::new();
489        while self.peek()?.token != Token::Semicolon {
490            let stack_depth = self.stack_depth;
491            let result = self.parse_value();
492            match result {
493                Ok(value) => args.push(value),
494                Err(err) => match err.error_kind {
495                    // We wish to return a more specific error if the instruction's argument list is invalid.
496                    // We check if the error from parse_value comes from parsing the argument itself
497                    // by verifying it:
498                    // (a) Was an UnexpectedToken error when a Value was expected.
499                    // (b) It originated at a stack_depth directly under the argument list, so the expected
500                    // value was an argument rather than an internal value inside an argument.
501                    ParserErrorKind::UnexpectedToken { expected, actual }
502                        if expected == TokenType::Value
503                            && (stack_depth + 1 == self.stack_depth) =>
504                    {
505                        return Err(ParserError {
506                            error_kind: ParserErrorKind::InvalidArgument { expected, actual },
507                            span: err.span,
508                        })
509                    }
510                    _ => return Err(err),
511                },
512            }
513        }
514        Ok(args)
515    }
516
517    pub fn parse_instruction(&mut self) -> Result<InstructionWithSpan, ParserError> {
518        let token = self.advance()?;
519        let instruction_ident = match &token.token {
520            Token::Ident(ident_str) => InstructionIdent::from_ident(ident_str).ok_or(
521                ParserError::unexpected_token(token.clone(), TokenType::Instruction),
522            )?,
523            _ => {
524                return Err(ParserError::unexpected_token(token, TokenType::Instruction));
525            }
526        };
527        let instruction_start = token.span.start;
528
529        let instruction = match instruction_ident {
530            //===============
531            // Pseudo-instructions
532            //===============
533            InstructionIdent::UsePreallocatedAddress => Instruction::UsePreallocatedAddress {
534                package_address: self.parse_value()?,
535                blueprint_name: self.parse_value()?,
536                address_reservation: self.parse_value()?,
537                preallocated_address: self.parse_value()?,
538            },
539            InstructionIdent::UseChild => Instruction::UseChild {
540                named_intent: self.parse_value()?,
541                subintent_hash: self.parse_value()?,
542            },
543
544            //===============
545            // Standard instructions (in canonical order)
546            //===============
547
548            // Bucket Lifecycle
549            InstructionIdent::TakeFromWorktop => Instruction::TakeFromWorktop {
550                resource_address: self.parse_value()?,
551                amount: self.parse_value()?,
552                new_bucket: self.parse_value()?,
553            },
554            InstructionIdent::TakeNonFungiblesFromWorktop => {
555                Instruction::TakeNonFungiblesFromWorktop {
556                    resource_address: self.parse_value()?,
557                    ids: self.parse_value()?,
558                    new_bucket: self.parse_value()?,
559                }
560            }
561            InstructionIdent::TakeAllFromWorktop => Instruction::TakeAllFromWorktop {
562                resource_address: self.parse_value()?,
563                new_bucket: self.parse_value()?,
564            },
565            InstructionIdent::ReturnToWorktop => Instruction::ReturnToWorktop {
566                bucket: self.parse_value()?,
567            },
568            InstructionIdent::BurnResource => Instruction::BurnResource {
569                bucket: self.parse_value()?,
570            },
571
572            // Resource Assertions
573            InstructionIdent::AssertWorktopContainsAny => Instruction::AssertWorktopContainsAny {
574                resource_address: self.parse_value()?,
575            },
576            InstructionIdent::AssertWorktopContains => Instruction::AssertWorktopContains {
577                resource_address: self.parse_value()?,
578                amount: self.parse_value()?,
579            },
580            InstructionIdent::AssertWorktopContainsNonFungibles => {
581                Instruction::AssertWorktopContainsNonFungibles {
582                    resource_address: self.parse_value()?,
583                    ids: self.parse_value()?,
584                }
585            }
586            InstructionIdent::AssertWorktopIsEmpty => Instruction::AssertWorktopIsEmpty,
587            InstructionIdent::AssertWorktopResourcesOnly => {
588                Instruction::AssertWorktopResourcesOnly {
589                    constraints: self.parse_value()?,
590                }
591            }
592            InstructionIdent::AssertWorktopResourcesInclude => {
593                Instruction::AssertWorktopResourcesInclude {
594                    constraints: self.parse_value()?,
595                }
596            }
597            InstructionIdent::AssertNextCallReturnsOnly => Instruction::AssertNextCallReturnsOnly {
598                constraints: self.parse_value()?,
599            },
600            InstructionIdent::AssertNextCallReturnsInclude => {
601                Instruction::AssertNextCallReturnsInclude {
602                    constraints: self.parse_value()?,
603                }
604            }
605            InstructionIdent::AssertBucketContents => Instruction::AssertBucketContents {
606                bucket: self.parse_value()?,
607                constraint: self.parse_value()?,
608            },
609
610            // Proof Lifecycle
611            InstructionIdent::CreateProofFromBucketOfAmount => {
612                Instruction::CreateProofFromBucketOfAmount {
613                    bucket: self.parse_value()?,
614                    amount: self.parse_value()?,
615                    new_proof: self.parse_value()?,
616                }
617            }
618            InstructionIdent::CreateProofFromBucketOfNonFungibles => {
619                Instruction::CreateProofFromBucketOfNonFungibles {
620                    bucket: self.parse_value()?,
621                    ids: self.parse_value()?,
622                    new_proof: self.parse_value()?,
623                }
624            }
625            InstructionIdent::CreateProofFromBucketOfAll => {
626                Instruction::CreateProofFromBucketOfAll {
627                    bucket: self.parse_value()?,
628                    new_proof: self.parse_value()?,
629                }
630            }
631            InstructionIdent::CreateProofFromAuthZoneOfAmount => {
632                Instruction::CreateProofFromAuthZoneOfAmount {
633                    resource_address: self.parse_value()?,
634                    amount: self.parse_value()?,
635                    new_proof: self.parse_value()?,
636                }
637            }
638            InstructionIdent::CreateProofFromAuthZoneOfNonFungibles => {
639                Instruction::CreateProofFromAuthZoneOfNonFungibles {
640                    resource_address: self.parse_value()?,
641                    ids: self.parse_value()?,
642                    new_proof: self.parse_value()?,
643                }
644            }
645            InstructionIdent::CreateProofFromAuthZoneOfAll => {
646                Instruction::CreateProofFromAuthZoneOfAll {
647                    resource_address: self.parse_value()?,
648                    new_proof: self.parse_value()?,
649                }
650            }
651            InstructionIdent::CloneProof => Instruction::CloneProof {
652                proof: self.parse_value()?,
653                new_proof: self.parse_value()?,
654            },
655            InstructionIdent::DropProof => Instruction::DropProof {
656                proof: self.parse_value()?,
657            },
658            InstructionIdent::PushToAuthZone => Instruction::PushToAuthZone {
659                proof: self.parse_value()?,
660            },
661            InstructionIdent::PopFromAuthZone => Instruction::PopFromAuthZone {
662                new_proof: self.parse_value()?,
663            },
664            InstructionIdent::DropAuthZoneProofs => Instruction::DropAuthZoneProofs,
665            InstructionIdent::DropAuthZoneRegularProofs => Instruction::DropAuthZoneRegularProofs,
666            InstructionIdent::DropAuthZoneSignatureProofs => {
667                Instruction::DropAuthZoneSignatureProofs
668            }
669            InstructionIdent::DropNamedProofs => Instruction::DropNamedProofs,
670            InstructionIdent::DropAllProofs => Instruction::DropAllProofs,
671
672            // Invocations
673            InstructionIdent::CallFunction => Instruction::CallFunction {
674                package_address: self.parse_value()?,
675                blueprint_name: self.parse_value()?,
676                function_name: self.parse_value()?,
677                args: self.parse_instruction_arguments()?,
678            },
679            InstructionIdent::CallMethod => Instruction::CallMethod {
680                address: self.parse_value()?,
681                method_name: self.parse_value()?,
682                args: self.parse_instruction_arguments()?,
683            },
684            InstructionIdent::CallRoyaltyMethod => Instruction::CallRoyaltyMethod {
685                address: self.parse_value()?,
686                method_name: self.parse_value()?,
687                args: self.parse_instruction_arguments()?,
688            },
689            InstructionIdent::CallMetadataMethod => Instruction::CallMetadataMethod {
690                address: self.parse_value()?,
691                method_name: self.parse_value()?,
692                args: self.parse_instruction_arguments()?,
693            },
694            InstructionIdent::CallRoleAssignmentMethod => Instruction::CallRoleAssignmentMethod {
695                address: self.parse_value()?,
696                method_name: self.parse_value()?,
697                args: self.parse_instruction_arguments()?,
698            },
699            InstructionIdent::CallDirectVaultMethod => Instruction::CallDirectVaultMethod {
700                address: self.parse_value()?,
701                method_name: self.parse_value()?,
702                args: self.parse_instruction_arguments()?,
703            },
704
705            // Address Allocation
706            InstructionIdent::AllocateGlobalAddress => Instruction::AllocateGlobalAddress {
707                package_address: self.parse_value()?,
708                blueprint_name: self.parse_value()?,
709                address_reservation: self.parse_value()?,
710                named_address: self.parse_value()?,
711            },
712
713            // Interaction with other intents
714            InstructionIdent::YieldToParent => Instruction::YieldToParent {
715                args: self.parse_instruction_arguments()?,
716            },
717            InstructionIdent::YieldToChild => Instruction::YieldToChild {
718                child: self.parse_value()?,
719                args: self.parse_instruction_arguments()?,
720            },
721            InstructionIdent::VerifyParent => Instruction::VerifyParent {
722                access_rule: self.parse_value()?,
723            },
724
725            //===============
726            // Direct vault aliases
727            //===============
728            InstructionIdent::RecallFromVault => Instruction::RecallFromVault {
729                vault_id: self.parse_value()?,
730                args: self.parse_instruction_arguments()?,
731            },
732            InstructionIdent::FreezeVault => Instruction::FreezeVault {
733                vault_id: self.parse_value()?,
734                args: self.parse_instruction_arguments()?,
735            },
736            InstructionIdent::UnfreezeVault => Instruction::UnfreezeVault {
737                vault_id: self.parse_value()?,
738                args: self.parse_instruction_arguments()?,
739            },
740            InstructionIdent::RecallNonFungiblesFromVault => {
741                Instruction::RecallNonFungiblesFromVault {
742                    vault_id: self.parse_value()?,
743                    args: self.parse_instruction_arguments()?,
744                }
745            }
746
747            //===============
748            // Call function aliases
749            //===============
750            InstructionIdent::PublishPackage => Instruction::PublishPackage {
751                args: self.parse_instruction_arguments()?,
752            },
753            InstructionIdent::PublishPackageAdvanced => Instruction::PublishPackageAdvanced {
754                args: self.parse_instruction_arguments()?,
755            },
756            InstructionIdent::CreateFungibleResource => Instruction::CreateFungibleResource {
757                args: self.parse_instruction_arguments()?,
758            },
759            InstructionIdent::CreateFungibleResourceWithInitialSupply => {
760                Instruction::CreateFungibleResourceWithInitialSupply {
761                    args: self.parse_instruction_arguments()?,
762                }
763            }
764            InstructionIdent::CreateNonFungibleResource => Instruction::CreateNonFungibleResource {
765                args: self.parse_instruction_arguments()?,
766            },
767            InstructionIdent::CreateNonFungibleResourceWithInitialSupply => {
768                Instruction::CreateNonFungibleResourceWithInitialSupply {
769                    args: self.parse_instruction_arguments()?,
770                }
771            }
772            InstructionIdent::CreateAccessController => Instruction::CreateAccessController {
773                args: self.parse_instruction_arguments()?,
774            },
775            InstructionIdent::CreateIdentity => Instruction::CreateIdentity {
776                args: self.parse_instruction_arguments()?,
777            },
778            InstructionIdent::CreateIdentityAdvanced => Instruction::CreateIdentityAdvanced {
779                args: self.parse_instruction_arguments()?,
780            },
781            InstructionIdent::CreateAccount => Instruction::CreateAccount {
782                args: self.parse_instruction_arguments()?,
783            },
784            InstructionIdent::CreateAccountAdvanced => Instruction::CreateAccountAdvanced {
785                args: self.parse_instruction_arguments()?,
786            },
787
788            //===============
789            // Call non-main method aliases
790            //===============
791            InstructionIdent::SetMetadata => Instruction::SetMetadata {
792                address: self.parse_value()?,
793                args: self.parse_instruction_arguments()?,
794            },
795            InstructionIdent::RemoveMetadata => Instruction::RemoveMetadata {
796                address: self.parse_value()?,
797                args: self.parse_instruction_arguments()?,
798            },
799            InstructionIdent::LockMetadata => Instruction::LockMetadata {
800                address: self.parse_value()?,
801                args: self.parse_instruction_arguments()?,
802            },
803            InstructionIdent::SetComponentRoyalty => Instruction::SetComponentRoyalty {
804                address: self.parse_value()?,
805                args: self.parse_instruction_arguments()?,
806            },
807            InstructionIdent::LockComponentRoyalty => Instruction::LockComponentRoyalty {
808                address: self.parse_value()?,
809                args: self.parse_instruction_arguments()?,
810            },
811            InstructionIdent::ClaimComponentRoyalties => Instruction::ClaimComponentRoyalties {
812                address: self.parse_value()?,
813                args: self.parse_instruction_arguments()?,
814            },
815            InstructionIdent::SetOwnerRole => Instruction::SetOwnerRole {
816                address: self.parse_value()?,
817                args: self.parse_instruction_arguments()?,
818            },
819            InstructionIdent::LockOwnerRole => Instruction::LockOwnerRole {
820                address: self.parse_value()?,
821                args: self.parse_instruction_arguments()?,
822            },
823            InstructionIdent::SetRole => Instruction::SetRole {
824                address: self.parse_value()?,
825                args: self.parse_instruction_arguments()?,
826            },
827
828            //===============
829            // Call main method aliases
830            //===============
831            InstructionIdent::MintFungible => Instruction::MintFungible {
832                address: self.parse_value()?,
833                args: self.parse_instruction_arguments()?,
834            },
835            InstructionIdent::MintNonFungible => Instruction::MintNonFungible {
836                address: self.parse_value()?,
837                args: self.parse_instruction_arguments()?,
838            },
839            InstructionIdent::MintRuidNonFungible => Instruction::MintRuidNonFungible {
840                address: self.parse_value()?,
841                args: self.parse_instruction_arguments()?,
842            },
843            InstructionIdent::ClaimPackageRoyalties => Instruction::ClaimPackageRoyalties {
844                address: self.parse_value()?,
845                args: self.parse_instruction_arguments()?,
846            },
847            InstructionIdent::CreateValidator => Instruction::CreateValidator {
848                args: self.parse_instruction_arguments()?,
849            },
850        };
851
852        let instruction_end = self.advance_exact(Token::Semicolon)?.span.end;
853
854        Ok(InstructionWithSpan {
855            instruction,
856            span: Span {
857                start: instruction_start,
858                end: instruction_end,
859            },
860        })
861    }
862
863    pub fn parse_value(&mut self) -> Result<ValueWithSpan, ParserError> {
864        self.track_stack_depth_increase()?;
865        let token = self.advance()?;
866        let value = match &token.token {
867            // ==============
868            // Basic Types
869            // ==============
870            Token::BoolLiteral(value) => Value::Bool(*value),
871            Token::U8Literal(value) => Value::U8(*value),
872            Token::U16Literal(value) => Value::U16(*value),
873            Token::U32Literal(value) => Value::U32(*value),
874            Token::U64Literal(value) => Value::U64(*value),
875            Token::U128Literal(value) => Value::U128(*value),
876            Token::I8Literal(value) => Value::I8(*value),
877            Token::I16Literal(value) => Value::I16(*value),
878            Token::I32Literal(value) => Value::I32(*value),
879            Token::I64Literal(value) => Value::I64(*value),
880            Token::I128Literal(value) => Value::I128(*value),
881            Token::StringLiteral(value) => Value::String(value.clone()),
882            Token::Ident(ident_str) => {
883                let value_ident = ManifestValueIdent::from_ident(ident_str).ok_or(
884                    ParserError::unexpected_token(token.clone(), TokenType::Value),
885                )?;
886                match value_ident {
887                    ManifestValueIdent::Enum => self.parse_enum_content()?,
888                    ManifestValueIdent::Array => self.parse_array_content()?,
889                    ManifestValueIdent::Tuple => self.parse_tuple_content()?,
890                    ManifestValueIdent::Map => self.parse_map_content()?,
891
892                    // ==============
893                    // Aliases
894                    // ==============
895                    ManifestValueIdent::Some => Value::Some(Box::new(self.parse_values_one()?)),
896                    ManifestValueIdent::None => Value::None,
897                    ManifestValueIdent::Ok => Value::Ok(Box::new(self.parse_values_one()?)),
898                    ManifestValueIdent::Err => Value::Err(Box::new(self.parse_values_one()?)),
899                    ManifestValueIdent::Bytes => Value::Bytes(Box::new(self.parse_values_one()?)),
900                    ManifestValueIdent::NonFungibleGlobalId => {
901                        Value::NonFungibleGlobalId(Box::new(self.parse_values_one()?))
902                    }
903
904                    // ==============
905                    // Custom Types
906                    // ==============
907                    ManifestValueIdent::Address => Value::Address(self.parse_values_one()?.into()),
908                    ManifestValueIdent::Bucket => Value::Bucket(self.parse_values_one()?.into()),
909                    ManifestValueIdent::Proof => Value::Proof(self.parse_values_one()?.into()),
910                    ManifestValueIdent::Expression => {
911                        Value::Expression(self.parse_values_one()?.into())
912                    }
913                    ManifestValueIdent::Blob => Value::Blob(self.parse_values_one()?.into()),
914                    ManifestValueIdent::Decimal => Value::Decimal(self.parse_values_one()?.into()),
915                    ManifestValueIdent::PreciseDecimal => {
916                        Value::PreciseDecimal(self.parse_values_one()?.into())
917                    }
918                    ManifestValueIdent::NonFungibleLocalId => {
919                        Value::NonFungibleLocalId(self.parse_values_one()?.into())
920                    }
921                    ManifestValueIdent::AddressReservation => {
922                        Value::AddressReservation(self.parse_values_one()?.into())
923                    }
924                    ManifestValueIdent::NamedAddress => {
925                        Value::NamedAddress(self.parse_values_one()?.into())
926                    }
927                    ManifestValueIdent::Intent => Value::Intent(self.parse_values_one()?.into()),
928                    ManifestValueIdent::NamedIntent => {
929                        Value::NamedIntent(self.parse_values_one()?.into())
930                    }
931                }
932            }
933            _ => {
934                return Err(ParserError::unexpected_token(token, TokenType::Value));
935            }
936        };
937        self.track_stack_depth_decrease()?;
938        Ok(ValueWithSpan {
939            value,
940            span: token.span,
941        })
942    }
943
944    pub fn parse_enum_content(&mut self) -> Result<Value, ParserError> {
945        self.advance_exact(Token::LessThan)?;
946
947        let discriminator_token = self.advance()?;
948        let discriminator = match discriminator_token.token {
949            Token::U8Literal(discriminator) => discriminator,
950            Token::Ident(discriminator) => KNOWN_ENUM_DISCRIMINATORS
951                .get(discriminator.as_str())
952                .cloned()
953                .ok_or(ParserError {
954                    error_kind: ParserErrorKind::UnknownEnumDiscriminator {
955                        actual: discriminator.clone(),
956                    },
957                    span: discriminator_token.span,
958                })?,
959            _ => {
960                return Err(ParserError::unexpected_token(
961                    discriminator_token,
962                    TokenType::EnumDiscriminator,
963                ))
964            }
965        };
966        self.advance_exact(Token::GreaterThan)?;
967
968        let fields = self.parse_values_any(Token::OpenParenthesis, Token::CloseParenthesis)?;
969
970        Ok(Value::Enum(discriminator, fields))
971    }
972
973    pub fn parse_array_content(&mut self) -> Result<Value, ParserError> {
974        let generics = self.parse_generics(1)?;
975        Ok(Value::Array(
976            generics[0].clone(),
977            self.parse_values_any(Token::OpenParenthesis, Token::CloseParenthesis)?,
978        ))
979    }
980
981    pub fn parse_tuple_content(&mut self) -> Result<Value, ParserError> {
982        Ok(Value::Tuple(self.parse_values_any(
983            Token::OpenParenthesis,
984            Token::CloseParenthesis,
985        )?))
986    }
987
988    pub fn parse_map_content(&mut self) -> Result<Value, ParserError> {
989        let generics = self.parse_generics(2)?;
990        self.advance_exact(Token::OpenParenthesis)?;
991        let mut entries = Vec::new();
992
993        while self.peek()?.token != Token::CloseParenthesis {
994            let key = self.parse_value()?;
995            self.advance_exact(Token::FatArrow)?;
996            let value = self.parse_value()?;
997            entries.push((key, value));
998            if self.peek()?.token != Token::CloseParenthesis {
999                self.advance_exact(Token::Comma)?;
1000            }
1001        }
1002        self.advance_exact(Token::CloseParenthesis)?;
1003        Ok(Value::Map(
1004            generics[0].clone(),
1005            generics[1].clone(),
1006            entries,
1007        ))
1008    }
1009
1010    /// Parse a comma-separated value list, enclosed by a pair of marks.
1011    fn parse_values_any(
1012        &mut self,
1013        open: Token,
1014        close: Token,
1015    ) -> Result<Vec<ValueWithSpan>, ParserError> {
1016        self.parse_values_any_with_open_close_spans(open, close)
1017            .map(|(values, _, _)| values)
1018    }
1019
1020    /// Parse a comma-separated value list, enclosed by a pair of marks.
1021    /// Return values and opening and closing span
1022    fn parse_values_any_with_open_close_spans(
1023        &mut self,
1024        open: Token,
1025        close: Token,
1026    ) -> Result<(Vec<ValueWithSpan>, Span, Span), ParserError> {
1027        let open_token = self.advance_exact(open)?;
1028        let mut values = Vec::new();
1029        while self.peek()?.token != close {
1030            values.push(self.parse_value()?);
1031            if self.peek()?.token != close {
1032                self.advance_exact(Token::Comma)?;
1033            }
1034        }
1035        let close_token = self.advance_exact(close)?;
1036        Ok((values, open_token.span, close_token.span))
1037    }
1038
1039    fn parse_values_one(&mut self) -> Result<ValueWithSpan, ParserError> {
1040        let (values, open_span, close_span) = self.parse_values_any_with_open_close_spans(
1041            Token::OpenParenthesis,
1042            Token::CloseParenthesis,
1043        )?;
1044        match values.len() {
1045            1 => Ok(values[0].clone()),
1046            _ => Err(ParserError {
1047                error_kind: ParserErrorKind::InvalidNumberOfValues {
1048                    actual: values.len(),
1049                    expected: 1,
1050                },
1051                span: Span {
1052                    start: open_span.end,
1053                    end: close_span.start,
1054                },
1055            }),
1056        }
1057    }
1058
1059    fn parse_generics(&mut self, n: usize) -> Result<Vec<ValueKindWithSpan>, ParserError> {
1060        let mut span_start = self.advance_exact(Token::LessThan)?.span.start;
1061        let mut value_kinds = Vec::new();
1062
1063        while self.peek()?.token != Token::GreaterThan {
1064            let token_value_kind = self.parse_value_kind()?;
1065            value_kinds.push(token_value_kind);
1066            if self.peek()?.token != Token::GreaterThan {
1067                self.advance_exact(Token::Comma)?;
1068            }
1069        }
1070
1071        let mut span_end = self.advance_exact(Token::GreaterThan)?.span.end;
1072
1073        if value_kinds.len() != 0 {
1074            span_start = value_kinds[0].span.start;
1075            span_end = value_kinds[value_kinds.len() - 1].span.end;
1076        }
1077
1078        if value_kinds.len() != n {
1079            Err(ParserError {
1080                error_kind: ParserErrorKind::InvalidNumberOfTypes {
1081                    expected: n,
1082                    actual: value_kinds.len(),
1083                },
1084                span: Span {
1085                    start: span_start,
1086                    end: span_end,
1087                },
1088            })
1089        } else {
1090            Ok(value_kinds)
1091        }
1092    }
1093
1094    fn parse_value_kind(&mut self) -> Result<ValueKindWithSpan, ParserError> {
1095        let token = self.advance()?;
1096        let value_kind = match &token.token {
1097            Token::Ident(ident_str) => ValueKind::from_ident(&ident_str).ok_or(
1098                ParserError::unexpected_token(token.clone(), TokenType::ValueKind),
1099            )?,
1100            _ => {
1101                return Err(ParserError::unexpected_token(token, TokenType::ValueKind));
1102            }
1103        };
1104        Ok(ValueKindWithSpan {
1105            value_kind,
1106            span: token.span,
1107        })
1108    }
1109}
1110
1111pub fn parser_error_diagnostics(
1112    s: &str,
1113    err: ParserError,
1114    style: CompileErrorDiagnosticsStyle,
1115) -> String {
1116    let (title, label) = match err.error_kind {
1117        ParserErrorKind::UnexpectedEof => (
1118            "unexpected end of file".to_string(),
1119            "unexpected end of file".to_string(),
1120        ),
1121        ParserErrorKind::UnexpectedToken { expected, actual } => {
1122            let title = format!("expected {}, found {}", expected, actual);
1123            let label = format!("expected {}", expected);
1124            (title, label)
1125        }
1126        ParserErrorKind::InvalidArgument { expected, actual } => {
1127            let title = format!(
1128                "expected {} or ';' to end an argument list, found {}",
1129                expected, actual
1130            );
1131            let label = format!("expected {} or ';' to end an argument list", expected);
1132            (title, label)
1133        }
1134        ParserErrorKind::InvalidNumberOfValues { expected, actual } => {
1135            let title = format!("expected {} number of values, found {}", expected, actual);
1136            let label = format!("expected {} number of values", expected);
1137            (title, label)
1138        }
1139        ParserErrorKind::InvalidNumberOfTypes { expected, actual } => {
1140            let title = format!("expected {} number of types, found {}", expected, actual);
1141            let label = format!("expected {} number of types", expected);
1142            (title, label)
1143        }
1144        ParserErrorKind::MaxDepthExceeded { actual, max } => {
1145            let title = format!("manifest actual depth {} exceeded max {}", actual, max);
1146            (title, "max depth exceeded".to_string())
1147        }
1148        ParserErrorKind::UnknownEnumDiscriminator { actual } => {
1149            let title = format!("unknown enum discriminator found '{}'", actual);
1150            (title, "unknown enum discriminator".to_string())
1151        }
1152    };
1153
1154    create_snippet(s, &err.span, &title, &label, style)
1155}
1156
1157#[cfg(test)]
1158mod tests {
1159    use super::*;
1160    use crate::manifest::lexer::tokenize;
1161    use crate::{position, span};
1162
1163    #[macro_export]
1164    macro_rules! parse_instruction_ok {
1165        ( $s:expr, $expected:expr ) => {{
1166            let mut parser = Parser::new(tokenize($s).unwrap(), PARSER_MAX_DEPTH).unwrap();
1167            assert_eq!(parser.parse_instruction(), Ok($expected));
1168            assert!(parser.is_eof());
1169        }};
1170    }
1171
1172    #[macro_export]
1173    macro_rules! parse_value_ok {
1174        ( $s:expr, $expected:expr ) => {{
1175            let mut parser = Parser::new(tokenize($s).unwrap(), PARSER_MAX_DEPTH).unwrap();
1176            assert_eq!(parser.parse_value().map(|tv| tv.value), Ok($expected));
1177            assert!(parser.is_eof());
1178        }};
1179    }
1180
1181    #[macro_export]
1182    macro_rules! parse_value_error {
1183        ( $s:expr, $expected:expr ) => {{
1184            let mut parser = Parser::new(tokenize($s).unwrap(), PARSER_MAX_DEPTH).unwrap();
1185            match parser.parse_value() {
1186                Ok(_) => {
1187                    panic!("Expected {:?} but no error is thrown", $expected);
1188                }
1189                Err(e) => {
1190                    assert_eq!(e, $expected);
1191                }
1192            }
1193        }};
1194    }
1195
1196    #[test]
1197    fn test_literals() {
1198        parse_value_ok!(r#"true"#, Value::Bool(true));
1199        parse_value_ok!(r#"false"#, Value::Bool(false));
1200        parse_value_ok!(r#"1i8"#, Value::I8(1));
1201        parse_value_ok!(r#"1i16"#, Value::I16(1));
1202        parse_value_ok!(r#"1i32"#, Value::I32(1));
1203        parse_value_ok!(r#"1i64"#, Value::I64(1));
1204        parse_value_ok!(r#"1i128"#, Value::I128(1));
1205        parse_value_ok!(r#"1u8"#, Value::U8(1));
1206        parse_value_ok!(r#"1u16"#, Value::U16(1));
1207        parse_value_ok!(r#"1u32"#, Value::U32(1));
1208        parse_value_ok!(r#"1u64"#, Value::U64(1));
1209        parse_value_ok!(r#"1u128"#, Value::U128(1));
1210        parse_value_ok!(r#""test""#, Value::String("test".into()));
1211    }
1212
1213    #[test]
1214    fn test_enum() {
1215        parse_value_ok!(
1216            r#"Enum<0u8>("Hello", 123u8)"#,
1217            Value::Enum(
1218                0,
1219                vec![
1220                    ValueWithSpan {
1221                        value: Value::String("Hello".into()),
1222                        span: span!(start = (10, 0, 10), end = (17, 0, 17)),
1223                    },
1224                    ValueWithSpan {
1225                        value: Value::U8(123),
1226                        span: span!(start = (19, 0, 19), end = (24, 0, 24)),
1227                    },
1228                ],
1229            )
1230        );
1231        parse_value_ok!(r#"Enum<0u8>()"#, Value::Enum(0, Vec::new()));
1232        parse_value_ok!(
1233            r#"Enum<PublicKey::Secp256k1>()"#,
1234            Value::Enum(0, Vec::new())
1235        );
1236        // Check we allow trailing commas
1237        parse_value_ok!(
1238            r#"Enum<0u8>("Hello", 123u8,)"#,
1239            Value::Enum(
1240                0,
1241                vec![
1242                    ValueWithSpan {
1243                        value: Value::String("Hello".into()),
1244                        span: span!(start = (10, 0, 10), end = (17, 0, 17)),
1245                    },
1246                    ValueWithSpan {
1247                        value: Value::U8(123),
1248                        span: span!(start = (19, 0, 19), end = (24, 0, 24)),
1249                    },
1250                ],
1251            )
1252        );
1253    }
1254
1255    #[test]
1256    fn test_array() {
1257        parse_value_ok!(
1258            r#"Array<U8>(1u8, 2u8)"#,
1259            Value::Array(
1260                ValueKindWithSpan {
1261                    value_kind: ValueKind::U8,
1262                    span: span!(start = (6, 0, 6), end = (8, 0, 8)),
1263                },
1264                vec![
1265                    ValueWithSpan {
1266                        value: Value::U8(1),
1267                        span: span!(start = (10, 0, 10), end = (13, 0, 13)),
1268                    },
1269                    ValueWithSpan {
1270                        value: Value::U8(2),
1271                        span: span!(start = (15, 0, 15), end = (18, 0, 18)),
1272                    }
1273                ],
1274            )
1275        );
1276        parse_value_ok!(
1277            r#"Array<U8>()"#,
1278            Value::Array(
1279                ValueKindWithSpan {
1280                    value_kind: ValueKind::U8,
1281                    span: span!(start = (6, 0, 6), end = (8, 0, 8)),
1282                },
1283                vec![]
1284            )
1285        );
1286        // Check we allow trailing commas
1287        parse_value_ok!(
1288            r#"Array<U8>(1u8, 2u8,)"#,
1289            Value::Array(
1290                ValueKindWithSpan {
1291                    value_kind: ValueKind::U8,
1292                    span: span!(start = (6, 0, 6), end = (8, 0, 8)),
1293                },
1294                vec![
1295                    ValueWithSpan {
1296                        value: Value::U8(1),
1297                        span: span!(start = (10, 0, 10), end = (13, 0, 13)),
1298                    },
1299                    ValueWithSpan {
1300                        value: Value::U8(2),
1301                        span: span!(start = (15, 0, 15), end = (18, 0, 18)),
1302                    }
1303                ],
1304            )
1305        );
1306    }
1307
1308    #[test]
1309    fn test_tuple() {
1310        parse_value_ok!(r#"Tuple()"#, Value::Tuple(vec![]));
1311        parse_value_ok!(
1312            r#"Tuple("Hello", 123u8)"#,
1313            Value::Tuple(vec![
1314                ValueWithSpan {
1315                    value: Value::String("Hello".into()),
1316                    span: span!(start = (6, 0, 6), end = (13, 0, 13)),
1317                },
1318                ValueWithSpan {
1319                    value: Value::U8(123),
1320                    span: span!(start = (15, 0, 15), end = (20, 0, 20)),
1321                },
1322            ])
1323        );
1324        parse_value_ok!(
1325            r#"Tuple(1u8, 2u8)"#,
1326            Value::Tuple(vec![
1327                ValueWithSpan {
1328                    value: Value::U8(1),
1329                    span: span!(start = (6, 0, 6), end = (9, 0, 9)),
1330                },
1331                ValueWithSpan {
1332                    value: Value::U8(2),
1333                    span: span!(start = (11, 0, 11), end = (14, 0, 14)),
1334                },
1335            ])
1336        );
1337
1338        // Check we allow trailing commas
1339        parse_value_ok!(
1340            r#"Tuple(1u8, 2u8,)"#,
1341            Value::Tuple(vec![
1342                ValueWithSpan {
1343                    value: Value::U8(1),
1344                    span: span!(start = (6, 0, 6), end = (9, 0, 9)),
1345                },
1346                ValueWithSpan {
1347                    value: Value::U8(2),
1348                    span: span!(start = (11, 0, 11), end = (14, 0, 14)),
1349                },
1350            ])
1351        );
1352    }
1353
1354    #[test]
1355    fn test_map() {
1356        parse_value_ok!(
1357            r#"Map<String, U8>("Hello" => 123u8)"#,
1358            Value::Map(
1359                ValueKindWithSpan {
1360                    value_kind: ValueKind::String,
1361                    span: span!(start = (4, 0, 4), end = (10, 0, 10)),
1362                },
1363                ValueKindWithSpan {
1364                    value_kind: ValueKind::U8,
1365                    span: span!(start = (12, 0, 12), end = (14, 0, 14)),
1366                },
1367                vec![(
1368                    ValueWithSpan {
1369                        value: Value::String("Hello".into()),
1370                        span: span!(start = (16, 0, 16), end = (23, 0, 23)),
1371                    },
1372                    ValueWithSpan {
1373                        value: Value::U8(123),
1374                        span: span!(start = (27, 0, 27), end = (32, 0, 32)),
1375                    }
1376                )]
1377            )
1378        );
1379        parse_value_ok!(
1380            r#"Map<String, U8>("Hello" => 123u8, "world!" => 1u8)"#,
1381            Value::Map(
1382                ValueKindWithSpan {
1383                    value_kind: ValueKind::String,
1384                    span: span!(start = (4, 0, 4), end = (10, 0, 10)),
1385                },
1386                ValueKindWithSpan {
1387                    value_kind: ValueKind::U8,
1388                    span: span!(start = (12, 0, 12), end = (14, 0, 14)),
1389                },
1390                vec![
1391                    (
1392                        ValueWithSpan {
1393                            value: Value::String("Hello".into()),
1394                            span: span!(start = (16, 0, 16), end = (23, 0, 23)),
1395                        },
1396                        ValueWithSpan {
1397                            value: Value::U8(123),
1398                            span: span!(start = (27, 0, 27), end = (32, 0, 32)),
1399                        }
1400                    ),
1401                    (
1402                        ValueWithSpan {
1403                            value: Value::String("world!".into()),
1404                            span: span!(start = (34, 0, 34), end = (42, 0, 42)),
1405                        },
1406                        ValueWithSpan {
1407                            value: Value::U8(1),
1408                            span: span!(start = (46, 0, 46), end = (49, 0, 49)),
1409                        }
1410                    )
1411                ]
1412            )
1413        );
1414
1415        // Check we allow trailing commas
1416        parse_value_ok!(
1417            r#"Map<String, U8>("Hello" => 123u8, "world!" => 1u8,)"#,
1418            Value::Map(
1419                ValueKindWithSpan {
1420                    value_kind: ValueKind::String,
1421                    span: span!(start = (4, 0, 4), end = (10, 0, 10)),
1422                },
1423                ValueKindWithSpan {
1424                    value_kind: ValueKind::U8,
1425                    span: span!(start = (12, 0, 12), end = (14, 0, 14)),
1426                },
1427                vec![
1428                    (
1429                        ValueWithSpan {
1430                            value: Value::String("Hello".into()),
1431                            span: span!(start = (16, 0, 16), end = (23, 0, 23)),
1432                        },
1433                        ValueWithSpan {
1434                            value: Value::U8(123),
1435                            span: span!(start = (27, 0, 27), end = (32, 0, 32)),
1436                        }
1437                    ),
1438                    (
1439                        ValueWithSpan {
1440                            value: Value::String("world!".into()),
1441                            span: span!(start = (34, 0, 34), end = (42, 0, 42)),
1442                        },
1443                        ValueWithSpan {
1444                            value: Value::U8(1),
1445                            span: span!(start = (46, 0, 46), end = (49, 0, 49)),
1446                        }
1447                    )
1448                ]
1449            )
1450        );
1451    }
1452
1453    #[test]
1454    fn test_failures() {
1455        parse_value_error!(
1456            r#"Enum<0u8"#,
1457            ParserError {
1458                error_kind: ParserErrorKind::UnexpectedEof,
1459                span: span!(start = (8, 0, 8), end = (8, 0, 8))
1460            }
1461        );
1462        parse_value_error!(
1463            r#"Enum<0u8)"#,
1464            ParserError {
1465                error_kind: ParserErrorKind::UnexpectedToken {
1466                    expected: TokenType::Exact(Token::GreaterThan),
1467                    actual: Token::CloseParenthesis,
1468                },
1469                span: span!(start = (8, 0, 8), end = (9, 0, 9))
1470            }
1471        );
1472        parse_value_error!(
1473            r#"Address("abc", "def")"#,
1474            ParserError {
1475                error_kind: ParserErrorKind::InvalidNumberOfValues {
1476                    actual: 2,
1477                    expected: 1,
1478                },
1479                span: span!(start = (8, 0, 8), end = (20, 0, 20)),
1480            }
1481        );
1482        parse_value_error!(
1483            r#"Address()"#,
1484            ParserError {
1485                error_kind: ParserErrorKind::InvalidNumberOfValues {
1486                    actual: 0,
1487                    expected: 1,
1488                },
1489                span: span!(start = (8, 0, 8), end = (8, 0, 8)),
1490            }
1491        );
1492        parse_value_error!(
1493            r#"Address(   )"#,
1494            ParserError {
1495                error_kind: ParserErrorKind::InvalidNumberOfValues {
1496                    actual: 0,
1497                    expected: 1,
1498                },
1499                span: span!(start = (8, 0, 8), end = (11, 0, 11)),
1500            }
1501        );
1502    }
1503
1504    #[test]
1505    fn test_deep_value_does_not_panic_with_stack_overflow() {
1506        let depth: usize = 1000;
1507        let mut value_string = "".to_string();
1508        for _ in 0..depth {
1509            value_string.push_str("Tuple(");
1510        }
1511        value_string.push_str("0u8");
1512        for _ in 0..depth {
1513            value_string.push_str(")");
1514        }
1515
1516        // Should actually be an error not a panic
1517        parse_value_error!(
1518            &value_string,
1519            ParserError {
1520                error_kind: ParserErrorKind::MaxDepthExceeded {
1521                    actual: 21,
1522                    max: 20,
1523                },
1524                span: span!(start = (120, 0, 120), end = (125, 0, 125))
1525            }
1526        );
1527    }
1528
1529    // Instruction parsing tests have been removed as they're largely outdated (inconsistent with the data model),
1530    // which may lead developers to invalid syntax.
1531    //
1532    // It's also not very useful as instruction parsing basically calls `parse_value` recursively
1533    //
1534    // That said, all manifest instructions should be tested in `generator.rs` and `e2e.rs`.
1535}