Skip to content

Commit

Permalink
common function for encoding packages
Browse files Browse the repository at this point in the history
  • Loading branch information
macovedj committed Jul 11, 2024
1 parent 5d98d8c commit a13b387
Showing 1 changed file with 73 additions and 61 deletions.
134 changes: 73 additions & 61 deletions crates/wit-component/src/encoding/wit/v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,73 +53,15 @@ impl Encoder<'_> {
// roundtripping.
let mut names = NameMap::new();
for pkg in self.packages {
let package = &self.resolve.packages[*pkg];
if self.packages.len() > 1 {
let mut sub_encoder = Encoder {
let sub_encoder = Encoder {
component: ComponentBuilder::default(),
resolve: self.resolve,
packages: self.packages,
};
let package_metadata = PackageMetadata::extract(self.resolve, *pkg);
sub_encoder.component.custom_section(&CustomSection {
name: PackageMetadata::SECTION_NAME.into(),
data: package_metadata.encode()?.into(),
});
for (name, &id) in self.resolve.packages[*pkg].interfaces.iter() {
let component_ty = sub_encoder.encode_interface(id, pkg)?;
let ty = sub_encoder.component.type_component(&component_ty);
sub_encoder.component.export(
name.as_ref(),
ComponentExportKind::Type,
ty,
None,
);
}
for (name, &world) in self.resolve.packages[*pkg].worlds.iter() {
// Encode the `world` directly as a component, then create a wrapper
// component that exports that component.
let component_ty = super::encode_world(self.resolve, world)?;

let world = &sub_encoder.resolve.worlds[world];
let mut wrapper = ComponentType::new();
wrapper.ty().component(&component_ty);
let pkg = &sub_encoder.resolve.packages[world.package.unwrap()];
wrapper.export(&pkg.name.interface_id(name), ComponentTypeRef::Component(0));
let ty = sub_encoder.component.type_component(&wrapper);
sub_encoder.component.export(
name.as_ref(),
ComponentExportKind::Type,
ty,
None,
);
}
let sub = self.component.component(sub_encoder.component);
names.append(sub, &package.name.to_string());
self.encode_package(&mut names, pkg, Some(sub_encoder))?;
} else {
for (name, &id) in self.resolve.packages[*pkg].interfaces.iter() {
let component_ty = self.encode_interface(id, pkg)?;
let ty = self.component.type_component(&component_ty);
self.component
.export(name.as_ref(), ComponentExportKind::Type, ty, None);
}
for (name, &world) in self.resolve.packages[*pkg].worlds.iter() {
// Encode the `world` directly as a component, then create a wrapper
// component that exports that component.
let component_ty = super::encode_world(self.resolve, world)?;
let world = &self.resolve.worlds[world];
let mut wrapper = ComponentType::new();
wrapper.ty().component(&component_ty);
let pkg = &self.resolve.packages[world.package.unwrap()];
wrapper.export(&pkg.name.interface_id(name), ComponentTypeRef::Component(0));
let ty = self.component.type_component(&wrapper);
self.component
.export(name.as_ref(), ComponentExportKind::Type, ty, None);
}
let package_metadata = PackageMetadata::extract(self.resolve, *pkg);
self.component.custom_section(&CustomSection {
name: PackageMetadata::SECTION_NAME.into(),
data: package_metadata.encode()?.into(),
});
self.encode_package(&mut names, pkg, None)?;
}
}
let mut final_names = ComponentNameSection::new();
Expand All @@ -129,6 +71,76 @@ impl Encoder<'_> {
Ok(())
}

fn encode_package(
&mut self,
names: &mut NameMap,
pkg: &PackageId,
mut sub_encoder: Option<Encoder>,
) -> Result<()> {
let package = &self.resolve.packages[*pkg];
if let Some(ref mut sub) = sub_encoder {
let package_metadata = PackageMetadata::extract(self.resolve, *pkg);
sub.component.custom_section(&CustomSection {
name: PackageMetadata::SECTION_NAME.into(),
data: package_metadata.encode()?.into(),
});
}

for (name, &id) in self.resolve.packages[*pkg].interfaces.iter() {
if let Some(ref mut sub) = sub_encoder {
let component_ty = sub.encode_interface(id, pkg)?;
let ty = sub.component.type_component(&component_ty);
sub.component
.export(name.as_ref(), ComponentExportKind::Type, ty, None);
} else {
let component_ty = self.encode_interface(id, pkg)?;
let ty = self.component.type_component(&component_ty);
self.component
.export(name.as_ref(), ComponentExportKind::Type, ty, None);
}
}
for (name, &world) in self.resolve.packages[*pkg].worlds.iter() {
if let Some(ref mut sub) = sub_encoder {
// Encode the `world` directly as a component, then create a wrapper
// component that exports that component.
let component_ty = super::encode_world(self.resolve, world)?;

let world = &sub.resolve.worlds[world];
let mut wrapper = ComponentType::new();
wrapper.ty().component(&component_ty);
let pkg = &sub.resolve.packages[world.package.unwrap()];
wrapper.export(&pkg.name.interface_id(name), ComponentTypeRef::Component(0));
let ty = sub.component.type_component(&wrapper);
sub.component
.export(name.as_ref(), ComponentExportKind::Type, ty, None);
} else {
// Encode the `world` directly as a component, then create a wrapper
// component that exports that component.
let component_ty = super::encode_world(self.resolve, world)?;
let world = &self.resolve.worlds[world];
let mut wrapper = ComponentType::new();
wrapper.ty().component(&component_ty);
let pkg = &self.resolve.packages[world.package.unwrap()];
wrapper.export(&pkg.name.interface_id(name), ComponentTypeRef::Component(0));
let ty = self.component.type_component(&wrapper);
self.component
.export(name.as_ref(), ComponentExportKind::Type, ty, None);
}
}
if sub_encoder.is_none() {
let package_metadata = PackageMetadata::extract(self.resolve, *pkg);
self.component.custom_section(&CustomSection {
name: PackageMetadata::SECTION_NAME.into(),
data: package_metadata.encode()?.into(),
});
}
if let Some(sub_encoder) = sub_encoder {
let sub = self.component.component(sub_encoder.component);
names.append(sub, &package.name.to_string());
}
Ok(())
}

fn encode_interface(&mut self, id: InterfaceId, pkg: &PackageId) -> Result<ComponentType> {
// Build a set of interfaces reachable from this document, including the
// interfaces in the document itself. This is used to import instances
Expand Down

0 comments on commit a13b387

Please sign in to comment.