Overgram/generator/src/main/java/io/github/lonamiwebs/overgram/parser/TLArg.java

221 lines
6.7 KiB
Java

package io.github.lonamiwebs.overgram.parser;
import java.util.ArrayList;
import java.util.List;
public class TLArg {
public final String name;
public final List<String> types;
public final boolean flags;
public final Flag flag;
public final boolean genericDefinition;
private TLArg(final String name, final List<String> types, final boolean flags, final Flag flag,
final boolean genericDefinition) {
this.name = name;
this.types = types;
this.flags = flags;
this.flag = flag;
this.genericDefinition = genericDefinition;
}
public static TLArg fromString(String string) {
final String[] tmp = string.split(":");
boolean genericDefinition = false;
if (tmp[1].equals("Type}")) {
tmp[1] = tmp[1].substring(0, tmp[1].length() - 1);
tmp[0] = tmp[0].substring(1);
genericDefinition = true;
}
boolean flags = false;
if (tmp[1].equals("#")) {
tmp[1] = "";
flags = true;
}
Flag flag = null;
final int flagIndex = tmp[1].indexOf('?');
if (flagIndex != -1) {
flag = Flag.fromString(tmp[1].substring(0, flagIndex));
tmp[1] = tmp[1].substring(flagIndex + 1);
}
final List<String> types = new ArrayList<>(2);
int angleBracket;
while ((angleBracket = tmp[1].indexOf("<")) != -1) {
types.add(tmp[1].substring(0, angleBracket));
tmp[1] = tmp[1].substring(angleBracket + 1, tmp[1].length() - 1);
}
types.add(tmp[1]);
return new TLArg(tmp[0], types, flags, flag, genericDefinition);
}
public String javaType() {
final StringBuilder builder = new StringBuilder();
boolean nested = false;
for (final String type : types) {
if (type.startsWith("!")) {
if (nested) {
throw new UnsupportedOperationException();
}
return "TLObject";
}
switch (type) {
case "vector":
case "Vector":
builder.append("List");
break;
case "int":
if (flag == null && !nested) {
builder.append("int");
} else {
builder.append("Integer");
}
break;
case "long":
// TODO handle int128 and int256 properly
case "int128":
case "int256":
if (flag == null && !nested) {
builder.append("long");
} else {
builder.append("Long");
}
break;
case "double":
if (flag == null && !nested) {
builder.append("double");
} else {
builder.append("Double");
}
break;
case "Bool":
if (flag == null && !nested) {
builder.append("boolean");
} else {
builder.append("Boolean");
}
break;
case "true":
builder.append("boolean");
break;
case "string":
builder.append("String");
break;
case "bytes":
builder.append("byte[]");
break;
default:
builder.append("Abstract.");
builder.append(TLObject.toCamelCase(type));
break;
}
builder.append('<');
nested = true;
}
builder.setLength(builder.length() - 1);
for (int i = 1; i < types.size(); ++i) {
builder.append('>');
}
return builder.toString();
}
public String javaSetCheck() {
return types.size() == 1 && types.get(0).equals("true") ? "" : " != null";
}
public static String toCamelCase(final String string) {
final StringBuilder result = new StringBuilder(string.length());
result.append(Character.toLowerCase(string.charAt(0)));
boolean upperNext = false;
for (int i = 1; i < string.length(); ++i) {
final char c = string.charAt(i);
if (c == '_') {
upperNext = true;
} else if (upperNext) {
upperNext = false;
result.append(Character.toUpperCase(c));
} else {
result.append(Character.toLowerCase(c));
}
}
return result.toString();
}
public String javaName() {
switch (name) {
case "lat":
return "latitude"; // not reserved but consistent
case "long":
return "longitude";
case "static":
return "isStatic";
case "public":
return "isPublic";
case "private":
return "isPrivate";
case "final":
return "last";
default:
return toCamelCase(name);
}
}
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
if (genericDefinition) {
builder.append('{');
}
builder.append(name);
builder.append(':');
if (flag != null) {
builder.append(flag.toString());
}
if (flags) {
builder.append('#');
} else {
for (final String type : types) {
builder.append(type);
builder.append('<');
}
builder.setLength(builder.length() - 1);
for (int i = 1; i < types.size(); ++i) {
builder.append('>');
}
}
if (genericDefinition) {
builder.append('}');
}
return builder.toString();
}
public static final class Flag {
public final String flagName;
public final int flagIndex;
private Flag(final String flagName, final int flagIndex) {
this.flagName = flagName;
this.flagIndex = flagIndex;
}
private static Flag fromString(final String string) {
final String[] tmp = string.split("\\.");
return new Flag(tmp[0], Integer.parseInt(tmp[1]));
}
@Override
public String toString() {
return flagName + "." + flagIndex + "?";
}
}
}