Generate code to read TLRequests' result

This commit is contained in:
Lonami Exo 2018-07-24 21:16:35 +02:00
parent 5f018c709e
commit 7fa0d033d6
6 changed files with 147 additions and 85 deletions

View File

@ -19,10 +19,10 @@ public class Generator {
writeAbstract(writer, types); writeAbstract(writer, types);
} }
try (final Writer writer = new BufferedWriter(new FileWriter(typesFile))) { try (final Writer writer = new BufferedWriter(new FileWriter(typesFile))) {
writeCode(writer, "Types", null, types, true); writeCode(writer, "Types", "%s", types, false);
} }
try (final Writer writer = new BufferedWriter(new FileWriter(functionsFile))) { try (final Writer writer = new BufferedWriter(new FileWriter(functionsFile))) {
writeCode(writer, "Functions", "TLRequest", functions, false); writeCode(writer, "Functions", "TLRequest<%s>", functions, true);
} }
} }
@ -50,7 +50,7 @@ public class Generator {
private static void writeCode( private static void writeCode(
final Writer writer, final String className, final String extendsName, final Writer writer, final String className, final String extendsName,
final List<TLObject> objects, final boolean generateGetList) throws IOException { final List<TLObject> objects, final boolean functions) throws IOException {
writer.write("package io.github.lonamiwebs.overgram.tl;\n"); writer.write("package io.github.lonamiwebs.overgram.tl;\n");
writer.write("import io.github.lonamiwebs.overgram.utils.BinaryReader;\n"); writer.write("import io.github.lonamiwebs.overgram.utils.BinaryReader;\n");
writer.write("import io.github.lonamiwebs.overgram.utils.BinaryWriter;\n"); writer.write("import io.github.lonamiwebs.overgram.utils.BinaryWriter;\n");
@ -60,6 +60,7 @@ public class Generator {
writer.write("public class "); writer.write("public class ");
writer.write(className); writer.write(className);
writer.write(" {\n"); writer.write(" {\n");
final boolean nested = extendsName.contains("<");
for (final Map.Entry<String, List<TLObject>> nsObjects : byNamespace(objects).entrySet()) { for (final Map.Entry<String, List<TLObject>> nsObjects : byNamespace(objects).entrySet()) {
if (!nsObjects.getKey().isEmpty()) { if (!nsObjects.getKey().isEmpty()) {
writer.write("public static class "); writer.write("public static class ");
@ -70,12 +71,8 @@ public class Generator {
writer.write("public static class "); writer.write("public static class ");
writer.write(Utils.toCamelCase(object.name, true)); writer.write(Utils.toCamelCase(object.name, true));
writer.write(" extends "); writer.write(" extends ");
if (extendsName == null) { writer.write(String.format(extendsName, object.typeAsArg().javaType(nested)));
writer.write("Abstract.");
writer.write(Utils.toCamelCase(object.type, true));
} else {
writer.write(extendsName);
}
writer.write(" {\n"); writer.write(" {\n");
writer.write("public static final int CONSTRUCTOR_ID = " + object.code + ";\n"); writer.write("public static final int CONSTRUCTOR_ID = " + object.code + ";\n");
@ -120,6 +117,9 @@ public class Generator {
writeSerialize(writer, object); writeSerialize(writer, object);
writeDeserialize(writer, object); writeDeserialize(writer, object);
if (functions) {
writeReadResult(writer, object);
}
writer.write("}\n"); writer.write("}\n");
} }
@ -128,7 +128,7 @@ public class Generator {
} }
} }
if (generateGetList) { if (!functions) {
writer.write("public static TLObject getFromId(final int id) throws ClassNotFoundException {\n"); writer.write("public static TLObject getFromId(final int id) throws ClassNotFoundException {\n");
writer.write("switch (id) {\n"); writer.write("switch (id) {\n");
@ -221,6 +221,18 @@ public class Generator {
// TODO We don't handle boxed vs. unboxed here, either // TODO We don't handle boxed vs. unboxed here, either
writer.write(VARIABLE_SUFFIX + i); writer.write(VARIABLE_SUFFIX + i);
writer.write(" = "); writer.write(" = ");
writeRead(writer, arg);
if (arg.flag != null) {
writer.write(" }\n");
} else {
writer.write('\n');
}
}
writer.write("}\n");
}
private static void writeRead(final Writer writer, final TLArg arg) throws IOException {
if (arg.types.get(0).equalsIgnoreCase("vector")) { if (arg.types.get(0).equalsIgnoreCase("vector")) {
switch (arg.types.get(1)) { switch (arg.types.get(1)) {
case "int": case "int":
@ -281,13 +293,15 @@ public class Generator {
break; break;
} }
} }
}
if (arg.flag != null) { private static void writeReadResult(final Writer writer, final TLObject object) throws IOException {
writer.write(" }\n"); writer.write("public ");
} else { writer.write(object.typeAsArg().javaType(true));
writer.write(" readResult(final BinaryReader reader) throws ClassNotFoundException {\n");
writer.write("return ");
writeRead(writer, object.typeAsArg());
writer.write('\n'); writer.write('\n');
}
}
writer.write("}\n"); writer.write("}\n");
} }

View File

@ -4,6 +4,7 @@ import io.github.lonamiwebs.overgram.utils.Utils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
public class TLArg { public class TLArg {
public final String name; public final String name;
@ -11,17 +12,19 @@ public class TLArg {
public final boolean flags; public final boolean flags;
public final Flag flag; public final Flag flag;
public final boolean genericDefinition; public final boolean genericDefinition;
public final TLArg genericOn;
private TLArg(final String name, final List<String> types, final boolean flags, final Flag flag, private TLArg(final String name, final List<String> types, final boolean flags, final Flag flag,
final boolean genericDefinition) { final boolean genericDefinition, final TLArg genericOn) {
this.name = name; this.name = name;
this.types = types; this.types = types;
this.flags = flags; this.flags = flags;
this.flag = flag; this.flag = flag;
this.genericDefinition = genericDefinition; this.genericDefinition = genericDefinition;
this.genericOn = genericOn;
} }
public static TLArg fromString(String string) { public static TLArg fromString(final String string, final Map<String, TLArg> genericDefinitions) {
final String[] tmp = string.split(":"); final String[] tmp = string.split(":");
boolean genericDefinition = false; boolean genericDefinition = false;
@ -52,13 +55,38 @@ public class TLArg {
} }
types.add(tmp[1]); types.add(tmp[1]);
return new TLArg(tmp[0], types, flags, flag, genericDefinition); final TLArg genericOn;
if (!genericDefinition && types.size() == 1) {
genericOn = genericDefinitions.get(types.get(0));
} else {
genericOn = null;
}
return new TLArg(tmp[0], types, flags, flag, genericDefinition, genericOn);
}
public static TLArg fromUnnamedString(final String string, final Map<String, TLArg> genericDefinitions) {
return fromString(":" + string, genericDefinitions);
} }
public String javaType() { public String javaType() {
final StringBuilder builder = new StringBuilder(); return javaType(false);
}
boolean nested = false; public String javaType(boolean nested) {
if (genericOn != null) {
return genericOn.javaType();
}
if (genericDefinition) {
if (types.size() == 1 && types.get(0).equals("Type")) {
return "TLObject";
} else {
throw new UnsupportedOperationException();
}
}
final StringBuilder builder = new StringBuilder();
for (final String type : types) { for (final String type : types) {
if (type.startsWith("!")) { if (type.startsWith("!")) {
if (nested) { if (nested) {

View File

@ -1,7 +1,9 @@
package io.github.lonamiwebs.overgram.parser; package io.github.lonamiwebs.overgram.parser;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
public class TLObject { public class TLObject {
@ -11,12 +13,15 @@ public class TLObject {
public final int code; public final int code;
public final List<TLArg> args; public final List<TLArg> args;
public final String type; public final String type;
private final Map<String, TLArg> genericDefinitions;
private TLObject(final String fullname, final int code, final List<TLArg> args, final String type) { private TLObject(final String fullname, final int code, final List<TLArg> args, final String type,
final Map<String, TLArg> genericDefinitions) {
this.fullname = fullname; this.fullname = fullname;
this.code = code; this.code = code;
this.args = args; this.args = args;
this.type = type; this.type = type;
this.genericDefinitions = genericDefinitions;
final String[] nsName = fullname.split("\\."); final String[] nsName = fullname.split("\\.");
if (nsName.length == 1) { if (nsName.length == 1) {
@ -47,13 +52,23 @@ public class TLObject {
code = tmp.length == 1 ? "0" : tmp[1]; code = tmp.length == 1 ? "0" : tmp[1];
final List<TLArg> args = new ArrayList<>(); final List<TLArg> args = new ArrayList<>();
final Map<String, TLArg> genericDefinitions = new HashMap<>(1);
if (!string.isEmpty()) { if (!string.isEmpty()) {
for (final String part : string.split(" ")) { for (final String part : string.split(" ")) {
args.add(TLArg.fromString(part)); final TLArg arg = TLArg.fromString(part, genericDefinitions);
if (arg.genericDefinition) {
genericDefinitions.put(arg.name, arg);
}
args.add(arg);
} }
} }
return new TLObject(name, Integer.parseUnsignedInt(code, 16), args, type); return new TLObject(name, Integer.parseUnsignedInt(code, 16), args, type, genericDefinitions);
}
public TLArg typeAsArg() {
return TLArg.fromUnnamedString(type, genericDefinitions);
} }
@Override @Override

View File

@ -80,7 +80,7 @@ ping#7abe77ec ping_id:long = Pong;
ping_delay_disconnect#f3427b8c ping_id:long disconnect_delay:int = Pong; ping_delay_disconnect#f3427b8c ping_id:long disconnect_delay:int = Pong;
destroy_session#e7512126 session_id:long = DestroySessionRes; destroy_session#e7512126 session_id:long = DestroySessionRes;
http_wait#9299359f max_delay:int wait_after:int max_wait:int = HttpWait; //http_wait#9299359f max_delay:int wait_after:int max_wait:int = HttpWait;
//test.useGzipPacked = GzipPacked; //test.useGzipPacked = GzipPacked;
//test.useServerDhInnerData = Server_DH_inner_data; //test.useServerDhInnerData = Server_DH_inner_data;

View File

@ -5,14 +5,15 @@ import io.github.lonamiwebs.overgram.network.connection.Connection;
import io.github.lonamiwebs.overgram.tl.*; import io.github.lonamiwebs.overgram.tl.*;
import io.github.lonamiwebs.overgram.utils.BinaryReader; import io.github.lonamiwebs.overgram.utils.BinaryReader;
import javax.naming.OperationNotSupportedException;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.concurrent.*; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
public class MTProtoSender { public class MTProtoSender {
private final MTProtoState state; private final MTProtoState state;
@ -261,7 +262,11 @@ public class MTProtoSender {
// TODO RPC error // TODO RPC error
final BinaryReader reader = new BinaryReader(ByteBuffer.wrap(result.result())); final BinaryReader reader = new BinaryReader(ByteBuffer.wrap(result.result()));
try {
replyMessage.future.complete(((TLRequest) replyMessage.object).readResult(reader)); replyMessage.future.complete(((TLRequest) replyMessage.object).readResult(reader));
} catch (ClassNotFoundException e) {
replyMessage.future.completeExceptionally(e);
}
} }
public void handleContainer(final TLMessage message) throws InterruptedException { public void handleContainer(final TLMessage message) throws InterruptedException {

View File

@ -2,6 +2,6 @@ package io.github.lonamiwebs.overgram.tl;
import io.github.lonamiwebs.overgram.utils.BinaryReader; import io.github.lonamiwebs.overgram.utils.BinaryReader;
public abstract class TLRequest<T extends TLObject> extends TLObject { public abstract class TLRequest<T> extends TLObject {
public abstract T readResult(final BinaryReader reader); public abstract T readResult(final BinaryReader reader) throws ClassNotFoundException;
} }