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