radix_transactions/manifest/
ast.rs

1use crate::manifest::token::Span;
2use radix_common::data::manifest::{ManifestCustomValueKind, ManifestValueKind};
3use strum::{EnumCount, EnumDiscriminants, FromRepr};
4
5use super::generator::*;
6
7#[derive(Debug, Clone, PartialEq, Eq, EnumDiscriminants, EnumCount)]
8#[strum_discriminants(derive(FromRepr))]
9pub enum Instruction {
10    //========================================
11    // PSEUDO-INSTRUCTIONS AT THE START
12    //========================================
13    UsePreallocatedAddress {
14        package_address: ValueWithSpan,
15        blueprint_name: ValueWithSpan,
16        address_reservation: ValueWithSpan,
17        preallocated_address: ValueWithSpan,
18    },
19
20    UseChild {
21        named_intent: ValueWithSpan,
22        subintent_hash: ValueWithSpan,
23    },
24
25    //========================================
26    // NORMAL INSTRUCTIONS
27    //========================================
28
29    // Bucket Lifecycle
30    TakeFromWorktop {
31        resource_address: ValueWithSpan,
32        amount: ValueWithSpan,
33        new_bucket: ValueWithSpan,
34    },
35    TakeNonFungiblesFromWorktop {
36        ids: ValueWithSpan,
37        resource_address: ValueWithSpan,
38        new_bucket: ValueWithSpan,
39    },
40    TakeAllFromWorktop {
41        resource_address: ValueWithSpan,
42        new_bucket: ValueWithSpan,
43    },
44    ReturnToWorktop {
45        bucket: ValueWithSpan,
46    },
47    BurnResource {
48        bucket: ValueWithSpan,
49    },
50
51    // Resource Assertions
52    AssertWorktopContains {
53        resource_address: ValueWithSpan,
54        amount: ValueWithSpan,
55    },
56    AssertWorktopContainsNonFungibles {
57        resource_address: ValueWithSpan,
58        ids: ValueWithSpan,
59    },
60    AssertWorktopContainsAny {
61        resource_address: ValueWithSpan,
62    },
63    AssertWorktopIsEmpty, // Alias
64    AssertWorktopResourcesOnly {
65        constraints: ValueWithSpan,
66    },
67    AssertWorktopResourcesInclude {
68        constraints: ValueWithSpan,
69    },
70    AssertNextCallReturnsOnly {
71        constraints: ValueWithSpan,
72    },
73    AssertNextCallReturnsInclude {
74        constraints: ValueWithSpan,
75    },
76    AssertBucketContents {
77        bucket: ValueWithSpan,
78        constraint: ValueWithSpan,
79    },
80
81    // Proof Lifecycle
82    CreateProofFromBucketOfAmount {
83        bucket: ValueWithSpan,
84        amount: ValueWithSpan,
85        new_proof: ValueWithSpan,
86    },
87    CreateProofFromBucketOfNonFungibles {
88        bucket: ValueWithSpan,
89        ids: ValueWithSpan,
90        new_proof: ValueWithSpan,
91    },
92    CreateProofFromBucketOfAll {
93        bucket: ValueWithSpan,
94        new_proof: ValueWithSpan,
95    },
96    CreateProofFromAuthZoneOfAmount {
97        resource_address: ValueWithSpan,
98        amount: ValueWithSpan,
99        new_proof: ValueWithSpan,
100    },
101    CreateProofFromAuthZoneOfNonFungibles {
102        resource_address: ValueWithSpan,
103        ids: ValueWithSpan,
104        new_proof: ValueWithSpan,
105    },
106    CreateProofFromAuthZoneOfAll {
107        resource_address: ValueWithSpan,
108        new_proof: ValueWithSpan,
109    },
110    CloneProof {
111        proof: ValueWithSpan,
112        new_proof: ValueWithSpan,
113    },
114    DropProof {
115        proof: ValueWithSpan,
116    },
117    PushToAuthZone {
118        proof: ValueWithSpan,
119    },
120    PopFromAuthZone {
121        new_proof: ValueWithSpan,
122    },
123    DropAuthZoneSignatureProofs,
124    DropAuthZoneRegularProofs,
125    DropAuthZoneProofs,
126    DropNamedProofs,
127    DropAllProofs,
128
129    // Invocations
130    CallFunction {
131        package_address: ValueWithSpan,
132        blueprint_name: ValueWithSpan,
133        function_name: ValueWithSpan,
134        args: Vec<ValueWithSpan>,
135    },
136    CallMethod {
137        address: ValueWithSpan,
138        method_name: ValueWithSpan,
139        args: Vec<ValueWithSpan>,
140    },
141    CallRoyaltyMethod {
142        address: ValueWithSpan,
143        method_name: ValueWithSpan,
144        args: Vec<ValueWithSpan>,
145    },
146    CallMetadataMethod {
147        address: ValueWithSpan,
148        method_name: ValueWithSpan,
149        args: Vec<ValueWithSpan>,
150    },
151    CallRoleAssignmentMethod {
152        address: ValueWithSpan,
153        method_name: ValueWithSpan,
154        args: Vec<ValueWithSpan>,
155    },
156    CallDirectVaultMethod {
157        address: ValueWithSpan,
158        method_name: ValueWithSpan,
159        args: Vec<ValueWithSpan>,
160    },
161
162    // Address Allocation
163    AllocateGlobalAddress {
164        package_address: ValueWithSpan,
165        blueprint_name: ValueWithSpan,
166        address_reservation: ValueWithSpan,
167        named_address: ValueWithSpan,
168    },
169
170    // Interaction with other intents
171    YieldToParent {
172        args: Vec<ValueWithSpan>,
173    },
174    YieldToChild {
175        child: ValueWithSpan,
176        args: Vec<ValueWithSpan>,
177    },
178    VerifyParent {
179        access_rule: ValueWithSpan,
180    },
181
182    //===============
183    // Direct vault aliases
184    //===============
185    RecallFromVault {
186        vault_id: ValueWithSpan,
187        args: Vec<ValueWithSpan>,
188    },
189    FreezeVault {
190        vault_id: ValueWithSpan,
191        args: Vec<ValueWithSpan>,
192    },
193    UnfreezeVault {
194        vault_id: ValueWithSpan,
195        args: Vec<ValueWithSpan>,
196    },
197    RecallNonFungiblesFromVault {
198        vault_id: ValueWithSpan,
199        args: Vec<ValueWithSpan>,
200    },
201
202    //===============
203    // Call function aliases
204    //===============
205    PublishPackage {
206        args: Vec<ValueWithSpan>,
207    },
208    PublishPackageAdvanced {
209        args: Vec<ValueWithSpan>,
210    },
211    CreateFungibleResource {
212        args: Vec<ValueWithSpan>,
213    },
214    CreateFungibleResourceWithInitialSupply {
215        args: Vec<ValueWithSpan>,
216    },
217    CreateNonFungibleResource {
218        args: Vec<ValueWithSpan>,
219    },
220    CreateNonFungibleResourceWithInitialSupply {
221        args: Vec<ValueWithSpan>,
222    },
223    CreateAccessController {
224        args: Vec<ValueWithSpan>,
225    },
226    CreateIdentity {
227        args: Vec<ValueWithSpan>,
228    },
229    CreateIdentityAdvanced {
230        args: Vec<ValueWithSpan>,
231    },
232    CreateAccount {
233        args: Vec<ValueWithSpan>,
234    },
235    CreateAccountAdvanced {
236        args: Vec<ValueWithSpan>,
237    },
238
239    //===============
240    // Non-main method aliases
241    //===============
242    SetMetadata {
243        address: ValueWithSpan,
244        args: Vec<ValueWithSpan>,
245    },
246    RemoveMetadata {
247        address: ValueWithSpan,
248        args: Vec<ValueWithSpan>,
249    },
250    LockMetadata {
251        address: ValueWithSpan,
252        args: Vec<ValueWithSpan>,
253    },
254    SetComponentRoyalty {
255        address: ValueWithSpan,
256        args: Vec<ValueWithSpan>,
257    },
258    SetOwnerRole {
259        address: ValueWithSpan,
260        args: Vec<ValueWithSpan>,
261    },
262    LockOwnerRole {
263        address: ValueWithSpan,
264        args: Vec<ValueWithSpan>,
265    },
266    SetRole {
267        address: ValueWithSpan,
268        args: Vec<ValueWithSpan>,
269    },
270    LockComponentRoyalty {
271        address: ValueWithSpan,
272        args: Vec<ValueWithSpan>,
273    },
274    ClaimComponentRoyalties {
275        address: ValueWithSpan,
276        args: Vec<ValueWithSpan>,
277    },
278
279    //===============
280    // Main method aliases
281    //===============
282    ClaimPackageRoyalties {
283        address: ValueWithSpan,
284        args: Vec<ValueWithSpan>,
285    },
286    MintFungible {
287        address: ValueWithSpan,
288        args: Vec<ValueWithSpan>,
289    },
290    MintNonFungible {
291        address: ValueWithSpan,
292        args: Vec<ValueWithSpan>,
293    },
294    MintRuidNonFungible {
295        address: ValueWithSpan,
296        args: Vec<ValueWithSpan>,
297    },
298    CreateValidator {
299        args: Vec<ValueWithSpan>,
300    },
301}
302
303/// This represents a slightly wider range of possibilities
304/// than an SBOR ManifestValueKind, including aliases and
305/// string-manifest-syntax-specific value kinds.
306#[derive(Debug, Clone, Copy, PartialEq, Eq)]
307pub enum ValueKind {
308    // ==============
309    // Simple basic value kinds
310    // ==============
311    Bool,
312    I8,
313    I16,
314    I32,
315    I64,
316    I128,
317    U8,
318    U16,
319    U32,
320    U64,
321    U128,
322    String,
323
324    // ==============
325    // Composite basic value kinds
326    // ==============
327    Enum,
328    Array,
329    Tuple,
330    Map,
331
332    // ==============
333    // Value kind aliases
334    // ==============
335    Bytes,
336    NonFungibleGlobalId,
337
338    // ==============
339    // Custom value kinds
340    // ==============
341    Address,
342    Bucket,
343    Proof,
344    Expression,
345    Blob,
346    Decimal,
347    PreciseDecimal,
348    NonFungibleLocalId,
349    AddressReservation,
350    NamedAddress,
351
352    // ==============
353    // Pretend value kinds
354    // ==============
355    Intent,
356    NamedIntent,
357}
358
359impl ValueKind {
360    pub fn from_ident(ident: &str) -> Option<Self> {
361        let value_kind = match ident {
362            // ==============
363            // Basic simple types
364            // ==============
365            "Bool" => Self::Bool,
366            "I8" => Self::I8,
367            "I16" => Self::I16,
368            "I32" => Self::I32,
369            "I64" => Self::I64,
370            "I128" => Self::I128,
371            "U8" => Self::U8,
372            "U16" => Self::U16,
373            "U32" => Self::U32,
374            "U64" => Self::U64,
375            "U128" => Self::U128,
376            "String" => Self::String,
377
378            // ==============
379            // Basic composite types
380            // ==============
381            "Enum" => Self::Enum,
382            "Array" => Self::Array,
383            "Tuple" => Self::Tuple,
384            "Map" => Self::Map,
385
386            // ==============
387            // Value kind aliases
388            // ==============
389            "Bytes" => Self::Bytes,
390            "NonFungibleGlobalId" => Self::NonFungibleGlobalId,
391
392            // ==============
393            // Custom types
394            // ==============
395            "Address" => Self::Address,
396            "Bucket" => Self::Bucket,
397            "Proof" => Self::Proof,
398            "Expression" => Self::Expression,
399            "Blob" => Self::Blob,
400            "Decimal" => Self::Decimal,
401            "PreciseDecimal" => Self::PreciseDecimal,
402            "NonFungibleLocalId" => Self::NonFungibleLocalId,
403            "AddressReservation" => Self::AddressReservation,
404            "NamedAddress" => Self::NamedAddress,
405            "Intent" => Self::Intent,
406            "NamedIntent" => Self::NamedIntent,
407
408            _ => {
409                return None;
410            }
411        };
412        Some(value_kind)
413    }
414}
415
416impl core::fmt::Display for ValueKind {
417    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
418        write!(f, "{:?}", self)
419    }
420}
421
422#[derive(Debug, Clone, PartialEq, Eq)]
423pub enum Value {
424    // ==============
425    // Basic values
426    // ==============
427    Bool(bool),
428    I8(i8),
429    I16(i16),
430    I32(i32),
431    I64(i64),
432    I128(i128),
433    U8(u8),
434    U16(u16),
435    U32(u32),
436    U64(u64),
437    U128(u128),
438    String(String),
439
440    // ==============
441    // Composite basic values
442    // ==============
443    Enum(u8, Vec<ValueWithSpan>),
444    Array(ValueKindWithSpan, Vec<ValueWithSpan>),
445    Tuple(Vec<ValueWithSpan>),
446    Map(
447        ValueKindWithSpan,
448        ValueKindWithSpan,
449        Vec<(ValueWithSpan, ValueWithSpan)>,
450    ),
451
452    // ==============
453    // Alias values
454    // ==============
455    Some(Box<ValueWithSpan>),
456    None,
457    Ok(Box<ValueWithSpan>),
458    Err(Box<ValueWithSpan>),
459    Bytes(Box<ValueWithSpan>),
460    NonFungibleGlobalId(Box<ValueWithSpan>),
461
462    // ==============
463    // Custom values
464    // ==============
465    Address(Box<ValueWithSpan>),
466    NamedAddress(Box<ValueWithSpan>),
467    Bucket(Box<ValueWithSpan>),
468    Proof(Box<ValueWithSpan>),
469    Expression(Box<ValueWithSpan>),
470    Blob(Box<ValueWithSpan>),
471    Decimal(Box<ValueWithSpan>),
472    PreciseDecimal(Box<ValueWithSpan>),
473    NonFungibleLocalId(Box<ValueWithSpan>),
474    AddressReservation(Box<ValueWithSpan>),
475    Intent(Box<ValueWithSpan>),
476    NamedIntent(Box<ValueWithSpan>),
477}
478
479impl Value {
480    pub const fn value_kind(&self) -> ValueKind {
481        match self {
482            // ==============
483            // Basic values
484            // ==============
485            Value::Bool(_) => ValueKind::Bool,
486            Value::I8(_) => ValueKind::I8,
487            Value::I16(_) => ValueKind::I16,
488            Value::I32(_) => ValueKind::I32,
489            Value::I64(_) => ValueKind::I64,
490            Value::I128(_) => ValueKind::I128,
491            Value::U8(_) => ValueKind::U8,
492            Value::U16(_) => ValueKind::U16,
493            Value::U32(_) => ValueKind::U32,
494            Value::U64(_) => ValueKind::U64,
495            Value::U128(_) => ValueKind::U128,
496            Value::String(_) => ValueKind::String,
497            Value::Enum(_, _) => ValueKind::Enum,
498            Value::Array(_, _) => ValueKind::Array,
499            Value::Tuple(_) => ValueKind::Tuple,
500            Value::Map(_, _, _) => ValueKind::Map,
501
502            // ==============
503            // Alias values
504            // ==============
505            Value::Some(_) => ValueKind::Enum,
506            Value::None => ValueKind::Enum,
507            Value::Ok(_) => ValueKind::Enum,
508            Value::Err(_) => ValueKind::Enum,
509            Value::Bytes(_) => ValueKind::Bytes,
510            Value::NonFungibleGlobalId(_) => ValueKind::NonFungibleGlobalId,
511
512            // ==============
513            // Custom values
514            // ==============
515            Value::Address(_) => ValueKind::Address,
516            Value::NamedAddress(_) => ValueKind::NamedAddress,
517            Value::Bucket(_) => ValueKind::Bucket,
518            Value::Proof(_) => ValueKind::Proof,
519            Value::Expression(_) => ValueKind::Expression,
520            Value::Blob(_) => ValueKind::Blob,
521            Value::Decimal(_) => ValueKind::Decimal,
522            Value::PreciseDecimal(_) => ValueKind::PreciseDecimal,
523            Value::NonFungibleLocalId(_) => ValueKind::NonFungibleLocalId,
524            Value::AddressReservation(_) => ValueKind::AddressReservation,
525            Value::Intent(_) => ValueKind::Intent,
526            Value::NamedIntent(_) => ValueKind::NamedIntent,
527        }
528    }
529}
530
531#[derive(Debug, Clone, PartialEq, Eq)]
532pub struct ValueKindWithSpan {
533    pub value_kind: ValueKind,
534    pub span: Span,
535}
536
537impl ValueKindWithSpan {
538    pub fn sbor_value_kind(&self) -> Result<ManifestValueKind, GeneratorError> {
539        let value_kind = match self.value_kind {
540            // ==============
541            // Simple basic value kinds
542            // ==============
543            ValueKind::Bool => ManifestValueKind::Bool,
544            ValueKind::I8 => ManifestValueKind::I8,
545            ValueKind::I16 => ManifestValueKind::I16,
546            ValueKind::I32 => ManifestValueKind::I32,
547            ValueKind::I64 => ManifestValueKind::I64,
548            ValueKind::I128 => ManifestValueKind::I128,
549            ValueKind::U8 => ManifestValueKind::U8,
550            ValueKind::U16 => ManifestValueKind::U16,
551            ValueKind::U32 => ManifestValueKind::U32,
552            ValueKind::U64 => ManifestValueKind::U64,
553            ValueKind::U128 => ManifestValueKind::U128,
554            ValueKind::String => ManifestValueKind::String,
555
556            // ==============
557            // Composite basic value kinds
558            // ==============
559            ValueKind::Enum => ManifestValueKind::Enum,
560            ValueKind::Array => ManifestValueKind::Array,
561            ValueKind::Tuple => ManifestValueKind::Tuple,
562            ValueKind::Map => ManifestValueKind::Map,
563
564            // ==============
565            // Value kind aliases
566            // ==============
567            ValueKind::Bytes => ManifestValueKind::Array,
568            ValueKind::NonFungibleGlobalId => ManifestValueKind::Tuple,
569
570            // ==============
571            // Custom value kinds
572            // ==============
573            ValueKind::Address => ManifestValueKind::Custom(ManifestCustomValueKind::Address),
574            ValueKind::NamedAddress => ManifestValueKind::Custom(ManifestCustomValueKind::Address),
575            ValueKind::Bucket => ManifestValueKind::Custom(ManifestCustomValueKind::Bucket),
576            ValueKind::Proof => ManifestValueKind::Custom(ManifestCustomValueKind::Proof),
577            ValueKind::Expression => ManifestValueKind::Custom(ManifestCustomValueKind::Expression),
578            ValueKind::Blob => ManifestValueKind::Custom(ManifestCustomValueKind::Blob),
579            ValueKind::Decimal => ManifestValueKind::Custom(ManifestCustomValueKind::Decimal),
580            ValueKind::PreciseDecimal => {
581                ManifestValueKind::Custom(ManifestCustomValueKind::PreciseDecimal)
582            }
583            ValueKind::NonFungibleLocalId => {
584                ManifestValueKind::Custom(ManifestCustomValueKind::NonFungibleLocalId)
585            }
586            ValueKind::AddressReservation => {
587                ManifestValueKind::Custom(ManifestCustomValueKind::AddressReservation)
588            }
589            ValueKind::NamedIntent => {
590                return Err(GeneratorError {
591                    span: self.span,
592                    error_kind: GeneratorErrorKind::NamedIntentCannotBeUsedAsValueKind,
593                })
594            }
595            ValueKind::Intent => {
596                return Err(GeneratorError {
597                    span: self.span,
598                    error_kind: GeneratorErrorKind::IntentCannotBeUsedAsValueKind,
599                })
600            }
601        };
602        Ok(value_kind)
603    }
604}
605
606/// In case of composite Value variants, eg. Enum, Tuple
607/// span information of the delimiters such as (, ) or <, >
608/// commas, discriminators is not stored.
609/// This is acceptable, since we still are able to produce error messages,
610/// which are precise enough.
611#[derive(Debug, Clone, PartialEq, Eq)]
612pub struct ValueWithSpan {
613    pub value: Value,
614    pub span: Span,
615}
616
617impl ValueWithSpan {
618    pub fn value_kind(&self) -> ValueKindWithSpan {
619        ValueKindWithSpan {
620            value_kind: self.value.value_kind(),
621            span: self.span,
622        }
623    }
624}
625
626#[derive(Debug, Clone, PartialEq, Eq)]
627pub struct InstructionWithSpan {
628    pub instruction: Instruction,
629    pub span: Span,
630}