1use std::fmt::Write;
2
3use anyhow::Result;
4pub use wit_parser;
5use wit_parser::*;
6pub mod abi;
7mod ns;
8pub use ns::Ns;
9pub mod source;
10pub use source::{Files, Source};
11mod types;
12pub use types::{TypeInfo, Types};
13mod path;
14pub use path::name_package_module;
15mod async_;
16pub use async_::AsyncFilterSet;
17mod chainable_method;
18pub use chainable_method::{ChainableMethodFilterSet, ChainingMode};
19
20#[derive(Default, Copy, Clone, PartialEq, Eq, Debug)]
21pub enum Direction {
22 #[default]
23 Import,
24 Export,
25}
26
27pub trait WorldGenerator {
28 fn generate(&mut self, resolve: &mut Resolve, id: WorldId, files: &mut Files) -> Result<()> {
29 if self.uses_nominal_type_ids() {
30 resolve.generate_nominal_type_ids(id);
31 }
32 let world = &resolve.worlds[id];
33 self.preprocess(resolve, id)?;
34
35 fn unwrap_name(key: &WorldKey) -> &str {
36 match key {
37 WorldKey::Name(name) => name,
38 WorldKey::Interface(_) => panic!("unexpected interface key"),
39 }
40 }
41
42 let mut funcs = Vec::new();
43 let mut types = Vec::new();
44 for (name, import) in world.imports.iter() {
45 match import {
46 WorldItem::Function(f) => funcs.push((unwrap_name(name), f)),
47 WorldItem::Interface { id, .. } => {
48 self.import_interface(resolve, name, *id, files)?
49 }
50 WorldItem::Type { id, .. } => types.push((unwrap_name(name), *id)),
51 }
52 }
53 if !types.is_empty() {
54 self.import_types(resolve, id, &types, files)?;
55 }
56 if !funcs.is_empty() {
57 self.import_funcs(resolve, id, &funcs, files)?;
58 }
59 funcs.clear();
60
61 self.finish_imports(resolve, id, files)?;
62
63 let mut interfaces = Vec::new();
70 for (name, export) in world.exports.iter() {
71 match export {
72 WorldItem::Function(f) => funcs.push((unwrap_name(name), f)),
73 WorldItem::Interface { id, .. } => interfaces.push((name, id)),
74 WorldItem::Type { .. } => unreachable!(),
75 }
76 }
77 if !funcs.is_empty() {
78 self.export_funcs(resolve, id, &funcs, files)?;
79 }
80
81 self.pre_export_interface(resolve, files)?;
82
83 for (name, id) in interfaces {
84 self.export_interface(resolve, name, *id, files)?;
85 }
86 self.finish(resolve, id, files)
87 }
88
89 fn uses_nominal_type_ids(&self) -> bool {
93 true
94 }
95
96 fn finish_imports(
97 &mut self,
98 resolve: &Resolve,
99 world: WorldId,
100 files: &mut Files,
101 ) -> Result<()> {
102 let _ = (resolve, world, files);
103 Ok(())
104 }
105
106 fn preprocess(&mut self, resolve: &Resolve, world: WorldId) -> Result<()> {
107 let _ = (resolve, world);
108 Ok(())
109 }
110
111 fn import_interface(
112 &mut self,
113 resolve: &Resolve,
114 name: &WorldKey,
115 iface: InterfaceId,
116 files: &mut Files,
117 ) -> Result<()>;
118
119 fn pre_export_interface(&mut self, resolve: &Resolve, files: &mut Files) -> Result<()> {
121 let _ = (resolve, files);
122 Ok(())
123 }
124
125 fn export_interface(
126 &mut self,
127 resolve: &Resolve,
128 name: &WorldKey,
129 iface: InterfaceId,
130 files: &mut Files,
131 ) -> Result<()>;
132 fn import_funcs(
133 &mut self,
134 resolve: &Resolve,
135 world: WorldId,
136 funcs: &[(&str, &Function)],
137 files: &mut Files,
138 ) -> Result<()>;
139 fn export_funcs(
140 &mut self,
141 resolve: &Resolve,
142 world: WorldId,
143 funcs: &[(&str, &Function)],
144 files: &mut Files,
145 ) -> Result<()>;
146 fn import_types(
147 &mut self,
148 resolve: &Resolve,
149 world: WorldId,
150 types: &[(&str, TypeId)],
151 files: &mut Files,
152 ) -> Result<()>;
153 fn finish(&mut self, resolve: &Resolve, world: WorldId, files: &mut Files) -> Result<()>;
154}
155
156pub trait InterfaceGenerator<'a> {
165 fn resolve(&self) -> &'a Resolve;
166
167 fn type_record(&mut self, id: TypeId, name: &str, record: &Record, docs: &Docs);
168 fn type_resource(&mut self, id: TypeId, name: &str, docs: &Docs);
169 fn type_flags(&mut self, id: TypeId, name: &str, flags: &Flags, docs: &Docs);
170 fn type_tuple(&mut self, id: TypeId, name: &str, tuple: &Tuple, docs: &Docs);
171 fn type_variant(&mut self, id: TypeId, name: &str, variant: &Variant, docs: &Docs);
172 fn type_option(&mut self, id: TypeId, name: &str, payload: &Type, docs: &Docs);
173 fn type_result(&mut self, id: TypeId, name: &str, result: &Result_, docs: &Docs);
174 fn type_enum(&mut self, id: TypeId, name: &str, enum_: &Enum, docs: &Docs);
175 fn type_alias(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs);
176 fn type_list(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs);
177 fn type_fixed_length_list(&mut self, id: TypeId, name: &str, ty: &Type, size: u32, docs: &Docs);
178 fn type_map(&mut self, id: TypeId, name: &str, key: &Type, value: &Type, docs: &Docs);
179 fn type_builtin(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs);
180 fn type_future(&mut self, id: TypeId, name: &str, ty: &Option<Type>, docs: &Docs);
181 fn type_stream(&mut self, id: TypeId, name: &str, ty: &Option<Type>, docs: &Docs);
182 fn types(&mut self, iface: InterfaceId) {
183 let iface = &self.resolve().interfaces[iface];
184 for (name, id) in iface.types.iter() {
185 self.define_type(name, *id);
186 }
187 }
188
189 fn define_type(&mut self, name: &str, id: TypeId) {
190 define_type(self, name, id)
191 }
192}
193
194pub fn define_type<'a, T>(generator: &mut T, name: &str, id: TypeId)
195where
196 T: InterfaceGenerator<'a> + ?Sized,
197{
198 let ty = &generator.resolve().types[id];
199 match &ty.kind {
200 TypeDefKind::Record(record) => generator.type_record(id, name, record, &ty.docs),
201 TypeDefKind::Resource => generator.type_resource(id, name, &ty.docs),
202 TypeDefKind::Flags(flags) => generator.type_flags(id, name, flags, &ty.docs),
203 TypeDefKind::Tuple(tuple) => generator.type_tuple(id, name, tuple, &ty.docs),
204 TypeDefKind::Enum(enum_) => generator.type_enum(id, name, enum_, &ty.docs),
205 TypeDefKind::Variant(variant) => generator.type_variant(id, name, variant, &ty.docs),
206 TypeDefKind::Option(t) => generator.type_option(id, name, t, &ty.docs),
207 TypeDefKind::Result(r) => generator.type_result(id, name, r, &ty.docs),
208 TypeDefKind::List(t) => generator.type_list(id, name, t, &ty.docs),
209 TypeDefKind::Type(t) => generator.type_alias(id, name, t, &ty.docs),
210 TypeDefKind::Future(t) => generator.type_future(id, name, t, &ty.docs),
211 TypeDefKind::Stream(t) => generator.type_stream(id, name, t, &ty.docs),
212 TypeDefKind::Handle(_) => panic!("handle types do not require definition"),
213 TypeDefKind::FixedLengthList(t, size) => {
214 generator.type_fixed_length_list(id, name, t, *size, &ty.docs)
215 }
216 TypeDefKind::Map(key, value) => generator.type_map(id, name, key, value, &ty.docs),
217 TypeDefKind::Unknown => unreachable!(),
218 }
219}
220
221pub trait AnonymousTypeGenerator<'a> {
222 fn resolve(&self) -> &'a Resolve;
223
224 fn anonymous_type_handle(&mut self, id: TypeId, handle: &Handle, docs: &Docs);
225 fn anonymous_type_tuple(&mut self, id: TypeId, ty: &Tuple, docs: &Docs);
226 fn anonymous_type_option(&mut self, id: TypeId, ty: &Type, docs: &Docs);
227 fn anonymous_type_result(&mut self, id: TypeId, ty: &Result_, docs: &Docs);
228 fn anonymous_type_list(&mut self, id: TypeId, ty: &Type, docs: &Docs);
229 fn anonymous_type_fixed_length_list(&mut self, id: TypeId, ty: &Type, size: u32, docs: &Docs);
230 fn anonymous_type_map(&mut self, id: TypeId, key: &Type, value: &Type, docs: &Docs);
231 fn anonymous_type_future(&mut self, id: TypeId, ty: &Option<Type>, docs: &Docs);
232 fn anonymous_type_stream(&mut self, id: TypeId, ty: &Option<Type>, docs: &Docs);
233 fn anonymous_type_type(&mut self, id: TypeId, ty: &Type, docs: &Docs);
234
235 fn define_anonymous_type(&mut self, id: TypeId) {
236 let ty = &self.resolve().types[id];
237 match &ty.kind {
238 TypeDefKind::Flags(_)
239 | TypeDefKind::Record(_)
240 | TypeDefKind::Resource
241 | TypeDefKind::Enum(_)
242 | TypeDefKind::Variant(_) => {
243 unreachable!()
244 }
245 TypeDefKind::Type(t) => self.anonymous_type_type(id, t, &ty.docs),
246 TypeDefKind::Tuple(tuple) => self.anonymous_type_tuple(id, tuple, &ty.docs),
247 TypeDefKind::Option(t) => self.anonymous_type_option(id, t, &ty.docs),
248 TypeDefKind::Result(r) => self.anonymous_type_result(id, r, &ty.docs),
249 TypeDefKind::List(t) => self.anonymous_type_list(id, t, &ty.docs),
250 TypeDefKind::Future(f) => self.anonymous_type_future(id, f, &ty.docs),
251 TypeDefKind::Stream(s) => self.anonymous_type_stream(id, s, &ty.docs),
252 TypeDefKind::Handle(handle) => self.anonymous_type_handle(id, handle, &ty.docs),
253 TypeDefKind::FixedLengthList(t, size) => {
254 self.anonymous_type_fixed_length_list(id, t, *size, &ty.docs)
255 }
256 TypeDefKind::Map(key, value) => self.anonymous_type_map(id, key, value, &ty.docs),
257 TypeDefKind::Unknown => unreachable!(),
258 }
259 }
260}
261
262pub fn generated_preamble(src: &mut Source, version: &str) {
263 uwriteln!(src, "// Generated by `wit-bindgen` {version}. DO NOT EDIT!")
264}
265
266pub fn dealias(resolve: &Resolve, mut id: TypeId) -> TypeId {
267 loop {
268 match &resolve.types[id].kind {
269 TypeDefKind::Type(Type::Id(that_id)) => id = *that_id,
270 _ => break id,
271 }
272 }
273}