///|
fn verify_generic(value : @upstream.TestUseGenericsReader) -> Unit raise {
let basic = value.get_basic()
let foo = basic.get_foo()
assert_eq(foo.get_int16_field(), 12345)
assert_eq(foo.get_u_int64_field(), 18446744073709551615UL)
assert_eq(foo.get_text_field(), "Python/C++ generic input")
let payload : @upstream.TestAllTypesReader = {
inner: basic.get_rev().get_foo().get_any_pointer_field().as_struct(),
}
assert_eq(payload.get_int32_field(), -23456)
assert_eq(payload.get_text_field(), "opaque struct")
let items = basic.get_list()
assert_eq(items.length(), 2)
for i in 0.. Bytes raise {
let message = @capnp.Builder::new()
let root = @upstream.TestUseGenericsBuilder::init_root(message)
let basic = root.init_basic()
let foo = basic.init_foo()
foo.set_int16_field(23456)
foo.set_u_int64_field(18446744073709551615UL)
foo.set_text_field("MoonBit typed reply")
basic
.init_rev()
.init_foo()
.set_any_pointer_field(
source.get_basic().get_rev().get_foo().get_any_pointer_field(),
)
let items = basic.init_list(2)
for i in 0..<2 {
items.get(i).init_foo().set_int16_field(i + 100)
items.get(i).init_bar().init_any_pointer_field().set_text("item-\{i}")
}
let inner = root.init_inner2()
inner.set_baz("ancestor-binding")
inner
.init_bar()
.set_any_pointer_field(source.get_inner2().get_bar().get_any_pointer_field())
inner.init_inner_bound().init_foo().set_int16_field(6789)
inner.init_inner_unbound().init_foo().set_text("unbound ancestor")
root.init_unspecified().init_foo().set_text("unbound parameter")
let enums = root.init_bind_enum_list().init_foo(3)
enums.set(0, @upstream.TestEnum::from_raw(0U))
enums.set(1, @upstream.TestEnum::from_raw(7U))
enums.set(2, @upstream.TestEnum::from_raw(40000U))
message.finish()
}
///|
fn copy_any(directory : String, kind : String) -> Unit raise {
let bytes = @fs.read_file_to_bytes(directory + "/python-any-" + kind + ".bin")
let source = @upstream.TestAnyPointerReader::from_message(
@capnp.read_message(bytes),
)
let pointer = source.get_any_pointer_field()
match kind {
"struct" => {
let value : @upstream.TestAllTypesReader = { inner: pointer.as_struct(), }
assert_eq(value.get_int64_field(), -9223372036854775807L - 1)
assert_eq(value.get_text_field(), "unknown fields survive copying")
}
"list" => {
let values = pointer.as_list()
assert_eq(values.get_int32(0), -2147483648)
assert_eq(values.get_int32(2), 2147483647)
}
"text" => assert_eq(pointer.as_text(), "AnyPointer 中文")
"data" => assert_eq(pointer.as_data(), b"\x00\xff\x01\x80")
_ => assert_true(pointer.is_null())
}
let message = @capnp.Builder::new()
@upstream.TestAnyPointerBuilder::init_root(message).set_any_pointer_field(
pointer,
)
@fs.write_bytes_to_file(
directory + "/moon-any-" + kind + ".bin",
message.finish(),
)
}
///|
fn write_struct(path : String, value : @capnp.StructReader) -> Unit raise {
let message = @capnp.Builder::new()
message.root_pointer().set_struct(value)
@fs.write_bytes_to_file(path, message.finish())
}
///|
fn verify_compiler(directory : String) -> Unit raise {
let source = @capnp.read_message(
@fs.read_file_to_bytes("codegen/fixtures/upstream.request.bin"),
)
let request = @compiler.CodeGeneratorRequestReader::from_message(source)
assert_eq(request.get_capnp_version().get_major(), 1U)
assert_eq(request.get_capnp_version().get_minor().to_uint(), 5U)
assert_eq(
request.get_requested_files().get(0).get_filename(),
"capnp/test.capnp",
)
let nodes = request.get_nodes()
let mut generic_id = 0UL
let mut all_types_id = 0UL
let mut any_pointer_id = 0UL
for i in 0.. generic_id = node.get_id()
"capnp/test.capnp:TestAllTypes" => all_types_id = node.get_id()
"capnp/test.capnp:TestAnyPointer" => any_pointer_id = node.get_id()
_ => ()
}
}
assert_true(generic_id != 0UL && all_types_id != 0UL && any_pointer_id != 0UL)
let mut saw_generic = false
let mut saw_brand = false
let mut saw_constant = false
for i in 0.. Unit raise @capnp.CapnpError) -> Unit raise {
try action() catch {
@capnp.CapnpError::TypeMismatch(_) => ()
_ => fail("unexpected error for inactive union member")
} noraise {
_ => fail("unknown discriminant exposed a known union member")
}
}
///|
fn verify_evolution(directory : String) -> Unit raise {
let old_as_new = @upstream.TestNewVersionReader::from_message(
@capnp.read_message(
@fs.read_file_to_bytes(directory + "/python-old-version.bin"),
),
)
assert_eq(old_as_new.get_old1(), 123L)
assert_eq(old_as_new.get_old2(), "old root")
assert_eq(old_as_new.get_new1(), 987L)
assert_eq(old_as_new.get_new2(), "baz")
assert_eq(old_as_new.get_old3().get_old1(), -456L)
assert_eq(old_as_new.get_old3().get_old2(), "old child")
assert_eq(old_as_new.get_old3().get_new1(), 987L)
assert_eq(old_as_new.get_old3().get_new2(), "baz")
let old_reply = @capnp.Builder::new()
let old = @upstream.TestOldVersionBuilder::init_root(old_reply)
old.set_old1(777L)
old.set_old2("MoonBit old root")
let child = old.init_old3()
child.set_old1(-777L)
child.set_old2("MoonBit old child")
@fs.write_bytes_to_file(
directory + "/moon-old-version.bin",
old_reply.finish(),
)
let new_as_old = @upstream.TestOldVersionReader::from_message(
@capnp.read_message(
@fs.read_file_to_bytes(directory + "/python-new-version.bin"),
),
)
assert_eq(new_as_old.get_old1(), 123L)
assert_eq(new_as_old.get_old2(), "new root")
assert_eq(new_as_old.get_old3().get_old1(), -456L)
assert_eq(new_as_old.get_old3().get_old2(), "new child")
// Forward through an older typed view without enumerating its known fields.
write_struct(directory + "/moon-new-via-old.bin", new_as_old.inner)
for alternative in ["a", "b"] {
let upgraded = @upstream.TestNewUnionVersionReader::from_message(
@capnp.read_message(
@fs.read_file_to_bytes(
directory + "/python-old-union-" + alternative + ".bin",
),
),
)
if alternative == "a" {
assert_true(upgraded.is_a())
assert_true(upgraded.get_a().is_a0())
upgraded.get_a().get_a0()
} else {
assert_true(upgraded.is_b())
assert_eq(upgraded.get_b(), 9007199254740993UL)
}
}
let union_reply = @capnp.Builder::new()
@upstream.TestNewUnionVersionBuilder::init_root(union_reply)
.init_a()
.set_a1(18446744073709551615UL)
@fs.write_bytes_to_file(
directory + "/moon-new-union.bin",
union_reply.finish(),
)
let unknown = @upstream.TestOldUnionVersionReader::from_message(
@capnp.read_message(
@fs.read_file_to_bytes(directory + "/python-unknown-union.bin"),
),
)
assert_eq(unknown.which(), 4U)
assert_false(unknown.is_a())
assert_false(unknown.is_b())
expect_inactive(() => unknown.get_a())
expect_inactive(() => ignore(unknown.get_b()))
write_struct(directory + "/moon-unknown-union.bin", unknown.inner)
}
///|
fn verify_union_groups(directory : String) -> Unit raise {
let nested = @upstream.TestUnionInUnionReader::from_message(
@capnp.read_message(
@fs.read_file_to_bytes(directory + "/python-nested-union.bin"),
),
)
assert_true(nested.get_outer().is_inner())
assert_true(nested.get_outer().get_inner().is_bar())
assert_eq(nested.get_outer().get_inner().get_bar(), -234)
let nested_reply = @capnp.Builder::new()
let outer = @upstream.TestUnionInUnionBuilder::init_root(nested_reply).get_outer()
outer.init_inner().set_bar(-234)
outer.set_baz(123456)
@fs.write_bytes_to_file(
directory + "/moon-nested-baz.bin",
nested_reply.finish(),
)
ignore(outer.init_inner())
@fs.write_bytes_to_file(
directory + "/moon-nested-reset.bin",
nested_reply.finish(),
)
let input = @upstream.TestInterleavedGroupsReader::from_message(
@capnp.read_message(
@fs.read_file_to_bytes(directory + "/python-interleaved.bin"),
),
)
let first = input.get_group1()
let second = input.get_group2()
assert_eq(first.get_foo(), 100U)
assert_eq(first.get_bar(), 1000UL)
assert_eq(first.get_waldo(), "group-1")
assert_eq(first.get_corge().get_grault(), 10000UL)
assert_eq(first.get_corge().get_garply(), 10U)
assert_eq(first.get_corge().get_plugh(), "plugh-1")
assert_eq(first.get_corge().get_xyzzy(), "xyzzy-1")
assert_eq(second.get_foo(), 200U)
assert_eq(second.get_bar(), 2000UL)
assert_eq(second.get_waldo(), "group-2")
assert_eq(second.get_corge().get_grault(), 20000UL)
assert_eq(second.get_corge().get_garply(), 20U)
assert_eq(second.get_corge().get_plugh(), "plugh-2")
assert_eq(second.get_corge().get_xyzzy(), "xyzzy-2")
let reply = @capnp.Builder::new()
let root = @upstream.TestInterleavedGroupsBuilder::init_root(reply)
let group1 = root.get_group1()
group1.set_foo(first.get_foo())
group1.set_bar(first.get_bar())
group1.set_waldo(first.get_waldo())
let corge1 = group1.init_corge()
corge1.set_grault(first.get_corge().get_grault())
corge1.set_garply(first.get_corge().get_garply())
corge1.set_plugh(first.get_corge().get_plugh())
corge1.set_xyzzy(first.get_corge().get_xyzzy())
let group2 = root.get_group2()
group2.set_foo(second.get_foo())
group2.set_bar(second.get_bar())
group2.set_waldo(second.get_waldo())
let corge2 = group2.init_corge()
corge2.set_grault(second.get_corge().get_grault())
corge2.set_garply(second.get_corge().get_garply())
corge2.set_plugh(second.get_corge().get_plugh())
corge2.set_xyzzy(second.get_corge().get_xyzzy())
group1.set_fred("replacement")
@fs.write_bytes_to_file(directory + "/moon-interleaved.bin", reply.finish())
ignore(root.init_group1())
@fs.write_bytes_to_file(
directory + "/moon-interleaved-reset.bin",
reply.finish(),
)
}
///|
fn main raise {
let args = @stdio.args()
guard args.length() == 2 else {
println(
"Usage: schema_compat DIRECTORY (first run peer.py prepare DIRECTORY)",
)
@stdio.exit(2)
return
}
let directory = args[1]
verify_evolution(directory)
verify_union_groups(directory)
let raw = @fs.read_file_to_bytes(directory + "/python-generics.bin")
let message = @capnp.read_message(raw)
assert_true(message.segment_count() > 1)
let source = @upstream.TestUseGenericsReader::from_message(message)
verify_generic(source)
let packed = @fs.read_file_to_bytes(directory + "/python-generics.packed.bin")
verify_generic(
@upstream.TestUseGenericsReader::from_message(
@capnp.read_message(@capnp.unpack(packed)),
),
)
@fs.write_bytes_to_file(
directory + "/moon-generics.bin",
generic_reply(source),
)
for kind in ["struct", "list", "text", "data", "null"] {
copy_any(directory, kind)
}
let constrained = @upstream.TestAnyOthersReader::from_message(
@capnp.read_message(
@fs.read_file_to_bytes(directory + "/python-constrained.bin"),
),
)
let typed : @upstream.TestAllTypesReader = {
inner: constrained.get_any_struct_field(),
}
assert_eq(typed.get_int32_field(), -123456)
assert_eq(constrained.get_any_list_field().get_int32(1), -456)
assert_true(constrained.get_capability_field().is_null())
let reply = @capnp.Builder::new()
let target = @upstream.TestAnyOthersBuilder::init_root(reply)
target.set_any_struct_field(constrained.get_any_struct_field())
target.set_any_list_field(constrained.get_any_list_field())
@fs.write_bytes_to_file(directory + "/moon-constrained.bin", reply.finish())
write_struct(
directory + "/moon-generic-constant.bin",
@upstream.const_generic_constant().inner,
)
write_struct(
directory + "/moon-any-constants.bin",
@upstream.const_any_pointer_constants().inner,
)
write_struct(
directory + "/moon-embedded-constant.bin",
@upstream.const_embedded_struct().inner,
)
let embedded_data = @upstream.const_embedded_data()
let embedded_text = @upstream.const_embedded_text()
assert_eq(
embedded_data,
@fs.read_file_to_bytes(directory + "/python-embedded-data.bin"),
)
assert_eq(
embedded_text,
@fs.read_file_to_string(directory + "/python-embedded-text.bin"),
)
@fs.write_bytes_to_file(directory + "/moon-embedded-data.bin", embedded_data)
@fs.write_string_to_file(directory + "/moon-embedded-text.bin", embedded_text)
verify_compiler(directory)
println(
"Verified unchanged upstream schema values; wrote typed reply and constants",
)
}