[YARP] Remove Java templates [ci skip]
This commit is contained in:
parent
fa70e361e0
commit
b7364069bf
@ -1,14 +0,0 @@
|
||||
package org.yarp;
|
||||
|
||||
// GENERATED BY <%= File.basename(__FILE__) %>
|
||||
public abstract class AbstractNodeVisitor<T> {
|
||||
|
||||
protected abstract T defaultVisit(Nodes.Node node);
|
||||
|
||||
<%- nodes.each do |node| -%>
|
||||
public T visit<%= node.name -%>(Nodes.<%= node.name -%> node) {
|
||||
return defaultVisit(node);
|
||||
}
|
||||
|
||||
<%- end -%>
|
||||
}
|
@ -1,293 +0,0 @@
|
||||
package org.yarp;
|
||||
|
||||
import org.yarp.ParseResult;
|
||||
|
||||
import java.lang.Short;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
// GENERATED BY <%= File.basename(__FILE__) %>
|
||||
// @formatter:off
|
||||
public class Loader {
|
||||
|
||||
public static ParseResult load(byte[] serialized, Nodes.Source source) {
|
||||
return new Loader(serialized, source).load();
|
||||
}
|
||||
|
||||
private static final class ConstantPool {
|
||||
|
||||
private final byte[] source;
|
||||
private final int bufferOffset;
|
||||
private final byte[][] cache;
|
||||
|
||||
ConstantPool(byte[] source, int bufferOffset, int length) {
|
||||
this.source = source;
|
||||
this.bufferOffset = bufferOffset;
|
||||
cache = new byte[length][];
|
||||
}
|
||||
|
||||
byte[] get(ByteBuffer buffer, int oneBasedIndex) {
|
||||
int index = oneBasedIndex - 1;
|
||||
byte[] constant = cache[index];
|
||||
if (constant == null) {
|
||||
int offset = bufferOffset + index * 8;
|
||||
int start = buffer.getInt(offset);
|
||||
int length = buffer.getInt(offset + 4);
|
||||
|
||||
constant = new byte[length];
|
||||
System.arraycopy(source, start, constant, 0, length);
|
||||
cache[index] = constant;
|
||||
}
|
||||
return constant;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final ByteBuffer buffer;
|
||||
private ConstantPool constantPool;
|
||||
private final Nodes.Source source;
|
||||
|
||||
private Loader(byte[] serialized, Nodes.Source source) {
|
||||
this.buffer = ByteBuffer.wrap(serialized).order(ByteOrder.nativeOrder());
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
private ParseResult load() {
|
||||
expect((byte) 'Y');
|
||||
expect((byte) 'A');
|
||||
expect((byte) 'R');
|
||||
expect((byte) 'P');
|
||||
|
||||
expect((byte) 0);
|
||||
expect((byte) 9);
|
||||
expect((byte) 0);
|
||||
|
||||
// This loads the name of the encoding. We don't actually do anything
|
||||
// with it just yet.
|
||||
int encodingLength = loadVarInt();
|
||||
byte[] encodingName = new byte[encodingLength];
|
||||
buffer.get(encodingName);
|
||||
|
||||
ParseResult.Comment[] comments = loadComments();
|
||||
ParseResult.Error[] errors = loadSyntaxErrors();
|
||||
ParseResult.Warning[] warnings = loadWarnings();
|
||||
|
||||
int constantPoolBufferOffset = buffer.getInt();
|
||||
int constantPoolLength = loadVarInt();
|
||||
this.constantPool = new ConstantPool(source.bytes, constantPoolBufferOffset, constantPoolLength);
|
||||
|
||||
Nodes.Node node = loadNode();
|
||||
|
||||
int left = constantPoolBufferOffset - buffer.position();
|
||||
if (left != 0) {
|
||||
throw new Error("Expected to consume all bytes while deserializing but there were " + left + " bytes left");
|
||||
}
|
||||
|
||||
boolean[] newlineMarked = new boolean[1 + source.getLineCount()];
|
||||
MarkNewlinesVisitor visitor = new MarkNewlinesVisitor(source, newlineMarked);
|
||||
node.accept(visitor);
|
||||
|
||||
return new ParseResult(node, comments, errors, warnings);
|
||||
}
|
||||
|
||||
private byte[] loadEmbeddedString() {
|
||||
int length = loadVarInt();
|
||||
byte[] string = new byte[length];
|
||||
buffer.get(string);
|
||||
return string;
|
||||
}
|
||||
|
||||
private byte[] loadString() {
|
||||
switch (buffer.get()) {
|
||||
case 1:
|
||||
int start = loadVarInt();
|
||||
int length = loadVarInt();
|
||||
byte[] string = new byte[length];
|
||||
System.arraycopy(source.bytes, start, string, 0, length);
|
||||
return string;
|
||||
case 2:
|
||||
return loadEmbeddedString();
|
||||
default:
|
||||
throw new Error("Expected 0 or 1 but was " + buffer.get());
|
||||
}
|
||||
}
|
||||
|
||||
private ParseResult.Comment[] loadComments() {
|
||||
int count = loadVarInt();
|
||||
ParseResult.Comment[] comments = new ParseResult.Comment[count];
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
ParseResult.CommentType type = ParseResult.CommentType.VALUES[buffer.get()];
|
||||
Nodes.Location location = loadLocation();
|
||||
|
||||
ParseResult.Comment comment = new ParseResult.Comment(type, location);
|
||||
comments[i] = comment;
|
||||
}
|
||||
|
||||
return comments;
|
||||
}
|
||||
|
||||
private ParseResult.Error[] loadSyntaxErrors() {
|
||||
int count = loadVarInt();
|
||||
ParseResult.Error[] errors = new ParseResult.Error[count];
|
||||
|
||||
// error messages only contain ASCII characters
|
||||
for (int i = 0; i < count; i++) {
|
||||
byte[] bytes = loadEmbeddedString();
|
||||
String message = new String(bytes, StandardCharsets.US_ASCII);
|
||||
Nodes.Location location = loadLocation();
|
||||
|
||||
ParseResult.Error error = new ParseResult.Error(message, location);
|
||||
errors[i] = error;
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
private ParseResult.Warning[] loadWarnings() {
|
||||
int count = loadVarInt();
|
||||
ParseResult.Warning[] warnings = new ParseResult.Warning[count];
|
||||
|
||||
// warning messages only contain ASCII characters
|
||||
for (int i = 0; i < count; i++) {
|
||||
byte[] bytes = loadEmbeddedString();
|
||||
String message = new String(bytes, StandardCharsets.US_ASCII);
|
||||
Nodes.Location location = loadLocation();
|
||||
|
||||
ParseResult.Warning warning = new ParseResult.Warning(message, location);
|
||||
warnings[i] = warning;
|
||||
}
|
||||
|
||||
return warnings;
|
||||
}
|
||||
|
||||
private Nodes.Node loadOptionalNode() {
|
||||
if (buffer.get(buffer.position()) != 0) {
|
||||
return loadNode();
|
||||
} else {
|
||||
buffer.position(buffer.position() + 1); // continue after the 0 byte
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Nodes.Location[] loadLocations() {
|
||||
int length = loadVarInt();
|
||||
if (length == 0) {
|
||||
return Nodes.Location.EMPTY_ARRAY;
|
||||
}
|
||||
Nodes.Location[] locations = new Nodes.Location[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
locations[i] = loadLocation();
|
||||
}
|
||||
return locations;
|
||||
}
|
||||
|
||||
private byte[] loadConstant() {
|
||||
return constantPool.get(buffer, loadVarInt());
|
||||
}
|
||||
|
||||
private byte[][] loadConstants() {
|
||||
int length = loadVarInt();
|
||||
if (length == 0) {
|
||||
return Nodes.EMPTY_BYTE_ARRAY_ARRAY;
|
||||
}
|
||||
byte[][] constants = new byte[length][];
|
||||
for (int i = 0; i < length; i++) {
|
||||
constants[i] = constantPool.get(buffer, loadVarInt());
|
||||
}
|
||||
return constants;
|
||||
}
|
||||
|
||||
private Nodes.Node[] loadNodes() {
|
||||
int length = loadVarInt();
|
||||
if (length == 0) {
|
||||
return Nodes.Node.EMPTY_ARRAY;
|
||||
}
|
||||
Nodes.Node[] nodes = new Nodes.Node[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
nodes[i] = loadNode();
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
|
||||
private Nodes.Location loadLocation() {
|
||||
return new Nodes.Location(loadVarInt(), loadVarInt());
|
||||
}
|
||||
|
||||
private Nodes.Location loadOptionalLocation() {
|
||||
if (buffer.get() != 0) {
|
||||
return loadLocation();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// From https://github.com/protocolbuffers/protobuf/blob/v23.1/java/core/src/main/java/com/google/protobuf/BinaryReader.java#L1507
|
||||
private int loadVarInt() {
|
||||
int x;
|
||||
if ((x = buffer.get()) >= 0) {
|
||||
return x;
|
||||
} else if ((x ^= (buffer.get() << 7)) < 0) {
|
||||
x ^= (~0 << 7);
|
||||
} else if ((x ^= (buffer.get() << 14)) >= 0) {
|
||||
x ^= (~0 << 7) ^ (~0 << 14);
|
||||
} else if ((x ^= (buffer.get() << 21)) < 0) {
|
||||
x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21);
|
||||
} else {
|
||||
x ^= buffer.get() << 28;
|
||||
x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21) ^ (~0 << 28);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
private short loadFlags() {
|
||||
int flags = loadVarInt();
|
||||
assert flags >= 0 && flags <= Short.MAX_VALUE;
|
||||
return (short) flags;
|
||||
}
|
||||
|
||||
private Nodes.Node loadNode() {
|
||||
int type = buffer.get() & 0xFF;
|
||||
int startOffset = loadVarInt();
|
||||
int length = loadVarInt();
|
||||
|
||||
switch (type) {
|
||||
<%- nodes.each_with_index do |node, index| -%>
|
||||
case <%= index + 1 %>:
|
||||
<%-
|
||||
params = node.needs_serialized_length? ? ["buffer.getInt()"] : []
|
||||
params.concat node.fields.map { |field|
|
||||
case field
|
||||
when YARP::NodeField then "#{field.java_cast}loadNode()"
|
||||
when YARP::OptionalNodeField then "#{field.java_cast}loadOptionalNode()"
|
||||
when YARP::StringField then "loadString()"
|
||||
when YARP::NodeListField then "loadNodes()"
|
||||
when YARP::LocationListField then "loadLocations()"
|
||||
when YARP::ConstantField then "loadConstant()"
|
||||
when YARP::ConstantListField then "loadConstants()"
|
||||
when YARP::LocationField then "loadLocation()"
|
||||
when YARP::OptionalLocationField then "loadOptionalLocation()"
|
||||
when YARP::UInt32Field then "loadVarInt()"
|
||||
when YARP::FlagsField then "loadFlags()"
|
||||
else raise
|
||||
end
|
||||
}
|
||||
params.concat ["startOffset", "length"]
|
||||
-%>
|
||||
return new Nodes.<%= node.name %>(<%= params.join(", ") -%>);
|
||||
<%- end -%>
|
||||
default:
|
||||
throw new Error("Unknown node type: " + type);
|
||||
}
|
||||
}
|
||||
|
||||
private void expect(byte value) {
|
||||
byte b = buffer.get();
|
||||
if (b != value) {
|
||||
throw new Error("Expected " + value + " but was " + b + " at position " + buffer.position());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// @formatter:on
|
@ -1,291 +0,0 @@
|
||||
package org.yarp;
|
||||
|
||||
import java.lang.Override;
|
||||
import java.lang.String;
|
||||
import java.lang.StringBuilder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
// GENERATED BY <%= File.basename(__FILE__) %>
|
||||
// @formatter:off
|
||||
public abstract class Nodes {
|
||||
|
||||
public static final byte[][] EMPTY_BYTE_ARRAY_ARRAY = {};
|
||||
|
||||
public static final class Location {
|
||||
|
||||
public static final Location[] EMPTY_ARRAY = {};
|
||||
|
||||
public final int startOffset;
|
||||
public final int length;
|
||||
|
||||
public Location(int startOffset, int length) {
|
||||
this.startOffset = startOffset;
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public int endOffset() {
|
||||
return startOffset + length;
|
||||
}
|
||||
}
|
||||
|
||||
public static final class Source {
|
||||
public final byte[] bytes;
|
||||
private final int[] lineOffsets;
|
||||
|
||||
public Source(byte[] bytes) {
|
||||
this(bytes, computeLineOffsets(bytes));
|
||||
}
|
||||
|
||||
public Source(byte[] bytes, int[] lineOffsets) {
|
||||
assert lineOffsets[0] == 0;
|
||||
this.bytes = bytes;
|
||||
this.lineOffsets = lineOffsets;
|
||||
}
|
||||
|
||||
public static int[] computeLineOffsets(byte[] bytes) {
|
||||
int[] lineOffsets = new int[8];
|
||||
int lineOffsetsSize = 0;
|
||||
lineOffsets[lineOffsetsSize++] = 0;
|
||||
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
if (bytes[i] == '\n') {
|
||||
if (lineOffsetsSize == lineOffsets.length) {
|
||||
lineOffsets = Arrays.copyOf(lineOffsets, lineOffsets.length * 2);
|
||||
}
|
||||
lineOffsets[lineOffsetsSize++] = i + 1;
|
||||
}
|
||||
}
|
||||
return Arrays.copyOf(lineOffsets, lineOffsetsSize);
|
||||
}
|
||||
|
||||
public int line(int byteOffset) {
|
||||
assert byteOffset >= 0 && byteOffset < bytes.length : byteOffset;
|
||||
int index = Arrays.binarySearch(lineOffsets, byteOffset);
|
||||
int line;
|
||||
if (index < 0) {
|
||||
line = -index - 1;
|
||||
} else {
|
||||
line = index + 1;
|
||||
}
|
||||
assert line >= 1 && line <= getLineCount() : line;
|
||||
return line;
|
||||
}
|
||||
|
||||
public int getLineCount() {
|
||||
return lineOffsets.length;
|
||||
}
|
||||
}
|
||||
|
||||
public static abstract class Node {
|
||||
|
||||
public static final Node[] EMPTY_ARRAY = {};
|
||||
|
||||
public final int startOffset;
|
||||
public final int length;
|
||||
private boolean newLineFlag = false;
|
||||
|
||||
public Node(int startOffset, int length) {
|
||||
this.startOffset = startOffset;
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public final int endOffset() {
|
||||
return startOffset + length;
|
||||
}
|
||||
|
||||
public final boolean hasNewLineFlag() {
|
||||
return newLineFlag;
|
||||
}
|
||||
|
||||
public void setNewLineFlag(Source source, boolean[] newlineMarked) {
|
||||
int line = source.line(this.startOffset);
|
||||
if (!newlineMarked[line]) {
|
||||
newlineMarked[line] = true;
|
||||
this.newLineFlag = true;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract <T> T accept(AbstractNodeVisitor<T> visitor);
|
||||
|
||||
public abstract <T> void visitChildNodes(AbstractNodeVisitor<T> visitor);
|
||||
|
||||
public abstract Node[] childNodes();
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toString("");
|
||||
}
|
||||
|
||||
private String toString(String indent) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(indent).append(this.getClass().getSimpleName());
|
||||
if (hasNewLineFlag()) {
|
||||
builder.append("[Li]");
|
||||
}
|
||||
builder.append('\n');
|
||||
for (Node child : childNodes()) {
|
||||
if (child != null) {
|
||||
builder.append(child.toString(indent + " "));
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
<%# FLAGS -%>
|
||||
<%- flags.each do |group| -%>
|
||||
|
||||
public static final class <%= group.name %> implements Comparable<<%= group.name %>> {
|
||||
<%- group.values.each_with_index do |value, index| -%>
|
||||
|
||||
// <%= value.comment %>
|
||||
public static final short <%= value.name %> = 1 << <%= index %>;
|
||||
<%- end -%>
|
||||
|
||||
<%- group.values.each do |value| -%>
|
||||
public static boolean is<%= value.camelcase %>(short flags) {
|
||||
return (flags & <%= value.name %>) != 0;
|
||||
}
|
||||
|
||||
<%- end -%>
|
||||
private final short flags;
|
||||
|
||||
public <%= group.name %>(short flags) {
|
||||
this.flags = flags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (!(other instanceof <%= group.name %>)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return flags == ((<%= group.name %>) other).flags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(<%= group.name %> other) {
|
||||
return flags - other.flags;
|
||||
}
|
||||
|
||||
<%- group.values.each do |value| -%>
|
||||
public boolean is<%= value.camelcase %>() {
|
||||
return (flags & <%= value.name %>) != 0;
|
||||
}
|
||||
|
||||
<%- end -%>
|
||||
}
|
||||
<%- end -%>
|
||||
<%# NODES -%>
|
||||
<%- nodes.each do |node| -%>
|
||||
|
||||
<%= "#{node.comment.split("\n").map { |line| "// #{line}" }.join("\n ")}\n" if node.comment -%>
|
||||
public static final class <%= node.name -%> extends Node {
|
||||
<%- if node.needs_serialized_length? -%>
|
||||
public final int serializedLength;
|
||||
<%- end -%>
|
||||
<%- node.fields.each do |field| -%>
|
||||
public final <%= field.java_type %> <%= field.name %>;<%= ' // optional' if field.class.name.start_with?('Optional') %>
|
||||
<%- end -%>
|
||||
|
||||
<%-
|
||||
params = node.needs_serialized_length? ? ["int serializedLength"] : []
|
||||
params.concat node.fields.map { "#{_1.java_type} #{_1.name}" }
|
||||
params.concat ["int startOffset", "int length"]
|
||||
-%>
|
||||
public <%=node.name -%>(<%= params.join(", ") %>) {
|
||||
super(startOffset, length);
|
||||
<%- if node.needs_serialized_length? -%>
|
||||
this.serializedLength = serializedLength;
|
||||
<%- end -%>
|
||||
<%- node.fields.each do |field| -%>
|
||||
this.<%= field.name %> = <%= field.name %>;
|
||||
<%- end -%>
|
||||
}
|
||||
<%# methods for flags -%>
|
||||
<%- node.fields.each do |field| -%>
|
||||
<%- if field.is_a?(YARP::FlagsField) -%>
|
||||
<%- flags.find { |flag| flag.name == field.kind }.tap { raise "Expected to find #{field.kind}" unless _1 }.values.each do |value| -%>
|
||||
|
||||
public boolean is<%= value.camelcase %>() {
|
||||
return <%= field.kind %>.is<%= value.camelcase %>(this.<%= field.name %>);
|
||||
}
|
||||
<%- end -%>
|
||||
<%- end -%>
|
||||
<%- end -%>
|
||||
<%# potential override of setNewLineFlag() -%>
|
||||
<%- if node.newline == false -%>
|
||||
|
||||
@Override
|
||||
public void setNewLineFlag(Source source, boolean[] newlineMarked) {
|
||||
// Never mark <%= node.name %> with a newline flag, mark children instead
|
||||
}
|
||||
<%- elsif node.newline.is_a?(String) -%>
|
||||
|
||||
@Override
|
||||
public void setNewLineFlag(Source source, boolean[] newlineMarked) {
|
||||
<%- field = node.fields.find { |f| f.name == node.newline } or raise node.newline -%>
|
||||
<%- case field -%>
|
||||
<%- when YARP::NodeField, YARP::OptionalNodeField -%>
|
||||
this.<%= field.name %>.setNewLineFlag(source, newlineMarked);
|
||||
<%- when YARP::NodeListField -%>
|
||||
Node first = this.<%= field.name %>.length > 0 ? this.<%= field.name %>[0] : null;
|
||||
if (first != null) {
|
||||
first.setNewLineFlag(source, newlineMarked);
|
||||
}
|
||||
<%- else raise field.class.name -%>
|
||||
<%- end -%>
|
||||
}
|
||||
<%- end -%>
|
||||
|
||||
public <T> void visitChildNodes(AbstractNodeVisitor<T> visitor) {
|
||||
<%- node.fields.each do |field| -%>
|
||||
<%- case field -%>
|
||||
<%- when YARP::NodeListField -%>
|
||||
for (Nodes.Node child : this.<%= field.name %>) {
|
||||
child.accept(visitor);
|
||||
}
|
||||
<%- when YARP::NodeField -%>
|
||||
this.<%= field.name %>.accept(visitor);
|
||||
<%- when YARP::OptionalNodeField -%>
|
||||
if (this.<%= field.name %> != null) {
|
||||
this.<%= field.name %>.accept(visitor);
|
||||
}
|
||||
<%- end -%>
|
||||
<%- end -%>
|
||||
}
|
||||
|
||||
public Node[] childNodes() {
|
||||
<%- if node.fields.none?(YARP::NodeListField) and node.fields.none?(YARP::NodeKindField) -%>
|
||||
return EMPTY_ARRAY;
|
||||
<%- elsif node.fields.one?(YARP::NodeListField) and node.fields.none?(YARP::NodeKindField) -%>
|
||||
return this.<%= node.fields.grep(YARP::NodeListField).first.name %>;
|
||||
<%- elsif node.fields.none?(YARP::NodeListField) -%>
|
||||
return new Node[] { <%= node.fields.grep(YARP::NodeKindField).map { "this.#{_1.name}" }.join(', ') %> };
|
||||
<%- else -%>
|
||||
ArrayList<Node> childNodes = new ArrayList<>();
|
||||
<%- node.fields.each do |field| -%>
|
||||
<%- case field -%>
|
||||
<%- when YARP::NodeField, YARP::OptionalNodeField -%>
|
||||
childNodes.add(this.<%= field.name %>);
|
||||
<%- when YARP::NodeListField -%>
|
||||
childNodes.addAll(Arrays.asList(this.<%= field.name %>));
|
||||
<%- end -%>
|
||||
<%- end -%>
|
||||
return childNodes.toArray(EMPTY_ARRAY);
|
||||
<%- end -%>
|
||||
}
|
||||
|
||||
public <T> T accept(AbstractNodeVisitor<T> visitor) {
|
||||
return visitor.visit<%= node.name -%>(this);
|
||||
}
|
||||
}
|
||||
<%- end -%>
|
||||
|
||||
}
|
||||
// @formatter:on
|
Loading…
x
Reference in New Issue
Block a user