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;
17
18#[derive(Default, Copy, Clone, PartialEq, Eq, Debug)]
19pub enum Direction {
20 #[default]
21 Import,
22 Export,
23}
24
25pub trait WorldGenerator {
26 fn generate(&mut self, resolve: &Resolve, id: WorldId, files: &mut Files) -> Result<()> {
27 let world = &resolve.worlds[id];
28 self.preprocess(resolve, id);
29
30 fn unwrap_name(key: &WorldKey) -> &str {
31 match key {
32 WorldKey::Name(name) => name,
33 WorldKey::Interface(_) => panic!("unexpected interface key"),
34 }
35 }
36
37 let mut funcs = Vec::new();
38 let mut types = Vec::new();
39 for (name, import) in world.imports.iter() {
40 match import {
41 WorldItem::Function(f) => funcs.push((unwrap_name(name), f)),
42 WorldItem::Interface { id, .. } => {
43 self.import_interface(resolve, name, *id, files)?
44 }
45 WorldItem::Type(id) => types.push((unwrap_name(name), *id)),
46 }
47 }
48 if !types.is_empty() {
49 self.import_types(resolve, id, &types, files);
50 }
51 if !funcs.is_empty() {
52 self.import_funcs(resolve, id, &funcs, files);
53 }
54 funcs.clear();
55
56 self.finish_imports(resolve, id, files);
57
58 let mut interfaces = Vec::new();
65 for (name, export) in world.exports.iter() {
66 match export {
67 WorldItem::Function(f) => funcs.push((unwrap_name(name), f)),
68 WorldItem::Interface { id, .. } => interfaces.push((name, id)),
69 WorldItem::Type(_) => unreachable!(),
70 }
71 }
72 if !funcs.is_empty() {
73 self.export_funcs(resolve, id, &funcs, files)?;
74 }
75
76 self.pre_export_interface(resolve, files)?;
77
78 for (name, id) in interfaces {
79 self.export_interface(resolve, name, *id, files)?;
80 }
81 self.finish(resolve, id, files)
82 }
83
84 fn finish_imports(&mut self, resolve: &Resolve, world: WorldId, files: &mut Files) {
85 let _ = (resolve, world, files);
86 }
87
88 fn preprocess(&mut self, resolve: &Resolve, world: WorldId) {
89 let _ = (resolve, world);
90 }
91
92 fn import_interface(
93 &mut self,
94 resolve: &Resolve,
95 name: &WorldKey,
96 iface: InterfaceId,
97 files: &mut Files,
98 ) -> Result<()>;
99
100 fn pre_export_interface(&mut self, resolve: &Resolve, files: &mut Files) -> Result<()> {
102 let _ = (resolve, files);
103 Ok(())
104 }
105
106 fn export_interface(
107 &mut self,
108 resolve: &Resolve,
109 name: &WorldKey,
110 iface: InterfaceId,
111 files: &mut Files,
112 ) -> Result<()>;
113 fn import_funcs(
114 &mut self,
115 resolve: &Resolve,
116 world: WorldId,
117 funcs: &[(&str, &Function)],
118 files: &mut Files,
119 );
120 fn export_funcs(
121 &mut self,
122 resolve: &Resolve,
123 world: WorldId,
124 funcs: &[(&str, &Function)],
125 files: &mut Files,
126 ) -> Result<()>;
127 fn import_types(
128 &mut self,
129 resolve: &Resolve,
130 world: WorldId,
131 types: &[(&str, TypeId)],
132 files: &mut Files,
133 );
134 fn finish(&mut self, resolve: &Resolve, world: WorldId, files: &mut Files) -> Result<()>;
135}
136
137pub trait InterfaceGenerator<'a> {
146 fn resolve(&self) -> &'a Resolve;
147
148 fn type_record(&mut self, id: TypeId, name: &str, record: &Record, docs: &Docs);
149 fn type_resource(&mut self, id: TypeId, name: &str, docs: &Docs);
150 fn type_flags(&mut self, id: TypeId, name: &str, flags: &Flags, docs: &Docs);
151 fn type_tuple(&mut self, id: TypeId, name: &str, flags: &Tuple, docs: &Docs);
152 fn type_variant(&mut self, id: TypeId, name: &str, variant: &Variant, docs: &Docs);
153 fn type_option(&mut self, id: TypeId, name: &str, payload: &Type, docs: &Docs);
154 fn type_result(&mut self, id: TypeId, name: &str, result: &Result_, docs: &Docs);
155 fn type_enum(&mut self, id: TypeId, name: &str, enum_: &Enum, docs: &Docs);
156 fn type_alias(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs);
157 fn type_list(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs);
158 fn type_builtin(&mut self, id: TypeId, name: &str, ty: &Type, docs: &Docs);
159 fn type_future(&mut self, id: TypeId, name: &str, ty: &Option<Type>, docs: &Docs);
160 fn type_stream(&mut self, id: TypeId, name: &str, ty: &Option<Type>, docs: &Docs);
161 fn types(&mut self, iface: InterfaceId) {
162 let iface = &self.resolve().interfaces[iface];
163 for (name, id) in iface.types.iter() {
164 self.define_type(name, *id);
165 }
166 }
167
168 fn define_type(&mut self, name: &str, id: TypeId) {
169 let ty = &self.resolve().types[id];
170 match &ty.kind {
171 TypeDefKind::Record(record) => self.type_record(id, name, record, &ty.docs),
172 TypeDefKind::Resource => self.type_resource(id, name, &ty.docs),
173 TypeDefKind::Flags(flags) => self.type_flags(id, name, flags, &ty.docs),
174 TypeDefKind::Tuple(tuple) => self.type_tuple(id, name, tuple, &ty.docs),
175 TypeDefKind::Enum(enum_) => self.type_enum(id, name, enum_, &ty.docs),
176 TypeDefKind::Variant(variant) => self.type_variant(id, name, variant, &ty.docs),
177 TypeDefKind::Option(t) => self.type_option(id, name, t, &ty.docs),
178 TypeDefKind::Result(r) => self.type_result(id, name, r, &ty.docs),
179 TypeDefKind::List(t) => self.type_list(id, name, t, &ty.docs),
180 TypeDefKind::Type(t) => self.type_alias(id, name, t, &ty.docs),
181 TypeDefKind::Future(t) => self.type_future(id, name, t, &ty.docs),
182 TypeDefKind::Stream(t) => self.type_stream(id, name, t, &ty.docs),
183 TypeDefKind::Handle(_) => panic!("handle types do not require definition"),
184 TypeDefKind::FixedSizeList(..) => todo!(),
185 TypeDefKind::Unknown => unreachable!(),
186 }
187 }
188}
189
190pub trait AnonymousTypeGenerator<'a> {
191 fn resolve(&self) -> &'a Resolve;
192
193 fn anonymous_type_handle(&mut self, id: TypeId, handle: &Handle, docs: &Docs);
194 fn anonymous_type_tuple(&mut self, id: TypeId, ty: &Tuple, docs: &Docs);
195 fn anonymous_type_option(&mut self, id: TypeId, ty: &Type, docs: &Docs);
196 fn anonymous_type_result(&mut self, id: TypeId, ty: &Result_, docs: &Docs);
197 fn anonymous_type_list(&mut self, id: TypeId, ty: &Type, docs: &Docs);
198 fn anonymous_type_future(&mut self, id: TypeId, ty: &Option<Type>, docs: &Docs);
199 fn anonymous_type_stream(&mut self, id: TypeId, ty: &Option<Type>, docs: &Docs);
200 fn anonymous_type_type(&mut self, id: TypeId, ty: &Type, docs: &Docs);
201
202 fn define_anonymous_type(&mut self, id: TypeId) {
203 let ty = &self.resolve().types[id];
204 match &ty.kind {
205 TypeDefKind::Flags(_)
206 | TypeDefKind::Record(_)
207 | TypeDefKind::Resource
208 | TypeDefKind::Enum(_)
209 | TypeDefKind::Variant(_) => {
210 unreachable!()
211 }
212 TypeDefKind::Type(t) => self.anonymous_type_type(id, t, &ty.docs),
213 TypeDefKind::Tuple(tuple) => self.anonymous_type_tuple(id, tuple, &ty.docs),
214 TypeDefKind::Option(t) => self.anonymous_type_option(id, t, &ty.docs),
215 TypeDefKind::Result(r) => self.anonymous_type_result(id, r, &ty.docs),
216 TypeDefKind::List(t) => self.anonymous_type_list(id, t, &ty.docs),
217 TypeDefKind::Future(f) => self.anonymous_type_future(id, f, &ty.docs),
218 TypeDefKind::Stream(s) => self.anonymous_type_stream(id, s, &ty.docs),
219 TypeDefKind::Handle(handle) => self.anonymous_type_handle(id, handle, &ty.docs),
220 TypeDefKind::FixedSizeList(..) => todo!(),
221 TypeDefKind::Unknown => unreachable!(),
222 }
223 }
224}
225
226pub fn generated_preamble(src: &mut Source, version: &str) {
227 uwriteln!(src, "// Generated by `wit-bindgen` {version}. DO NOT EDIT!")
228}
229
230pub fn dealias(resolve: &Resolve, mut id: TypeId) -> TypeId {
231 loop {
232 match &resolve.types[id].kind {
233 TypeDefKind::Type(Type::Id(that_id)) => id = *that_id,
234 _ => break id,
235 }
236 }
237}