generic interface generation (WIP
This commit is contained in:
parent
86ccdd5a55
commit
2d8fe31a59
2 changed files with 124 additions and 74 deletions
|
@ -381,6 +381,7 @@ private:
|
||||||
return kj::strTree("org.capnproto.ListList.", suffix, "<", kj::mv(inner), ">");
|
return kj::strTree("org.capnproto.ListList.", suffix, "<", kj::mv(inner), ">");
|
||||||
}
|
}
|
||||||
case schema::Type::INTERFACE:
|
case schema::Type::INTERFACE:
|
||||||
|
return kj::strTree("org.capnproto.PrimitiveList.Void.", suffix);
|
||||||
case schema::Type::ANY_POINTER:
|
case schema::Type::ANY_POINTER:
|
||||||
KJ_FAIL_REQUIRE("unimplemented");
|
KJ_FAIL_REQUIRE("unimplemented");
|
||||||
}
|
}
|
||||||
|
@ -811,6 +812,23 @@ private:
|
||||||
return kj::str(typeName(type, kj::str("factory")));
|
return kj::str(typeName(type, kj::str("factory")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case schema::Type::INTERFACE: {
|
||||||
|
auto interfaceSchema = type.asInterface();
|
||||||
|
auto node = interfaceSchema.getProto();
|
||||||
|
if (node.getIsGeneric()) {
|
||||||
|
auto factoryArgs = getFactoryArguments(interfaceSchema, interfaceSchema);
|
||||||
|
return kj::strTree(
|
||||||
|
javaFullName(interfaceSchema), ".newFactory(",
|
||||||
|
kj::StringTree(
|
||||||
|
KJ_MAP(arg, factoryArgs) {
|
||||||
|
return kj::strTree(arg);
|
||||||
|
}, ","),
|
||||||
|
")"
|
||||||
|
).flatten();
|
||||||
|
} else {
|
||||||
|
return kj::str(typeName(type, kj::str("factory")));
|
||||||
|
}
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
KJ_UNREACHABLE;
|
KJ_UNREACHABLE;
|
||||||
}
|
}
|
||||||
|
@ -1030,8 +1048,8 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
} else if (kind == FieldKind::INTERFACE) {
|
} else if (kind == FieldKind::INTERFACE) {
|
||||||
|
|
||||||
auto factoryArg = kj::str(typeName(field.getType()), ".factory");
|
auto factoryArg = makeFactoryArg(field.getType());
|
||||||
auto clientType = kj::str(typeName(field.getType()), ".Client");
|
auto clientType = kj::str(typeName(field.getType()), ".Client");
|
||||||
|
|
||||||
return FieldText {
|
return FieldText {
|
||||||
|
@ -1627,10 +1645,88 @@ private:
|
||||||
|
|
||||||
auto typeName = javaFullName(schema);
|
auto typeName = javaFullName(schema);
|
||||||
|
|
||||||
|
|
||||||
|
kj::String genericParamTypes;
|
||||||
|
if (proto.getIsGeneric()) {
|
||||||
|
auto typeParams = getTypeParameters(schema);
|
||||||
|
genericParamTypes = kj::strTree(
|
||||||
|
"<",
|
||||||
|
kj::StringTree(
|
||||||
|
KJ_MAP(arg, typeParams) {
|
||||||
|
return kj::strTree(arg);
|
||||||
|
}, ", "),
|
||||||
|
">").flatten();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
genericParamTypes = kj::str("");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto typeParamVec = getTypeParameters(schema);
|
||||||
|
bool hasTypeParams = typeParamVec.size() > 0;
|
||||||
|
|
||||||
|
kj::StringTree readerTypeParamsTree;
|
||||||
|
kj::StringTree builderTypeParamsTree;
|
||||||
|
kj::StringTree factoryTypeParamsTree;
|
||||||
|
if (hasTypeParams) {
|
||||||
|
builderTypeParamsTree = kj::strTree(
|
||||||
|
"<",
|
||||||
|
kj::StringTree(KJ_MAP(p, typeParamVec) {
|
||||||
|
return kj::strTree(p, "_Builder");
|
||||||
|
}, ", "),
|
||||||
|
">");
|
||||||
|
readerTypeParamsTree = kj::strTree(
|
||||||
|
"<",
|
||||||
|
kj::StringTree(KJ_MAP(p, typeParamVec) {
|
||||||
|
return kj::strTree(p, "_Reader");
|
||||||
|
}, ", "),
|
||||||
|
">");
|
||||||
|
|
||||||
|
factoryTypeParamsTree = kj::strTree(
|
||||||
|
"<",
|
||||||
|
kj::StringTree(KJ_MAP(p, typeParamVec) {
|
||||||
|
return kj::strTree(p, "_Builder, ", p, "_Reader");
|
||||||
|
}, ", "),
|
||||||
|
">");
|
||||||
|
}
|
||||||
|
kj::String readerTypeParams = readerTypeParamsTree.flatten();
|
||||||
|
auto readerTypeParamsInferred = (hasTypeParams ? "<>" : "");
|
||||||
|
kj::String builderTypeParams = builderTypeParamsTree.flatten();
|
||||||
|
kj::String factoryTypeParams = factoryTypeParamsTree.flatten();
|
||||||
|
|
||||||
|
kj::StringTree factoryArgs = kj::StringTree(KJ_MAP(p, typeParamVec) {
|
||||||
|
return kj::strTree("org.capnproto.PointerFactory<", p, "_Builder, ", p, "_Reader> ", p, "_Factory");
|
||||||
|
}, ", ");
|
||||||
|
|
||||||
|
kj::StringTree factoryMembers = kj::strTree(KJ_MAP(p, typeParamVec) {
|
||||||
|
return kj::strTree(spaces(indent), " final org.capnproto.PointerFactory<", p, "_Builder, ", p, "_Reader> ", p, "_Factory;\n");
|
||||||
|
});
|
||||||
|
|
||||||
|
kj::String factoryRef = hasTypeParams
|
||||||
|
? kj::str(kj::strTree("newFactory(",
|
||||||
|
kj::StringTree(KJ_MAP(p, typeParamVec) {
|
||||||
|
return kj::strTree(p, "_Factory");
|
||||||
|
}, ", ")
|
||||||
|
, ")"))
|
||||||
|
: kj::str("factory");
|
||||||
|
|
||||||
|
|
||||||
return InterfaceText {
|
return InterfaceText {
|
||||||
kj::strTree(
|
kj::strTree(
|
||||||
spaces(indent), "public static class ", name, " {\n",
|
spaces(indent), "public static class ", name, genericParamTypes, " {\n",
|
||||||
spaces(indent), " public static final class Factory extends org.capnproto.Capability.Factory<Client> {\n",
|
|
||||||
|
spaces(indent), " public static final class Factory", factoryTypeParams, "\n",
|
||||||
|
spaces(indent), " extends org.capnproto.Capability.Factory<Client> {\n",
|
||||||
|
factoryMembers.flatten(),
|
||||||
|
spaces(indent), " public Factory(",
|
||||||
|
factoryArgs.flatten(),
|
||||||
|
") {\n",
|
||||||
|
KJ_MAP(p, typeParamVec) {
|
||||||
|
return kj::strTree(spaces(indent), " this.", p, "_Factory = ", p, "_Factory;\n");
|
||||||
|
},
|
||||||
|
spaces(indent), " }\n",
|
||||||
|
|
||||||
|
|
||||||
|
//spaces(indent), " public static final class Factory extends org.capnproto.Capability.Factory<Client> {\n",
|
||||||
spaces(indent), " public final Client newClient(org.capnproto.ClientHook hook) {\n",
|
spaces(indent), " public final Client newClient(org.capnproto.ClientHook hook) {\n",
|
||||||
spaces(indent), " return new Client(hook);\n",
|
spaces(indent), " return new Client(hook);\n",
|
||||||
spaces(indent), " }\n",
|
spaces(indent), " }\n",
|
||||||
|
@ -1712,8 +1808,7 @@ private:
|
||||||
paramType = kj::str(titleCase, "Params");
|
paramType = kj::str(titleCase, "Params");
|
||||||
genericParamType = kj::str(paramType);
|
genericParamType = kj::str(paramType);
|
||||||
} else {
|
} else {
|
||||||
KJ_FAIL_REQUIRE("Generic interfaces not supported");
|
genericParamType = kj::str(paramType);
|
||||||
//genericParamType = paramType;
|
|
||||||
//genericParamType.addMemberTemplate(kj::str(titleCase, "Params"), nullptr);
|
//genericParamType.addMemberTemplate(kj::str(titleCase, "Params"), nullptr);
|
||||||
//paramType.addMemberTemplate(kj::str(titleCase, "Params"),
|
//paramType.addMemberTemplate(kj::str(titleCase, "Params"),
|
||||||
// kj::heapArray(implicitParams.asPtr()));
|
// kj::heapArray(implicitParams.asPtr()));
|
||||||
|
@ -1734,8 +1829,7 @@ private:
|
||||||
resultType = kj::str(titleCase, "Results");
|
resultType = kj::str(titleCase, "Results");
|
||||||
genericResultType = kj::str(resultType);
|
genericResultType = kj::str(resultType);
|
||||||
} else {
|
} else {
|
||||||
KJ_FAIL_REQUIRE("Generic interfaces not supported");
|
genericResultType = kj::str(resultType);
|
||||||
//genericResultType = resultType;
|
|
||||||
//genericResultType.addMemberTemplate(kj::str(titleCase, "Results"), nullptr);
|
//genericResultType.addMemberTemplate(kj::str(titleCase, "Results"), nullptr);
|
||||||
//resultType.addMemberTemplate(kj::str(titleCase, "Results"),
|
//resultType.addMemberTemplate(kj::str(titleCase, "Results"),
|
||||||
// kj::heapArray(implicitParams.asPtr()));
|
// kj::heapArray(implicitParams.asPtr()));
|
||||||
|
@ -1761,6 +1855,28 @@ private:
|
||||||
kj::String paramFactory = kj::str(shortParamType, ".factory");
|
kj::String paramFactory = kj::str(shortParamType, ".factory");
|
||||||
kj::String resultFactory = kj::str(shortResultType, ".factory");
|
kj::String resultFactory = kj::str(shortResultType, ".factory");
|
||||||
|
|
||||||
|
if (paramProto.getIsGeneric()) {
|
||||||
|
auto paramFactoryArgs = getFactoryArguments(paramSchema, paramSchema);
|
||||||
|
paramFactory = paramFactoryArgs.size() == 0
|
||||||
|
? kj::str(shortParamType, ".factory")
|
||||||
|
: kj::strTree("newFactory(",
|
||||||
|
kj::StringTree(KJ_MAP(arg, paramFactoryArgs) {
|
||||||
|
return kj::strTree(arg);
|
||||||
|
}, ", "),
|
||||||
|
")").flatten();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resultProto.getIsGeneric()) {
|
||||||
|
auto resultFactoryArgs = getFactoryArguments(resultSchema, paramSchema);
|
||||||
|
resultFactory = resultFactoryArgs.size() == 0
|
||||||
|
? kj::str(shortResultType, ".factory")
|
||||||
|
: kj::strTree("newFactory(",
|
||||||
|
kj::StringTree(KJ_MAP(arg, resultFactoryArgs) {
|
||||||
|
return kj::strTree(arg);
|
||||||
|
}, ", "),
|
||||||
|
")").flatten();
|
||||||
|
}
|
||||||
|
|
||||||
auto interfaceProto = method.getContainingInterface().getProto();
|
auto interfaceProto = method.getContainingInterface().getProto();
|
||||||
uint64_t interfaceId = interfaceProto.getId();
|
uint64_t interfaceId = interfaceProto.getId();
|
||||||
auto interfaceIdHex = kj::hex(interfaceId);
|
auto interfaceIdHex = kj::hex(interfaceId);
|
||||||
|
|
|
@ -1,66 +0,0 @@
|
||||||
package org.capnproto;
|
|
||||||
|
|
||||||
import org.capnproto.demo.Demo;
|
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
|
|
||||||
public class LocalCapabilityTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testLocalServer() throws ExecutionException, InterruptedException {
|
|
||||||
var demo = new TestCap0Impl();
|
|
||||||
var client = new Demo.TestCap0.Client(demo);
|
|
||||||
var request = client.testMethod0Request();
|
|
||||||
var params = request.getParams();
|
|
||||||
params.setParam0(4321);
|
|
||||||
var response = request.send();
|
|
||||||
var results = response.get();
|
|
||||||
Assert.assertEquals(params.getParam0(), results.getResult0());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGenericServer() throws ExecutionException, InterruptedException {
|
|
||||||
var demo = new TestCap0Impl();
|
|
||||||
var client = new Demo.TestCap0.Client(demo);
|
|
||||||
var request = client.testMethod0Request();
|
|
||||||
var params = request.getParams();
|
|
||||||
var response = request.send();
|
|
||||||
var results = response.get();
|
|
||||||
Assert.assertEquals(params.getParam0(), results.getResult0());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testLocalTwoStagePipeline() {
|
|
||||||
|
|
||||||
var server0 = new Demo.Iface0.Server() {
|
|
||||||
boolean method0called = false;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected CompletableFuture<java.lang.Void> method0(CallContext<Demo.Iface0.Method0Params.Reader, Demo.Iface0.Method0Results.Builder> ctx) {
|
|
||||||
method0called = true;
|
|
||||||
return CompletableFuture.completedFuture(null);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var server1 = new Demo.Iface1.Server() {
|
|
||||||
@Override
|
|
||||||
protected CompletableFuture<java.lang.Void> method1(CallContext<Demo.Iface1.Method1Params.Reader, Demo.Iface1.Method1Results.Builder> ctx) {
|
|
||||||
ctx.getResults().setResult0(new Demo.Iface0.Client(server0));
|
|
||||||
return CompletableFuture.completedFuture(null);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var iface1Client = new Demo.Iface1.Client(server1);
|
|
||||||
var request1 = iface1Client.method1Request();
|
|
||||||
var response = request1.send();
|
|
||||||
var iface0 = response.getResult0();
|
|
||||||
var request0 = iface0.method0Request();
|
|
||||||
var response0 = request0.send();
|
|
||||||
response0.join();
|
|
||||||
Assert.assertTrue(!response0.isCompletedExceptionally());
|
|
||||||
Assert.assertTrue(server0.method0called);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue