lib/choir/src/composition/module/serialization/fragment.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 const std = @import("std");
2 const choir = @import("../../../root.zig");
3 const composition = @import("../../root.zig");
4 const model = @import("../root.zig");
5 const serialization = @import("root.zig");
6
7 const artifact = choir.backends.artifact;
8 const product = choir.product;
9 const source = composition.source;
10 const Reader = serialization.format.Reader;
11 const Writer = serialization.format.Writer;
12
13 pub fn write(
14 writer: *Writer,
15 value: model.Fragment,
16 manifests: *serialization.reference.Manifests,
17 ) serialization.SerializeError!void {
18 try writer.writeInt(u64, value.id.value);
19 try writer.writeInt(u64, value.partition.value);
20 try writer.writeTag(value.pipeline);
21 try writeProduct(writer, value.pipeline_input, manifests);
22 try writer.writeCount(value.artifacts.len);
23 for (value.artifacts) |artifact_value| try writeArtifact(writer, artifact_value);
24 try writer.writeCount(value.exports.len);
25 for (value.exports) |export_value| try writeExport(writer, export_value);
26 try writer.writeCount(value.imports.len);
27 for (value.imports) |import_value| try writeImport(writer, import_value);
28 try serialization.provenance.write(writer, value.provenance);
29 }
30
31 pub fn read(
32 allocator: std.mem.Allocator,
33 reader: *Reader,
34 module: *model.CompositionModule,
35 records: *product.revision.Store,
36 manifests: *const serialization.reference.Manifests,
37 ) serialization.DeserializeError!void {
38 const id = source.FragmentId{ .value = try reader.readInt(u64) };
39 const partition = source.PartitionId{ .value = try reader.readInt(u64) };
40 const pipeline = try reader.readTag(source.Pipeline);
41 const pipeline_input = try serialization.reference.readRecord(records, reader, manifests);
42
43 const artifact_count = try reader.readCount();
44 const artifacts = try allocator.alloc(artifact.Artifact, artifact_count);
45 var artifacts_initialized: usize = 0;
46 defer {
47 var index = artifacts_initialized;
48 while (index != 0) {
49 index -= 1;
50 artifacts[index].deinit();
51 }
52 allocator.free(artifacts);
53 }
54 for (artifacts) |*artifact_value| {
55 artifact_value.* = try readArtifact(allocator, reader);
56 artifacts_initialized += 1;
57 }
58
59 const export_count = try reader.readCount();
60 const exports = try allocator.alloc(model.ExportSpec, export_count);
61 defer allocator.free(exports);
62 for (exports) |*export_value| export_value.* = try readExport(reader);
63
64 const import_count = try reader.readCount();
65 const imports = try allocator.alloc(model.ImportSpec, import_count);
66 defer allocator.free(imports);
67 for (imports) |*import_value| import_value.* = try readImport(reader);
68 const provenance = try serialization.provenance.read(reader);
69
70 try module.addFragment(.{
71 .id = id,
72 .partition = partition,
73 .pipeline = pipeline,
74 .pipeline_input = pipeline_input,
75 .artifacts = artifacts,
76 .exports = exports,
77 .imports = imports,
78 .provenance = provenance,
79 });
80 }
81
82 fn writeProduct(
83 writer: *Writer,
84 key: product.ProductKey,
85 manifests: *serialization.reference.Manifests,
86 ) serialization.SerializeError!void {
87 try writer.writeBlob(key.record.bytes());
88 try writer.writeInt(u32, @intCast(try manifests.intern(key.record.compilerManifest())));
89 }
90
91 fn writeArtifact(writer: *Writer, value: artifact.Artifact) serialization.SerializeError!void {
92 const bytes = try artifact.serialization.serialize(writer.allocator, &value);
93 defer writer.allocator.free(bytes);
94 try writer.writeBlob(bytes);
95 }
96
97 fn readArtifact(allocator: std.mem.Allocator, reader: *Reader) serialization.DeserializeError!artifact.Artifact {
98 return try artifact.serialization.deserialize(allocator, try reader.readBlob());
99 }
100
101 fn writeExport(writer: *Writer, value: model.Export) serialization.SerializeError!void {
102 try writer.writeString(value.name);
103 try writer.writeString(value.symbol);
104 try writer.writeInt(u32, value.abi_version);
105 }
106
107 fn readExport(reader: *Reader) serialization.DeserializeError!model.ExportSpec {
108 const name = try reader.readString();
109 const symbol = try reader.readString();
110 const abi_version = try reader.readInt(u32);
111 return .{
112 .name = name,
113 .symbol = symbol,
114 .abi_version = abi_version,
115 };
116 }
117
118 fn writeImport(writer: *Writer, value: model.Import) serialization.SerializeError!void {
119 try writer.writeString(value.name);
120 try writer.writeString(value.symbol);
121 try writer.writeInt(u32, value.abi_version);
122 try writer.writeTag(value.kind);
123 }
124
125 fn readImport(reader: *Reader) serialization.DeserializeError!model.ImportSpec {
126 const name = try reader.readString();
127 const symbol = try reader.readString();
128 const abi_version = try reader.readInt(u32);
129 const kind = try reader.readTag(model.ImportKind);
130 return .{
131 .name = name,
132 .symbol = symbol,
133 .abi_version = abi_version,
134 .kind = kind,
135 };
136 }