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