frame_support_procedural/construct_runtime/expand/
metadata.rs1use crate::construct_runtime::{parse::PalletPath, Pallet};
19use proc_macro2::TokenStream;
20use quote::quote;
21use std::str::FromStr;
22use syn::Ident;
23
24pub fn expand_runtime_metadata(
25 runtime: &Ident,
26 pallet_declarations: &[Pallet],
27 scrate: &TokenStream,
28 extrinsic: &TokenStream,
29 system_path: &PalletPath,
30) -> TokenStream {
31 let pallets = pallet_declarations
32 .iter()
33 .filter_map(|pallet_declaration| {
34 pallet_declaration.find_part("Pallet").map(|_| {
35 let filtered_names: Vec<_> = pallet_declaration
36 .pallet_parts()
37 .iter()
38 .filter(|part| part.name() != "Pallet")
39 .map(|part| part.name())
40 .collect();
41 (pallet_declaration, filtered_names)
42 })
43 })
44 .map(|(decl, filtered_names)| {
45 let name = &decl.name;
46 let index = &decl.index;
47 let storage = expand_pallet_metadata_storage(&filtered_names, runtime, decl);
48 let calls = expand_pallet_metadata_calls(&filtered_names, runtime, decl);
49 let event = expand_pallet_metadata_events(&filtered_names, runtime, decl);
50 let constants = expand_pallet_metadata_constants(runtime, decl);
51 let errors = expand_pallet_metadata_errors(runtime, decl);
52 let docs = expand_pallet_metadata_docs(runtime, decl);
53 let attr = decl.cfg_pattern.iter().fold(TokenStream::new(), |acc, pattern| {
54 let attr = TokenStream::from_str(&format!("#[cfg({})]", pattern.original()))
55 .expect("was successfully parsed before; qed");
56 quote! {
57 #acc
58 #attr
59 }
60 });
61 let deprecation_info = expand_pallet_metadata_deprecation(runtime, decl);
62 quote! {
63 #attr
64 #scrate::__private::metadata_ir::PalletMetadataIR {
65 name: stringify!(#name),
66 index: #index,
67 storage: #storage,
68 calls: #calls,
69 event: #event,
70 constants: #constants,
71 error: #errors,
72 docs: #docs,
73 deprecation_info: #deprecation_info,
74 }
75 }
76 })
77 .collect::<Vec<_>>();
78
79 quote! {
80 impl #runtime {
81 fn metadata_ir() -> #scrate::__private::metadata_ir::MetadataIR {
82 let rt = #runtime;
99
100 let ty = #scrate::__private::scale_info::meta_type::<#extrinsic>();
101 let address_ty = #scrate::__private::scale_info::meta_type::<
102 <<#extrinsic as #scrate::sp_runtime::traits::Extrinsic>::SignaturePayload as #scrate::sp_runtime::traits::SignaturePayload>::SignatureAddress
103 >();
104 let call_ty = #scrate::__private::scale_info::meta_type::<
105 <#extrinsic as #scrate::sp_runtime::traits::Extrinsic>::Call
106 >();
107 let signature_ty = #scrate::__private::scale_info::meta_type::<
108 <<#extrinsic as #scrate::sp_runtime::traits::Extrinsic>::SignaturePayload as #scrate::sp_runtime::traits::SignaturePayload>::Signature
109 >();
110 let extra_ty = #scrate::__private::scale_info::meta_type::<
111 <<#extrinsic as #scrate::sp_runtime::traits::Extrinsic>::SignaturePayload as #scrate::sp_runtime::traits::SignaturePayload>::SignatureExtra
112 >();
113
114 #scrate::__private::metadata_ir::MetadataIR {
115 pallets: #scrate::__private::vec![ #(#pallets),* ],
116 extrinsic: #scrate::__private::metadata_ir::ExtrinsicMetadataIR {
117 ty,
118 version: <#extrinsic as #scrate::sp_runtime::traits::ExtrinsicMetadata>::VERSION,
119 address_ty,
120 call_ty,
121 signature_ty,
122 extra_ty,
123 signed_extensions: <
124 <
125 #extrinsic as #scrate::sp_runtime::traits::ExtrinsicMetadata
126 >::SignedExtensions as #scrate::sp_runtime::traits::SignedExtension
127 >::metadata()
128 .into_iter()
129 .map(|meta| #scrate::__private::metadata_ir::SignedExtensionMetadataIR {
130 identifier: meta.identifier,
131 ty: meta.ty,
132 additional_signed: meta.additional_signed,
133 })
134 .collect(),
135 },
136 ty: #scrate::__private::scale_info::meta_type::<#runtime>(),
137 apis: (&rt).runtime_metadata(),
138 outer_enums: #scrate::__private::metadata_ir::OuterEnumsIR {
139 call_enum_ty: #scrate::__private::scale_info::meta_type::<
140 <#runtime as #system_path::Config>::RuntimeCall
141 >(),
142 event_enum_ty: #scrate::__private::scale_info::meta_type::<RuntimeEvent>(),
143 error_enum_ty: #scrate::__private::scale_info::meta_type::<RuntimeError>(),
144 }
145 }
146 }
147
148 pub fn metadata() -> #scrate::__private::metadata::RuntimeMetadataPrefixed {
149 #scrate::__private::metadata_ir::into_v14(#runtime::metadata_ir())
152 }
153
154 pub fn metadata_at_version(version: u32) -> Option<#scrate::__private::OpaqueMetadata> {
155 #scrate::__private::metadata_ir::into_version(#runtime::metadata_ir(), version).map(|prefixed| {
156 #scrate::__private::OpaqueMetadata::new(prefixed.into())
157 })
158 }
159
160 pub fn metadata_versions() -> #scrate::__private::Vec<u32> {
161 #scrate::__private::metadata_ir::supported_versions()
162 }
163 }
164 }
165}
166
167fn expand_pallet_metadata_storage(
168 filtered_names: &[&'static str],
169 runtime: &Ident,
170 decl: &Pallet,
171) -> TokenStream {
172 if filtered_names.contains(&"Storage") {
173 let instance = decl.instance.as_ref().into_iter();
174 let path = &decl.path;
175
176 quote! {
177 Some(#path::Pallet::<#runtime #(, #path::#instance)*>::storage_metadata())
178 }
179 } else {
180 quote!(None)
181 }
182}
183
184fn expand_pallet_metadata_calls(
185 filtered_names: &[&'static str],
186 runtime: &Ident,
187 decl: &Pallet,
188) -> TokenStream {
189 if filtered_names.contains(&"Call") {
190 let instance = decl.instance.as_ref().into_iter();
191 let path = &decl.path;
192
193 quote! {
194 Some(#path::Pallet::<#runtime #(, #path::#instance)*>::call_functions())
195 }
196 } else {
197 quote!(None)
198 }
199}
200
201fn expand_pallet_metadata_events(
202 filtered_names: &[&'static str],
203 runtime: &Ident,
204 decl: &Pallet,
205) -> TokenStream {
206 if filtered_names.contains(&"Event") {
207 let path = &decl.path;
208 let part_is_generic = !decl
209 .find_part("Event")
210 .expect("Event part exists; qed")
211 .generics
212 .params
213 .is_empty();
214 let pallet_event = match (decl.instance.as_ref(), part_is_generic) {
215 (Some(inst), true) => quote!(#path::Event::<#runtime, #path::#inst>),
216 (Some(inst), false) => quote!(#path::Event::<#path::#inst>),
217 (None, true) => quote!(#path::Event::<#runtime>),
218 (None, false) => quote!(#path::Event),
219 };
220
221 quote! {
222 Some(
223 #pallet_event::event_metadata::<#pallet_event>()
224 )
225 }
226 } else {
227 quote!(None)
228 }
229}
230
231fn expand_pallet_metadata_deprecation(runtime: &Ident, decl: &Pallet) -> TokenStream {
232 let path = &decl.path;
233 let instance = decl.instance.as_ref().into_iter();
234
235 quote! { #path::Pallet::<#runtime #(, #path::#instance)*>::deprecation_info() }
236}
237
238fn expand_pallet_metadata_constants(runtime: &Ident, decl: &Pallet) -> TokenStream {
239 let path = &decl.path;
240 let instance = decl.instance.as_ref().into_iter();
241
242 quote! {
243 #path::Pallet::<#runtime #(, #path::#instance)*>::pallet_constants_metadata()
244 }
245}
246
247fn expand_pallet_metadata_errors(runtime: &Ident, decl: &Pallet) -> TokenStream {
248 let path = &decl.path;
249 let instance = decl.instance.as_ref().into_iter();
250
251 quote! {
252 #path::Pallet::<#runtime #(, #path::#instance)*>::error_metadata()
253 }
254}
255
256fn expand_pallet_metadata_docs(runtime: &Ident, decl: &Pallet) -> TokenStream {
257 let path = &decl.path;
258 let instance = decl.instance.as_ref().into_iter();
259
260 quote! {
261 #path::Pallet::<#runtime #(, #path::#instance)*>::pallet_documentation_metadata()
262 }
263}