Compare commits
52 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
d9978d572f | ||
|
26448fc1b8 | ||
|
6bafed9886 | ||
|
5b39288d60 | ||
|
5d3a415afb | ||
|
3b9a2479ca | ||
|
915afcbf4d | ||
|
70adaaf6cf | ||
|
a06ddc7d0a | ||
|
ea4f6db7a9 | ||
|
5afe301750 | ||
|
73d24bf13f | ||
|
bf2cd90acf | ||
|
b224157c53 | ||
|
4654b690fe | ||
|
87f31652d7 | ||
|
f836a26001 | ||
|
7ceede1cc6 | ||
|
686cef66ac | ||
|
9118f2271b | ||
|
6cc6894528 | ||
|
5a10da543d | ||
|
bb855a6e27 | ||
|
ee1e71da84 | ||
|
70f83caf1d | ||
|
77894edce9 | ||
|
16b22d2e49 | ||
|
938b404ec7 | ||
|
f9e5657a83 | ||
|
c22d6719d9 | ||
1eb4b0334c | |||
|
95d8811bcb | ||
216899e0d9 | |||
23df869676 | |||
|
25779e6c0c | ||
|
4ff1eb0179 | ||
|
40d7f35a8e | ||
|
7177f5944b | ||
|
9faebd75a0 | ||
|
9da2c8f5d9 | ||
|
bc34559de0 | ||
|
58eb0d0b5c | ||
|
a97a5ee9b5 | ||
|
d103367b43 | ||
|
8cdeec91c9 | ||
|
9b36d831c6 | ||
|
cb24914793 | ||
|
9d7264891c | ||
|
1a1a696c53 | ||
|
1df131c204 | ||
|
cd1c6eb816 | ||
|
8d66542067 |
@ -1,79 +0,0 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
|
||||||
|
|
||||||
import static it.cavallium.data.generator.plugin.DataModel.fixType;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public final class ParsedClass {
|
|
||||||
|
|
||||||
public String stringRepresenter;
|
|
||||||
|
|
||||||
public LinkedHashMap<String, String> data;
|
|
||||||
public List<TransformationConfiguration> differentThanPrev;
|
|
||||||
public boolean differentThanNext;
|
|
||||||
|
|
||||||
public ParsedClass(ClassConfiguration baseTypesData) {
|
|
||||||
this.stringRepresenter = baseTypesData.stringRepresenter;
|
|
||||||
if (baseTypesData.data != null) {
|
|
||||||
this.data = baseTypesData.data.entrySet().stream()
|
|
||||||
.map(e -> Map.entry(e.getKey(), fixType(e.getValue())))
|
|
||||||
.collect(Collectors.toMap(Entry::getKey, Entry::getValue, (a, b) -> {
|
|
||||||
throw new IllegalStateException();
|
|
||||||
}, LinkedHashMap::new));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ParsedClass() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStringRepresenter() {
|
|
||||||
return stringRepresenter;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LinkedHashMap<String, String> getData() {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (o == null || getClass() != o.getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
ParsedClass that = (ParsedClass) o;
|
|
||||||
return Objects.equals(stringRepresenter, that.stringRepresenter) && Objects.equals(data, that.data);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int hash = 0;
|
|
||||||
hash += ConfigUtils.hashCode(stringRepresenter);
|
|
||||||
hash += ConfigUtils.hashCode(data);
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ParsedClass copy() {
|
|
||||||
var cc = new ParsedClass();
|
|
||||||
if (this.stringRepresenter != null) cc.stringRepresenter = this.stringRepresenter;
|
|
||||||
cc.data = new LinkedHashMap<>(data);
|
|
||||||
cc.differentThanNext = differentThanNext;
|
|
||||||
cc.differentThanPrev = differentThanPrev;
|
|
||||||
return cc;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addDifferentThanPrev(TransformationConfiguration transformation) {
|
|
||||||
if (differentThanPrev == null) {
|
|
||||||
differentThanPrev = new ArrayList<>();
|
|
||||||
}
|
|
||||||
differentThanPrev.add(transformation);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
package it.cavallium.data.generator;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
public interface DataInitializer<T> {
|
|
||||||
|
|
||||||
@NotNull T initialize() throws IOException;
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
package it.cavallium.data.generator;
|
|
||||||
|
|
||||||
import java.io.DataInput;
|
|
||||||
import java.io.DataOutput;
|
|
||||||
import java.io.IOException;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
public interface DataSerializer<T> {
|
|
||||||
|
|
||||||
void serialize(DataOutput dataOutput, @NotNull T data) throws IOException;
|
|
||||||
|
|
||||||
@NotNull T deserialize(DataInput dataInput) throws IOException;
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
package it.cavallium.data.generator;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
public interface DataUpgrader<T, U> {
|
|
||||||
|
|
||||||
@NotNull U upgrade(@NotNull T data) throws IOException;
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
package it.cavallium.data.generator;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
public interface NativeNullable<T> {
|
|
||||||
|
|
||||||
boolean isEmpty();
|
|
||||||
|
|
||||||
default boolean isPresent() {
|
|
||||||
return !isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
T orElse(@NotNull T defaultValue);
|
|
||||||
|
|
||||||
@NotNull NativeNullable<? extends T> or(@NotNull NativeNullable<? extends T> fallback);
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
T getNullable();
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
T getNullable(@Nullable T defaultValue);
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
package it.cavallium.data.generator.nativedata;
|
|
||||||
|
|
||||||
import it.cavallium.data.generator.DataSerializer;
|
|
||||||
import java.io.DataInput;
|
|
||||||
import java.io.DataOutput;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
public class ArrayInt52Serializer implements DataSerializer< List<Int52>> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void serialize(DataOutput dataOutput, List<Int52> data) throws IOException {
|
|
||||||
dataOutput.writeInt(data.size());
|
|
||||||
for (Int52 datum : data) {
|
|
||||||
Int52Serializer.INSTANCE.serialize(dataOutput, datum);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public List<Int52> deserialize(DataInput dataInput) throws IOException {
|
|
||||||
var data = new Int52[dataInput.readInt()];
|
|
||||||
for (int i = 0; i < data.length; i++) {
|
|
||||||
data[i] = Int52Serializer.INSTANCE.deserialize(dataInput);
|
|
||||||
}
|
|
||||||
return List.of(data);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
package it.cavallium.data.generator.nativedata;
|
|
||||||
|
|
||||||
import it.cavallium.data.generator.DataSerializer;
|
|
||||||
import java.io.DataInput;
|
|
||||||
import java.io.DataOutput;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
public class ArrayStringSerializer implements DataSerializer<List<String>> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void serialize(DataOutput dataOutput, @NotNull List<String> data) throws IOException {
|
|
||||||
dataOutput.writeInt(data.size());
|
|
||||||
for (int i = 0; i < data.size(); i++) {
|
|
||||||
dataOutput.writeUTF(data.get(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public List<String> deserialize(DataInput dataInput) throws IOException {
|
|
||||||
var data = new String[dataInput.readInt()];
|
|
||||||
for (int i = 0; i < data.length; i++) {
|
|
||||||
data[i] = dataInput.readUTF();
|
|
||||||
}
|
|
||||||
return List.of(data);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,63 +0,0 @@
|
|||||||
package it.cavallium.data.generator.nativedata;
|
|
||||||
|
|
||||||
import it.cavallium.data.generator.DataSerializer;
|
|
||||||
import java.io.DataInput;
|
|
||||||
import java.io.DataOutput;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.CharBuffer;
|
|
||||||
import java.nio.channels.Channels;
|
|
||||||
import java.nio.charset.CharacterCodingException;
|
|
||||||
import java.nio.charset.CharsetDecoder;
|
|
||||||
import java.nio.charset.CharsetEncoder;
|
|
||||||
import java.nio.charset.CodingErrorAction;
|
|
||||||
import java.nio.charset.MalformedInputException;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.nio.charset.UnmappableCharacterException;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
public class StringSerializer implements DataSerializer<String> {
|
|
||||||
|
|
||||||
public static final StringSerializer INSTANCE = new StringSerializer();
|
|
||||||
private static final ThreadLocal<CharsetEncoder> UTF8_ENCODER = ThreadLocal.withInitial(() -> StandardCharsets.UTF_8
|
|
||||||
.newEncoder()
|
|
||||||
.onUnmappableCharacter(CodingErrorAction.REPORT)
|
|
||||||
.onMalformedInput(CodingErrorAction.REPORT)
|
|
||||||
);
|
|
||||||
private static final ThreadLocal<CharsetDecoder> UTF8_DECODER = ThreadLocal.withInitial(() -> StandardCharsets.UTF_8
|
|
||||||
.newDecoder()
|
|
||||||
.onUnmappableCharacter(CodingErrorAction.REPORT)
|
|
||||||
.onMalformedInput(CodingErrorAction.REPORT)
|
|
||||||
);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void serialize(DataOutput dataOutput, @NotNull String data) throws IOException {
|
|
||||||
try {
|
|
||||||
var bytes = UTF8_ENCODER.get().reset().encode(CharBuffer.wrap(data));
|
|
||||||
|
|
||||||
dataOutput.writeInt(bytes.limit());
|
|
||||||
if (bytes.hasArray()) {
|
|
||||||
dataOutput.write(bytes.array(), bytes.arrayOffset(), bytes.limit());
|
|
||||||
} else {
|
|
||||||
while (bytes.hasRemaining()) {
|
|
||||||
dataOutput.writeByte(bytes.get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IllegalStateException | CharacterCodingException ex) {
|
|
||||||
throw new IOException("Can't encode this UTF-8 string", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public String deserialize(DataInput dataInput) throws IOException {
|
|
||||||
byte[] bytes = new byte[dataInput.readInt()];
|
|
||||||
dataInput.readFully(bytes);
|
|
||||||
try {
|
|
||||||
CharBuffer decoded = UTF8_DECODER.get().reset().decode(ByteBuffer.wrap(bytes));
|
|
||||||
return decoded.toString();
|
|
||||||
} catch (IllegalStateException | CharacterCodingException ex) {
|
|
||||||
throw new IOException("Can't decode this UTF-8 string", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
package it.cavallium.data.generator.nativedata;
|
|
||||||
|
|
||||||
import it.cavallium.data.generator.DataUpgrader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class UpgradeUtil {
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static <A, B> List<B> upgradeArray(List<A> from, DataUpgrader<A, B> upgrader)
|
|
||||||
throws IOException {
|
|
||||||
Object[] array;
|
|
||||||
if (from instanceof ImmutableWrappedArrayList<A> immutableWrappedArrayList) {
|
|
||||||
array = immutableWrappedArrayList.a;
|
|
||||||
} else {
|
|
||||||
array = from.toArray();
|
|
||||||
}
|
|
||||||
for (int i = 0; i < array.length; i++) {
|
|
||||||
array[i] = (B) upgrader.upgrade((A) array[i]);
|
|
||||||
}
|
|
||||||
return (ImmutableWrappedArrayList<B>) new ImmutableWrappedArrayList<>(array);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <A, B> B upgradeNullable(A nullableValue, DataUpgrader<A, B> upgrader) throws IOException {
|
|
||||||
if (nullableValue == null) {
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
return upgrader.upgrade(nullableValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
module data.generator.runtime {
|
|
||||||
exports it.cavallium.data.generator.nativedata;
|
|
||||||
exports it.cavallium.data.generator;
|
|
||||||
requires org.jetbrains.annotations;
|
|
||||||
requires it.unimi.dsi.fastutil;
|
|
||||||
}
|
|
@ -5,18 +5,18 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<name>Data generator</name>
|
<name>Data generator</name>
|
||||||
<artifactId>data-generator-plugin</artifactId>
|
<artifactId>datagen-plugin</artifactId>
|
||||||
<version>${revision}</version>
|
<version>${revision}</version>
|
||||||
<packaging>maven-plugin</packaging>
|
<packaging>maven-plugin</packaging>
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>it.cavallium</groupId>
|
<groupId>it.cavallium</groupId>
|
||||||
<version>${revision}</version>
|
<version>${revision}</version>
|
||||||
<artifactId>data-generator</artifactId>
|
<artifactId>datagen-parent</artifactId>
|
||||||
</parent>
|
</parent>
|
||||||
<properties>
|
<properties>
|
||||||
<revision>1.0.0.0-SNAPSHOT</revision>
|
<revision>1.0.0.0-SNAPSHOT</revision>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<fastutil.version>8.5.11</fastutil.version>
|
<fastutil.version>8.5.12</fastutil.version>
|
||||||
<maven.version>4.0.0-alpha-3</maven.version>
|
<maven.version>4.0.0-alpha-3</maven.version>
|
||||||
</properties>
|
</properties>
|
||||||
<repositories>
|
<repositories>
|
||||||
@ -30,6 +30,11 @@
|
|||||||
<name>MCHV Snapshot Apache Maven Packages</name>
|
<name>MCHV Snapshot Apache Maven Packages</name>
|
||||||
<url>https://mvn.mchv.eu/repository/mchv-snapshot</url>
|
<url>https://mvn.mchv.eu/repository/mchv-snapshot</url>
|
||||||
</repository>
|
</repository>
|
||||||
|
<repository>
|
||||||
|
<id>fabric</id>
|
||||||
|
<name>FabricMC repository</name>
|
||||||
|
<url>https://maven.fabricmc.net/</url>
|
||||||
|
</repository>
|
||||||
</repositories>
|
</repositories>
|
||||||
<distributionManagement>
|
<distributionManagement>
|
||||||
<repository>
|
<repository>
|
||||||
@ -54,7 +59,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-plugin-plugin</artifactId>
|
<artifactId>maven-plugin-plugin</artifactId>
|
||||||
<version>3.7.1</version>
|
<version>3.10.1</version>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.maven.plugin-tools</groupId>
|
<groupId>org.apache.maven.plugin-tools</groupId>
|
||||||
@ -77,9 +82,9 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>3.10.1</version>
|
<version>3.11.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<release>17</release>
|
<release>21</release>
|
||||||
<encoding>UTF-8</encoding>
|
<encoding>UTF-8</encoding>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
@ -180,17 +185,17 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.yaml</groupId>
|
<groupId>org.yaml</groupId>
|
||||||
<artifactId>snakeyaml</artifactId>
|
<artifactId>snakeyaml</artifactId>
|
||||||
<version>1.33</version>
|
<version>2.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.squareup</groupId>
|
<groupId>net.fabricmc</groupId>
|
||||||
<artifactId>javapoet</artifactId>
|
<artifactId>javapoet</artifactId>
|
||||||
<version>1.14.0-records</version>
|
<version>0.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jetbrains</groupId>
|
<groupId>org.jetbrains</groupId>
|
||||||
<artifactId>annotations</artifactId>
|
<artifactId>annotations</artifactId>
|
||||||
<version>23.1.0</version>
|
<version>24.0.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>it.unimi.dsi</groupId>
|
<groupId>it.unimi.dsi</groupId>
|
||||||
@ -212,7 +217,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.maven.plugin-tools</groupId>
|
<groupId>org.apache.maven.plugin-tools</groupId>
|
||||||
<artifactId>maven-plugin-annotations</artifactId>
|
<artifactId>maven-plugin-annotations</artifactId>
|
||||||
<version>3.7.1</version>
|
<version>3.8.1</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -228,7 +233,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.logging.log4j</groupId>
|
<groupId>org.apache.logging.log4j</groupId>
|
||||||
<artifactId>log4j-core</artifactId>
|
<artifactId>log4j-core</artifactId>
|
||||||
<version>2.19.0</version>
|
<version>2.20.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
@ -238,7 +243,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.logging.log4j</groupId>
|
<groupId>org.apache.logging.log4j</groupId>
|
||||||
<artifactId>log4j-slf4j2-impl</artifactId>
|
<artifactId>log4j-slf4j2-impl</artifactId>
|
||||||
<version>2.19.0</version>
|
<version>2.20.0</version>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
@ -264,7 +269,7 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>it.cavallium</groupId>
|
<groupId>it.cavallium</groupId>
|
||||||
<artifactId>data-generator-runtime</artifactId>
|
<artifactId>datagen</artifactId>
|
||||||
<version>${revision}</version>
|
<version>${revision}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
import static java.nio.file.StandardOpenOption.CREATE;
|
import static java.nio.file.StandardOpenOption.CREATE;
|
||||||
import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;
|
import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;
|
||||||
@ -29,6 +29,7 @@ public abstract class ClassGenerator {
|
|||||||
protected final boolean deepCheckBeforeCreatingNewEqualInstances;
|
protected final boolean deepCheckBeforeCreatingNewEqualInstances;
|
||||||
protected final boolean useRecordBuilders;
|
protected final boolean useRecordBuilders;
|
||||||
protected final boolean generateOldSerializers;
|
protected final boolean generateOldSerializers;
|
||||||
|
protected final boolean binaryStrings;
|
||||||
|
|
||||||
public ClassGenerator(ClassGeneratorParams params) {
|
public ClassGenerator(ClassGeneratorParams params) {
|
||||||
this.generatedFilesToDelete = params.generatedFilesToDelete;
|
this.generatedFilesToDelete = params.generatedFilesToDelete;
|
||||||
@ -38,6 +39,7 @@ public abstract class ClassGenerator {
|
|||||||
this.deepCheckBeforeCreatingNewEqualInstances = params.deepCheckBeforeCreatingNewEqualInstances;
|
this.deepCheckBeforeCreatingNewEqualInstances = params.deepCheckBeforeCreatingNewEqualInstances;
|
||||||
this.useRecordBuilders = params.useRecordBuilders;
|
this.useRecordBuilders = params.useRecordBuilders;
|
||||||
this.generateOldSerializers = params.generateOldSerializers;
|
this.generateOldSerializers = params.generateOldSerializers;
|
||||||
|
this.binaryStrings = params.binaryStrings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run() throws IOException {
|
public void run() throws IOException {
|
||||||
@ -89,5 +91,6 @@ public abstract class ClassGenerator {
|
|||||||
Path outPath,
|
Path outPath,
|
||||||
boolean deepCheckBeforeCreatingNewEqualInstances,
|
boolean deepCheckBeforeCreatingNewEqualInstances,
|
||||||
boolean useRecordBuilders,
|
boolean useRecordBuilders,
|
||||||
boolean generateOldSerializers) {}
|
boolean generateOldSerializers,
|
||||||
|
boolean binaryStrings) {}
|
||||||
}
|
}
|
@ -1,8 +1,8 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
import com.squareup.javapoet.CodeBlock;
|
import com.squareup.javapoet.CodeBlock;
|
||||||
import com.squareup.javapoet.TypeName;
|
import com.squareup.javapoet.TypeName;
|
||||||
import it.cavallium.data.generator.plugin.ComputedType.VersionedComputedType;
|
import it.cavallium.datagen.plugin.ComputedType.VersionedComputedType;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@ -12,6 +12,7 @@ public sealed interface ComputedType permits VersionedComputedType, ComputedType
|
|||||||
String getName();
|
String getName();
|
||||||
|
|
||||||
TypeName getJTypeName(String basePackageName);
|
TypeName getJTypeName(String basePackageName);
|
||||||
|
TypeName getJTypeNameGeneric(String basePackageName);
|
||||||
|
|
||||||
TypeName getJSerializerName(String basePackageName);
|
TypeName getJSerializerName(String basePackageName);
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
import com.squareup.javapoet.ClassName;
|
import com.squareup.javapoet.ClassName;
|
||||||
|
|
@ -1,10 +1,10 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
import com.squareup.javapoet.ClassName;
|
import com.squareup.javapoet.ClassName;
|
||||||
import com.squareup.javapoet.CodeBlock;
|
import com.squareup.javapoet.CodeBlock;
|
||||||
import com.squareup.javapoet.ParameterizedTypeName;
|
import com.squareup.javapoet.ParameterizedTypeName;
|
||||||
import com.squareup.javapoet.TypeName;
|
import com.squareup.javapoet.TypeName;
|
||||||
import it.cavallium.data.generator.nativedata.UpgradeUtil;
|
import it.cavallium.datagen.nativedata.UpgradeUtil;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@ -71,6 +71,11 @@ public final class ComputedTypeArrayFixed implements ComputedTypeArray {
|
|||||||
computedTypeSupplier.get(baseType).getJTypeName(basePackageName));
|
computedTypeSupplier.get(baseType).getJTypeName(basePackageName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TypeName getJTypeNameGeneric(String basePackageName) {
|
||||||
|
return getJTypeName(basePackageName);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClassName getJSerializerName(String basePackageName) {
|
public ClassName getJSerializerName(String basePackageName) {
|
||||||
return ClassName.get(currentVersion.getSerializersPackage(basePackageName), "Array" + baseType + "Serializer");
|
return ClassName.get(currentVersion.getSerializersPackage(basePackageName), "Array" + baseType + "Serializer");
|
@ -1,19 +1,9 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
import com.squareup.javapoet.ClassName;
|
import com.squareup.javapoet.ClassName;
|
||||||
import com.squareup.javapoet.ParameterizedTypeName;
|
import com.squareup.javapoet.ParameterizedTypeName;
|
||||||
import com.squareup.javapoet.TypeName;
|
import com.squareup.javapoet.TypeName;
|
||||||
import it.cavallium.data.generator.nativedata.ArrayInt52Serializer;
|
import it.cavallium.datagen.nativedata.*;
|
||||||
import it.cavallium.data.generator.nativedata.ArrayStringSerializer;
|
|
||||||
import it.cavallium.data.generator.nativedata.ArraybooleanSerializer;
|
|
||||||
import it.cavallium.data.generator.nativedata.ArraybyteSerializer;
|
|
||||||
import it.cavallium.data.generator.nativedata.ArraycharSerializer;
|
|
||||||
import it.cavallium.data.generator.nativedata.ArraydoubleSerializer;
|
|
||||||
import it.cavallium.data.generator.nativedata.ArrayfloatSerializer;
|
|
||||||
import it.cavallium.data.generator.nativedata.ArrayintSerializer;
|
|
||||||
import it.cavallium.data.generator.nativedata.ArraylongSerializer;
|
|
||||||
import it.cavallium.data.generator.nativedata.ArrayshortSerializer;
|
|
||||||
import it.cavallium.data.generator.nativedata.Serializers;
|
|
||||||
import it.unimi.dsi.fastutil.booleans.BooleanList;
|
import it.unimi.dsi.fastutil.booleans.BooleanList;
|
||||||
import it.unimi.dsi.fastutil.bytes.ByteList;
|
import it.unimi.dsi.fastutil.bytes.ByteList;
|
||||||
import it.unimi.dsi.fastutil.chars.CharList;
|
import it.unimi.dsi.fastutil.chars.CharList;
|
||||||
@ -29,13 +19,15 @@ import java.util.stream.Stream;
|
|||||||
public final class ComputedTypeArrayNative implements ComputedTypeArray {
|
public final class ComputedTypeArrayNative implements ComputedTypeArray {
|
||||||
|
|
||||||
private final String baseType;
|
private final String baseType;
|
||||||
|
private final boolean binaryStrings;
|
||||||
|
|
||||||
private ComputedTypeNative computedChild;
|
private ComputedTypeNative computedChild;
|
||||||
private final ComputedTypeSupplier computedTypeSupplier;
|
private final ComputedTypeSupplier computedTypeSupplier;
|
||||||
|
|
||||||
public ComputedTypeArrayNative(String baseType, ComputedTypeSupplier computedTypeSupplier) {
|
public ComputedTypeArrayNative(String baseType, ComputedTypeSupplier computedTypeSupplier, boolean binaryStrings) {
|
||||||
this.baseType = baseType;
|
this.baseType = baseType;
|
||||||
this.computedTypeSupplier = computedTypeSupplier;
|
this.computedTypeSupplier = computedTypeSupplier;
|
||||||
|
this.binaryStrings = binaryStrings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ComputedType getBase() {
|
public ComputedType getBase() {
|
||||||
@ -96,6 +88,11 @@ public final class ComputedTypeArrayNative implements ComputedTypeArray {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TypeName getJTypeNameGeneric(String basePackageName) {
|
||||||
|
return getJTypeName(basePackageName);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClassName getJSerializerName(String basePackageName) {
|
public ClassName getJSerializerName(String basePackageName) {
|
||||||
return switch (baseType) {
|
return switch (baseType) {
|
||||||
@ -107,7 +104,7 @@ public final class ComputedTypeArrayNative implements ComputedTypeArray {
|
|||||||
case "long" -> ClassName.get(ArraylongSerializer.class);
|
case "long" -> ClassName.get(ArraylongSerializer.class);
|
||||||
case "float" -> ClassName.get(ArrayfloatSerializer.class);
|
case "float" -> ClassName.get(ArrayfloatSerializer.class);
|
||||||
case "double" -> ClassName.get(ArraydoubleSerializer.class);
|
case "double" -> ClassName.get(ArraydoubleSerializer.class);
|
||||||
case "String" -> ClassName.get(ArrayStringSerializer.class);
|
case "String" -> binaryStrings ? ClassName.get(ArrayBinaryStringSerializer.class) : ClassName.get(ArrayStringSerializer.class);
|
||||||
case "Int52" -> ClassName.get(ArrayInt52Serializer.class);
|
case "Int52" -> ClassName.get(ArrayInt52Serializer.class);
|
||||||
default -> throw new UnsupportedOperationException();
|
default -> throw new UnsupportedOperationException();
|
||||||
};
|
};
|
||||||
@ -115,10 +112,14 @@ public final class ComputedTypeArrayNative implements ComputedTypeArray {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldLocation getJSerializerInstance(String basePackageName) {
|
public FieldLocation getJSerializerInstance(String basePackageName) {
|
||||||
|
if (baseType.equals("String") && binaryStrings) {
|
||||||
|
return new FieldLocation(ClassName.get(Serializers.class), "ArrayBinaryStringSerializerInstance");
|
||||||
|
} else {
|
||||||
var className = ClassName.get(Serializers.class);
|
var className = ClassName.get(Serializers.class);
|
||||||
var serializerFieldName = "Array" + baseType + "SerializerInstance";
|
var serializerFieldName = "Array" + baseType + "SerializerInstance";
|
||||||
return new FieldLocation(className, serializerFieldName);
|
return new FieldLocation(className, serializerFieldName);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeName getJUpgraderName(String basePackageName) {
|
public TypeName getJUpgraderName(String basePackageName) {
|
@ -1,11 +1,11 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
import com.squareup.javapoet.ClassName;
|
import com.squareup.javapoet.ClassName;
|
||||||
import com.squareup.javapoet.CodeBlock;
|
import com.squareup.javapoet.CodeBlock;
|
||||||
import com.squareup.javapoet.ParameterizedTypeName;
|
import com.squareup.javapoet.ParameterizedTypeName;
|
||||||
import com.squareup.javapoet.TypeName;
|
import com.squareup.javapoet.TypeName;
|
||||||
import it.cavallium.data.generator.nativedata.UpgradeUtil;
|
import it.cavallium.datagen.nativedata.UpgradeUtil;
|
||||||
import it.cavallium.data.generator.plugin.ComputedType.VersionedComputedType;
|
import it.cavallium.datagen.plugin.ComputedType.VersionedComputedType;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@ -88,6 +88,11 @@ public final class ComputedTypeArrayVersioned implements VersionedComputedType,
|
|||||||
computedTypeSupplier.get(baseType).getJTypeName(basePackageName));
|
computedTypeSupplier.get(baseType).getJTypeName(basePackageName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TypeName getJTypeNameGeneric(String basePackageName) {
|
||||||
|
return getJTypeName(basePackageName);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClassName getJSerializerName(String basePackageName) {
|
public ClassName getJSerializerName(String basePackageName) {
|
||||||
return ClassName.get(baseType.version().getSerializersPackage(basePackageName), "Array" + baseType.type() + "Serializer");
|
return ClassName.get(baseType.version().getSerializersPackage(basePackageName), "Array" + baseType.type() + "Serializer");
|
@ -1,8 +1,9 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
import com.squareup.javapoet.ClassName;
|
import com.squareup.javapoet.ClassName;
|
||||||
import com.squareup.javapoet.CodeBlock;
|
import com.squareup.javapoet.CodeBlock;
|
||||||
import it.cavallium.data.generator.plugin.ComputedType.VersionedComputedType;
|
import com.squareup.javapoet.TypeName;
|
||||||
|
import it.cavallium.datagen.plugin.ComputedType.VersionedComputedType;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@ -101,6 +102,11 @@ public final class ComputedTypeBase implements VersionedComputedType {
|
|||||||
return ClassName.get(getVersion().getDataPackage(basePackageName), type.type());
|
return ClassName.get(getVersion().getDataPackage(basePackageName), type.type());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TypeName getJTypeNameGeneric(String basePackageName) {
|
||||||
|
return getJTypeName(basePackageName);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClassName getJSerializerName(String basePackageName) {
|
public ClassName getJSerializerName(String basePackageName) {
|
||||||
return ClassName.get(type.version().getSerializersPackage(basePackageName), type.type() + "Serializer");
|
return ClassName.get(type.version().getSerializersPackage(basePackageName), type.type() + "Serializer");
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
import com.squareup.javapoet.ClassName;
|
import com.squareup.javapoet.ClassName;
|
||||||
import com.squareup.javapoet.ParameterizedTypeName;
|
import com.squareup.javapoet.ParameterizedTypeName;
|
||||||
@ -64,7 +64,7 @@ public final class ComputedTypeCustom implements ComputedType {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
it.cavallium.data.generator.plugin.ComputedTypeCustom that = (it.cavallium.data.generator.plugin.ComputedTypeCustom) o;
|
ComputedTypeCustom that = (ComputedTypeCustom) o;
|
||||||
|
|
||||||
if (!Objects.equals(type, that.type)) {
|
if (!Objects.equals(type, that.type)) {
|
||||||
return false;
|
return false;
|
||||||
@ -93,6 +93,11 @@ public final class ComputedTypeCustom implements ComputedType {
|
|||||||
return typeName;
|
return typeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TypeName getJTypeNameGeneric(String basePackageName) {
|
||||||
|
return getJTypeName(basePackageName);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeName getJSerializerName(String basePackageName) {
|
public TypeName getJSerializerName(String basePackageName) {
|
||||||
return ClassName.bestGuess(serializer);
|
return ClassName.bestGuess(serializer);
|
@ -1,10 +1,9 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
import com.squareup.javapoet.ClassName;
|
import com.squareup.javapoet.ClassName;
|
||||||
import com.squareup.javapoet.TypeName;
|
import com.squareup.javapoet.TypeName;
|
||||||
import it.cavallium.data.generator.nativedata.Int52Serializer;
|
import it.cavallium.datagen.nativedata.*;
|
||||||
import it.cavallium.data.generator.nativedata.Serializers;
|
|
||||||
import it.cavallium.data.generator.nativedata.StringSerializer;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -16,12 +15,14 @@ public final class ComputedTypeNative implements ComputedType {
|
|||||||
|
|
||||||
private final String type;
|
private final String type;
|
||||||
private final ComputedTypeSupplier computedTypeSupplier;
|
private final ComputedTypeSupplier computedTypeSupplier;
|
||||||
|
private final boolean binaryStrings;
|
||||||
private boolean primitive;
|
private boolean primitive;
|
||||||
|
|
||||||
public ComputedTypeNative(String type, ComputedTypeSupplier computedTypeSupplier) {
|
public ComputedTypeNative(String type, ComputedTypeSupplier computedTypeSupplier, boolean binaryStrings) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.computedTypeSupplier = computedTypeSupplier;
|
this.computedTypeSupplier = computedTypeSupplier;
|
||||||
this.primitive = PRIMITIVE_TYPES.contains(type);
|
this.primitive = PRIMITIVE_TYPES.contains(type);
|
||||||
|
this.binaryStrings = binaryStrings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
@ -31,7 +32,7 @@ public final class ComputedTypeNative implements ComputedType {
|
|||||||
@Override
|
@Override
|
||||||
public TypeName getJTypeName(String basePackageName) {
|
public TypeName getJTypeName(String basePackageName) {
|
||||||
return switch (type) {
|
return switch (type) {
|
||||||
case "String" -> ClassName.get(String.class);
|
case "String" -> binaryStrings ? ClassName.get(BinaryString.class) : ClassName.get(String.class);
|
||||||
case "boolean" -> TypeName.BOOLEAN;
|
case "boolean" -> TypeName.BOOLEAN;
|
||||||
case "short" -> TypeName.SHORT;
|
case "short" -> TypeName.SHORT;
|
||||||
case "char" -> TypeName.CHAR;
|
case "char" -> TypeName.CHAR;
|
||||||
@ -40,15 +41,20 @@ public final class ComputedTypeNative implements ComputedType {
|
|||||||
case "float" -> TypeName.FLOAT;
|
case "float" -> TypeName.FLOAT;
|
||||||
case "double" -> TypeName.DOUBLE;
|
case "double" -> TypeName.DOUBLE;
|
||||||
case "byte" -> TypeName.BYTE;
|
case "byte" -> TypeName.BYTE;
|
||||||
case "Int52" -> ClassName.get(it.cavallium.data.generator.nativedata.Int52.class);
|
case "Int52" -> ClassName.get(Int52.class);
|
||||||
default -> throw new UnsupportedOperationException(type + " is not a known native type");
|
default -> throw new UnsupportedOperationException(type + " is not a known native type");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TypeName getJTypeNameGeneric(String basePackageName) {
|
||||||
|
return getJTypeName(basePackageName);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeName getJSerializerName(String basePackageName) {
|
public TypeName getJSerializerName(String basePackageName) {
|
||||||
return switch (type) {
|
return switch (type) {
|
||||||
case "String" -> ClassName.get(StringSerializer.class);
|
case "String" -> binaryStrings ? ClassName.get(BinaryStringSerializer.class) : ClassName.get(StringSerializer.class);
|
||||||
case "boolean", "byte", "short", "char", "int", "long", "float", "double" ->
|
case "boolean", "byte", "short", "char", "int", "long", "float", "double" ->
|
||||||
throw new UnsupportedOperationException("Type " + type
|
throw new UnsupportedOperationException("Type " + type
|
||||||
+ " is a native type, so it doesn't have a serializer");
|
+ " is a native type, so it doesn't have a serializer");
|
||||||
@ -59,8 +65,12 @@ public final class ComputedTypeNative implements ComputedType {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldLocation getJSerializerInstance(String basePackageName) {
|
public FieldLocation getJSerializerInstance(String basePackageName) {
|
||||||
|
if (type.equals("String") && binaryStrings) {
|
||||||
|
return new FieldLocation(ClassName.get(Serializers.class), "BinaryStringSerializerInstance");
|
||||||
|
} else {
|
||||||
return new FieldLocation(ClassName.get(Serializers.class), type + "SerializerInstance");
|
return new FieldLocation(ClassName.get(Serializers.class), type + "SerializerInstance");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeName getJUpgraderName(String basePackageName) {
|
public TypeName getJUpgraderName(String basePackageName) {
|
||||||
@ -81,7 +91,7 @@ public final class ComputedTypeNative implements ComputedType {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
it.cavallium.data.generator.plugin.ComputedTypeNative that = (it.cavallium.data.generator.plugin.ComputedTypeNative) o;
|
ComputedTypeNative that = (ComputedTypeNative) o;
|
||||||
|
|
||||||
return Objects.equals(type, that.type);
|
return Objects.equals(type, that.type);
|
||||||
}
|
}
|
||||||
@ -101,10 +111,10 @@ public final class ComputedTypeNative implements ComputedType {
|
|||||||
return computedTypeSupplier.getDependents(getName());
|
return computedTypeSupplier.getDependents(getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<it.cavallium.data.generator.plugin.ComputedTypeNative> get(ComputedTypeSupplier computedTypeSupplier) {
|
public static List<ComputedTypeNative> get(ComputedTypeSupplier computedTypeSupplier, boolean binaryStrings) {
|
||||||
return Stream
|
return Stream
|
||||||
.of("String", "boolean", "short", "char", "int", "long", "float", "double", "byte", "Int52")
|
.of("String", "boolean", "short", "char", "int", "long", "float", "double", "byte", "Int52")
|
||||||
.map(name -> new it.cavallium.data.generator.plugin.ComputedTypeNative(name, computedTypeSupplier))
|
.map(name -> new ComputedTypeNative(name, computedTypeSupplier, binaryStrings))
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
import com.squareup.javapoet.ClassName;
|
import com.squareup.javapoet.ClassName;
|
||||||
|
|
@ -1,9 +1,11 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
import com.squareup.javapoet.ClassName;
|
import com.squareup.javapoet.ClassName;
|
||||||
import com.squareup.javapoet.CodeBlock;
|
import com.squareup.javapoet.CodeBlock;
|
||||||
|
import com.squareup.javapoet.ParameterizedTypeName;
|
||||||
import com.squareup.javapoet.TypeName;
|
import com.squareup.javapoet.TypeName;
|
||||||
import it.cavallium.data.generator.nativedata.UpgradeUtil;
|
import it.cavallium.datagen.TypedNullable;
|
||||||
|
import it.cavallium.datagen.nativedata.UpgradeUtil;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@ -68,11 +70,21 @@ public final class ComputedTypeNullableFixed implements ComputedTypeNullable {
|
|||||||
return getJTypeNameOfVersion(currentVersion, basePackageName);
|
return getJTypeNameOfVersion(currentVersion, basePackageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TypeName getJTypeNameGeneric(String basePackageName) {
|
||||||
|
return getJTypeNameGenericOfVersion(currentVersion, basePackageName);
|
||||||
|
}
|
||||||
|
|
||||||
private TypeName getJTypeNameOfVersion(ComputedVersion version, String basePackageName) {
|
private TypeName getJTypeNameOfVersion(ComputedVersion version, String basePackageName) {
|
||||||
return ClassName.get(version.getDataNullablesPackage(basePackageName),
|
return ClassName.get(version.getDataNullablesPackage(basePackageName),
|
||||||
"Nullable" + baseType);
|
"Nullable" + baseType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private TypeName getJTypeNameGenericOfVersion(ComputedVersion version, String basePackageName) {
|
||||||
|
return ParameterizedTypeName.get(ClassName.get(TypedNullable.class),
|
||||||
|
ClassName.get(version.getDataPackage(basePackageName), baseType));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClassName getJSerializerName(String basePackageName) {
|
public ClassName getJSerializerName(String basePackageName) {
|
||||||
return ClassName.get(currentVersion.getSerializersPackage(basePackageName),
|
return ClassName.get(currentVersion.getSerializersPackage(basePackageName),
|
||||||
@ -102,7 +114,7 @@ public final class ComputedTypeNullableFixed implements ComputedTypeNullable {
|
|||||||
var upgraderInstance = getBase().getJUpgraderInstance(basePackageName);
|
var upgraderInstance = getBase().getJUpgraderInstance(basePackageName);
|
||||||
builder.add("new $T($T.upgradeNullable(", next.getJTypeName(basePackageName), UpgradeUtil.class);
|
builder.add("new $T($T.upgradeNullable(", next.getJTypeName(basePackageName), UpgradeUtil.class);
|
||||||
builder.add(content);
|
builder.add(content);
|
||||||
builder.add(".value(), $T.$N)", upgraderInstance.className(), upgraderInstance.fieldName());
|
builder.add(".getNullable(), $T.$N)", upgraderInstance.className(), upgraderInstance.fieldName());
|
||||||
builder.add(")");
|
builder.add(")");
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
@ -1,28 +1,9 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
import com.squareup.javapoet.ClassName;
|
import com.squareup.javapoet.ClassName;
|
||||||
import com.squareup.javapoet.TypeName;
|
import com.squareup.javapoet.TypeName;
|
||||||
import it.cavallium.data.generator.nativedata.NullableInt52;
|
import it.cavallium.datagen.nativedata.*;
|
||||||
import it.cavallium.data.generator.nativedata.NullableInt52Serializer;
|
|
||||||
import it.cavallium.data.generator.nativedata.NullableString;
|
|
||||||
import it.cavallium.data.generator.nativedata.NullableStringSerializer;
|
|
||||||
import it.cavallium.data.generator.nativedata.Nullableboolean;
|
|
||||||
import it.cavallium.data.generator.nativedata.NullablebooleanSerializer;
|
|
||||||
import it.cavallium.data.generator.nativedata.Nullablebyte;
|
|
||||||
import it.cavallium.data.generator.nativedata.NullablebyteSerializer;
|
|
||||||
import it.cavallium.data.generator.nativedata.Nullablechar;
|
|
||||||
import it.cavallium.data.generator.nativedata.NullablecharSerializer;
|
|
||||||
import it.cavallium.data.generator.nativedata.Nullabledouble;
|
|
||||||
import it.cavallium.data.generator.nativedata.NullabledoubleSerializer;
|
|
||||||
import it.cavallium.data.generator.nativedata.Nullablefloat;
|
|
||||||
import it.cavallium.data.generator.nativedata.NullablefloatSerializer;
|
|
||||||
import it.cavallium.data.generator.nativedata.Nullableint;
|
|
||||||
import it.cavallium.data.generator.nativedata.NullableintSerializer;
|
|
||||||
import it.cavallium.data.generator.nativedata.Nullablelong;
|
|
||||||
import it.cavallium.data.generator.nativedata.NullablelongSerializer;
|
|
||||||
import it.cavallium.data.generator.nativedata.Nullableshort;
|
|
||||||
import it.cavallium.data.generator.nativedata.NullableshortSerializer;
|
|
||||||
import it.cavallium.data.generator.nativedata.Serializers;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@ -30,14 +11,16 @@ public final class ComputedTypeNullableNative implements ComputedTypeNullable {
|
|||||||
|
|
||||||
private final String baseType;
|
private final String baseType;
|
||||||
private final ComputedVersion latestVersion;
|
private final ComputedVersion latestVersion;
|
||||||
|
private final boolean binaryStrings;
|
||||||
|
|
||||||
private ComputedTypeNative computedChild;
|
private ComputedTypeNative computedChild;
|
||||||
private final ComputedTypeSupplier computedTypeSupplier;
|
private final ComputedTypeSupplier computedTypeSupplier;
|
||||||
|
|
||||||
public ComputedTypeNullableNative(String baseType, ComputedVersion latestVersion, ComputedTypeSupplier computedTypeSupplier) {
|
public ComputedTypeNullableNative(String baseType, ComputedVersion latestVersion, ComputedTypeSupplier computedTypeSupplier, boolean binaryStrings) {
|
||||||
this.baseType = baseType;
|
this.baseType = baseType;
|
||||||
this.latestVersion = latestVersion;
|
this.latestVersion = latestVersion;
|
||||||
this.computedTypeSupplier = computedTypeSupplier;
|
this.computedTypeSupplier = computedTypeSupplier;
|
||||||
|
this.binaryStrings = binaryStrings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ComputedTypeNative getBase() {
|
public ComputedTypeNative getBase() {
|
||||||
@ -93,12 +76,17 @@ public final class ComputedTypeNullableNative implements ComputedTypeNullable {
|
|||||||
case "long" -> ClassName.get(Nullablelong.class);
|
case "long" -> ClassName.get(Nullablelong.class);
|
||||||
case "float" -> ClassName.get(Nullablefloat.class);
|
case "float" -> ClassName.get(Nullablefloat.class);
|
||||||
case "double" -> ClassName.get(Nullabledouble.class);
|
case "double" -> ClassName.get(Nullabledouble.class);
|
||||||
case "String" -> ClassName.get(NullableString.class);
|
case "String" -> binaryStrings ? ClassName.get(NullableBinaryString.class) : ClassName.get(NullableString.class);
|
||||||
case "Int52" -> ClassName.get(NullableInt52.class);
|
case "Int52" -> ClassName.get(NullableInt52.class);
|
||||||
default -> ClassName.get(latestVersion.getDataNullablesPackage(basePackageName), "Nullable" + baseType);
|
default -> ClassName.get(latestVersion.getDataNullablesPackage(basePackageName), "Nullable" + baseType);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TypeName getJTypeNameGeneric(String basePackageName) {
|
||||||
|
return getJTypeName(basePackageName);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClassName getJSerializerName(String basePackageName) {
|
public ClassName getJSerializerName(String basePackageName) {
|
||||||
return switch (baseType) {
|
return switch (baseType) {
|
||||||
@ -110,7 +98,7 @@ public final class ComputedTypeNullableNative implements ComputedTypeNullable {
|
|||||||
case "long" -> ClassName.get(NullablelongSerializer.class);
|
case "long" -> ClassName.get(NullablelongSerializer.class);
|
||||||
case "float" -> ClassName.get(NullablefloatSerializer.class);
|
case "float" -> ClassName.get(NullablefloatSerializer.class);
|
||||||
case "double" -> ClassName.get(NullabledoubleSerializer.class);
|
case "double" -> ClassName.get(NullabledoubleSerializer.class);
|
||||||
case "String" -> ClassName.get(NullableStringSerializer.class);
|
case "String" -> binaryStrings ? ClassName.get(NullableBinaryStringSerializer.class) : ClassName.get(NullableStringSerializer.class);
|
||||||
case "Int52" -> ClassName.get(NullableInt52Serializer.class);
|
case "Int52" -> ClassName.get(NullableInt52Serializer.class);
|
||||||
default -> throw new UnsupportedOperationException();
|
default -> throw new UnsupportedOperationException();
|
||||||
};
|
};
|
||||||
@ -118,6 +106,9 @@ public final class ComputedTypeNullableNative implements ComputedTypeNullable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldLocation getJSerializerInstance(String basePackageName) {
|
public FieldLocation getJSerializerInstance(String basePackageName) {
|
||||||
|
if (baseType.equals("String") && binaryStrings) {
|
||||||
|
return new FieldLocation(ClassName.get(Serializers.class), "NullableBinaryStringSerializerInstance");
|
||||||
|
} else {
|
||||||
var className = switch (baseType) {
|
var className = switch (baseType) {
|
||||||
case "boolean", "byte", "short", "char", "int", "long", "float", "double", "String", "Int52" ->
|
case "boolean", "byte", "short", "char", "int", "long", "float", "double", "String", "Int52" ->
|
||||||
ClassName.get(Serializers.class);
|
ClassName.get(Serializers.class);
|
||||||
@ -126,6 +117,7 @@ public final class ComputedTypeNullableNative implements ComputedTypeNullable {
|
|||||||
var serializerFieldName = "Nullable" + baseType + "SerializerInstance";
|
var serializerFieldName = "Nullable" + baseType + "SerializerInstance";
|
||||||
return new FieldLocation(className, serializerFieldName);
|
return new FieldLocation(className, serializerFieldName);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeName getJUpgraderName(String basePackageName) {
|
public TypeName getJUpgraderName(String basePackageName) {
|
@ -1,10 +1,12 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
import com.squareup.javapoet.ClassName;
|
import com.squareup.javapoet.ClassName;
|
||||||
import com.squareup.javapoet.CodeBlock;
|
import com.squareup.javapoet.CodeBlock;
|
||||||
|
import com.squareup.javapoet.ParameterizedTypeName;
|
||||||
import com.squareup.javapoet.TypeName;
|
import com.squareup.javapoet.TypeName;
|
||||||
import it.cavallium.data.generator.nativedata.UpgradeUtil;
|
import it.cavallium.datagen.TypedNullable;
|
||||||
import it.cavallium.data.generator.plugin.ComputedType.VersionedComputedType;
|
import it.cavallium.datagen.nativedata.UpgradeUtil;
|
||||||
|
import it.cavallium.datagen.plugin.ComputedType.VersionedComputedType;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@ -81,11 +83,21 @@ public final class ComputedTypeNullableVersioned implements ComputedTypeNullable
|
|||||||
return getJTypeNameOfVersion(baseType.version(), basePackageName);
|
return getJTypeNameOfVersion(baseType.version(), basePackageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TypeName getJTypeNameGeneric(String basePackageName) {
|
||||||
|
return getJTypeNameGenericOfVersion(baseType.version(), basePackageName);
|
||||||
|
}
|
||||||
|
|
||||||
private TypeName getJTypeNameOfVersion(ComputedVersion version, String basePackageName) {
|
private TypeName getJTypeNameOfVersion(ComputedVersion version, String basePackageName) {
|
||||||
return ClassName.get(version.getDataNullablesPackage(basePackageName),
|
return ClassName.get(version.getDataNullablesPackage(basePackageName),
|
||||||
"Nullable" + baseType.type());
|
"Nullable" + baseType.type());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private TypeName getJTypeNameGenericOfVersion(ComputedVersion version, String basePackageName) {
|
||||||
|
return ParameterizedTypeName.get(ClassName.get(TypedNullable.class),
|
||||||
|
ClassName.get(version.getDataPackage(basePackageName), baseType.type()));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClassName getJSerializerName(String basePackageName) {
|
public ClassName getJSerializerName(String basePackageName) {
|
||||||
return ClassName.get(baseType.version().getSerializersPackage(basePackageName),
|
return ClassName.get(baseType.version().getSerializersPackage(basePackageName),
|
||||||
@ -115,7 +127,7 @@ public final class ComputedTypeNullableVersioned implements ComputedTypeNullable
|
|||||||
var upgraderInstance = getBase().getJUpgraderInstance(basePackageName);
|
var upgraderInstance = getBase().getJUpgraderInstance(basePackageName);
|
||||||
builder.add("new $T($T.upgradeNullable(", next.getJTypeName(basePackageName), UpgradeUtil.class);
|
builder.add("new $T($T.upgradeNullable(", next.getJTypeName(basePackageName), UpgradeUtil.class);
|
||||||
builder.add(content);
|
builder.add(content);
|
||||||
builder.add(".value(), $T.$N)", upgraderInstance.className(), upgraderInstance.fieldName());
|
builder.add(".getNullable(), $T.$N)", upgraderInstance.className(), upgraderInstance.fieldName());
|
||||||
builder.add(")");
|
builder.add(")");
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
@ -1,8 +1,9 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
import com.squareup.javapoet.ClassName;
|
import com.squareup.javapoet.ClassName;
|
||||||
import com.squareup.javapoet.CodeBlock;
|
import com.squareup.javapoet.CodeBlock;
|
||||||
import it.cavallium.data.generator.plugin.ComputedType.VersionedComputedType;
|
import com.squareup.javapoet.TypeName;
|
||||||
|
import it.cavallium.datagen.plugin.ComputedType.VersionedComputedType;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -33,9 +34,9 @@ public final class ComputedTypeSuper implements VersionedComputedType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public it.cavallium.data.generator.plugin.ComputedTypeSuper withChangeAtVersion(ComputedVersion version,
|
public ComputedTypeSuper withChangeAtVersion(ComputedVersion version,
|
||||||
VersionChangeChecker versionChangeChecker, LinkedHashMap<String, VersionedType> data) {
|
VersionChangeChecker versionChangeChecker, LinkedHashMap<String, VersionedType> data) {
|
||||||
return new it.cavallium.data.generator.plugin.ComputedTypeSuper(type.withVersion(version),
|
return new ComputedTypeSuper(type.withVersion(version),
|
||||||
subTypes.stream().map(subType -> subType.withVersionIfChanged(version, versionChangeChecker)).toList(),
|
subTypes.stream().map(subType -> subType.withVersionIfChanged(version, versionChangeChecker)).toList(),
|
||||||
computedTypeSupplier
|
computedTypeSupplier
|
||||||
);
|
);
|
||||||
@ -62,7 +63,7 @@ public final class ComputedTypeSuper implements VersionedComputedType {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
it.cavallium.data.generator.plugin.ComputedTypeSuper that = (it.cavallium.data.generator.plugin.ComputedTypeSuper) o;
|
ComputedTypeSuper that = (ComputedTypeSuper) o;
|
||||||
|
|
||||||
if (!Objects.equals(type, that.type)) {
|
if (!Objects.equals(type, that.type)) {
|
||||||
return false;
|
return false;
|
||||||
@ -97,6 +98,11 @@ public final class ComputedTypeSuper implements VersionedComputedType {
|
|||||||
return ClassName.get(getVersion().getDataPackage(basePackageName), type.type());
|
return ClassName.get(getVersion().getDataPackage(basePackageName), type.type());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TypeName getJTypeNameGeneric(String basePackageName) {
|
||||||
|
return ClassName.get(getVersion().getDataPackage(basePackageName), type.type());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClassName getJSerializerName(String basePackageName) {
|
public ClassName getJSerializerName(String basePackageName) {
|
||||||
return ClassName.get(type.version().getSerializersPackage(basePackageName), type.type() + "Serializer");
|
return ClassName.get(type.version().getSerializersPackage(basePackageName), type.type() + "Serializer");
|
@ -1,8 +1,7 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
@ -1,11 +1,9 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
import static it.cavallium.data.generator.plugin.DataModel.joinPackage;
|
import static it.cavallium.datagen.plugin.DataModel.joinPackage;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.StringJoiner;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public class ComputedVersion implements Comparable<ComputedVersion> {
|
public class ComputedVersion implements Comparable<ComputedVersion> {
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
@ -1,9 +1,9 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
import static java.util.Objects.requireNonNull;
|
import static java.util.Objects.requireNonNull;
|
||||||
import static java.util.function.Function.identity;
|
import static java.util.function.Function.identity;
|
||||||
|
|
||||||
import it.cavallium.data.generator.plugin.ComputedType.VersionedComputedType;
|
import it.cavallium.datagen.plugin.ComputedType.VersionedComputedType;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
@ -63,7 +63,8 @@ public class DataModel {
|
|||||||
Map<String, ClassConfiguration> baseTypesData,
|
Map<String, ClassConfiguration> baseTypesData,
|
||||||
Map<String, Set<String>> superTypesData,
|
Map<String, Set<String>> superTypesData,
|
||||||
Map<String, CustomTypesConfiguration> customTypesData,
|
Map<String, CustomTypesConfiguration> customTypesData,
|
||||||
Map<String, VersionConfiguration> rawVersions) {
|
Map<String, VersionConfiguration> rawVersions,
|
||||||
|
boolean binaryStrings) {
|
||||||
|
|
||||||
this.hash = hash;
|
this.hash = hash;
|
||||||
|
|
||||||
@ -159,7 +160,7 @@ public class DataModel {
|
|||||||
.stream()
|
.stream()
|
||||||
.filter(x -> x.size() > 1)
|
.filter(x -> x.size() > 1)
|
||||||
.forEach(x -> {
|
.forEach(x -> {
|
||||||
var type = x.get(0);
|
var type = x.getFirst();
|
||||||
throw new IllegalArgumentException("Type " + type + " has been defined more than once (check base, super, and custom types)!");
|
throw new IllegalArgumentException("Type " + type + " has been defined more than once (check base, super, and custom types)!");
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -209,19 +210,19 @@ public class DataModel {
|
|||||||
+ t.transformClass);
|
+ t.transformClass);
|
||||||
}
|
}
|
||||||
transformClass.addDifferentThanPrev(transformation);
|
transformClass.addDifferentThanPrev(transformation);
|
||||||
var definition = removeAndGetIndex(transformClass.data, t.from);
|
var definition = transformClass.remove(t.from);
|
||||||
if (definition.isEmpty()) {
|
if (definition.isEmpty()) {
|
||||||
throw new IllegalArgumentException(transformCoordinate + " refers to an unknown field: " + t.from);
|
throw new IllegalArgumentException(transformCoordinate + " refers to an unknown field: " + t.from);
|
||||||
}
|
}
|
||||||
var prevDef = tryInsertAtIndex(transformClass.data,
|
ParsedClass.FieldInfo prevDef = transformClass.insert(
|
||||||
|
Objects.requireNonNullElse(t.index, definition.get().getKey()),
|
||||||
t.to,
|
t.to,
|
||||||
definition.get().getValue(),
|
new ParsedClass.InputFieldInfo(definition.get().getValue().typeName(), List.of())
|
||||||
definition.get().getKey()
|
|
||||||
);
|
);
|
||||||
if (prevDef != null) {
|
if (prevDef != null) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
transformCoordinate + " tries to overwrite the existing field \"" + t.to + "\" of value \""
|
transformCoordinate + " tries to overwrite the existing field \"" + t.to + "\" of value \""
|
||||||
+ prevDef + "\" with the field \"" + t.from + "\" of type \"" + definition.orElse(null) + "\"");
|
+ prevDef.typeName() + "\" with the field \"" + t.from + "\" of type \"" + definition.orElse(null) + "\"");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case "new-data" -> {
|
case "new-data" -> {
|
||||||
@ -235,15 +236,12 @@ public class DataModel {
|
|||||||
if (!allTypes.contains(extractTypeName(t.type))) {
|
if (!allTypes.contains(extractTypeName(t.type))) {
|
||||||
throw new IllegalArgumentException(transformCoordinate + " refers to an unknown type: " + t.type);
|
throw new IllegalArgumentException(transformCoordinate + " refers to an unknown type: " + t.type);
|
||||||
}
|
}
|
||||||
String prevDef;
|
var type = fixType(t.type);
|
||||||
if (t.index != null) {
|
var fieldInfo = new ParsedClass.InputFieldInfo(type, t.getContextParameters());
|
||||||
prevDef = tryInsertAtIndex(transformClass.data, t.to, fixType(t.type), t.index);
|
ParsedClass.FieldInfo prevDef = transformClass.insert(t.index, t.to, fieldInfo);
|
||||||
} else {
|
|
||||||
prevDef = transformClass.data.putIfAbsent(t.to, fixType(t.type));
|
|
||||||
}
|
|
||||||
if (prevDef != null) {
|
if (prevDef != null) {
|
||||||
throw new IllegalArgumentException(transformCoordinate + " tries to overwrite the existing field \""
|
throw new IllegalArgumentException(transformCoordinate + " tries to overwrite the existing field \""
|
||||||
+ t.to + "\" of value \"" + prevDef
|
+ t.to + "\" of value \"" + prevDef.typeName()
|
||||||
+ "\" with the new type \"" + t.type + "\"");
|
+ "\" with the new type \"" + t.type + "\"");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -272,7 +270,7 @@ public class DataModel {
|
|||||||
if (!allTypes.contains(extractTypeName(t.type))) {
|
if (!allTypes.contains(extractTypeName(t.type))) {
|
||||||
throw new IllegalArgumentException(transformCoordinate + " refers to an unknown type: " + t.type);
|
throw new IllegalArgumentException(transformCoordinate + " refers to an unknown type: " + t.type);
|
||||||
}
|
}
|
||||||
String prevDefinition = transformClass.data.replace(t.from, fixType(t.type));
|
var prevDefinition = transformClass.replace(t.from, new ParsedClass.InputFieldInfo(fixType(t.type), t.getContextParameters()));
|
||||||
if (prevDefinition == null) {
|
if (prevDefinition == null) {
|
||||||
throw new IllegalArgumentException(transformCoordinate + " refers to an unknown field: " + t.from);
|
throw new IllegalArgumentException(transformCoordinate + " refers to an unknown field: " + t.from);
|
||||||
}
|
}
|
||||||
@ -331,7 +329,7 @@ public class DataModel {
|
|||||||
List<ComputedType> versionBaseTypes = computedClassConfig.get(versionIndexF).entrySet().stream()
|
List<ComputedType> versionBaseTypes = computedClassConfig.get(versionIndexF).entrySet().stream()
|
||||||
.map(e -> {
|
.map(e -> {
|
||||||
var data = new LinkedHashMap<String, VersionedType>();
|
var data = new LinkedHashMap<String, VersionedType>();
|
||||||
e.getValue().getData().forEach((key, value) -> data.put(key, new VersionedType(value, version)));
|
e.getValue().getData().forEach((key, value) -> data.put(key, new VersionedType(value.typeName(), version)));
|
||||||
return new ComputedTypeBase(new VersionedType(e.getKey(), version),
|
return new ComputedTypeBase(new VersionedType(e.getKey(), version),
|
||||||
e.getValue().stringRepresenter, data, computedTypeSupplier);
|
e.getValue().stringRepresenter, data, computedTypeSupplier);
|
||||||
}).collect(Collectors.toList());
|
}).collect(Collectors.toList());
|
||||||
@ -348,8 +346,8 @@ public class DataModel {
|
|||||||
var nullableRawTypes = computedClassConfig.values().stream()
|
var nullableRawTypes = computedClassConfig.values().stream()
|
||||||
.flatMap(x -> x.values().stream())
|
.flatMap(x -> x.values().stream())
|
||||||
.flatMap(x -> x.getData().values().stream())
|
.flatMap(x -> x.getData().values().stream())
|
||||||
.filter(x -> x.startsWith("-"))
|
.filter(x -> x.typeName().startsWith("-"))
|
||||||
.map(nullableName -> nullableName.substring(1))
|
.map(nullableName -> nullableName.typeName().substring(1))
|
||||||
.toList();
|
.toList();
|
||||||
// Compute nullable versioned types
|
// Compute nullable versioned types
|
||||||
nullableRawTypes.stream()
|
nullableRawTypes.stream()
|
||||||
@ -366,7 +364,7 @@ public class DataModel {
|
|||||||
nullableRawTypes.stream()
|
nullableRawTypes.stream()
|
||||||
.filter(NATIVE_TYPES::contains)
|
.filter(NATIVE_TYPES::contains)
|
||||||
.map(baseType ->
|
.map(baseType ->
|
||||||
new ComputedTypeNullableNative(baseType, computedVersions.get(latestVersion), computedTypeSupplier))
|
new ComputedTypeNullableNative(baseType, computedVersions.get(latestVersion), computedTypeSupplier, binaryStrings))
|
||||||
.forEach(versionBaseTypes::add);
|
.forEach(versionBaseTypes::add);
|
||||||
}
|
}
|
||||||
// Compute array types
|
// Compute array types
|
||||||
@ -374,8 +372,8 @@ public class DataModel {
|
|||||||
var arrayRawTypes = computedClassConfig.values().stream()
|
var arrayRawTypes = computedClassConfig.values().stream()
|
||||||
.flatMap(x -> x.values().stream())
|
.flatMap(x -> x.values().stream())
|
||||||
.flatMap(x -> x.getData().values().stream())
|
.flatMap(x -> x.getData().values().stream())
|
||||||
.filter(x -> x.startsWith("§"))
|
.filter(x -> x.typeName().startsWith("§"))
|
||||||
.map(nullableName -> nullableName.substring(1))
|
.map(nullableName -> nullableName.typeName().substring(1))
|
||||||
.toList();
|
.toList();
|
||||||
// Compute array versioned types
|
// Compute array versioned types
|
||||||
arrayRawTypes.stream()
|
arrayRawTypes.stream()
|
||||||
@ -392,11 +390,11 @@ public class DataModel {
|
|||||||
arrayRawTypes.stream()
|
arrayRawTypes.stream()
|
||||||
.filter(NATIVE_TYPES::contains)
|
.filter(NATIVE_TYPES::contains)
|
||||||
.map(baseType ->
|
.map(baseType ->
|
||||||
new ComputedTypeArrayNative(baseType, computedTypeSupplier))
|
new ComputedTypeArrayNative(baseType, computedTypeSupplier, binaryStrings))
|
||||||
.forEach(versionBaseTypes::add);
|
.forEach(versionBaseTypes::add);
|
||||||
}
|
}
|
||||||
// Compute native types
|
// Compute native types
|
||||||
versionBaseTypes.addAll(ComputedTypeNative.get(computedTypeSupplier));
|
versionBaseTypes.addAll(ComputedTypeNative.get(computedTypeSupplier, binaryStrings));
|
||||||
|
|
||||||
var allLatestTypes = versionBaseTypes.stream().distinct().collect(Collectors.toMap(ComputedType::getName, identity()));
|
var allLatestTypes = versionBaseTypes.stream().distinct().collect(Collectors.toMap(ComputedType::getName, identity()));
|
||||||
|
|
||||||
@ -441,7 +439,7 @@ public class DataModel {
|
|||||||
.entrySet()
|
.entrySet()
|
||||||
.stream()
|
.stream()
|
||||||
.collect(Collectors.toMap(Entry::getKey, e -> {
|
.collect(Collectors.toMap(Entry::getKey, e -> {
|
||||||
var fieldTypeName = e.getValue();
|
var fieldTypeName = e.getValue().typeName();
|
||||||
return new VersionedType(fieldTypeName, computedVersions.get(currentOrNewerTypeVersion.getInt(fieldTypeName)));
|
return new VersionedType(fieldTypeName, computedVersions.get(currentOrNewerTypeVersion.getInt(fieldTypeName)));
|
||||||
}, (a, b) -> {
|
}, (a, b) -> {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
@ -582,40 +580,6 @@ public class DataModel {
|
|||||||
this.baseTypeDataChanges = baseTypeDataChanges;
|
this.baseTypeDataChanges = baseTypeDataChanges;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String tryInsertAtIndex(LinkedHashMap<String, String> data, String key, String value, int index) {
|
|
||||||
var before = new LinkedHashMap<String, String>();
|
|
||||||
var after = new LinkedHashMap<String, String>();
|
|
||||||
int i = 0;
|
|
||||||
for (Entry<String, String> entry : data.entrySet()) {
|
|
||||||
if (i < index) {
|
|
||||||
before.put(entry.getKey(), entry.getValue());
|
|
||||||
} else {
|
|
||||||
after.put(entry.getKey(), entry.getValue());
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
data.clear();
|
|
||||||
data.putAll(before);
|
|
||||||
var prev = data.putIfAbsent(key, value);
|
|
||||||
data.putAll(after);
|
|
||||||
return prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Optional<Entry<Integer, String>> removeAndGetIndex(LinkedHashMap<String, String> data, String find) {
|
|
||||||
int foundIndex = -1;
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
for (Entry<String, String> entry : data.entrySet()) {
|
|
||||||
if (entry.getKey().equals(find)) {
|
|
||||||
foundIndex = i;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (foundIndex == -1) return Optional.empty();
|
|
||||||
return Optional.of(Map.entry(foundIndex, requireNonNull(data.remove(find))));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static String getNextVersion(Map<String, String> versionsSequence, String version) {
|
public static String getNextVersion(Map<String, String> versionsSequence, String version) {
|
||||||
return versionsSequence.get(version);
|
return versionsSequence.get(version);
|
||||||
@ -641,7 +605,7 @@ public class DataModel {
|
|||||||
if (list.size() != 1) {
|
if (list.size() != 1) {
|
||||||
throw exceptionGenerator.apply(list);
|
throw exceptionGenerator.apply(list);
|
||||||
}
|
}
|
||||||
return list.get(0);
|
return list.getFirst();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -660,7 +624,7 @@ public class DataModel {
|
|||||||
if (list.isEmpty()) {
|
if (list.isEmpty()) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
return Optional.of(list.get(0));
|
return Optional.of(list.getFirst());
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
import com.squareup.javapoet.TypeName;
|
import com.squareup.javapoet.TypeName;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
@ -0,0 +1,42 @@
|
|||||||
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
|
import com.squareup.javapoet.ClassName;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
public sealed interface JInterfaceLocation {
|
||||||
|
|
||||||
|
static JInterfaceLocation parse(String className, String instanceFieldLocation) {
|
||||||
|
if ((instanceFieldLocation != null) == (className != null)) {
|
||||||
|
if (instanceFieldLocation != null) {
|
||||||
|
throw new IllegalArgumentException("instance field location and class name are both set! You must set one");
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("instance field location and class name are both empty! You must set one");
|
||||||
|
}
|
||||||
|
} else if (instanceFieldLocation != null) {
|
||||||
|
var fieldClass = StringUtils.substringBeforeLast(instanceFieldLocation, ".");
|
||||||
|
var fieldName = StringUtils.substringAfterLast(instanceFieldLocation, ".");
|
||||||
|
var fieldClassName = ClassName.bestGuess(fieldClass);
|
||||||
|
return new JInterfaceLocationInstanceField(new FieldLocation(fieldClassName, fieldName));
|
||||||
|
} else {
|
||||||
|
return new JInterfaceLocationClassName(ClassName.bestGuess(className));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String getIdentifier();
|
||||||
|
|
||||||
|
record JInterfaceLocationClassName(ClassName className) implements JInterfaceLocation {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getIdentifier() {
|
||||||
|
return "C:" + className.reflectionName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
record JInterfaceLocationInstanceField(FieldLocation fieldLocation) implements JInterfaceLocation {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getIdentifier() {
|
||||||
|
return "F:" + fieldLocation.className() + "." + fieldLocation.fieldName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -29,6 +29,12 @@ public class MavenPlugin extends AbstractMojo {
|
|||||||
@Parameter( required = true, defaultValue = "false")
|
@Parameter( required = true, defaultValue = "false")
|
||||||
private String useRecordBuilder;
|
private String useRecordBuilder;
|
||||||
|
|
||||||
|
@Parameter(defaultValue = "false")
|
||||||
|
private String generateTestResources;
|
||||||
|
|
||||||
|
@Parameter(defaultValue = "false")
|
||||||
|
private String binaryStrings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @parameter default-value="${project}"
|
* @parameter default-value="${project}"
|
||||||
* @required
|
* @required
|
||||||
@ -41,12 +47,13 @@ public class MavenPlugin extends AbstractMojo {
|
|||||||
public void execute() throws MojoExecutionException, MojoFailureException {
|
public void execute() throws MojoExecutionException, MojoFailureException {
|
||||||
try {
|
try {
|
||||||
SourcesGenerator sourcesGenerator = SourcesGenerator.load(configPath.toPath());
|
SourcesGenerator sourcesGenerator = SourcesGenerator.load(configPath.toPath());
|
||||||
Path genRecordsPath = project.getBasedir().getAbsoluteFile().toPath().resolve("target").resolve("generated-sources").resolve("database-classes");
|
project.hasLifecyclePhase("generate-test-sources");
|
||||||
|
Path genRecordsPath = project.getBasedir().getAbsoluteFile().toPath().resolve("target").resolve(Boolean.parseBoolean(generateTestResources) ? "generated-test-sources" : "generated-sources").resolve("database-classes");
|
||||||
|
|
||||||
Path outPath = genRecordsPath.resolve("java");
|
Path outPath = genRecordsPath.resolve("java");
|
||||||
this.project.addCompileSourceRoot(outPath.toString());
|
this.project.addCompileSourceRoot(outPath.toString());
|
||||||
sourcesGenerator.generateSources(basePackageName, outPath, Boolean.parseBoolean(useRecordBuilder), false, Boolean.parseBoolean(deepCheckBeforeCreatingNewEqualInstances),
|
sourcesGenerator.generateSources(basePackageName, outPath, Boolean.parseBoolean(useRecordBuilder), false, Boolean.parseBoolean(deepCheckBeforeCreatingNewEqualInstances),
|
||||||
Boolean.parseBoolean(generateOldSerializers));
|
Boolean.parseBoolean(generateOldSerializers), Boolean.parseBoolean(binaryStrings));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new MojoExecutionException("Exception while generating classes", e);
|
throw new MojoExecutionException("Exception while generating classes", e);
|
||||||
}
|
}
|
@ -1,12 +1,18 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public final class MoveDataConfiguration implements TransformationConfiguration {
|
public final class MoveDataConfiguration implements TransformationConfiguration {
|
||||||
|
|
||||||
public String transformClass;
|
public String transformClass;
|
||||||
public String from;
|
public String from;
|
||||||
public String to;
|
public String to;
|
||||||
|
@Nullable
|
||||||
|
public Integer index;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getTransformClass() {
|
public String getTransformClass() {
|
||||||
@ -27,9 +33,8 @@ public final class MoveDataConfiguration implements TransformationConfiguration
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
MoveDataConfiguration that = (MoveDataConfiguration) o;
|
MoveDataConfiguration that = (MoveDataConfiguration) o;
|
||||||
return Objects.equals(transformClass, that.transformClass) && Objects.equals(from, that.from) && Objects.equals(to,
|
return Objects.equals(transformClass, that.transformClass) && Objects.equals(from, that.from)
|
||||||
that.to
|
&& Objects.equals(to, that.to) && Objects.equals(index, that.index);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -38,6 +43,7 @@ public final class MoveDataConfiguration implements TransformationConfiguration
|
|||||||
hash += ConfigUtils.hashCode(transformClass);
|
hash += ConfigUtils.hashCode(transformClass);
|
||||||
hash += ConfigUtils.hashCode(from);
|
hash += ConfigUtils.hashCode(from);
|
||||||
hash += ConfigUtils.hashCode(to);
|
hash += ConfigUtils.hashCode(to);
|
||||||
|
hash += ConfigUtils.hashCode(index);
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,6 +52,7 @@ public final class MoveDataConfiguration implements TransformationConfiguration
|
|||||||
if (this.transformClass != null) c.transformClass = this.transformClass;
|
if (this.transformClass != null) c.transformClass = this.transformClass;
|
||||||
if (this.from != null) c.from = this.from;
|
if (this.from != null) c.from = this.from;
|
||||||
if (this.to != null) c.to = this.to;
|
if (this.to != null) c.to = this.to;
|
||||||
|
if (this.index != null) c.index = this.index;
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,9 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public class NewDataConfiguration implements TransformationConfiguration {
|
public class NewDataConfiguration implements TransformationConfiguration {
|
||||||
@ -9,8 +12,11 @@ public class NewDataConfiguration implements TransformationConfiguration {
|
|||||||
public String to;
|
public String to;
|
||||||
public String type;
|
public String type;
|
||||||
public String initializer;
|
public String initializer;
|
||||||
|
public String initializerInstance;
|
||||||
@Nullable
|
@Nullable
|
||||||
public Integer index;
|
public Integer index;
|
||||||
|
@Nullable
|
||||||
|
public List<String> contextParameters;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getTransformClass() {
|
public String getTransformClass() {
|
||||||
@ -22,6 +28,15 @@ public class NewDataConfiguration implements TransformationConfiguration {
|
|||||||
return "new-data";
|
return "new-data";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JInterfaceLocation getInitializerLocation() {
|
||||||
|
return JInterfaceLocation.parse(initializer, initializerInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public List<String> getContextParameters() {
|
||||||
|
return Objects.requireNonNullElse(contextParameters, List.of());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) {
|
if (this == o) {
|
||||||
@ -33,7 +48,9 @@ public class NewDataConfiguration implements TransformationConfiguration {
|
|||||||
NewDataConfiguration that = (NewDataConfiguration) o;
|
NewDataConfiguration that = (NewDataConfiguration) o;
|
||||||
return Objects.equals(transformClass, that.transformClass) && Objects.equals(to, that.to)
|
return Objects.equals(transformClass, that.transformClass) && Objects.equals(to, that.to)
|
||||||
&& Objects.equals(type, that.type) && Objects.equals(initializer, that.initializer)
|
&& Objects.equals(type, that.type) && Objects.equals(initializer, that.initializer)
|
||||||
&& Objects.equals(index, that.index);
|
&& Objects.equals(initializerInstance, that.initializerInstance)
|
||||||
|
&& Objects.equals(index, that.index)
|
||||||
|
&& Objects.equals(contextParameters, that.contextParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -43,7 +60,9 @@ public class NewDataConfiguration implements TransformationConfiguration {
|
|||||||
hash += ConfigUtils.hashCode(to);
|
hash += ConfigUtils.hashCode(to);
|
||||||
hash += ConfigUtils.hashCode(type);
|
hash += ConfigUtils.hashCode(type);
|
||||||
hash += ConfigUtils.hashCode(initializer);
|
hash += ConfigUtils.hashCode(initializer);
|
||||||
|
hash += ConfigUtils.hashCode(initializerInstance);
|
||||||
hash += ConfigUtils.hashCode(index);
|
hash += ConfigUtils.hashCode(index);
|
||||||
|
hash += ConfigUtils.hashCode(contextParameters);
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,9 +70,11 @@ public class NewDataConfiguration implements TransformationConfiguration {
|
|||||||
var c = new NewDataConfiguration();
|
var c = new NewDataConfiguration();
|
||||||
if (this.transformClass != null) c.transformClass = this.transformClass;
|
if (this.transformClass != null) c.transformClass = this.transformClass;
|
||||||
if (this.initializer != null) c.initializer = this.initializer;
|
if (this.initializer != null) c.initializer = this.initializer;
|
||||||
|
if (this.initializerInstance != null) c.initializerInstance = this.initializerInstance;
|
||||||
if (this.to != null) c.to = this.to;
|
if (this.to != null) c.to = this.to;
|
||||||
if (this.type != null) c.type = this.type;
|
if (this.type != null) c.type = this.type;
|
||||||
if (this.index != null) c.index = this.index;
|
if (this.index != null) c.index = this.index;
|
||||||
|
if (this.contextParameters != null) c.contextParameters = this.contextParameters;
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,165 @@
|
|||||||
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import static it.cavallium.datagen.plugin.DataModel.fixType;
|
||||||
|
import static it.cavallium.datagen.plugin.DataModel.joinPackage;
|
||||||
|
import static java.util.Objects.requireNonNull;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public final class ParsedClass {
|
||||||
|
|
||||||
|
public record InputFieldInfo(@NotNull String typeName, @NotNull List<String> contextParams) {}
|
||||||
|
|
||||||
|
public record FieldInfo(@NotNull String typeName, @NotNull LinkedHashMap<String, String> contextFieldsData) {}
|
||||||
|
|
||||||
|
public String stringRepresenter;
|
||||||
|
|
||||||
|
public LinkedHashMap<String, FieldInfo> data;
|
||||||
|
public List<TransformationConfiguration> differentThanPrev;
|
||||||
|
public boolean differentThanNext;
|
||||||
|
|
||||||
|
public ParsedClass(ClassConfiguration baseTypesData) {
|
||||||
|
this.stringRepresenter = baseTypesData.stringRepresenter;
|
||||||
|
if (baseTypesData.data != null) {
|
||||||
|
this.data = baseTypesData.data.entrySet().stream()
|
||||||
|
.map(e -> Map.entry(e.getKey(), fixType(e.getValue())))
|
||||||
|
.collect(Collectors.toMap(Entry::getKey,
|
||||||
|
v -> new FieldInfo(v.getValue(),
|
||||||
|
new LinkedHashMap<>(0)),
|
||||||
|
(a, b) -> {throw new IllegalStateException();},
|
||||||
|
LinkedHashMap::new));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ParsedClass() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStringRepresenter() {
|
||||||
|
return stringRepresenter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LinkedHashMap<String, FieldInfo> getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (o == null || getClass() != o.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ParsedClass that = (ParsedClass) o;
|
||||||
|
return Objects.equals(stringRepresenter, that.stringRepresenter) && Objects.equals(data, that.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int hash = 0;
|
||||||
|
hash += ConfigUtils.hashCode(stringRepresenter);
|
||||||
|
hash += ConfigUtils.hashCode(data);
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ParsedClass copy() {
|
||||||
|
var cc = new ParsedClass();
|
||||||
|
if (this.stringRepresenter != null) cc.stringRepresenter = this.stringRepresenter;
|
||||||
|
cc.data = new LinkedHashMap<>(data);
|
||||||
|
cc.differentThanNext = differentThanNext;
|
||||||
|
cc.differentThanPrev = differentThanPrev;
|
||||||
|
return cc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addDifferentThanPrev(TransformationConfiguration transformation) {
|
||||||
|
if (differentThanPrev == null) {
|
||||||
|
differentThanPrev = new ArrayList<>();
|
||||||
|
}
|
||||||
|
differentThanPrev.add(transformation);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class NoContextParameterException extends RuntimeException {
|
||||||
|
private final String contextParameter;
|
||||||
|
|
||||||
|
public NoContextParameterException(String contextParameter) {
|
||||||
|
this.contextParameter = contextParameter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getContextParameter() {
|
||||||
|
return contextParameter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static LinkedHashMap<String, String> computeContextParametersTypes(
|
||||||
|
LinkedHashMap<String, ParsedClass.FieldInfo> data, @NotNull List<String> contextParameters)
|
||||||
|
throws NoContextParameterException {
|
||||||
|
return contextParameters.stream().collect(Collectors.toMap(Function.identity(), param -> {
|
||||||
|
var type = data.get(param);
|
||||||
|
if (type == null) {
|
||||||
|
throw new NoContextParameterException(param);
|
||||||
|
}
|
||||||
|
return type.typeName();
|
||||||
|
}, (c, a) -> {
|
||||||
|
throw new IllegalStateException("Unreachable");
|
||||||
|
}, LinkedHashMap::new));
|
||||||
|
}
|
||||||
|
|
||||||
|
public FieldInfo insert(@Nullable Integer index, String to, InputFieldInfo fieldInfo) throws NoContextParameterException {
|
||||||
|
var value = convertFieldInfo(fieldInfo);
|
||||||
|
if (index == null) {
|
||||||
|
return data.putIfAbsent(to, value);
|
||||||
|
} else {
|
||||||
|
return tryInsertAtIndex(data, to, value, index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<Entry<Integer, FieldInfo>> remove(String find) {
|
||||||
|
int foundIndex = -1;
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
for (var entry : data.entrySet()) {
|
||||||
|
if (entry.getKey().equals(find)) {
|
||||||
|
foundIndex = i;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (foundIndex == -1) return Optional.empty();
|
||||||
|
return Optional.of(Map.entry(foundIndex, requireNonNull(data.remove(find))));
|
||||||
|
}
|
||||||
|
|
||||||
|
public FieldInfo replace(String from, InputFieldInfo fieldInfo) {
|
||||||
|
return data.replace(from, convertFieldInfo(fieldInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
private FieldInfo convertFieldInfo(InputFieldInfo fieldInfo) {
|
||||||
|
return new FieldInfo(fieldInfo.typeName, computeContextParametersTypes(data, fieldInfo.contextParams));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ParsedClass.FieldInfo tryInsertAtIndex(LinkedHashMap<String, ParsedClass.FieldInfo> data, String key,
|
||||||
|
FieldInfo value, int index) {
|
||||||
|
var before = new LinkedHashMap<String, ParsedClass.FieldInfo>(index);
|
||||||
|
var after = new LinkedHashMap<String, ParsedClass.FieldInfo>(data.size() - index);
|
||||||
|
int i = 0;
|
||||||
|
for (Entry<String, ParsedClass.FieldInfo> entry : data.entrySet()) {
|
||||||
|
if (i < index) {
|
||||||
|
before.put(entry.getKey(), entry.getValue());
|
||||||
|
} else {
|
||||||
|
after.put(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
data.clear();
|
||||||
|
data.putAll(before);
|
||||||
|
var prev = data.putIfAbsent(key, value);
|
||||||
|
data.putAll(after);
|
||||||
|
return prev;
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
import static it.cavallium.data.generator.plugin.DataModel.fixType;
|
import static it.cavallium.datagen.plugin.DataModel.fixType;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
import com.squareup.javapoet.CodeBlock;
|
import com.squareup.javapoet.CodeBlock;
|
||||||
import java.util.List;
|
import java.util.List;
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
import static java.nio.file.StandardOpenOption.CREATE;
|
import static java.nio.file.StandardOpenOption.CREATE;
|
||||||
import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;
|
import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;
|
||||||
@ -12,27 +12,30 @@ import com.squareup.javapoet.ParameterSpec;
|
|||||||
import com.squareup.javapoet.ParameterizedTypeName;
|
import com.squareup.javapoet.ParameterizedTypeName;
|
||||||
import com.squareup.javapoet.TypeName;
|
import com.squareup.javapoet.TypeName;
|
||||||
import com.squareup.javapoet.TypeSpec.Builder;
|
import com.squareup.javapoet.TypeSpec.Builder;
|
||||||
import it.cavallium.data.generator.plugin.ClassGenerator.ClassGeneratorParams;
|
import it.cavallium.datagen.nativedata.Int52;
|
||||||
import it.cavallium.data.generator.plugin.classgen.GenBaseType;
|
import it.cavallium.datagen.plugin.ClassGenerator.ClassGeneratorParams;
|
||||||
import it.cavallium.data.generator.plugin.classgen.GenCurrentVersion;
|
import it.cavallium.datagen.plugin.classgen.GenBaseType;
|
||||||
import it.cavallium.data.generator.plugin.classgen.GenDataBaseX;
|
import it.cavallium.datagen.plugin.classgen.GenCurrentVersion;
|
||||||
import it.cavallium.data.generator.plugin.classgen.GenDataSuperX;
|
import it.cavallium.datagen.plugin.classgen.GenDataBaseX;
|
||||||
import it.cavallium.data.generator.plugin.classgen.GenIBaseType;
|
import it.cavallium.datagen.plugin.classgen.GenDataSuperX;
|
||||||
import it.cavallium.data.generator.plugin.classgen.GenINullableBaseType;
|
import it.cavallium.datagen.plugin.classgen.GenIBaseType;
|
||||||
import it.cavallium.data.generator.plugin.classgen.GenINullableIType;
|
import it.cavallium.datagen.plugin.classgen.GenINullableBaseType;
|
||||||
import it.cavallium.data.generator.plugin.classgen.GenINullableSuperType;
|
import it.cavallium.datagen.plugin.classgen.GenINullableIType;
|
||||||
import it.cavallium.data.generator.plugin.classgen.GenIType;
|
import it.cavallium.datagen.plugin.classgen.GenINullableSuperType;
|
||||||
import it.cavallium.data.generator.plugin.classgen.GenIVersion;
|
import it.cavallium.datagen.plugin.classgen.GenIType;
|
||||||
import it.cavallium.data.generator.plugin.classgen.GenNullableX;
|
import it.cavallium.datagen.plugin.classgen.GenIVersion;
|
||||||
import it.cavallium.data.generator.plugin.classgen.GenSerializerArrayX;
|
import it.cavallium.datagen.plugin.classgen.GenNullableX;
|
||||||
import it.cavallium.data.generator.plugin.classgen.GenSerializerBaseX;
|
import it.cavallium.datagen.plugin.classgen.GenSerializerArrayX;
|
||||||
import it.cavallium.data.generator.plugin.classgen.GenSerializerNullableX;
|
import it.cavallium.datagen.plugin.classgen.GenSerializerBaseX;
|
||||||
import it.cavallium.data.generator.plugin.classgen.GenSerializerSuperX;
|
import it.cavallium.datagen.plugin.classgen.GenSerializerNullableX;
|
||||||
import it.cavallium.data.generator.plugin.classgen.GenSuperType;
|
import it.cavallium.datagen.plugin.classgen.GenSerializerSuperX;
|
||||||
import it.cavallium.data.generator.plugin.classgen.GenUpgraderBaseX;
|
import it.cavallium.datagen.plugin.classgen.GenSuperType;
|
||||||
import it.cavallium.data.generator.plugin.classgen.GenUpgraderSuperX;
|
import it.cavallium.datagen.plugin.classgen.GenUpgraderBaseX;
|
||||||
import it.cavallium.data.generator.plugin.classgen.GenVersion;
|
import it.cavallium.datagen.plugin.classgen.GenUpgraderSuperX;
|
||||||
import it.cavallium.data.generator.plugin.classgen.GenVersions;
|
import it.cavallium.datagen.plugin.classgen.GenVersion;
|
||||||
|
import it.cavallium.datagen.plugin.classgen.GenVersions;
|
||||||
|
import it.cavallium.stream.SafeDataInput;
|
||||||
|
import it.cavallium.stream.SafeDataOutput;
|
||||||
import it.unimi.dsi.fastutil.booleans.BooleanList;
|
import it.unimi.dsi.fastutil.booleans.BooleanList;
|
||||||
import it.unimi.dsi.fastutil.bytes.ByteList;
|
import it.unimi.dsi.fastutil.bytes.ByteList;
|
||||||
import it.unimi.dsi.fastutil.chars.CharList;
|
import it.unimi.dsi.fastutil.chars.CharList;
|
||||||
@ -41,8 +44,6 @@ import it.unimi.dsi.fastutil.floats.FloatList;
|
|||||||
import it.unimi.dsi.fastutil.ints.IntList;
|
import it.unimi.dsi.fastutil.ints.IntList;
|
||||||
import it.unimi.dsi.fastutil.longs.LongList;
|
import it.unimi.dsi.fastutil.longs.LongList;
|
||||||
import it.unimi.dsi.fastutil.shorts.ShortList;
|
import it.unimi.dsi.fastutil.shorts.ShortList;
|
||||||
import java.io.DataInput;
|
|
||||||
import java.io.DataOutput;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@ -68,13 +69,13 @@ public class SourcesGenerator {
|
|||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(SourcesGenerator.class);
|
private static final Logger logger = LoggerFactory.getLogger(SourcesGenerator.class);
|
||||||
private static final boolean OVERRIDE_ALL_NULLABLE_METHODS = false;
|
private static final boolean OVERRIDE_ALL_NULLABLE_METHODS = false;
|
||||||
|
private static final String SERIAL_VERSION = "6";
|
||||||
|
|
||||||
private final DataModel dataModel;
|
private final SourcesGeneratorConfiguration configuration;
|
||||||
|
|
||||||
private SourcesGenerator(InputStream yamlDataStream) {
|
private SourcesGenerator(InputStream yamlDataStream) {
|
||||||
Yaml yaml = new Yaml();
|
Yaml yaml = new Yaml();
|
||||||
var configuration = yaml.loadAs(yamlDataStream, SourcesGeneratorConfiguration.class);
|
this.configuration = yaml.loadAs(yamlDataStream, SourcesGeneratorConfiguration.class);
|
||||||
this.dataModel = configuration.buildDataModel();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SourcesGenerator load(InputStream yamlData) {
|
public static SourcesGenerator load(InputStream yamlData) {
|
||||||
@ -99,8 +100,15 @@ public class SourcesGenerator {
|
|||||||
* @param useRecordBuilders if true, the data will have @RecordBuilder annotation
|
* @param useRecordBuilders if true, the data will have @RecordBuilder annotation
|
||||||
* @param force force overwrite
|
* @param force force overwrite
|
||||||
* @param deepCheckBeforeCreatingNewEqualInstances if true, use equals, if false, use ==
|
* @param deepCheckBeforeCreatingNewEqualInstances if true, use equals, if false, use ==
|
||||||
|
* @param binaryStrings use binary strings
|
||||||
*/
|
*/
|
||||||
public void generateSources(String basePackageName, Path outPath, boolean useRecordBuilders, boolean force, boolean deepCheckBeforeCreatingNewEqualInstances, boolean generateOldSerializers) throws IOException {
|
public void generateSources(String basePackageName,
|
||||||
|
Path outPath,
|
||||||
|
boolean useRecordBuilders,
|
||||||
|
boolean force,
|
||||||
|
boolean deepCheckBeforeCreatingNewEqualInstances,
|
||||||
|
boolean generateOldSerializers,
|
||||||
|
boolean binaryStrings) throws IOException {
|
||||||
Path basePackageNamePath;
|
Path basePackageNamePath;
|
||||||
{
|
{
|
||||||
Path basePackageNamePathPartial = outPath;
|
Path basePackageNamePathPartial = outPath;
|
||||||
@ -110,21 +118,26 @@ public class SourcesGenerator {
|
|||||||
basePackageNamePath = basePackageNamePathPartial;
|
basePackageNamePath = basePackageNamePathPartial;
|
||||||
}
|
}
|
||||||
var hashPath = basePackageNamePath.resolve(".hash");
|
var hashPath = basePackageNamePath.resolve(".hash");
|
||||||
|
var dataModel = configuration.buildDataModel(binaryStrings);
|
||||||
var curHash = dataModel.computeHash();
|
var curHash = dataModel.computeHash();
|
||||||
if (Files.isRegularFile(hashPath) && Files.isReadable(hashPath)) {
|
if (Files.isRegularFile(hashPath) && Files.isReadable(hashPath)) {
|
||||||
var lines = Files.readAllLines(hashPath, StandardCharsets.UTF_8);
|
var lines = Files.readAllLines(hashPath, StandardCharsets.UTF_8);
|
||||||
if (lines.size() >= 5) {
|
if (lines.size() >= 7) {
|
||||||
var prevBasePackageName = lines.get(0);
|
var prevBasePackageName = lines.get(0);
|
||||||
var prevRecordBuilders = lines.get(1);
|
var prevRecordBuilders = lines.get(1);
|
||||||
var prevHash = lines.get(2);
|
var prevHash = lines.get(2);
|
||||||
var prevDeepCheckBeforeCreatingNewEqualInstances = lines.get(3);
|
var prevDeepCheckBeforeCreatingNewEqualInstances = lines.get(3);
|
||||||
var prevGenerateOldSerializers = lines.get(4);
|
var prevGenerateOldSerializers = lines.get(4);
|
||||||
|
var prevSerialVersion = lines.get(5);
|
||||||
|
var prevBinaryStrings = lines.get(6);
|
||||||
|
|
||||||
if (!force
|
if (!force
|
||||||
&& prevBasePackageName.equals(basePackageName)
|
&& prevBasePackageName.equals(basePackageName)
|
||||||
&& (prevRecordBuilders.equalsIgnoreCase("true") == useRecordBuilders)
|
&& (prevRecordBuilders.equalsIgnoreCase("true") == useRecordBuilders)
|
||||||
&& (prevDeepCheckBeforeCreatingNewEqualInstances.equalsIgnoreCase("true") == deepCheckBeforeCreatingNewEqualInstances)
|
&& (prevDeepCheckBeforeCreatingNewEqualInstances.equalsIgnoreCase("true") == deepCheckBeforeCreatingNewEqualInstances)
|
||||||
&& (prevGenerateOldSerializers.equalsIgnoreCase("true") == generateOldSerializers)
|
&& (prevGenerateOldSerializers.equalsIgnoreCase("true") == generateOldSerializers)
|
||||||
|
&& (prevBinaryStrings.equalsIgnoreCase("true") == binaryStrings)
|
||||||
|
&& (prevSerialVersion.equals(SERIAL_VERSION))
|
||||||
&& prevHash.equals(Integer.toString(curHash))) {
|
&& prevHash.equals(Integer.toString(curHash))) {
|
||||||
logger.info("Skipped sources generation because it didn't change");
|
logger.info("Skipped sources generation because it didn't change");
|
||||||
return;
|
return;
|
||||||
@ -150,7 +163,8 @@ public class SourcesGenerator {
|
|||||||
.collect(Collectors.toCollection(HashSet::new));
|
.collect(Collectors.toCollection(HashSet::new));
|
||||||
}
|
}
|
||||||
|
|
||||||
var genParams = new ClassGeneratorParams(generatedFilesToDelete, dataModel, basePackageName, outPath, deepCheckBeforeCreatingNewEqualInstances, useRecordBuilders, generateOldSerializers);
|
var genParams = new ClassGeneratorParams(generatedFilesToDelete, dataModel, basePackageName, outPath,
|
||||||
|
deepCheckBeforeCreatingNewEqualInstances, useRecordBuilders, generateOldSerializers, binaryStrings);
|
||||||
|
|
||||||
// Create the Versions class
|
// Create the Versions class
|
||||||
new GenVersions(genParams).run();
|
new GenVersions(genParams).run();
|
||||||
@ -198,14 +212,28 @@ public class SourcesGenerator {
|
|||||||
new GenUpgraderSuperX(genParams).run();
|
new GenUpgraderSuperX(genParams).run();
|
||||||
|
|
||||||
// Update the hash at the end
|
// Update the hash at the end
|
||||||
|
var newHashRaw = basePackageName + '\n'
|
||||||
|
+ useRecordBuilders + '\n'
|
||||||
|
+ deepCheckBeforeCreatingNewEqualInstances + '\n'
|
||||||
|
+ generateOldSerializers + '\n'
|
||||||
|
+ binaryStrings + '\n'
|
||||||
|
+ SERIAL_VERSION + '\n'
|
||||||
|
+ curHash + '\n';
|
||||||
|
String oldHashRaw;
|
||||||
|
if (Files.exists(hashPath)) {
|
||||||
|
oldHashRaw = Files.readString(hashPath, StandardCharsets.UTF_8);
|
||||||
|
} else {
|
||||||
|
oldHashRaw = null;
|
||||||
|
}
|
||||||
|
if (!Objects.equals(newHashRaw, oldHashRaw)) {
|
||||||
Files.writeString(hashPath,
|
Files.writeString(hashPath,
|
||||||
basePackageName + '\n' + useRecordBuilders + '\n' + deepCheckBeforeCreatingNewEqualInstances + '\n' + curHash
|
newHashRaw,
|
||||||
+ '\n',
|
|
||||||
StandardCharsets.UTF_8,
|
StandardCharsets.UTF_8,
|
||||||
TRUNCATE_EXISTING,
|
TRUNCATE_EXISTING,
|
||||||
WRITE,
|
WRITE,
|
||||||
CREATE
|
CREATE
|
||||||
);
|
);
|
||||||
|
}
|
||||||
generatedFilesToDelete.remove(outPath.relativize(hashPath));
|
generatedFilesToDelete.remove(outPath.relativize(hashPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,8 +277,8 @@ public class SourcesGenerator {
|
|||||||
private static String getSpecialNativePackage(String specialNativeType) {
|
private static String getSpecialNativePackage(String specialNativeType) {
|
||||||
//noinspection SwitchStatementWithTooFewBranches
|
//noinspection SwitchStatementWithTooFewBranches
|
||||||
return switch (specialNativeType) {
|
return switch (specialNativeType) {
|
||||||
case "Int52" -> "it.cavallium.data.generator.nativedata";
|
case "Int52" -> Int52.class.getPackageName();
|
||||||
default -> "java.lang";
|
default -> Integer.class.getPackageName();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,10 +307,9 @@ public class SourcesGenerator {
|
|||||||
serializeMethod.addModifiers(Modifier.PUBLIC);
|
serializeMethod.addModifiers(Modifier.PUBLIC);
|
||||||
serializeMethod.addModifiers(Modifier.FINAL);
|
serializeMethod.addModifiers(Modifier.FINAL);
|
||||||
serializeMethod.returns(TypeName.VOID);
|
serializeMethod.returns(TypeName.VOID);
|
||||||
serializeMethod.addParameter(ParameterSpec.builder(DataOutput.class, "dataOutput").build());
|
serializeMethod.addParameter(ParameterSpec.builder(SafeDataOutput.class, "dataOutput").build());
|
||||||
serializeMethod
|
serializeMethod
|
||||||
.addParameter(ParameterSpec.builder(classType, "data").addAnnotation(NotNull.class).build());
|
.addParameter(ParameterSpec.builder(classType, "data").addAnnotation(NotNull.class).build());
|
||||||
serializeMethod.addException(IOException.class);
|
|
||||||
serializeMethod.addStatement("$T.requireNonNull(data)", Objects.class);
|
serializeMethod.addStatement("$T.requireNonNull(data)", Objects.class);
|
||||||
return serializeMethod;
|
return serializeMethod;
|
||||||
}
|
}
|
||||||
@ -294,8 +321,7 @@ public class SourcesGenerator {
|
|||||||
deserializeMethod.addModifiers(Modifier.PUBLIC);
|
deserializeMethod.addModifiers(Modifier.PUBLIC);
|
||||||
deserializeMethod.addModifiers(Modifier.FINAL);
|
deserializeMethod.addModifiers(Modifier.FINAL);
|
||||||
deserializeMethod.returns(classType);
|
deserializeMethod.returns(classType);
|
||||||
deserializeMethod.addParameter(ParameterSpec.builder(DataInput.class, "dataInput").build());
|
deserializeMethod.addParameter(ParameterSpec.builder(SafeDataInput.class, "dataInput").build());
|
||||||
deserializeMethod.addException(IOException.class);
|
|
||||||
return deserializeMethod;
|
return deserializeMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -395,7 +421,7 @@ public class SourcesGenerator {
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String capitalize(String field) {
|
public static String capitalize(String field) {
|
||||||
return Character.toUpperCase(field.charAt(0)) + field.substring(1);
|
return Character.toUpperCase(field.charAt(0)) + field.substring(1);
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@ -37,14 +37,15 @@ public class SourcesGeneratorConfiguration {
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataModel buildDataModel() {
|
public DataModel buildDataModel(boolean binaryStrings) {
|
||||||
return new DataModel(hashCode(),
|
return new DataModel(hashCode(),
|
||||||
currentVersion,
|
currentVersion,
|
||||||
Objects.requireNonNullElse(interfacesData, Map.of()),
|
Objects.requireNonNullElse(interfacesData, Map.of()),
|
||||||
Objects.requireNonNullElse(baseTypesData, Map.of()),
|
Objects.requireNonNullElse(baseTypesData, Map.of()),
|
||||||
Objects.requireNonNullElse(superTypesData, Map.of()),
|
Objects.requireNonNullElse(superTypesData, Map.of()),
|
||||||
Objects.requireNonNullElse(customTypesData, Map.of()),
|
Objects.requireNonNullElse(customTypesData, Map.of()),
|
||||||
Objects.requireNonNullElse(versions, Map.of())
|
Objects.requireNonNullElse(versions, Map.of()),
|
||||||
|
binaryStrings
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
import static java.lang.Boolean.parseBoolean;
|
import static java.lang.Boolean.parseBoolean;
|
||||||
|
|
||||||
@ -19,7 +19,8 @@ public class Standalone {
|
|||||||
parseBoolean(args[3]),
|
parseBoolean(args[3]),
|
||||||
parseBoolean(args[4]),
|
parseBoolean(args[4]),
|
||||||
parseBoolean(args[5]),
|
parseBoolean(args[5]),
|
||||||
parseBoolean(args[6])
|
parseBoolean(args[6]),
|
||||||
|
parseBoolean(args[7])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
public interface TransformationConfiguration {
|
public interface TransformationConfiguration {
|
||||||
|
|
@ -1,5 +1,9 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class UpgradeDataConfiguration implements TransformationConfiguration {
|
public class UpgradeDataConfiguration implements TransformationConfiguration {
|
||||||
@ -8,6 +12,9 @@ public class UpgradeDataConfiguration implements TransformationConfiguration {
|
|||||||
public String from;
|
public String from;
|
||||||
public String type;
|
public String type;
|
||||||
public String upgrader;
|
public String upgrader;
|
||||||
|
public String upgraderInstance;
|
||||||
|
@Nullable
|
||||||
|
public List<String> contextParameters;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getTransformClass() {
|
public String getTransformClass() {
|
||||||
@ -19,6 +26,15 @@ public class UpgradeDataConfiguration implements TransformationConfiguration {
|
|||||||
return "upgrade-data";
|
return "upgrade-data";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JInterfaceLocation getUpgraderLocation() {
|
||||||
|
return JInterfaceLocation.parse(upgrader, upgraderInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public List<String> getContextParameters() {
|
||||||
|
return Objects.requireNonNullElse(contextParameters, List.of());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) {
|
if (this == o) {
|
||||||
@ -29,7 +45,9 @@ public class UpgradeDataConfiguration implements TransformationConfiguration {
|
|||||||
}
|
}
|
||||||
UpgradeDataConfiguration that = (UpgradeDataConfiguration) o;
|
UpgradeDataConfiguration that = (UpgradeDataConfiguration) o;
|
||||||
return Objects.equals(transformClass, that.transformClass) && Objects.equals(from, that.from)
|
return Objects.equals(transformClass, that.transformClass) && Objects.equals(from, that.from)
|
||||||
&& Objects.equals(type, that.type) && Objects.equals(upgrader, that.upgrader);
|
&& Objects.equals(type, that.type) && Objects.equals(upgrader, that.upgrader)
|
||||||
|
&& Objects.equals(upgraderInstance, that.upgraderInstance)
|
||||||
|
&& Objects.equals(contextParameters, that.contextParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -39,6 +57,8 @@ public class UpgradeDataConfiguration implements TransformationConfiguration {
|
|||||||
hash += ConfigUtils.hashCode(from);
|
hash += ConfigUtils.hashCode(from);
|
||||||
hash += ConfigUtils.hashCode(type);
|
hash += ConfigUtils.hashCode(type);
|
||||||
hash += ConfigUtils.hashCode(upgrader);
|
hash += ConfigUtils.hashCode(upgrader);
|
||||||
|
hash += ConfigUtils.hashCode(upgraderInstance);
|
||||||
|
hash += ConfigUtils.hashCode(contextParameters);
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,6 +68,8 @@ public class UpgradeDataConfiguration implements TransformationConfiguration {
|
|||||||
if (this.from != null) c.from = this.from;
|
if (this.from != null) c.from = this.from;
|
||||||
if (this.type != null) c.type = this.type;
|
if (this.type != null) c.type = this.type;
|
||||||
if (this.upgrader != null) c.upgrader = this.upgrader;
|
if (this.upgrader != null) c.upgrader = this.upgrader;
|
||||||
|
if (this.upgraderInstance != null) c.upgraderInstance = this.upgraderInstance;
|
||||||
|
if (this.contextParameters != null) c.contextParameters = this.contextParameters;
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
|
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.datagen.plugin;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
package it.cavallium.data.generator.plugin.classgen;
|
package it.cavallium.datagen.plugin.classgen;
|
||||||
|
|
||||||
import com.squareup.javapoet.TypeSpec;
|
import com.squareup.javapoet.TypeSpec;
|
||||||
import it.cavallium.data.generator.plugin.ClassGenerator;
|
import it.cavallium.datagen.plugin.ClassGenerator;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import javax.lang.model.element.Modifier;
|
import javax.lang.model.element.Modifier;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.data.generator.plugin.classgen;
|
package it.cavallium.datagen.plugin.classgen;
|
||||||
|
|
||||||
import com.squareup.javapoet.ClassName;
|
import com.squareup.javapoet.ClassName;
|
||||||
import com.squareup.javapoet.CodeBlock;
|
import com.squareup.javapoet.CodeBlock;
|
||||||
@ -11,11 +11,10 @@ import com.squareup.javapoet.TypeSpec;
|
|||||||
import com.squareup.javapoet.TypeSpec.Builder;
|
import com.squareup.javapoet.TypeSpec.Builder;
|
||||||
import com.squareup.javapoet.TypeVariableName;
|
import com.squareup.javapoet.TypeVariableName;
|
||||||
import com.squareup.javapoet.WildcardTypeName;
|
import com.squareup.javapoet.WildcardTypeName;
|
||||||
import it.cavallium.data.generator.plugin.ClassGenerator;
|
import it.cavallium.datagen.plugin.ClassGenerator;
|
||||||
import it.cavallium.data.generator.plugin.ComputedType;
|
import it.cavallium.datagen.plugin.ComputedType;
|
||||||
import it.cavallium.data.generator.plugin.ComputedVersion;
|
import it.cavallium.datagen.plugin.ComputedVersion;
|
||||||
import java.io.DataInput;
|
import it.cavallium.stream.SafeDataInput;
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@ -119,8 +118,8 @@ public class GenCurrentVersion extends ClassGenerator {
|
|||||||
.addModifiers(Modifier.PUBLIC).addModifiers(Modifier.STATIC).addModifiers(Modifier.FINAL).returns(TypeVariableName.get("U"))
|
.addModifiers(Modifier.PUBLIC).addModifiers(Modifier.STATIC).addModifiers(Modifier.FINAL).returns(TypeVariableName.get("U"))
|
||||||
.addParameter(ParameterSpec.builder(TypeName.INT, "oldVersion").build()).addParameter(
|
.addParameter(ParameterSpec.builder(TypeName.INT, "oldVersion").build()).addParameter(
|
||||||
ParameterSpec.builder(ClassName.get(dataModel.getRootPackage(basePackageName), "BaseType"), "type").build())
|
ParameterSpec.builder(ClassName.get(dataModel.getRootPackage(basePackageName), "BaseType"), "type").build())
|
||||||
.addParameter(ParameterSpec.builder(DataInput.class, "oldDataInput").build())
|
.addParameter(ParameterSpec.builder(SafeDataInput.class, "oldDataInput").build())
|
||||||
.addException(IOException.class).beginControlFlow("return upgradeDataToLatestVersion(oldVersion, switch (oldVersion)");
|
.beginControlFlow("return upgradeDataToLatestVersion(oldVersion, switch (oldVersion)");
|
||||||
for (var versionConfiguration : dataModel.getVersionsSet()) {
|
for (var versionConfiguration : dataModel.getVersionsSet()) {
|
||||||
// Add a case in which the data version deserializes the serialized data and upgrades it
|
// Add a case in which the data version deserializes the serialized data and upgrades it
|
||||||
var versions = ClassName.get(dataModel.getRootPackage(basePackageName), "Versions");
|
var versions = ClassName.get(dataModel.getRootPackage(basePackageName), "Versions");
|
||||||
@ -131,7 +130,7 @@ public class GenCurrentVersion extends ClassGenerator {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
var upgradeDataToLatestVersion1Method = upgradeDataToLatestVersion1MethodBuilder
|
var upgradeDataToLatestVersion1Method = upgradeDataToLatestVersion1MethodBuilder
|
||||||
.addStatement("default -> throw new $T(\"Unknown version: \" + oldVersion)", IOException.class)
|
.addStatement("default -> throw new $T(\"Unknown version: \" + oldVersion)", UnsupportedOperationException.class)
|
||||||
.addCode(CodeBlock.of("$<});"))
|
.addCode(CodeBlock.of("$<});"))
|
||||||
.build();
|
.build();
|
||||||
currentVersionClass.addMethod(upgradeDataToLatestVersion1Method);
|
currentVersionClass.addMethod(upgradeDataToLatestVersion1Method);
|
||||||
@ -145,7 +144,6 @@ public class GenCurrentVersion extends ClassGenerator {
|
|||||||
.returns(TypeVariableName.get("U"))
|
.returns(TypeVariableName.get("U"))
|
||||||
.addParameter(ParameterSpec.builder(TypeName.INT, "oldVersion").build())
|
.addParameter(ParameterSpec.builder(TypeName.INT, "oldVersion").build())
|
||||||
.addParameter(ParameterSpec.builder(TypeVariableName.get("T"), "oldData").build())
|
.addParameter(ParameterSpec.builder(TypeVariableName.get("T"), "oldData").build())
|
||||||
.addException(IOException.class)
|
|
||||||
.addStatement("$T data = oldData", Object.class);
|
.addStatement("$T data = oldData", Object.class);
|
||||||
upgradeDataToLatestVersion2MethodBuilder.beginControlFlow("switch (oldVersion)");
|
upgradeDataToLatestVersion2MethodBuilder.beginControlFlow("switch (oldVersion)");
|
||||||
for (var versionConfiguration : dataModel.getVersionsSet()) {
|
for (var versionConfiguration : dataModel.getVersionsSet()) {
|
||||||
@ -168,7 +166,7 @@ public class GenCurrentVersion extends ClassGenerator {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
upgradeDataToLatestVersion2MethodBuilder.addStatement("default: throw new $T(\"Unknown version: \" + oldVersion)", IOException.class);
|
upgradeDataToLatestVersion2MethodBuilder.addStatement("default: throw new $T(\"Unknown version: \" + oldVersion)", UnsupportedOperationException.class);
|
||||||
upgradeDataToLatestVersion2MethodBuilder.endControlFlow();
|
upgradeDataToLatestVersion2MethodBuilder.endControlFlow();
|
||||||
currentVersionClass.addMethod(upgradeDataToLatestVersion2MethodBuilder.build());
|
currentVersionClass.addMethod(upgradeDataToLatestVersion2MethodBuilder.build());
|
||||||
}
|
}
|
@ -1,13 +1,13 @@
|
|||||||
package it.cavallium.data.generator.plugin.classgen;
|
package it.cavallium.datagen.plugin.classgen;
|
||||||
|
|
||||||
import com.squareup.javapoet.ClassName;
|
import com.squareup.javapoet.ClassName;
|
||||||
import com.squareup.javapoet.MethodSpec;
|
import com.squareup.javapoet.MethodSpec;
|
||||||
import com.squareup.javapoet.ParameterSpec;
|
import com.squareup.javapoet.ParameterSpec;
|
||||||
import com.squareup.javapoet.TypeSpec;
|
import com.squareup.javapoet.TypeSpec;
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
import io.soabase.recordbuilder.core.RecordBuilder;
|
||||||
import it.cavallium.data.generator.plugin.ClassGenerator;
|
import it.cavallium.datagen.plugin.ClassGenerator;
|
||||||
import it.cavallium.data.generator.plugin.ComputedTypeBase;
|
import it.cavallium.datagen.plugin.ComputedTypeBase;
|
||||||
import it.cavallium.data.generator.plugin.ComputedVersion;
|
import it.cavallium.datagen.plugin.ComputedVersion;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import javax.lang.model.element.Modifier;
|
import javax.lang.model.element.Modifier;
|
||||||
@ -68,7 +68,7 @@ public class GenDataBaseX extends ClassGenerator {
|
|||||||
.addModifiers(Modifier.PUBLIC, Modifier.STATIC);
|
.addModifiers(Modifier.PUBLIC, Modifier.STATIC);
|
||||||
|
|
||||||
base.getData().forEach((fieldName, fieldType) -> {
|
base.getData().forEach((fieldName, fieldType) -> {
|
||||||
var fieldTypeName = fieldType.getJTypeName(basePackageName);
|
var fieldTypeName = fieldType.getJTypeNameGeneric(basePackageName);
|
||||||
|
|
||||||
var param = ParameterSpec
|
var param = ParameterSpec
|
||||||
.builder(fieldTypeName, fieldName)
|
.builder(fieldTypeName, fieldName)
|
||||||
@ -90,13 +90,11 @@ public class GenDataBaseX extends ClassGenerator {
|
|||||||
}
|
}
|
||||||
if (fieldTypeName.isPrimitive() || !deepCheckBeforeCreatingNewEqualInstances) {
|
if (fieldTypeName.isPrimitive() || !deepCheckBeforeCreatingNewEqualInstances) {
|
||||||
setter.addCode("return $N == this.$N ? this : new $T(", fieldName, fieldName, type);
|
setter.addCode("return $N == this.$N ? this : new $T(", fieldName, fieldName, type);
|
||||||
setter.addCode(String.join(", ", base.getData().keySet()));
|
|
||||||
setter.addStatement(")");
|
|
||||||
} else {
|
} else {
|
||||||
setter.addCode("return $T.equals($N, this.$N) ? this : new $T(", Objects.class, fieldName, fieldName, type);
|
setter.addCode("return $T.equals($N, this.$N) ? this : new $T(", Objects.class, fieldName, fieldName, type);
|
||||||
|
}
|
||||||
setter.addCode(String.join(", ", base.getData().keySet()));
|
setter.addCode(String.join(", ", base.getData().keySet()));
|
||||||
setter.addStatement(")");
|
setter.addStatement(")");
|
||||||
}
|
|
||||||
|
|
||||||
classBuilder.addMethod(setter.build());
|
classBuilder.addMethod(setter.build());
|
||||||
});
|
});
|
||||||
@ -117,6 +115,16 @@ public class GenDataBaseX extends ClassGenerator {
|
|||||||
classBuilder.addMethod(ofMethod.build());
|
classBuilder.addMethod(ofMethod.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final String stringRepresenter = base.getStringRepresenter();
|
||||||
|
if (version.isCurrent() && stringRepresenter != null && !stringRepresenter.isBlank()) {
|
||||||
|
var toStringMethod = MethodSpec.methodBuilder("toString");
|
||||||
|
toStringMethod.addModifiers(Modifier.PUBLIC);
|
||||||
|
toStringMethod.addAnnotation(Override.class);
|
||||||
|
toStringMethod.returns(String.class);
|
||||||
|
toStringMethod.addStatement("return " + stringRepresenter + "(this)");
|
||||||
|
classBuilder.addMethod(toStringMethod.build());
|
||||||
|
}
|
||||||
|
|
||||||
return new GeneratedClass(type.packageName(), classBuilder);
|
return new GeneratedClass(type.packageName(), classBuilder);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,12 +1,13 @@
|
|||||||
package it.cavallium.data.generator.plugin.classgen;
|
package it.cavallium.datagen.plugin.classgen;
|
||||||
|
|
||||||
import com.squareup.javapoet.ClassName;
|
import com.squareup.javapoet.ClassName;
|
||||||
import com.squareup.javapoet.MethodSpec;
|
import com.squareup.javapoet.MethodSpec;
|
||||||
import com.squareup.javapoet.ParameterSpec;
|
import com.squareup.javapoet.ParameterSpec;
|
||||||
|
import com.squareup.javapoet.TypeName;
|
||||||
import com.squareup.javapoet.TypeSpec;
|
import com.squareup.javapoet.TypeSpec;
|
||||||
import it.cavallium.data.generator.plugin.ClassGenerator;
|
import it.cavallium.datagen.plugin.ClassGenerator;
|
||||||
import it.cavallium.data.generator.plugin.ComputedTypeSuper;
|
import it.cavallium.datagen.plugin.ComputedTypeSuper;
|
||||||
import it.cavallium.data.generator.plugin.ComputedVersion;
|
import it.cavallium.datagen.plugin.ComputedVersion;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import javax.lang.model.element.Modifier;
|
import javax.lang.model.element.Modifier;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
@ -36,6 +37,17 @@ public class GenDataSuperX extends ClassGenerator {
|
|||||||
|
|
||||||
classBuilder.addModifiers(Modifier.PUBLIC);
|
classBuilder.addModifiers(Modifier.PUBLIC);
|
||||||
|
|
||||||
|
if (version.isCurrent()) {
|
||||||
|
classBuilder.addModifiers(Modifier.SEALED);
|
||||||
|
Stream<TypeName> superTypesThatExtendThisSuperType = dataModel.getSuperTypesComputed(version)
|
||||||
|
.filter(computedTypeSuper -> dataModel.getExtendsInterfaces(computedTypeSuper).anyMatch(typeSuper::equals))
|
||||||
|
.map(computedTypeSuper -> computedTypeSuper.getJTypeName(basePackageName));
|
||||||
|
Stream<TypeName> subTypes = typeSuper.subTypes().stream()
|
||||||
|
.map(subType -> subType.getJTypeName(basePackageName));
|
||||||
|
Stream<TypeName> permittedSubclasses = Stream.concat(superTypesThatExtendThisSuperType, subTypes).distinct();
|
||||||
|
classBuilder.addPermittedSubclasses(permittedSubclasses.toList());
|
||||||
|
}
|
||||||
|
|
||||||
dataModel.getTypeSameVersions(typeSuper).forEach(v -> {
|
dataModel.getTypeSameVersions(typeSuper).forEach(v -> {
|
||||||
var iTypeClass = ClassName.get(v.getPackage(basePackageName), "IBaseType");
|
var iTypeClass = ClassName.get(v.getPackage(basePackageName), "IBaseType");
|
||||||
classBuilder.addSuperinterface(iTypeClass);
|
classBuilder.addSuperinterface(iTypeClass);
|
||||||
@ -49,7 +61,7 @@ public class GenDataSuperX extends ClassGenerator {
|
|||||||
Stream
|
Stream
|
||||||
.concat(dataModel.getCommonInterfaceData(typeSuper), dataModel.getCommonInterfaceGetters(typeSuper))
|
.concat(dataModel.getCommonInterfaceData(typeSuper), dataModel.getCommonInterfaceGetters(typeSuper))
|
||||||
.forEach(superType -> {
|
.forEach(superType -> {
|
||||||
var returnType = superType.getValue().getJTypeName(basePackageName);
|
var returnType = superType.getValue().getJTypeNameGeneric(basePackageName);
|
||||||
var getter = MethodSpec
|
var getter = MethodSpec
|
||||||
.methodBuilder(superType.getKey())
|
.methodBuilder(superType.getKey())
|
||||||
.addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
|
.addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
|
||||||
@ -61,7 +73,7 @@ public class GenDataSuperX extends ClassGenerator {
|
|||||||
});
|
});
|
||||||
|
|
||||||
dataModel.getCommonInterfaceData(typeSuper).forEach(superType -> {
|
dataModel.getCommonInterfaceData(typeSuper).forEach(superType -> {
|
||||||
var returnType = superType.getValue().getJTypeName(basePackageName);
|
var returnType = superType.getValue().getJTypeNameGeneric(basePackageName);
|
||||||
|
|
||||||
var setter = MethodSpec
|
var setter = MethodSpec
|
||||||
.methodBuilder("set" + StringUtils.capitalize(superType.getKey()))
|
.methodBuilder("set" + StringUtils.capitalize(superType.getKey()))
|
@ -1,10 +1,10 @@
|
|||||||
package it.cavallium.data.generator.plugin.classgen;
|
package it.cavallium.datagen.plugin.classgen;
|
||||||
|
|
||||||
import com.squareup.javapoet.ClassName;
|
import com.squareup.javapoet.ClassName;
|
||||||
import com.squareup.javapoet.MethodSpec;
|
import com.squareup.javapoet.MethodSpec;
|
||||||
import com.squareup.javapoet.TypeSpec;
|
import com.squareup.javapoet.TypeSpec;
|
||||||
import it.cavallium.data.generator.plugin.ClassGenerator;
|
import it.cavallium.datagen.plugin.ClassGenerator;
|
||||||
import it.cavallium.data.generator.plugin.ComputedVersion;
|
import it.cavallium.datagen.plugin.ComputedVersion;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import javax.lang.model.element.Modifier;
|
import javax.lang.model.element.Modifier;
|
||||||
|
|
@ -1,10 +1,10 @@
|
|||||||
package it.cavallium.data.generator.plugin.classgen;
|
package it.cavallium.datagen.plugin.classgen;
|
||||||
|
|
||||||
import com.squareup.javapoet.ClassName;
|
import com.squareup.javapoet.ClassName;
|
||||||
import com.squareup.javapoet.MethodSpec;
|
import com.squareup.javapoet.MethodSpec;
|
||||||
import com.squareup.javapoet.TypeSpec;
|
import com.squareup.javapoet.TypeSpec;
|
||||||
import it.cavallium.data.generator.plugin.ClassGenerator;
|
import it.cavallium.datagen.plugin.ClassGenerator;
|
||||||
import it.cavallium.data.generator.plugin.ComputedVersion;
|
import it.cavallium.datagen.plugin.ComputedVersion;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import javax.lang.model.element.Modifier;
|
import javax.lang.model.element.Modifier;
|
||||||
|
|
@ -1,10 +1,10 @@
|
|||||||
package it.cavallium.data.generator.plugin.classgen;
|
package it.cavallium.datagen.plugin.classgen;
|
||||||
|
|
||||||
import com.squareup.javapoet.ClassName;
|
import com.squareup.javapoet.ClassName;
|
||||||
import com.squareup.javapoet.TypeSpec;
|
import com.squareup.javapoet.TypeSpec;
|
||||||
import it.cavallium.data.generator.nativedata.INullable;
|
import it.cavallium.datagen.nativedata.INullable;
|
||||||
import it.cavallium.data.generator.plugin.ClassGenerator;
|
import it.cavallium.datagen.plugin.ClassGenerator;
|
||||||
import it.cavallium.data.generator.plugin.ComputedVersion;
|
import it.cavallium.datagen.plugin.ComputedVersion;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import javax.lang.model.element.Modifier;
|
import javax.lang.model.element.Modifier;
|
||||||
|
|
@ -1,10 +1,10 @@
|
|||||||
package it.cavallium.data.generator.plugin.classgen;
|
package it.cavallium.datagen.plugin.classgen;
|
||||||
|
|
||||||
import com.squareup.javapoet.ClassName;
|
import com.squareup.javapoet.ClassName;
|
||||||
import com.squareup.javapoet.MethodSpec;
|
import com.squareup.javapoet.MethodSpec;
|
||||||
import com.squareup.javapoet.TypeSpec;
|
import com.squareup.javapoet.TypeSpec;
|
||||||
import it.cavallium.data.generator.plugin.ClassGenerator;
|
import it.cavallium.datagen.plugin.ClassGenerator;
|
||||||
import it.cavallium.data.generator.plugin.ComputedVersion;
|
import it.cavallium.datagen.plugin.ComputedVersion;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import javax.lang.model.element.Modifier;
|
import javax.lang.model.element.Modifier;
|
||||||
|
|
@ -1,9 +1,9 @@
|
|||||||
package it.cavallium.data.generator.plugin.classgen;
|
package it.cavallium.datagen.plugin.classgen;
|
||||||
|
|
||||||
import com.squareup.javapoet.ClassName;
|
import com.squareup.javapoet.ClassName;
|
||||||
import com.squareup.javapoet.TypeSpec;
|
import com.squareup.javapoet.TypeSpec;
|
||||||
import it.cavallium.data.generator.plugin.ClassGenerator;
|
import it.cavallium.datagen.plugin.ClassGenerator;
|
||||||
import it.cavallium.data.generator.plugin.ComputedVersion;
|
import it.cavallium.datagen.plugin.ComputedVersion;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import javax.lang.model.element.Modifier;
|
import javax.lang.model.element.Modifier;
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.data.generator.plugin.classgen;
|
package it.cavallium.datagen.plugin.classgen;
|
||||||
|
|
||||||
import com.squareup.javapoet.ClassName;
|
import com.squareup.javapoet.ClassName;
|
||||||
import com.squareup.javapoet.MethodSpec;
|
import com.squareup.javapoet.MethodSpec;
|
||||||
@ -7,9 +7,8 @@ import com.squareup.javapoet.ParameterizedTypeName;
|
|||||||
import com.squareup.javapoet.TypeName;
|
import com.squareup.javapoet.TypeName;
|
||||||
import com.squareup.javapoet.TypeSpec;
|
import com.squareup.javapoet.TypeSpec;
|
||||||
import com.squareup.javapoet.TypeVariableName;
|
import com.squareup.javapoet.TypeVariableName;
|
||||||
import it.cavallium.data.generator.DataSerializer;
|
import it.cavallium.datagen.DataSerializer;
|
||||||
import it.cavallium.data.generator.plugin.ClassGenerator;
|
import it.cavallium.datagen.plugin.ClassGenerator;
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import javax.lang.model.element.Modifier;
|
import javax.lang.model.element.Modifier;
|
||||||
|
|
||||||
@ -35,7 +34,6 @@ public class GenIVersion extends ClassGenerator {
|
|||||||
TypeVariableName.get("B")
|
TypeVariableName.get("B")
|
||||||
))
|
))
|
||||||
.returns(ParameterizedTypeName.get(ClassName.get(DataSerializer.class), TypeVariableName.get("T")))
|
.returns(ParameterizedTypeName.get(ClassName.get(DataSerializer.class), TypeVariableName.get("T")))
|
||||||
.addException(IOException.class)
|
|
||||||
.addParameter(ParameterSpec
|
.addParameter(ParameterSpec
|
||||||
.builder(ClassName.get(dataModel.getRootPackage(basePackageName), "BaseType"), "type")
|
.builder(ClassName.get(dataModel.getRootPackage(basePackageName), "BaseType"), "type")
|
||||||
.build());
|
.build());
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.data.generator.plugin.classgen;
|
package it.cavallium.datagen.plugin.classgen;
|
||||||
|
|
||||||
import com.squareup.javapoet.ClassName;
|
import com.squareup.javapoet.ClassName;
|
||||||
import com.squareup.javapoet.FieldSpec;
|
import com.squareup.javapoet.FieldSpec;
|
||||||
@ -6,16 +6,16 @@ import com.squareup.javapoet.MethodSpec;
|
|||||||
import com.squareup.javapoet.ParameterSpec;
|
import com.squareup.javapoet.ParameterSpec;
|
||||||
import com.squareup.javapoet.ParameterizedTypeName;
|
import com.squareup.javapoet.ParameterizedTypeName;
|
||||||
import com.squareup.javapoet.TypeSpec;
|
import com.squareup.javapoet.TypeSpec;
|
||||||
import it.cavallium.data.generator.TypedNullable;
|
import it.cavallium.datagen.TypedNullable;
|
||||||
import it.cavallium.data.generator.nativedata.INullable;
|
import it.cavallium.datagen.nativedata.INullable;
|
||||||
import it.cavallium.data.generator.plugin.ClassGenerator;
|
import it.cavallium.datagen.plugin.ClassGenerator;
|
||||||
import it.cavallium.data.generator.plugin.ComputedTypeBase;
|
import it.cavallium.datagen.plugin.ComputedTypeBase;
|
||||||
import it.cavallium.data.generator.plugin.ComputedTypeCustom;
|
import it.cavallium.datagen.plugin.ComputedTypeCustom;
|
||||||
import it.cavallium.data.generator.plugin.ComputedTypeNullable;
|
import it.cavallium.datagen.plugin.ComputedTypeNullable;
|
||||||
import it.cavallium.data.generator.plugin.ComputedTypeNullableFixed;
|
import it.cavallium.datagen.plugin.ComputedTypeNullableFixed;
|
||||||
import it.cavallium.data.generator.plugin.ComputedTypeNullableVersioned;
|
import it.cavallium.datagen.plugin.ComputedTypeNullableVersioned;
|
||||||
import it.cavallium.data.generator.plugin.ComputedTypeSuper;
|
import it.cavallium.datagen.plugin.ComputedTypeSuper;
|
||||||
import it.cavallium.data.generator.plugin.ComputedVersion;
|
import it.cavallium.datagen.plugin.ComputedVersion;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import javax.lang.model.element.Modifier;
|
import javax.lang.model.element.Modifier;
|
||||||
@ -88,9 +88,10 @@ public class GenNullableX extends ClassGenerator {
|
|||||||
classBuilder.addField(FieldSpec
|
classBuilder.addField(FieldSpec
|
||||||
.builder(type, "NULL").addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL).initializer("new $T(null)", type).build());
|
.builder(type, "NULL").addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL).initializer("new $T(null)", type).build());
|
||||||
|
|
||||||
if (version.isCurrent()) {
|
|
||||||
classBuilder.addSuperinterfaces(List.of(iNullableITypeClass, iNullableClass, typedNullable));
|
classBuilder.addSuperinterfaces(List.of(iNullableITypeClass, iNullableClass, typedNullable));
|
||||||
|
|
||||||
|
if (version.isCurrent()) {
|
||||||
|
|
||||||
classBuilder.addMethod(MethodSpec
|
classBuilder.addMethod(MethodSpec
|
||||||
.methodBuilder("of")
|
.methodBuilder("of")
|
||||||
.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
|
.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
|
@ -1,23 +1,24 @@
|
|||||||
package it.cavallium.data.generator.plugin.classgen;
|
package it.cavallium.datagen.plugin.classgen;
|
||||||
|
|
||||||
import com.squareup.javapoet.ArrayTypeName;
|
import com.squareup.javapoet.ArrayTypeName;
|
||||||
import com.squareup.javapoet.ClassName;
|
import com.squareup.javapoet.ClassName;
|
||||||
import com.squareup.javapoet.MethodSpec;
|
import com.squareup.javapoet.MethodSpec;
|
||||||
import com.squareup.javapoet.ParameterSpec;
|
import com.squareup.javapoet.ParameterSpec;
|
||||||
import com.squareup.javapoet.ParameterizedTypeName;
|
import com.squareup.javapoet.ParameterizedTypeName;
|
||||||
|
import com.squareup.javapoet.TypeName;
|
||||||
import com.squareup.javapoet.TypeSpec;
|
import com.squareup.javapoet.TypeSpec;
|
||||||
import com.squareup.javapoet.TypeSpec.Builder;
|
import com.squareup.javapoet.TypeSpec.Builder;
|
||||||
import it.cavallium.data.generator.DataSerializer;
|
import com.squareup.javapoet.WildcardTypeName;
|
||||||
import it.cavallium.data.generator.nativedata.ImmutableWrappedArrayList;
|
import it.cavallium.datagen.DataSerializer;
|
||||||
import it.cavallium.data.generator.plugin.ClassGenerator;
|
import it.cavallium.datagen.NotSerializableException;
|
||||||
import it.cavallium.data.generator.plugin.ComputedTypeArray;
|
import it.cavallium.datagen.nativedata.ImmutableWrappedArrayList;
|
||||||
import it.cavallium.data.generator.plugin.ComputedTypeArrayFixed;
|
import it.cavallium.datagen.plugin.ClassGenerator;
|
||||||
import it.cavallium.data.generator.plugin.ComputedTypeArrayVersioned;
|
import it.cavallium.datagen.plugin.ComputedTypeArray;
|
||||||
import it.cavallium.data.generator.plugin.ComputedVersion;
|
import it.cavallium.datagen.plugin.ComputedTypeArrayFixed;
|
||||||
import java.io.DataInput;
|
import it.cavallium.datagen.plugin.ComputedTypeArrayVersioned;
|
||||||
import java.io.DataOutput;
|
import it.cavallium.datagen.plugin.ComputedVersion;
|
||||||
import java.io.IOException;
|
import it.cavallium.stream.SafeDataInput;
|
||||||
import java.io.NotSerializableException;
|
import it.cavallium.stream.SafeDataOutput;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import javax.lang.model.element.Modifier;
|
import javax.lang.model.element.Modifier;
|
||||||
@ -25,6 +26,11 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
|
|
||||||
public class GenSerializerArrayX extends ClassGenerator {
|
public class GenSerializerArrayX extends ClassGenerator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enabling this option can slow down deserialization updates
|
||||||
|
*/
|
||||||
|
private static final boolean USE_NATIVE_TYPED_ARRAYS = false;
|
||||||
|
|
||||||
public GenSerializerArrayX(ClassGeneratorParams params) {
|
public GenSerializerArrayX(ClassGeneratorParams params) {
|
||||||
super(params);
|
super(params);
|
||||||
}
|
}
|
||||||
@ -63,9 +69,8 @@ public class GenSerializerArrayX extends ClassGenerator {
|
|||||||
var method = MethodSpec.methodBuilder("serialize");
|
var method = MethodSpec.methodBuilder("serialize");
|
||||||
|
|
||||||
method.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
method.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
||||||
method.addException(IOException.class);
|
|
||||||
|
|
||||||
method.addParameter(ParameterSpec.builder(DataOutput.class, "out").build());
|
method.addParameter(ParameterSpec.builder(SafeDataOutput.class, "out").build());
|
||||||
method.addParameter(ParameterSpec
|
method.addParameter(ParameterSpec
|
||||||
.builder(typeArray.getJTypeName(basePackageName), "data")
|
.builder(typeArray.getJTypeName(basePackageName), "data")
|
||||||
.addAnnotation(NotNull.class)
|
.addAnnotation(NotNull.class)
|
||||||
@ -77,9 +82,9 @@ public class GenSerializerArrayX extends ClassGenerator {
|
|||||||
method.addStatement("final int sz = data.size()");
|
method.addStatement("final int sz = data.size()");
|
||||||
method.addStatement("out.writeInt(sz)");
|
method.addStatement("out.writeInt(sz)");
|
||||||
method.addCode("\n");
|
method.addCode("\n");
|
||||||
method.beginControlFlow("for (int i = 0; i < sz; ++i)");
|
method.beginControlFlow("for (var item : data)");
|
||||||
var baseSerializerInstance = typeArray.getBase().getJSerializerInstance(basePackageName);
|
var baseSerializerInstance = typeArray.getBase().getJSerializerInstance(basePackageName);
|
||||||
method.addStatement("$T.$N.serialize(out, ($T) data.get(i))",
|
method.addStatement("$T.$N.serialize(out, ($T) item)",
|
||||||
baseSerializerInstance.className(),
|
baseSerializerInstance.className(),
|
||||||
baseSerializerInstance.fieldName(),
|
baseSerializerInstance.fieldName(),
|
||||||
typeArray.getBase().getJTypeName(basePackageName)
|
typeArray.getBase().getJTypeName(basePackageName)
|
||||||
@ -96,26 +101,40 @@ public class GenSerializerArrayX extends ClassGenerator {
|
|||||||
var method = MethodSpec.methodBuilder("deserialize");
|
var method = MethodSpec.methodBuilder("deserialize");
|
||||||
|
|
||||||
method.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
method.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
||||||
method.addException(IOException.class);
|
|
||||||
|
|
||||||
var typeArrayClassName = typeArray.getJTypeName(basePackageName);
|
var typeArrayClassName = typeArray.getJTypeName(basePackageName);
|
||||||
|
|
||||||
|
var arrayComponentTypeName = typeArray.getBase().getJTypeName(basePackageName);
|
||||||
|
var typedArrayTypeName = ArrayTypeName.of(arrayComponentTypeName);
|
||||||
|
|
||||||
method.returns(typeArrayClassName);
|
method.returns(typeArrayClassName);
|
||||||
method.addAnnotation(NotNull.class);
|
method.addAnnotation(NotNull.class);
|
||||||
|
|
||||||
method.addParameter(ParameterSpec.builder(DataInput.class, "in").build());
|
method.addParameter(ParameterSpec.builder(SafeDataInput.class, "in").build());
|
||||||
|
|
||||||
method.addStatement("int sz = in.readInt()");
|
method.addStatement("int sz = in.readInt()");
|
||||||
var arrayTypeName = ArrayTypeName.of(typeArray.getBase().getJTypeName(basePackageName));
|
if (USE_NATIVE_TYPED_ARRAYS) {
|
||||||
method.addStatement("$T a = new $T[sz]", arrayTypeName, arrayTypeName.componentType);
|
method.addStatement("$T a = new $T[sz]", typedArrayTypeName, arrayComponentTypeName);
|
||||||
|
} else {
|
||||||
|
method.addStatement("$T a = new $T[sz]", Object[].class, Object.class);
|
||||||
|
}
|
||||||
method.addCode("\n");
|
method.addCode("\n");
|
||||||
method.beginControlFlow("for (int i = 0; i < sz; ++i)");
|
method.beginControlFlow("for (int i = 0; i < sz; ++i)");
|
||||||
var baseSerializerInstance = typeArray.getBase().getJSerializerInstance(basePackageName);
|
var baseSerializerInstance = typeArray.getBase().getJSerializerInstance(basePackageName);
|
||||||
|
|
||||||
method.addStatement("a[i] = $T.$N.deserialize(in)", baseSerializerInstance.className(), baseSerializerInstance.fieldName());
|
method.addStatement("a[i] = $T.$N.deserialize(in)", baseSerializerInstance.className(), baseSerializerInstance.fieldName());
|
||||||
method.endControlFlow();
|
method.endControlFlow();
|
||||||
|
|
||||||
method.addCode("\n");
|
method.addCode("\n");
|
||||||
method.addStatement("return new $T(a)", ParameterizedTypeName.get(ClassName.get(ImmutableWrappedArrayList.class),
|
if (USE_NATIVE_TYPED_ARRAYS) {
|
||||||
typeArray.getBase().getJTypeName(basePackageName)));
|
method.addStatement("return $T.of(a)", ParameterizedTypeName.get(ClassName.get(ImmutableWrappedArrayList.class), arrayComponentTypeName));
|
||||||
|
} else {
|
||||||
|
method.addStatement("return ($T) ($T) $T.of(a)",
|
||||||
|
ParameterizedTypeName.get(ClassName.get(ImmutableWrappedArrayList.class), arrayComponentTypeName),
|
||||||
|
ParameterizedTypeName.get(ClassName.get(ImmutableWrappedArrayList.class), WildcardTypeName.subtypeOf(TypeName.OBJECT)),
|
||||||
|
ClassName.get(ImmutableWrappedArrayList.class)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
classBuilder.addMethod(method.build());
|
classBuilder.addMethod(method.build());
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.data.generator.plugin.classgen;
|
package it.cavallium.datagen.plugin.classgen;
|
||||||
|
|
||||||
import com.squareup.javapoet.ClassName;
|
import com.squareup.javapoet.ClassName;
|
||||||
import com.squareup.javapoet.CodeBlock;
|
import com.squareup.javapoet.CodeBlock;
|
||||||
@ -7,14 +7,13 @@ import com.squareup.javapoet.ParameterSpec;
|
|||||||
import com.squareup.javapoet.ParameterizedTypeName;
|
import com.squareup.javapoet.ParameterizedTypeName;
|
||||||
import com.squareup.javapoet.TypeSpec;
|
import com.squareup.javapoet.TypeSpec;
|
||||||
import com.squareup.javapoet.TypeSpec.Builder;
|
import com.squareup.javapoet.TypeSpec.Builder;
|
||||||
import it.cavallium.data.generator.DataSerializer;
|
import it.cavallium.datagen.DataSerializer;
|
||||||
import it.cavallium.data.generator.plugin.ClassGenerator;
|
import it.cavallium.datagen.NotSerializableException;
|
||||||
import it.cavallium.data.generator.plugin.ComputedTypeBase;
|
import it.cavallium.datagen.plugin.ClassGenerator;
|
||||||
import it.cavallium.data.generator.plugin.ComputedVersion;
|
import it.cavallium.datagen.plugin.ComputedTypeBase;
|
||||||
import java.io.DataInput;
|
import it.cavallium.datagen.plugin.ComputedVersion;
|
||||||
import java.io.DataOutput;
|
import it.cavallium.stream.SafeDataInput;
|
||||||
import java.io.IOException;
|
import it.cavallium.stream.SafeDataOutput;
|
||||||
import java.io.NotSerializableException;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import javax.lang.model.element.Modifier;
|
import javax.lang.model.element.Modifier;
|
||||||
@ -60,9 +59,8 @@ public class GenSerializerBaseX extends ClassGenerator {
|
|||||||
var method = MethodSpec.methodBuilder("serialize");
|
var method = MethodSpec.methodBuilder("serialize");
|
||||||
|
|
||||||
method.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
method.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
||||||
method.addException(IOException.class);
|
|
||||||
|
|
||||||
method.addParameter(ParameterSpec.builder(DataOutput.class, "out").build());
|
method.addParameter(ParameterSpec.builder(SafeDataOutput.class, "out").build());
|
||||||
method.addParameter(ParameterSpec
|
method.addParameter(ParameterSpec
|
||||||
.builder(typeBase.getJTypeName(basePackageName), "data")
|
.builder(typeBase.getJTypeName(basePackageName), "data")
|
||||||
.addAnnotation(NotNull.class)
|
.addAnnotation(NotNull.class)
|
||||||
@ -95,13 +93,12 @@ public class GenSerializerBaseX extends ClassGenerator {
|
|||||||
var method = MethodSpec.methodBuilder("deserialize");
|
var method = MethodSpec.methodBuilder("deserialize");
|
||||||
|
|
||||||
method.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
method.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
||||||
method.addException(IOException.class);
|
|
||||||
|
|
||||||
ClassName typeBaseClassName = typeBase.getJTypeName(basePackageName);
|
ClassName typeBaseClassName = typeBase.getJTypeName(basePackageName);
|
||||||
method.returns(typeBaseClassName);
|
method.returns(typeBaseClassName);
|
||||||
method.addAnnotation(NotNull.class);
|
method.addAnnotation(NotNull.class);
|
||||||
|
|
||||||
method.addParameter(ParameterSpec.builder(DataInput.class, "in").build());
|
method.addParameter(ParameterSpec.builder(SafeDataInput.class, "in").build());
|
||||||
|
|
||||||
method.addCode("return new $T(\n$>", typeBaseClassName);
|
method.addCode("return new $T(\n$>", typeBaseClassName);
|
||||||
typeBase.getData().entrySet().stream().flatMap(entry -> {
|
typeBase.getData().entrySet().stream().flatMap(entry -> {
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.data.generator.plugin.classgen;
|
package it.cavallium.datagen.plugin.classgen;
|
||||||
|
|
||||||
import com.squareup.javapoet.ClassName;
|
import com.squareup.javapoet.ClassName;
|
||||||
import com.squareup.javapoet.MethodSpec;
|
import com.squareup.javapoet.MethodSpec;
|
||||||
@ -6,16 +6,15 @@ import com.squareup.javapoet.ParameterSpec;
|
|||||||
import com.squareup.javapoet.ParameterizedTypeName;
|
import com.squareup.javapoet.ParameterizedTypeName;
|
||||||
import com.squareup.javapoet.TypeSpec;
|
import com.squareup.javapoet.TypeSpec;
|
||||||
import com.squareup.javapoet.TypeSpec.Builder;
|
import com.squareup.javapoet.TypeSpec.Builder;
|
||||||
import it.cavallium.data.generator.DataSerializer;
|
import it.cavallium.datagen.DataSerializer;
|
||||||
import it.cavallium.data.generator.plugin.ClassGenerator;
|
import it.cavallium.datagen.NotSerializableException;
|
||||||
import it.cavallium.data.generator.plugin.ComputedTypeNullable;
|
import it.cavallium.datagen.plugin.ClassGenerator;
|
||||||
import it.cavallium.data.generator.plugin.ComputedTypeNullableFixed;
|
import it.cavallium.datagen.plugin.ComputedTypeNullable;
|
||||||
import it.cavallium.data.generator.plugin.ComputedTypeNullableVersioned;
|
import it.cavallium.datagen.plugin.ComputedTypeNullableFixed;
|
||||||
import it.cavallium.data.generator.plugin.ComputedVersion;
|
import it.cavallium.datagen.plugin.ComputedTypeNullableVersioned;
|
||||||
import java.io.DataInput;
|
import it.cavallium.datagen.plugin.ComputedVersion;
|
||||||
import java.io.DataOutput;
|
import it.cavallium.stream.SafeDataInput;
|
||||||
import java.io.IOException;
|
import it.cavallium.stream.SafeDataOutput;
|
||||||
import java.io.NotSerializableException;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import javax.lang.model.element.Modifier;
|
import javax.lang.model.element.Modifier;
|
||||||
@ -43,7 +42,7 @@ public class GenSerializerNullableX extends ClassGenerator {
|
|||||||
|
|
||||||
private GeneratedClass generateTypeVersioned(ComputedVersion version, ComputedTypeNullable typeNullable) {
|
private GeneratedClass generateTypeVersioned(ComputedVersion version, ComputedTypeNullable typeNullable) {
|
||||||
ClassName serializerClassName = typeNullable.getJSerializerName(basePackageName);
|
ClassName serializerClassName = typeNullable.getJSerializerName(basePackageName);
|
||||||
var typeNullableClassName = typeNullable.getJTypeName(basePackageName);
|
var typeNullableClassName = typeNullable.getJTypeNameGeneric(basePackageName);
|
||||||
|
|
||||||
var classBuilder = TypeSpec.classBuilder(serializerClassName.simpleName());
|
var classBuilder = TypeSpec.classBuilder(serializerClassName.simpleName());
|
||||||
|
|
||||||
@ -66,11 +65,10 @@ public class GenSerializerNullableX extends ClassGenerator {
|
|||||||
var baseSerializerInstance = base.getJSerializerInstance(basePackageName);
|
var baseSerializerInstance = base.getJSerializerInstance(basePackageName);
|
||||||
|
|
||||||
method.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
method.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
||||||
method.addException(IOException.class);
|
|
||||||
|
|
||||||
method.addParameter(ParameterSpec.builder(DataOutput.class, "out").build());
|
method.addParameter(ParameterSpec.builder(SafeDataOutput.class, "out").build());
|
||||||
method.addParameter(ParameterSpec
|
method.addParameter(ParameterSpec
|
||||||
.builder(typeNullable.getJTypeName(basePackageName), "data")
|
.builder(typeNullable.getJTypeNameGeneric(basePackageName), "data")
|
||||||
.addAnnotation(NotNull.class)
|
.addAnnotation(NotNull.class)
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
@ -101,13 +99,12 @@ public class GenSerializerNullableX extends ClassGenerator {
|
|||||||
var baseSerializerInstance = base.getJSerializerInstance(basePackageName);
|
var baseSerializerInstance = base.getJSerializerInstance(basePackageName);
|
||||||
|
|
||||||
method.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
method.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
||||||
method.addException(IOException.class);
|
|
||||||
|
|
||||||
var typeNullableClassName = typeNullable.getJTypeName(basePackageName);
|
var typeNullableClassName = typeNullable.getJTypeName(basePackageName);
|
||||||
method.returns(typeNullableClassName);
|
method.returns(typeNullableClassName);
|
||||||
method.addAnnotation(NotNull.class);
|
method.addAnnotation(NotNull.class);
|
||||||
|
|
||||||
method.addParameter(ParameterSpec.builder(DataInput.class, "in").build());
|
method.addParameter(ParameterSpec.builder(SafeDataInput.class, "in").build());
|
||||||
|
|
||||||
method.addStatement("return in.readBoolean() ? new $T(($T) $T.$N.deserialize(in)) : $T.empty()",
|
method.addStatement("return in.readBoolean() ? new $T(($T) $T.$N.deserialize(in)) : $T.empty()",
|
||||||
typeNullableClassName,
|
typeNullableClassName,
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.data.generator.plugin.classgen;
|
package it.cavallium.datagen.plugin.classgen;
|
||||||
|
|
||||||
import com.squareup.javapoet.ClassName;
|
import com.squareup.javapoet.ClassName;
|
||||||
import com.squareup.javapoet.MethodSpec;
|
import com.squareup.javapoet.MethodSpec;
|
||||||
@ -6,15 +6,14 @@ import com.squareup.javapoet.ParameterSpec;
|
|||||||
import com.squareup.javapoet.ParameterizedTypeName;
|
import com.squareup.javapoet.ParameterizedTypeName;
|
||||||
import com.squareup.javapoet.TypeSpec;
|
import com.squareup.javapoet.TypeSpec;
|
||||||
import com.squareup.javapoet.TypeSpec.Builder;
|
import com.squareup.javapoet.TypeSpec.Builder;
|
||||||
import it.cavallium.data.generator.DataSerializer;
|
import it.cavallium.datagen.DataSerializer;
|
||||||
import it.cavallium.data.generator.plugin.ClassGenerator;
|
import it.cavallium.datagen.NotSerializableException;
|
||||||
import it.cavallium.data.generator.plugin.ComputedType;
|
import it.cavallium.datagen.plugin.ClassGenerator;
|
||||||
import it.cavallium.data.generator.plugin.ComputedTypeSuper;
|
import it.cavallium.datagen.plugin.ComputedType;
|
||||||
import it.cavallium.data.generator.plugin.ComputedVersion;
|
import it.cavallium.datagen.plugin.ComputedTypeSuper;
|
||||||
import java.io.DataInput;
|
import it.cavallium.datagen.plugin.ComputedVersion;
|
||||||
import java.io.DataOutput;
|
import it.cavallium.stream.SafeDataInput;
|
||||||
import java.io.IOException;
|
import it.cavallium.stream.SafeDataOutput;
|
||||||
import java.io.NotSerializableException;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import javax.lang.model.element.Modifier;
|
import javax.lang.model.element.Modifier;
|
||||||
@ -61,11 +60,10 @@ public class GenSerializerSuperX extends ClassGenerator {
|
|||||||
int max = typeSuper.subTypes().size();
|
int max = typeSuper.subTypes().size();
|
||||||
var method = MethodSpec.methodBuilder("checkIdValidity");
|
var method = MethodSpec.methodBuilder("checkIdValidity");
|
||||||
method.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL);
|
method.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL);
|
||||||
method.addException(IOException.class);
|
|
||||||
method.addParameter(ParameterSpec.builder(int.class, "id").build());
|
method.addParameter(ParameterSpec.builder(int.class, "id").build());
|
||||||
|
|
||||||
method.beginControlFlow("if (id < 0 || id >= $L)", max);
|
method.beginControlFlow("if (id < 0 || id >= $L)", max);
|
||||||
method.addStatement("throw new $T(new $T(id))", IOException.class, IndexOutOfBoundsException.class);
|
method.addStatement("throw new $T(id)", IndexOutOfBoundsException.class);
|
||||||
method.endControlFlow();
|
method.endControlFlow();
|
||||||
|
|
||||||
classBuilder.addMethod(method.build());
|
classBuilder.addMethod(method.build());
|
||||||
@ -75,9 +73,8 @@ public class GenSerializerSuperX extends ClassGenerator {
|
|||||||
var method = MethodSpec.methodBuilder("serialize");
|
var method = MethodSpec.methodBuilder("serialize");
|
||||||
|
|
||||||
method.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
method.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
||||||
method.addException(IOException.class);
|
|
||||||
|
|
||||||
method.addParameter(ParameterSpec.builder(DataOutput.class, "out").build());
|
method.addParameter(ParameterSpec.builder(SafeDataOutput.class, "out").build());
|
||||||
method.addParameter(ParameterSpec
|
method.addParameter(ParameterSpec
|
||||||
.builder(typeSuper.getJTypeName(basePackageName), "data")
|
.builder(typeSuper.getJTypeName(basePackageName), "data")
|
||||||
.addAnnotation(NotNull.class)
|
.addAnnotation(NotNull.class)
|
||||||
@ -118,13 +115,12 @@ public class GenSerializerSuperX extends ClassGenerator {
|
|||||||
var method = MethodSpec.methodBuilder("deserialize");
|
var method = MethodSpec.methodBuilder("deserialize");
|
||||||
|
|
||||||
method.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
method.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
||||||
method.addException(IOException.class);
|
|
||||||
|
|
||||||
ClassName typeSuperClassName = typeSuper.getJTypeName(basePackageName);
|
ClassName typeSuperClassName = typeSuper.getJTypeName(basePackageName);
|
||||||
method.returns(typeSuperClassName);
|
method.returns(typeSuperClassName);
|
||||||
method.addAnnotation(NotNull.class);
|
method.addAnnotation(NotNull.class);
|
||||||
|
|
||||||
method.addParameter(ParameterSpec.builder(DataInput.class, "in").build());
|
method.addParameter(ParameterSpec.builder(SafeDataInput.class, "in").build());
|
||||||
|
|
||||||
method.addStatement("int id = in.readUnsignedByte()");
|
method.addStatement("int id = in.readUnsignedByte()");
|
||||||
method.beginControlFlow("return switch (id)");
|
method.beginControlFlow("return switch (id)");
|
@ -1,7 +1,7 @@
|
|||||||
package it.cavallium.data.generator.plugin.classgen;
|
package it.cavallium.datagen.plugin.classgen;
|
||||||
|
|
||||||
import com.squareup.javapoet.TypeSpec;
|
import com.squareup.javapoet.TypeSpec;
|
||||||
import it.cavallium.data.generator.plugin.ClassGenerator;
|
import it.cavallium.datagen.plugin.ClassGenerator;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import javax.lang.model.element.Modifier;
|
import javax.lang.model.element.Modifier;
|
||||||
|
|
@ -1,6 +1,4 @@
|
|||||||
package it.cavallium.data.generator.plugin.classgen;
|
package it.cavallium.datagen.plugin.classgen;
|
||||||
|
|
||||||
import static it.cavallium.data.generator.plugin.DataModel.fixType;
|
|
||||||
|
|
||||||
import com.squareup.javapoet.ClassName;
|
import com.squareup.javapoet.ClassName;
|
||||||
import com.squareup.javapoet.CodeBlock;
|
import com.squareup.javapoet.CodeBlock;
|
||||||
@ -11,19 +9,12 @@ import com.squareup.javapoet.ParameterizedTypeName;
|
|||||||
import com.squareup.javapoet.TypeName;
|
import com.squareup.javapoet.TypeName;
|
||||||
import com.squareup.javapoet.TypeSpec;
|
import com.squareup.javapoet.TypeSpec;
|
||||||
import com.squareup.javapoet.TypeSpec.Builder;
|
import com.squareup.javapoet.TypeSpec.Builder;
|
||||||
import it.cavallium.data.generator.DataInitializer;
|
import it.cavallium.datagen.*;
|
||||||
import it.cavallium.data.generator.DataUpgrader;
|
import it.cavallium.datagen.plugin.*;
|
||||||
import it.cavallium.data.generator.plugin.ClassGenerator;
|
import it.cavallium.datagen.plugin.ComputedType.VersionedComputedType;
|
||||||
import it.cavallium.data.generator.plugin.ComputedType;
|
import it.cavallium.datagen.plugin.JInterfaceLocation.JInterfaceLocationClassName;
|
||||||
import it.cavallium.data.generator.plugin.ComputedType.VersionedComputedType;
|
import it.cavallium.datagen.plugin.JInterfaceLocation.JInterfaceLocationInstanceField;
|
||||||
import it.cavallium.data.generator.plugin.ComputedTypeBase;
|
|
||||||
import it.cavallium.data.generator.plugin.ComputedVersion;
|
|
||||||
import it.cavallium.data.generator.plugin.MoveDataConfiguration;
|
|
||||||
import it.cavallium.data.generator.plugin.NewDataConfiguration;
|
|
||||||
import it.cavallium.data.generator.plugin.RemoveDataConfiguration;
|
|
||||||
import it.cavallium.data.generator.plugin.TransformationConfiguration;
|
|
||||||
import it.cavallium.data.generator.plugin.UpgradeDataConfiguration;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -35,6 +26,7 @@ import java.util.stream.IntStream;
|
|||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import javax.lang.model.element.Modifier;
|
import javax.lang.model.element.Modifier;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public class GenUpgraderBaseX extends ClassGenerator {
|
public class GenUpgraderBaseX extends ClassGenerator {
|
||||||
|
|
||||||
@ -63,7 +55,7 @@ public class GenUpgraderBaseX extends ClassGenerator {
|
|||||||
|
|
||||||
classBuilder.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
classBuilder.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
||||||
|
|
||||||
classBuilder.addSuperinterface(ParameterizedTypeName.get(ClassName.get(DataUpgrader.class),
|
classBuilder.superclass(ParameterizedTypeName.get(ClassName.get(DataUpgraderSimple.class),
|
||||||
typeBaseClassName,
|
typeBaseClassName,
|
||||||
nextTypeBase.getJTypeName(basePackageName)
|
nextTypeBase.getJTypeName(basePackageName)
|
||||||
));
|
));
|
||||||
@ -79,7 +71,6 @@ public class GenUpgraderBaseX extends ClassGenerator {
|
|||||||
var method = MethodSpec.methodBuilder("upgrade");
|
var method = MethodSpec.methodBuilder("upgrade");
|
||||||
|
|
||||||
method.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
method.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
||||||
method.addException(IOException.class);
|
|
||||||
|
|
||||||
ClassName typeBaseClassName = typeBase.getJTypeName(basePackageName);
|
ClassName typeBaseClassName = typeBase.getJTypeName(basePackageName);
|
||||||
ClassName nextTypeBaseClassName = nextTypeBase.getJTypeName(basePackageName);
|
ClassName nextTypeBaseClassName = nextTypeBase.getJTypeName(basePackageName);
|
||||||
@ -92,6 +83,7 @@ public class GenUpgraderBaseX extends ClassGenerator {
|
|||||||
|
|
||||||
AtomicInteger nextInitializerStaticFieldId = new AtomicInteger();
|
AtomicInteger nextInitializerStaticFieldId = new AtomicInteger();
|
||||||
HashMap<String, String> initializerStaticFieldNames = new HashMap<>();
|
HashMap<String, String> initializerStaticFieldNames = new HashMap<>();
|
||||||
|
HashMap<String, ContextInfo> contextStaticFieldCodeBlocks = new HashMap<>();
|
||||||
AtomicInteger nextUpgraderStaticFieldId = new AtomicInteger();
|
AtomicInteger nextUpgraderStaticFieldId = new AtomicInteger();
|
||||||
HashMap<String, String> upgraderStaticFieldNames = new HashMap<>();
|
HashMap<String, String> upgraderStaticFieldNames = new HashMap<>();
|
||||||
List<TransformationConfiguration> transformations = dataModel.getChanges(nextTypeBase);
|
List<TransformationConfiguration> transformations = dataModel.getChanges(nextTypeBase);
|
||||||
@ -118,20 +110,29 @@ public class GenUpgraderBaseX extends ClassGenerator {
|
|||||||
var i = e.getKey();
|
var i = e.getKey();
|
||||||
var newDataConfiguration = e.getValue();
|
var newDataConfiguration = e.getValue();
|
||||||
var computedTypes = dataModel.getComputedTypes(nextTypeBase.getVersion());
|
var computedTypes = dataModel.getComputedTypes(nextTypeBase.getVersion());
|
||||||
var newFieldType = Objects.requireNonNull(computedTypes.get(fixType(newDataConfiguration.type)));
|
var newFieldType = Objects.requireNonNull(computedTypes.get(DataModel.fixType(newDataConfiguration.type)));
|
||||||
var initializerClass = ClassName.bestGuess(newDataConfiguration.initializer);
|
var initializerLocation = newDataConfiguration.getInitializerLocation();
|
||||||
|
|
||||||
|
var contextInfo = createContextStaticClass(typeBase, e.getValue().to,
|
||||||
|
contextStaticFieldCodeBlocks,
|
||||||
|
classBuilder,
|
||||||
|
initializerLocation,
|
||||||
|
newDataConfiguration.getContextParameters()
|
||||||
|
);
|
||||||
|
|
||||||
var genericInitializerClass = ParameterizedTypeName.get(ClassName.get(DataInitializer.class),
|
var genericInitializerClass = ParameterizedTypeName.get(ClassName.get(DataInitializer.class),
|
||||||
|
contextInfo.typeName(),
|
||||||
newFieldType.getJTypeName(basePackageName).box()
|
newFieldType.getJTypeName(basePackageName).box()
|
||||||
);
|
);
|
||||||
|
|
||||||
var initializerName = createInitializerStaticField(nextInitializerStaticFieldId,
|
var initializerName = createInitializerStaticField(nextInitializerStaticFieldId,
|
||||||
initializerStaticFieldNames,
|
initializerStaticFieldNames,
|
||||||
classBuilder,
|
classBuilder,
|
||||||
initializerClass,
|
initializerLocation,
|
||||||
genericInitializerClass
|
genericInitializerClass
|
||||||
);
|
);
|
||||||
|
|
||||||
return new Field(newDataConfiguration.to, newFieldType, CodeBlock.of("$N.initialize()", initializerName), i + 1);
|
return new Field(newDataConfiguration.to, newFieldType, CodeBlock.of("$N.initialize($L)", initializerName, contextInfo.contextApply), i + 1);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
resultFields = fields.<ResultField>mapMulti((field, consumer) -> {
|
resultFields = fields.<ResultField>mapMulti((field, consumer) -> {
|
||||||
@ -148,7 +149,7 @@ public class GenUpgraderBaseX extends ClassGenerator {
|
|||||||
fieldName = moveDataConfiguration.to;
|
fieldName = moveDataConfiguration.to;
|
||||||
} else if (transformation instanceof NewDataConfiguration newDataConfiguration) {
|
} else if (transformation instanceof NewDataConfiguration newDataConfiguration) {
|
||||||
if (newDataConfiguration.to.equals(fieldName)) {
|
if (newDataConfiguration.to.equals(fieldName)) {
|
||||||
var type = dataModel.getComputedTypes(version).get(fixType(newDataConfiguration.type));
|
var type = dataModel.getComputedTypes(version).get(DataModel.fixType(newDataConfiguration.type));
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"New field " + typeBase.getName() + "." + fieldName + " of type \"" + type + "\" at version \"" + nextTypeBase.getVersion()
|
"New field " + typeBase.getName() + "." + fieldName + " of type \"" + type + "\" at version \"" + nextTypeBase.getVersion()
|
||||||
+ "\" conflicts with another field of type \"" + fieldType + "\" with the same name at version \""
|
+ "\" conflicts with another field of type \"" + fieldType + "\" with the same name at version \""
|
||||||
@ -166,11 +167,20 @@ public class GenUpgraderBaseX extends ClassGenerator {
|
|||||||
if (!upgradeDataConfiguration.from.equals(fieldName)) {
|
if (!upgradeDataConfiguration.from.equals(fieldName)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
var upgraderClass = ClassName.bestGuess(upgradeDataConfiguration.upgrader);
|
var upgraderImplementationLocation = upgradeDataConfiguration.getUpgraderLocation();
|
||||||
var cb = CodeBlock.builder();
|
var cb = CodeBlock.builder();
|
||||||
var newFieldType = Objects
|
var newFieldType = Objects
|
||||||
.requireNonNull(dataModel.getComputedTypes(nextTypeBase.getVersion()).get(fixType(upgradeDataConfiguration.type)));
|
.requireNonNull(dataModel.getComputedTypes(nextTypeBase.getVersion()).get(DataModel.fixType(upgradeDataConfiguration.type)));
|
||||||
|
|
||||||
|
var contextInfo = createContextStaticClass(typeBase, upgradeDataConfiguration.from,
|
||||||
|
contextStaticFieldCodeBlocks,
|
||||||
|
classBuilder,
|
||||||
|
upgraderImplementationLocation,
|
||||||
|
upgradeDataConfiguration.getContextParameters()
|
||||||
|
);
|
||||||
|
|
||||||
var genericUpgraderClass = ParameterizedTypeName.get(ClassName.get(DataUpgrader.class),
|
var genericUpgraderClass = ParameterizedTypeName.get(ClassName.get(DataUpgrader.class),
|
||||||
|
contextInfo.typeName(),
|
||||||
fieldType.getJTypeName(basePackageName).box(),
|
fieldType.getJTypeName(basePackageName).box(),
|
||||||
newFieldType.getJTypeName(basePackageName).box()
|
newFieldType.getJTypeName(basePackageName).box()
|
||||||
);
|
);
|
||||||
@ -178,13 +188,14 @@ public class GenUpgraderBaseX extends ClassGenerator {
|
|||||||
var upgraderName = createUpgraderStaticField(nextUpgraderStaticFieldId,
|
var upgraderName = createUpgraderStaticField(nextUpgraderStaticFieldId,
|
||||||
upgraderStaticFieldNames,
|
upgraderStaticFieldNames,
|
||||||
classBuilder,
|
classBuilder,
|
||||||
upgraderClass,
|
upgraderImplementationLocation,
|
||||||
genericUpgraderClass
|
genericUpgraderClass
|
||||||
);
|
);
|
||||||
|
|
||||||
cb.add("($T) $N.upgrade(($T) ",
|
cb.add("($T) $N.upgrade($L, ($T) ",
|
||||||
newFieldType.getJTypeName(basePackageName),
|
newFieldType.getJTypeName(basePackageName),
|
||||||
upgraderName,
|
upgraderName,
|
||||||
|
contextInfo.contextApply,
|
||||||
fieldType.getJTypeName(basePackageName)
|
fieldType.getJTypeName(basePackageName)
|
||||||
);
|
);
|
||||||
cb.add(codeBlock);
|
cb.add(codeBlock);
|
||||||
@ -225,37 +236,98 @@ public class GenUpgraderBaseX extends ClassGenerator {
|
|||||||
private String createInitializerStaticField(AtomicInteger nextInitializerStaticFieldId,
|
private String createInitializerStaticField(AtomicInteger nextInitializerStaticFieldId,
|
||||||
HashMap<String, String> initializerStaticFieldNames,
|
HashMap<String, String> initializerStaticFieldNames,
|
||||||
Builder classBuilder,
|
Builder classBuilder,
|
||||||
ClassName initializerClass,
|
JInterfaceLocation initializerLocation,
|
||||||
TypeName genericInitializerClass) {
|
TypeName genericInitializerClass) {
|
||||||
var ref = initializerClass.reflectionName();
|
var identifier = initializerLocation.getIdentifier();
|
||||||
var initializerName = initializerStaticFieldNames.get(ref);
|
var initializerName = initializerStaticFieldNames.get(identifier);
|
||||||
if (initializerName == null) {
|
if (initializerName == null) {
|
||||||
initializerName = "I" + nextInitializerStaticFieldId.getAndIncrement();
|
initializerName = "I" + nextInitializerStaticFieldId.getAndIncrement();
|
||||||
classBuilder.addField(FieldSpec
|
var fieldBuilder = FieldSpec
|
||||||
.builder(genericInitializerClass, initializerName)
|
.builder(genericInitializerClass, initializerName)
|
||||||
.addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL)
|
.addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL);
|
||||||
.initializer("new $T()", initializerClass)
|
switch (initializerLocation) {
|
||||||
.build());
|
case JInterfaceLocationClassName className -> fieldBuilder.initializer("new $T()", className.className());
|
||||||
initializerStaticFieldNames.put(ref, initializerName);
|
case JInterfaceLocationInstanceField instanceField -> fieldBuilder.initializer("$T.$N",
|
||||||
|
instanceField.fieldLocation().className(),
|
||||||
|
instanceField.fieldLocation().fieldName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
classBuilder.addField(fieldBuilder.build());
|
||||||
|
initializerStaticFieldNames.put(identifier, initializerName);
|
||||||
}
|
}
|
||||||
return initializerName;
|
return initializerName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
record ContextInfo(TypeName typeName, CodeBlock contextApply) {}
|
||||||
|
|
||||||
|
private ContextInfo createContextStaticClass(ComputedTypeBase typeBase,
|
||||||
|
String fieldName,
|
||||||
|
HashMap<String, ContextInfo> contextStaticFieldCodeBlocks,
|
||||||
|
Builder classBuilder,
|
||||||
|
JInterfaceLocation initializerLocation,
|
||||||
|
@NotNull List<String> contextParameters) {
|
||||||
|
var identifier = initializerLocation.getIdentifier();
|
||||||
|
var contextStaticFieldCodeBlock = contextStaticFieldCodeBlocks.get(identifier);
|
||||||
|
if (contextStaticFieldCodeBlock == null) {
|
||||||
|
var codeBlockBuilder = CodeBlock.builder();
|
||||||
|
TypeName typeName;
|
||||||
|
|
||||||
|
if (contextParameters.isEmpty()) {
|
||||||
|
typeName = ClassName.get(DataContextNone.class);
|
||||||
|
codeBlockBuilder.add("$T.INSTANCE", typeName);
|
||||||
|
} else {
|
||||||
|
var name = "Context" + SourcesGenerator.capitalize(fieldName);
|
||||||
|
var contextTypeClassBuilder = TypeSpec.recordBuilder(name)
|
||||||
|
.addSuperinterface(ClassName.get(DataContext.class))
|
||||||
|
.addModifiers(Modifier.PUBLIC, Modifier.STATIC);
|
||||||
|
typeName = typeBase.getJUpgraderName(basePackageName).nestedClass(name);
|
||||||
|
|
||||||
|
codeBlockBuilder.add("new $T(", typeName);
|
||||||
|
boolean first = true;
|
||||||
|
for (String contextParameter : contextParameters) {
|
||||||
|
var fieldType = typeBase.getData().get(contextParameter);
|
||||||
|
contextTypeClassBuilder.addRecordComponent(ParameterSpec.builder(fieldType.getJTypeNameGeneric(basePackageName), contextParameter).build());
|
||||||
|
|
||||||
|
if (first) {
|
||||||
|
first = false;
|
||||||
|
} else {
|
||||||
|
codeBlockBuilder.add(", ");
|
||||||
|
}
|
||||||
|
codeBlockBuilder.add("data.$N()", contextParameter);
|
||||||
|
}
|
||||||
|
codeBlockBuilder.add(")");
|
||||||
|
|
||||||
|
var clazz = contextTypeClassBuilder.build();
|
||||||
|
classBuilder.addType(clazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
contextStaticFieldCodeBlock = new ContextInfo(typeName, codeBlockBuilder.build());
|
||||||
|
contextStaticFieldCodeBlocks.put(identifier, contextStaticFieldCodeBlock);
|
||||||
|
}
|
||||||
|
return contextStaticFieldCodeBlock;
|
||||||
|
}
|
||||||
|
|
||||||
private String createUpgraderStaticField(AtomicInteger nextUpgraderStaticFieldId,
|
private String createUpgraderStaticField(AtomicInteger nextUpgraderStaticFieldId,
|
||||||
HashMap<String, String> upgraderStaticFieldNames,
|
HashMap<String, String> upgraderStaticFieldNames,
|
||||||
Builder classBuilder,
|
Builder classBuilder,
|
||||||
ClassName upgraderClass,
|
JInterfaceLocation upgraderLocation,
|
||||||
TypeName genericUpgraderClass) {
|
TypeName genericUpgraderClass) {
|
||||||
var ref = upgraderClass.reflectionName();
|
var identifier = upgraderLocation.getIdentifier();
|
||||||
var upgraderName = upgraderStaticFieldNames.get(ref);
|
var upgraderName = upgraderStaticFieldNames.get(identifier);
|
||||||
if (upgraderName == null) {
|
if (upgraderName == null) {
|
||||||
upgraderName = "U" + nextUpgraderStaticFieldId.getAndIncrement();
|
upgraderName = "U" + nextUpgraderStaticFieldId.getAndIncrement();
|
||||||
classBuilder.addField(FieldSpec
|
var fieldBuilder = FieldSpec
|
||||||
.builder(genericUpgraderClass, upgraderName)
|
.builder(genericUpgraderClass, upgraderName)
|
||||||
.addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL)
|
.addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL);
|
||||||
.initializer("new $T()", upgraderClass)
|
switch (upgraderLocation) {
|
||||||
.build());
|
case JInterfaceLocationClassName className -> fieldBuilder.initializer("new $T()", className.className());
|
||||||
upgraderStaticFieldNames.put(ref, upgraderName);
|
case JInterfaceLocationInstanceField instanceField -> fieldBuilder.initializer("$T.$N",
|
||||||
|
instanceField.fieldLocation().className(),
|
||||||
|
instanceField.fieldLocation().fieldName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
classBuilder.addField(fieldBuilder.build());
|
||||||
|
upgraderStaticFieldNames.put(identifier, upgraderName);
|
||||||
}
|
}
|
||||||
return upgraderName;
|
return upgraderName;
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.data.generator.plugin.classgen;
|
package it.cavallium.datagen.plugin.classgen;
|
||||||
|
|
||||||
import com.squareup.javapoet.ClassName;
|
import com.squareup.javapoet.ClassName;
|
||||||
import com.squareup.javapoet.CodeBlock;
|
import com.squareup.javapoet.CodeBlock;
|
||||||
@ -7,13 +7,13 @@ import com.squareup.javapoet.ParameterSpec;
|
|||||||
import com.squareup.javapoet.ParameterizedTypeName;
|
import com.squareup.javapoet.ParameterizedTypeName;
|
||||||
import com.squareup.javapoet.TypeSpec;
|
import com.squareup.javapoet.TypeSpec;
|
||||||
import com.squareup.javapoet.TypeSpec.Builder;
|
import com.squareup.javapoet.TypeSpec.Builder;
|
||||||
import it.cavallium.data.generator.DataUpgrader;
|
import it.cavallium.datagen.DataUpgrader;
|
||||||
import it.cavallium.data.generator.plugin.ClassGenerator;
|
import it.cavallium.datagen.DataUpgraderSimple;
|
||||||
import it.cavallium.data.generator.plugin.ComputedType;
|
import it.cavallium.datagen.plugin.ClassGenerator;
|
||||||
import it.cavallium.data.generator.plugin.ComputedType.VersionedComputedType;
|
import it.cavallium.datagen.plugin.ComputedType;
|
||||||
import it.cavallium.data.generator.plugin.ComputedTypeSuper;
|
import it.cavallium.datagen.plugin.ComputedType.VersionedComputedType;
|
||||||
import it.cavallium.data.generator.plugin.ComputedVersion;
|
import it.cavallium.datagen.plugin.ComputedTypeSuper;
|
||||||
import java.io.IOException;
|
import it.cavallium.datagen.plugin.ComputedVersion;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import javax.lang.model.element.Modifier;
|
import javax.lang.model.element.Modifier;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@ -45,7 +45,7 @@ public class GenUpgraderSuperX extends ClassGenerator {
|
|||||||
|
|
||||||
classBuilder.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
classBuilder.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
||||||
|
|
||||||
classBuilder.addSuperinterface(ParameterizedTypeName.get(ClassName.get(DataUpgrader.class),
|
classBuilder.superclass(ParameterizedTypeName.get(ClassName.get(DataUpgraderSimple.class),
|
||||||
typeBaseClassName,
|
typeBaseClassName,
|
||||||
nextTypeSuper.getJTypeName(basePackageName)
|
nextTypeSuper.getJTypeName(basePackageName)
|
||||||
));
|
));
|
||||||
@ -61,7 +61,6 @@ public class GenUpgraderSuperX extends ClassGenerator {
|
|||||||
var method = MethodSpec.methodBuilder("upgrade");
|
var method = MethodSpec.methodBuilder("upgrade");
|
||||||
|
|
||||||
method.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
method.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
||||||
method.addException(IOException.class);
|
|
||||||
|
|
||||||
ClassName typeSuperClassName = typeSuper.getJTypeName(basePackageName);
|
ClassName typeSuperClassName = typeSuper.getJTypeName(basePackageName);
|
||||||
ClassName nextTypeSuperClassName = nextTypeSuper.getJTypeName(basePackageName);
|
ClassName nextTypeSuperClassName = nextTypeSuper.getJTypeName(basePackageName);
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.data.generator.plugin.classgen;
|
package it.cavallium.datagen.plugin.classgen;
|
||||||
|
|
||||||
import com.squareup.javapoet.ClassName;
|
import com.squareup.javapoet.ClassName;
|
||||||
import com.squareup.javapoet.CodeBlock;
|
import com.squareup.javapoet.CodeBlock;
|
||||||
@ -9,17 +9,17 @@ import com.squareup.javapoet.TypeName;
|
|||||||
import com.squareup.javapoet.TypeSpec;
|
import com.squareup.javapoet.TypeSpec;
|
||||||
import com.squareup.javapoet.TypeSpec.Builder;
|
import com.squareup.javapoet.TypeSpec.Builder;
|
||||||
import com.squareup.javapoet.TypeVariableName;
|
import com.squareup.javapoet.TypeVariableName;
|
||||||
import it.cavallium.data.generator.DataSerializer;
|
import it.cavallium.datagen.DataSerializer;
|
||||||
import it.cavallium.data.generator.DataUpgrader;
|
import it.cavallium.datagen.DataUpgrader;
|
||||||
import it.cavallium.data.generator.plugin.ClassGenerator;
|
import it.cavallium.datagen.DataUpgraderSimple;
|
||||||
import it.cavallium.data.generator.plugin.ComputedType.VersionedComputedType;
|
import it.cavallium.datagen.plugin.ClassGenerator;
|
||||||
import it.cavallium.data.generator.plugin.ComputedTypeArrayFixed;
|
import it.cavallium.datagen.plugin.ComputedType.VersionedComputedType;
|
||||||
import it.cavallium.data.generator.plugin.ComputedTypeBase;
|
import it.cavallium.datagen.plugin.ComputedTypeArrayFixed;
|
||||||
import it.cavallium.data.generator.plugin.ComputedTypeCustom;
|
import it.cavallium.datagen.plugin.ComputedTypeBase;
|
||||||
import it.cavallium.data.generator.plugin.ComputedTypeNullableFixed;
|
import it.cavallium.datagen.plugin.ComputedTypeCustom;
|
||||||
import it.cavallium.data.generator.plugin.ComputedTypeSuper;
|
import it.cavallium.datagen.plugin.ComputedTypeNullableFixed;
|
||||||
import it.cavallium.data.generator.plugin.ComputedVersion;
|
import it.cavallium.datagen.plugin.ComputedTypeSuper;
|
||||||
import java.io.IOException;
|
import it.cavallium.datagen.plugin.ComputedVersion;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import javax.lang.model.element.Modifier;
|
import javax.lang.model.element.Modifier;
|
||||||
@ -105,7 +105,6 @@ public class GenVersion extends ClassGenerator {
|
|||||||
var methodBuilder = MethodSpec.methodBuilder("upgradeToNextVersion");
|
var methodBuilder = MethodSpec.methodBuilder("upgradeToNextVersion");
|
||||||
|
|
||||||
methodBuilder.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL);
|
methodBuilder.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL);
|
||||||
methodBuilder.addException(ClassName.get(IOException.class));
|
|
||||||
|
|
||||||
var nextIBaseType = ClassName.get(nextVersion.getPackage(basePackageName), "IBaseType");
|
var nextIBaseType = ClassName.get(nextVersion.getPackage(basePackageName), "IBaseType");
|
||||||
methodBuilder.returns(nextIBaseType);
|
methodBuilder.returns(nextIBaseType);
|
||||||
@ -166,7 +165,7 @@ public class GenVersion extends ClassGenerator {
|
|||||||
var serializerClassName = type.getJSerializerName(basePackageName);
|
var serializerClassName = type.getJSerializerName(basePackageName);
|
||||||
|
|
||||||
var fieldBuilder = FieldSpec.builder(ParameterizedTypeName.get(ClassName.get(DataSerializer.class),
|
var fieldBuilder = FieldSpec.builder(ParameterizedTypeName.get(ClassName.get(DataSerializer.class),
|
||||||
type.getJTypeName(basePackageName)
|
type.getJTypeNameGeneric(basePackageName)
|
||||||
), serializerFieldLocation.fieldName(), Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL);
|
), serializerFieldLocation.fieldName(), Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL);
|
||||||
fieldBuilder.initializer("new $T()", serializerClassName);
|
fieldBuilder.initializer("new $T()", serializerClassName);
|
||||||
classBuilder.addField(fieldBuilder.build());
|
classBuilder.addField(fieldBuilder.build());
|
||||||
@ -190,7 +189,7 @@ public class GenVersion extends ClassGenerator {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var genericClassName = ParameterizedTypeName.get(ClassName.get(DataUpgrader.class),
|
var genericClassName = ParameterizedTypeName.get(ClassName.get(DataUpgraderSimple.class),
|
||||||
type.getJTypeName(basePackageName), nextVersion.getJTypeName(basePackageName)
|
type.getJTypeName(basePackageName), nextVersion.getJTypeName(basePackageName)
|
||||||
);
|
);
|
||||||
var upgraderClassName = type.getJUpgraderName(basePackageName);
|
var upgraderClassName = type.getJUpgraderName(basePackageName);
|
||||||
@ -211,7 +210,6 @@ public class GenVersion extends ClassGenerator {
|
|||||||
|
|
||||||
methodBuilder.addModifiers(Modifier.PUBLIC);
|
methodBuilder.addModifiers(Modifier.PUBLIC);
|
||||||
methodBuilder.addAnnotation(Override.class);
|
methodBuilder.addAnnotation(Override.class);
|
||||||
methodBuilder.addException(ClassName.get(IOException.class));
|
|
||||||
|
|
||||||
var iBaseTypeClassName = ClassName.get(version.getPackage(basePackageName), "IBaseType");
|
var iBaseTypeClassName = ClassName.get(version.getPackage(basePackageName), "IBaseType");
|
||||||
methodBuilder.addTypeVariable(TypeVariableName.get("T", iBaseTypeClassName));
|
methodBuilder.addTypeVariable(TypeVariableName.get("T", iBaseTypeClassName));
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.data.generator.plugin.classgen;
|
package it.cavallium.datagen.plugin.classgen;
|
||||||
|
|
||||||
import com.squareup.javapoet.ArrayTypeName;
|
import com.squareup.javapoet.ArrayTypeName;
|
||||||
import com.squareup.javapoet.ClassName;
|
import com.squareup.javapoet.ClassName;
|
||||||
@ -6,11 +6,9 @@ import com.squareup.javapoet.CodeBlock;
|
|||||||
import com.squareup.javapoet.FieldSpec;
|
import com.squareup.javapoet.FieldSpec;
|
||||||
import com.squareup.javapoet.TypeName;
|
import com.squareup.javapoet.TypeName;
|
||||||
import com.squareup.javapoet.TypeSpec;
|
import com.squareup.javapoet.TypeSpec;
|
||||||
import it.cavallium.data.generator.plugin.ClassGenerator;
|
import it.cavallium.datagen.plugin.ClassGenerator;
|
||||||
import it.cavallium.data.generator.plugin.ComputedVersion;
|
import it.cavallium.datagen.plugin.ComputedVersion;
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import javax.lang.model.element.Modifier;
|
import javax.lang.model.element.Modifier;
|
@ -5,13 +5,13 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<name>Data generator runtime</name>
|
<name>Data generator runtime</name>
|
||||||
<artifactId>data-generator-runtime</artifactId>
|
<artifactId>datagen</artifactId>
|
||||||
<version>${revision}</version>
|
<version>${revision}</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>it.cavallium</groupId>
|
<groupId>it.cavallium</groupId>
|
||||||
<version>${revision}</version>
|
<version>${revision}</version>
|
||||||
<artifactId>data-generator</artifactId>
|
<artifactId>datagen-parent</artifactId>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<properties>
|
<properties>
|
||||||
@ -67,7 +67,7 @@
|
|||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>3.8.1</version>
|
<version>3.8.1</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<release>17</release>
|
<release>21</release>
|
||||||
<encoding>UTF-8</encoding>
|
<encoding>UTF-8</encoding>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
@ -101,6 +101,37 @@
|
|||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-source-plugin</artifactId>
|
||||||
|
<version>3.2.1</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>attach-sources</id>
|
||||||
|
<phase>verify</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>jar-no-fork</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
<version>3.5.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>attach-javadoc</id>
|
||||||
|
<phase>verify</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>jar</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<doclint>all,-missing</doclint>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
<pluginManagement>
|
<pluginManagement>
|
||||||
<plugins>
|
<plugins>
|
||||||
@ -128,7 +159,7 @@
|
|||||||
</goals>
|
</goals>
|
||||||
</pluginExecutionFilter>
|
</pluginExecutionFilter>
|
||||||
<action>
|
<action>
|
||||||
<ignore></ignore>
|
<ignore/>
|
||||||
</action>
|
</action>
|
||||||
</pluginExecution>
|
</pluginExecution>
|
||||||
</pluginExecutions>
|
</pluginExecutions>
|
||||||
@ -159,6 +190,17 @@
|
|||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-params</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava</artifactId>
|
||||||
|
<version>33.0.0-jre</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
@ -175,7 +217,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>junit-jupiter-api</artifactId>
|
<artifactId>junit-jupiter-api</artifactId>
|
||||||
<version>5.9.0</version>
|
<version>5.9.2</version>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<groupId>org.hamcrest</groupId>
|
<groupId>org.hamcrest</groupId>
|
||||||
@ -183,6 +225,95 @@
|
|||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-params</artifactId>
|
||||||
|
<version>5.9.2</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>java9</id>
|
||||||
|
<activation>
|
||||||
|
<activeByDefault>true</activeByDefault>
|
||||||
|
</activation>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>build-helper-maven-plugin</artifactId>
|
||||||
|
<version>3.6.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>add-source</id>
|
||||||
|
<phase>generate-sources</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>add-source</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<sources>
|
||||||
|
<source>src/java9/java</source>
|
||||||
|
</sources>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
<profile>
|
||||||
|
<id>benchmark</id>
|
||||||
|
<activation>
|
||||||
|
<activeByDefault>false</activeByDefault>
|
||||||
|
</activation>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.openjdk.jmh</groupId>
|
||||||
|
<artifactId>jmh-core</artifactId>
|
||||||
|
<version>1.36</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.openjdk.jmh</groupId>
|
||||||
|
<artifactId>jmh-generator-annprocess</artifactId>
|
||||||
|
<version>1.36</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>build-helper-maven-plugin</artifactId>
|
||||||
|
<version>3.6.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>add-source</id>
|
||||||
|
<phase>generate-sources</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>add-source</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<sources>
|
||||||
|
<source>src/benchmark/java</source>
|
||||||
|
</sources>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.8.1</version>
|
||||||
|
<configuration>
|
||||||
|
<release>21</release>
|
||||||
|
<encoding>UTF-8</encoding>
|
||||||
|
<excludes>
|
||||||
|
<exclude>src/main/java/module-info.java</exclude>
|
||||||
|
</excludes>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
</project>
|
</project>
|
@ -0,0 +1,14 @@
|
|||||||
|
package it.cavallium.buffer;
|
||||||
|
|
||||||
|
import org.openjdk.jmh.runner.Runner;
|
||||||
|
import org.openjdk.jmh.runner.RunnerException;
|
||||||
|
import org.openjdk.jmh.runner.options.Options;
|
||||||
|
import org.openjdk.jmh.runner.options.OptionsBuilder;
|
||||||
|
|
||||||
|
public class BenchmarkMain {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws RunnerException {
|
||||||
|
Options opt = new OptionsBuilder().include(BufEncoderBench.class.getSimpleName()).build();
|
||||||
|
new Runner(opt).run();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,124 @@
|
|||||||
|
package it.cavallium.buffer;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
|
public class BenchmarkMainManual {
|
||||||
|
|
||||||
|
public static class BenchmarkZeroCopy {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
var s2 = new ZeroAllocationEncoderBenchState();
|
||||||
|
s2.prepare();
|
||||||
|
while (true) {
|
||||||
|
s2.reset();
|
||||||
|
encodeMediumTextZeroCopy(s2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BenchmarkJava {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
var s2 = new ZeroAllocationEncoderBenchState();
|
||||||
|
s2.prepare();
|
||||||
|
while (true) {
|
||||||
|
s2.reset();
|
||||||
|
encodeMediumTextJava(s2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ZeroAllocationEncoderBenchState {
|
||||||
|
private static final List<String> WORDS = List.of(
|
||||||
|
"\uD83D\uDC69\uD83C\uDFFF\u200D\uD83D\uDC69\uD83C\uDFFF\u200D\uD83D\uDC67\uD83C\uDFFF\u200D\uD83D\uDC66\uD83C\uDFFF",
|
||||||
|
"hello",
|
||||||
|
"test",
|
||||||
|
"òàòà§òè+=))=732e0",
|
||||||
|
"ل موقع يسمح لزواره الكرام بتحويل الكتابة العربي الى كتابة مفه",
|
||||||
|
"\uD800\uDF3C\uD800\uDF30\uD800\uDF32 \uD800\uDF32\uD800\uDF3B\uD800\uDF34\uD800\uDF43 \uD800\uDF39̈\uD800\uDF44\uD800\uDF30\uD800\uDF3D, \uD800\uDF3D\uD800\uDF39 \uD800\uDF3C\uD800\uDF39\uD800\uDF43 \uD800\uDF45\uD800\uDF3F \uD800\uDF3D\uD800\uDF33\uD800\uDF30\uD800\uDF3D \uD800\uDF31\uD800\uDF42\uD800\uDF39\uD800\uDF32\uD800\uDF32\uD800\uDF39\uD800\uDF38.",
|
||||||
|
"Z̤͔ͧ̑̓ä͖̭̈̇lͮ̒ͫǧ̗͚̚o̙̔ͮ̇͐̇",
|
||||||
|
"من left اليمين to الى right اليسار",
|
||||||
|
"a\u202Db\u202Ec\u202Dd\u202Ee\u202Df\u202Eg",
|
||||||
|
"﷽﷽﷽﷽﷽﷽﷽﷽﷽﷽﷽﷽﷽﷽﷽﷽",
|
||||||
|
"\uD83D\uDC71\uD83D\uDC71\uD83C\uDFFB\uD83D\uDC71\uD83C\uDFFC\uD83D\uDC71\uD83C\uDFFD\uD83D\uDC71\uD83C\uDFFE\uD83D\uDC71\uD83C\uDFFF",
|
||||||
|
"\uD83E\uDDDF\u200D♀\uFE0F\uD83E\uDDDF\u200D♂\uFE0F",
|
||||||
|
"\uD83D\uDC68\u200D❤\uFE0F\u200D\uD83D\uDC8B\u200D\uD83D\uDC68\uD83D\uDC69\u200D\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC66\uD83C\uDFF3\uFE0F\u200D⚧\uFE0F\uD83C\uDDF5\uD83C\uDDF7",
|
||||||
|
"田中さんにあげて下さい",
|
||||||
|
"ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็ ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็ ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็",
|
||||||
|
"\uD801\uDC1C \uD801\uDC14\uD801\uDC07\uD801\uDC1D\uD801\uDC00\uD801\uDC21\uD801\uDC07\uD801\uDC13 \uD801\uDC19\uD801\uDC0A\uD801\uDC21\uD801\uDC1D\uD801\uDC13/\uD801\uDC1D\uD801\uDC07\uD801\uDC17\uD801\uDC0A\uD801\uDC24\uD801\uDC14 \uD801\uDC12\uD801\uDC0B\uD801\uDC17 \uD801\uDC12\uD801\uDC0C \uD801\uDC1C \uD801\uDC21\uD801\uDC00\uD801\uDC16\uD801\uDC07\uD801\uDC24\uD801\uDC13\uD801\uDC1D \uD801\uDC31\uD801\uDC42 \uD801\uDC44 \uD801\uDC14\uD801\uDC07\uD801\uDC1D\uD801\uDC00\uD801\uDC21\uD801\uDC07\uD801\uDC13 \uD801\uDC0F\uD801\uDC06\uD801\uDC05\uD801\uDC24\uD801\uDC06\uD801\uDC1A\uD801\uDC0A\uD801\uDC21\uD801\uDC1D\uD801\uDC06\uD801\uDC13\uD801\uDC06",
|
||||||
|
"表ポあA鷗ŒéB逍Üߪąñ丂㐀\uD840\uDC00",
|
||||||
|
"᚛ᚄᚓᚐᚋᚒᚄ ᚑᚄᚂᚑᚏᚅ᚜\n" +
|
||||||
|
"᚛ ᚜\n",
|
||||||
|
"Powerلُلُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ冗\n" +
|
||||||
|
"\uD83C\uDFF30\uD83C\uDF08\uFE0F\n" +
|
||||||
|
"జ్ఞ\u200Cా"
|
||||||
|
);
|
||||||
|
String shortText;
|
||||||
|
byte[] shortTextBytes;
|
||||||
|
BufDataInput shortTextInput;
|
||||||
|
BufDataOutput shortTextOutput;
|
||||||
|
String mediumText;
|
||||||
|
byte[] mediumTextBytes;
|
||||||
|
BufDataInput mediumTextInput;
|
||||||
|
BufDataOutput mediumTextOutput;
|
||||||
|
String longText;
|
||||||
|
byte[] longTextBytes;
|
||||||
|
BufDataInput longTextInput;
|
||||||
|
BufDataOutput longTextOutput;
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
longTextInput.reset();
|
||||||
|
longTextOutput.resetUnderlyingBuffer();
|
||||||
|
mediumTextInput.reset();
|
||||||
|
mediumTextOutput.resetUnderlyingBuffer();
|
||||||
|
shortTextInput.reset();
|
||||||
|
shortTextOutput.resetUnderlyingBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void prepare() {
|
||||||
|
var l = new ArrayList<String>();
|
||||||
|
var maxI = ThreadLocalRandom.current().nextInt(1, 20);
|
||||||
|
for (int i = 0; i < maxI; i++) {
|
||||||
|
l.addAll(WORDS);
|
||||||
|
}
|
||||||
|
Collections.shuffle(l);
|
||||||
|
var fullText = String.join(" ", l);
|
||||||
|
var out = BufDataOutput.create(Integer.BYTES + fullText.getBytes(StandardCharsets.UTF_8).length);
|
||||||
|
|
||||||
|
out.resetUnderlyingBuffer();
|
||||||
|
longText = fullText;
|
||||||
|
longTextBytes = longText.getBytes(StandardCharsets.UTF_8);
|
||||||
|
out.writeMediumText(longText, StandardCharsets.UTF_8);
|
||||||
|
longTextInput = BufDataInput.create(out.toList());
|
||||||
|
longTextOutput = BufDataOutput.create(Integer.BYTES + longTextBytes.length);
|
||||||
|
|
||||||
|
out.resetUnderlyingBuffer();
|
||||||
|
mediumText = fullText.substring(0, 128);
|
||||||
|
mediumTextBytes = mediumText.getBytes(StandardCharsets.UTF_8);
|
||||||
|
out.writeMediumText(mediumText, StandardCharsets.UTF_8);
|
||||||
|
mediumTextInput = BufDataInput.create(out.toList());
|
||||||
|
mediumTextOutput = BufDataOutput.create(Integer.BYTES + mediumTextBytes.length);
|
||||||
|
|
||||||
|
out.resetUnderlyingBuffer();
|
||||||
|
shortText = fullText.substring(0, 15);
|
||||||
|
shortTextBytes = shortText.getBytes(StandardCharsets.UTF_8);
|
||||||
|
out.writeMediumText(shortText, StandardCharsets.UTF_8);
|
||||||
|
shortTextInput = BufDataInput.create(out.toList());
|
||||||
|
shortTextOutput = BufDataOutput.create(Integer.BYTES + shortTextBytes.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Buf encodeMediumTextZeroCopy(ZeroAllocationEncoderBenchState benchState) {
|
||||||
|
var out = benchState.mediumTextOutput;
|
||||||
|
out.writeMediumTextZeroCopy(benchState.mediumText);
|
||||||
|
return out.toList();
|
||||||
|
}
|
||||||
|
public static Buf encodeMediumTextJava(ZeroAllocationEncoderBenchState benchState) {
|
||||||
|
var out = benchState.mediumTextOutput;
|
||||||
|
out.writeMediumTextLegacy(benchState.mediumText, StandardCharsets.UTF_8);
|
||||||
|
return out.toList();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,174 @@
|
|||||||
|
package it.cavallium.buffer;
|
||||||
|
|
||||||
|
import org.openjdk.jmh.annotations.*;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@State(Scope.Benchmark)
|
||||||
|
@OutputTimeUnit(TimeUnit.SECONDS)
|
||||||
|
@BenchmarkMode(Mode.Throughput)
|
||||||
|
@Fork(value = 1, warmups = 1)
|
||||||
|
@Warmup(time = 2, iterations = 6)
|
||||||
|
@Measurement(time = 2, iterations = 6)
|
||||||
|
public class BufEncoderBench {
|
||||||
|
|
||||||
|
@State(Scope.Thread)
|
||||||
|
public static class ZeroAllocationEncoderState {
|
||||||
|
ZeroAllocationEncoder encoder;
|
||||||
|
BufDataOutput bufOutput;
|
||||||
|
|
||||||
|
@Setup
|
||||||
|
public void prepare() {
|
||||||
|
encoder = ZeroAllocationEncoder.INSTANCE;
|
||||||
|
bufOutput = BufDataOutput.create(1024);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@State(Scope.Benchmark)
|
||||||
|
public static class ZeroAllocationEncoderBenchState {
|
||||||
|
private static final List<String> WORDS = List.of(
|
||||||
|
"\uD83D\uDC69\uD83C\uDFFF\u200D\uD83D\uDC69\uD83C\uDFFF\u200D\uD83D\uDC67\uD83C\uDFFF\u200D\uD83D\uDC66\uD83C\uDFFF",
|
||||||
|
"hello",
|
||||||
|
"test",
|
||||||
|
"òàòà§òè+=))=732e0",
|
||||||
|
"ل موقع يسمح لزواره الكرام بتحويل الكتابة العربي الى كتابة مفه",
|
||||||
|
"\uD800\uDF3C\uD800\uDF30\uD800\uDF32 \uD800\uDF32\uD800\uDF3B\uD800\uDF34\uD800\uDF43 \uD800\uDF39̈\uD800\uDF44\uD800\uDF30\uD800\uDF3D, \uD800\uDF3D\uD800\uDF39 \uD800\uDF3C\uD800\uDF39\uD800\uDF43 \uD800\uDF45\uD800\uDF3F \uD800\uDF3D\uD800\uDF33\uD800\uDF30\uD800\uDF3D \uD800\uDF31\uD800\uDF42\uD800\uDF39\uD800\uDF32\uD800\uDF32\uD800\uDF39\uD800\uDF38.",
|
||||||
|
"Z̤͔ͧ̑̓ä͖̭̈̇lͮ̒ͫǧ̗͚̚o̙̔ͮ̇͐̇",
|
||||||
|
"من left اليمين to الى right اليسار",
|
||||||
|
"a\u202Db\u202Ec\u202Dd\u202Ee\u202Df\u202Eg",
|
||||||
|
"﷽﷽﷽﷽﷽﷽﷽﷽﷽﷽﷽﷽﷽﷽﷽﷽",
|
||||||
|
"\uD83D\uDC71\uD83D\uDC71\uD83C\uDFFB\uD83D\uDC71\uD83C\uDFFC\uD83D\uDC71\uD83C\uDFFD\uD83D\uDC71\uD83C\uDFFE\uD83D\uDC71\uD83C\uDFFF",
|
||||||
|
"\uD83E\uDDDF\u200D♀\uFE0F\uD83E\uDDDF\u200D♂\uFE0F",
|
||||||
|
"\uD83D\uDC68\u200D❤\uFE0F\u200D\uD83D\uDC8B\u200D\uD83D\uDC68\uD83D\uDC69\u200D\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC66\uD83C\uDFF3\uFE0F\u200D⚧\uFE0F\uD83C\uDDF5\uD83C\uDDF7",
|
||||||
|
"田中さんにあげて下さい",
|
||||||
|
"ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็ ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็ ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็",
|
||||||
|
"\uD801\uDC1C \uD801\uDC14\uD801\uDC07\uD801\uDC1D\uD801\uDC00\uD801\uDC21\uD801\uDC07\uD801\uDC13 \uD801\uDC19\uD801\uDC0A\uD801\uDC21\uD801\uDC1D\uD801\uDC13/\uD801\uDC1D\uD801\uDC07\uD801\uDC17\uD801\uDC0A\uD801\uDC24\uD801\uDC14 \uD801\uDC12\uD801\uDC0B\uD801\uDC17 \uD801\uDC12\uD801\uDC0C \uD801\uDC1C \uD801\uDC21\uD801\uDC00\uD801\uDC16\uD801\uDC07\uD801\uDC24\uD801\uDC13\uD801\uDC1D \uD801\uDC31\uD801\uDC42 \uD801\uDC44 \uD801\uDC14\uD801\uDC07\uD801\uDC1D\uD801\uDC00\uD801\uDC21\uD801\uDC07\uD801\uDC13 \uD801\uDC0F\uD801\uDC06\uD801\uDC05\uD801\uDC24\uD801\uDC06\uD801\uDC1A\uD801\uDC0A\uD801\uDC21\uD801\uDC1D\uD801\uDC06\uD801\uDC13\uD801\uDC06",
|
||||||
|
"表ポあA鷗ŒéB逍Üߪąñ丂㐀\uD840\uDC00",
|
||||||
|
"᚛ᚄᚓᚐᚋᚒᚄ ᚑᚄᚂᚑᚏᚅ᚜\n" +
|
||||||
|
"᚛ ᚜\n",
|
||||||
|
"Powerلُلُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ冗\n" +
|
||||||
|
"\uD83C\uDFF30\uD83C\uDF08\uFE0F\n" +
|
||||||
|
"జ్ఞ\u200Cా"
|
||||||
|
);
|
||||||
|
String shortText;
|
||||||
|
byte[] shortTextBytes;
|
||||||
|
BufDataInput shortTextInput;
|
||||||
|
BufDataOutput shortTextOutput;
|
||||||
|
String mediumText;
|
||||||
|
byte[] mediumTextBytes;
|
||||||
|
BufDataInput mediumTextInput;
|
||||||
|
BufDataOutput mediumTextOutput;
|
||||||
|
String longText;
|
||||||
|
byte[] longTextBytes;
|
||||||
|
BufDataInput longTextInput;
|
||||||
|
BufDataOutput longTextOutput;
|
||||||
|
|
||||||
|
@Setup(Level.Invocation)
|
||||||
|
public void reset() {
|
||||||
|
longTextInput.reset();
|
||||||
|
longTextOutput.resetUnderlyingBuffer();
|
||||||
|
mediumTextInput.reset();
|
||||||
|
mediumTextOutput.resetUnderlyingBuffer();
|
||||||
|
shortTextInput.reset();
|
||||||
|
shortTextOutput.resetUnderlyingBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Setup(Level.Invocation)
|
||||||
|
public void prepare() {
|
||||||
|
var l = new ArrayList<String>();
|
||||||
|
var maxI = ThreadLocalRandom.current().nextInt(1, 20);
|
||||||
|
for (int i = 0; i < maxI; i++) {
|
||||||
|
l.addAll(WORDS);
|
||||||
|
}
|
||||||
|
Collections.shuffle(l);
|
||||||
|
var fullText = String.join(" ", l);
|
||||||
|
var out = BufDataOutput.create(Integer.BYTES + fullText.getBytes(StandardCharsets.UTF_8).length);
|
||||||
|
|
||||||
|
out.resetUnderlyingBuffer();
|
||||||
|
longText = fullText;
|
||||||
|
longTextBytes = longText.getBytes(StandardCharsets.UTF_8);
|
||||||
|
out.writeMediumText(longText, StandardCharsets.UTF_8);
|
||||||
|
longTextInput = BufDataInput.create(out.toList());
|
||||||
|
longTextOutput = BufDataOutput.create(Integer.BYTES + longTextBytes.length);
|
||||||
|
|
||||||
|
out.resetUnderlyingBuffer();
|
||||||
|
mediumText = fullText.substring(0, 128);
|
||||||
|
mediumTextBytes = mediumText.getBytes(StandardCharsets.UTF_8);
|
||||||
|
out.writeMediumText(mediumText, StandardCharsets.UTF_8);
|
||||||
|
mediumTextInput = BufDataInput.create(out.toList());
|
||||||
|
mediumTextOutput = BufDataOutput.create(Integer.BYTES + mediumTextBytes.length);
|
||||||
|
|
||||||
|
out.resetUnderlyingBuffer();
|
||||||
|
shortText = fullText.substring(0, 15);
|
||||||
|
shortTextBytes = shortText.getBytes(StandardCharsets.UTF_8);
|
||||||
|
out.writeMediumText(shortText, StandardCharsets.UTF_8);
|
||||||
|
shortTextInput = BufDataInput.create(out.toList());
|
||||||
|
shortTextOutput = BufDataOutput.create(Integer.BYTES + shortTextBytes.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public Buf encodeShortTextZeroCopy(ZeroAllocationEncoderState encoderState, ZeroAllocationEncoderBenchState benchState) {
|
||||||
|
var out = benchState.shortTextOutput;
|
||||||
|
out.writeMediumTextZeroCopy(benchState.shortText);
|
||||||
|
return out.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public Buf encodeMediumTextZeroCopy(ZeroAllocationEncoderState encoderState, ZeroAllocationEncoderBenchState benchState) {
|
||||||
|
var out = benchState.mediumTextOutput;
|
||||||
|
out.writeMediumTextZeroCopy(benchState.mediumText);
|
||||||
|
return out.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public Buf encodeLongTextZeroCopy(ZeroAllocationEncoderState encoderState, ZeroAllocationEncoderBenchState benchState) {
|
||||||
|
var out = benchState.longTextOutput;
|
||||||
|
out.writeMediumTextZeroCopy(benchState.longText);
|
||||||
|
return out.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public Buf encodeShortTextJava(ZeroAllocationEncoderBenchState benchState) {
|
||||||
|
var out = benchState.shortTextOutput;
|
||||||
|
out.writeMediumTextLegacy(benchState.shortText, StandardCharsets.UTF_8);
|
||||||
|
return out.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public Buf encodeMediumTextJava(ZeroAllocationEncoderBenchState benchState) {
|
||||||
|
var out = benchState.mediumTextOutput;
|
||||||
|
out.writeMediumTextLegacy(benchState.mediumText, StandardCharsets.UTF_8);
|
||||||
|
return out.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public Buf encodeLongTextJava(ZeroAllocationEncoderBenchState benchState) {
|
||||||
|
var out = benchState.longTextOutput;
|
||||||
|
out.writeMediumTextLegacy(benchState.longText, StandardCharsets.UTF_8);
|
||||||
|
return out.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public String decodeShortText(ZeroAllocationEncoderState encoderState, ZeroAllocationEncoderBenchState benchState) {
|
||||||
|
var in = benchState.shortTextInput;
|
||||||
|
return in.readMediumText(StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
@Benchmark
|
||||||
|
public String decodeMediumText(ZeroAllocationEncoderState encoderState, ZeroAllocationEncoderBenchState benchState) {
|
||||||
|
var in = benchState.mediumTextInput;
|
||||||
|
return in.readMediumText(StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
@Benchmark
|
||||||
|
public String decodeLongText(ZeroAllocationEncoderState encoderState, ZeroAllocationEncoderBenchState benchState) {
|
||||||
|
var in = benchState.longTextInput;
|
||||||
|
return in.readMediumText(StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,178 @@
|
|||||||
|
package it.cavallium.buffer;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.openjdk.jmh.annotations.*;
|
||||||
|
|
||||||
|
@State(Scope.Benchmark)
|
||||||
|
@OutputTimeUnit(TimeUnit.SECONDS)
|
||||||
|
@BenchmarkMode(Mode.Throughput)
|
||||||
|
@Fork(value = 1, warmups = 1)
|
||||||
|
@Warmup(time = 1, iterations = 3)
|
||||||
|
@Measurement(time = 1, iterations = 6)
|
||||||
|
public class ZeroAllocationEncoderBench {
|
||||||
|
|
||||||
|
@State(Scope.Thread)
|
||||||
|
public static class ZeroAllocationEncoderState {
|
||||||
|
ZeroAllocationEncoder encoder;
|
||||||
|
BufDataOutput bufOutput;
|
||||||
|
|
||||||
|
@Setup
|
||||||
|
public void prepare() {
|
||||||
|
encoder = ZeroAllocationEncoder.INSTANCE;
|
||||||
|
bufOutput = BufDataOutput.create(1024);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@State(Scope.Benchmark)
|
||||||
|
public static class ZeroAllocationEncoderBenchState {
|
||||||
|
private static final List<String> WORDS = List.of(
|
||||||
|
"\uD83D\uDC69\uD83C\uDFFF\u200D\uD83D\uDC69\uD83C\uDFFF\u200D\uD83D\uDC67\uD83C\uDFFF\u200D\uD83D\uDC66\uD83C\uDFFF",
|
||||||
|
"hello",
|
||||||
|
"test",
|
||||||
|
"òàòà§òè+=))=732e0",
|
||||||
|
"ل موقع يسمح لزواره الكرام بتحويل الكتابة العربي الى كتابة مفه",
|
||||||
|
"\uD800\uDF3C\uD800\uDF30\uD800\uDF32 \uD800\uDF32\uD800\uDF3B\uD800\uDF34\uD800\uDF43 \uD800\uDF39̈\uD800\uDF44\uD800\uDF30\uD800\uDF3D, \uD800\uDF3D\uD800\uDF39 \uD800\uDF3C\uD800\uDF39\uD800\uDF43 \uD800\uDF45\uD800\uDF3F \uD800\uDF3D\uD800\uDF33\uD800\uDF30\uD800\uDF3D \uD800\uDF31\uD800\uDF42\uD800\uDF39\uD800\uDF32\uD800\uDF32\uD800\uDF39\uD800\uDF38.",
|
||||||
|
"Z̤͔ͧ̑̓ä͖̭̈̇lͮ̒ͫǧ̗͚̚o̙̔ͮ̇͐̇",
|
||||||
|
"من left اليمين to الى right اليسار",
|
||||||
|
"a\u202Db\u202Ec\u202Dd\u202Ee\u202Df\u202Eg",
|
||||||
|
"﷽﷽﷽﷽﷽﷽﷽﷽﷽﷽﷽﷽﷽﷽﷽﷽",
|
||||||
|
"\uD83D\uDC71\uD83D\uDC71\uD83C\uDFFB\uD83D\uDC71\uD83C\uDFFC\uD83D\uDC71\uD83C\uDFFD\uD83D\uDC71\uD83C\uDFFE\uD83D\uDC71\uD83C\uDFFF",
|
||||||
|
"\uD83E\uDDDF\u200D♀\uFE0F\uD83E\uDDDF\u200D♂\uFE0F",
|
||||||
|
"\uD83D\uDC68\u200D❤\uFE0F\u200D\uD83D\uDC8B\u200D\uD83D\uDC68\uD83D\uDC69\u200D\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC66\uD83C\uDFF3\uFE0F\u200D⚧\uFE0F\uD83C\uDDF5\uD83C\uDDF7",
|
||||||
|
"田中さんにあげて下さい",
|
||||||
|
"ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็ ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็ ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็",
|
||||||
|
"\uD801\uDC1C \uD801\uDC14\uD801\uDC07\uD801\uDC1D\uD801\uDC00\uD801\uDC21\uD801\uDC07\uD801\uDC13 \uD801\uDC19\uD801\uDC0A\uD801\uDC21\uD801\uDC1D\uD801\uDC13/\uD801\uDC1D\uD801\uDC07\uD801\uDC17\uD801\uDC0A\uD801\uDC24\uD801\uDC14 \uD801\uDC12\uD801\uDC0B\uD801\uDC17 \uD801\uDC12\uD801\uDC0C \uD801\uDC1C \uD801\uDC21\uD801\uDC00\uD801\uDC16\uD801\uDC07\uD801\uDC24\uD801\uDC13\uD801\uDC1D \uD801\uDC31\uD801\uDC42 \uD801\uDC44 \uD801\uDC14\uD801\uDC07\uD801\uDC1D\uD801\uDC00\uD801\uDC21\uD801\uDC07\uD801\uDC13 \uD801\uDC0F\uD801\uDC06\uD801\uDC05\uD801\uDC24\uD801\uDC06\uD801\uDC1A\uD801\uDC0A\uD801\uDC21\uD801\uDC1D\uD801\uDC06\uD801\uDC13\uD801\uDC06",
|
||||||
|
"表ポあA鷗ŒéB逍Üߪąñ丂㐀\uD840\uDC00",
|
||||||
|
"᚛ᚄᚓᚐᚋᚒᚄ ᚑᚄᚂᚑᚏᚅ᚜\n" +
|
||||||
|
"᚛ ᚜\n",
|
||||||
|
"Powerلُلُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ冗\n" +
|
||||||
|
"\uD83C\uDFF30\uD83C\uDF08\uFE0F\n" +
|
||||||
|
"జ్ఞ\u200Cా"
|
||||||
|
);
|
||||||
|
String shortText;
|
||||||
|
byte[] shortTextBytes;
|
||||||
|
BufDataInput shortTextInput;
|
||||||
|
BufDataOutput shortTextOutput;
|
||||||
|
String mediumText;
|
||||||
|
byte[] mediumTextBytes;
|
||||||
|
BufDataInput mediumTextInput;
|
||||||
|
BufDataOutput mediumTextOutput;
|
||||||
|
String longText;
|
||||||
|
byte[] longTextBytes;
|
||||||
|
BufDataInput longTextInput;
|
||||||
|
BufDataOutput longTextOutput;
|
||||||
|
|
||||||
|
@Setup(Level.Invocation)
|
||||||
|
public void reset() {
|
||||||
|
longTextInput.reset();
|
||||||
|
longTextOutput.resetUnderlyingBuffer();
|
||||||
|
mediumTextInput.reset();
|
||||||
|
mediumTextOutput.resetUnderlyingBuffer();
|
||||||
|
shortTextInput.reset();
|
||||||
|
shortTextOutput.resetUnderlyingBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Setup
|
||||||
|
public void prepare() {
|
||||||
|
var l = new ArrayList<String>();
|
||||||
|
var maxI = ThreadLocalRandom.current().nextInt(1, 20);
|
||||||
|
for (int i = 0; i < maxI; i++) {
|
||||||
|
l.addAll(WORDS);
|
||||||
|
}
|
||||||
|
Collections.shuffle(l);
|
||||||
|
var fullText = String.join(" ", l);
|
||||||
|
longText = fullText;
|
||||||
|
longTextBytes = longText.getBytes(StandardCharsets.UTF_8);
|
||||||
|
longTextInput = BufDataInput.create(Buf.wrap(longTextBytes));
|
||||||
|
longTextOutput = BufDataOutput.create(longTextBytes.length);
|
||||||
|
mediumText = fullText.substring(0, 128);
|
||||||
|
mediumTextBytes = mediumText.getBytes(StandardCharsets.UTF_8);
|
||||||
|
mediumTextInput = BufDataInput.create(Buf.wrap(mediumTextBytes));
|
||||||
|
mediumTextOutput = BufDataOutput.create(mediumTextBytes.length);
|
||||||
|
shortText = fullText.substring(0, 15);
|
||||||
|
shortTextBytes = shortText.getBytes(StandardCharsets.UTF_8);
|
||||||
|
shortTextInput = BufDataInput.create(Buf.wrap(shortTextBytes));
|
||||||
|
shortTextOutput = BufDataOutput.create(shortTextBytes.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public BufDataOutput encodeShortTextZeroCopy(ZeroAllocationEncoderState encoderState, ZeroAllocationEncoderBenchState benchState) {
|
||||||
|
var out = benchState.shortTextOutput;
|
||||||
|
encoderState.encoder.encodeTo(benchState.shortText, out);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public BufDataOutput encodeMediumTextZeroCopy(ZeroAllocationEncoderState encoderState, ZeroAllocationEncoderBenchState benchState) {
|
||||||
|
var out = benchState.mediumTextOutput;
|
||||||
|
encoderState.encoder.encodeTo(benchState.mediumText, out);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public BufDataOutput encodeLongTextZeroCopy(ZeroAllocationEncoderState encoderState, ZeroAllocationEncoderBenchState benchState) {
|
||||||
|
var out = benchState.longTextOutput;
|
||||||
|
encoderState.encoder.encodeTo(benchState.longText, out);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public BufDataOutput encodeShortTextJava(ZeroAllocationEncoderBenchState benchState) {
|
||||||
|
var out = benchState.shortTextOutput;
|
||||||
|
out.write(benchState.shortText.getBytes(StandardCharsets.UTF_8));
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public BufDataOutput encodeMediumTextJava(ZeroAllocationEncoderBenchState benchState) {
|
||||||
|
var out = benchState.mediumTextOutput;
|
||||||
|
out.write(benchState.mediumText.getBytes(StandardCharsets.UTF_8));
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public BufDataOutput encodeLongTextJava(ZeroAllocationEncoderBenchState benchState) {
|
||||||
|
var out = benchState.longTextOutput;
|
||||||
|
out.write(benchState.longText.getBytes(StandardCharsets.UTF_8));
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public String decodeShortTextZeroCopy(ZeroAllocationEncoderState encoderState, ZeroAllocationEncoderBenchState benchState) {
|
||||||
|
return encoderState.encoder.decodeFrom(benchState.shortTextInput, benchState.shortTextBytes.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public String decodeMediumTextZeroCopy(ZeroAllocationEncoderState encoderState, ZeroAllocationEncoderBenchState benchState) {
|
||||||
|
return encoderState.encoder.decodeFrom(benchState.mediumTextInput, benchState.mediumTextBytes.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public String decodeLongTextZeroCopy(ZeroAllocationEncoderState encoderState, ZeroAllocationEncoderBenchState benchState) {
|
||||||
|
return encoderState.encoder.decodeFrom(benchState.longTextInput, benchState.longTextBytes.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public String decodeShortTextJava(ZeroAllocationEncoderBenchState benchState) {
|
||||||
|
return new String(benchState.shortTextInput.readAllBytes(), StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public String decodeMediumTextJava(ZeroAllocationEncoderBenchState benchState) {
|
||||||
|
return new String(benchState.mediumTextInput.readAllBytes(), StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public String decodeLongTextJava(ZeroAllocationEncoderBenchState benchState) {
|
||||||
|
return new String(benchState.longTextInput.readAllBytes(), StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
9
datagen/src/java9/java/module-info.java
Normal file
9
datagen/src/java9/java/module-info.java
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
module it.cavallium.datagen {
|
||||||
|
exports it.cavallium.datagen.nativedata;
|
||||||
|
exports it.cavallium.datagen;
|
||||||
|
exports it.cavallium.stream;
|
||||||
|
exports it.cavallium.buffer;
|
||||||
|
|
||||||
|
requires org.jetbrains.annotations;
|
||||||
|
requires it.unimi.dsi.fastutil;
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package it.cavallium.buffer;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
public interface ArraysComparator extends Comparator<byte[]> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
int compare(byte[] a, byte[] b);
|
||||||
|
|
||||||
|
int compare(byte[] a, int aFrom, int aTo, byte[] b, int bFrom, int bTo);
|
||||||
|
}
|
313
datagen/src/main/java/it/cavallium/buffer/Buf.java
Normal file
313
datagen/src/main/java/it/cavallium/buffer/Buf.java
Normal file
@ -0,0 +1,313 @@
|
|||||||
|
package it.cavallium.buffer;
|
||||||
|
|
||||||
|
import it.cavallium.datagen.nativedata.Int52;
|
||||||
|
import it.cavallium.stream.SafeByteArrayInputStream;
|
||||||
|
import it.cavallium.stream.SafeByteArrayOutputStream;
|
||||||
|
import it.cavallium.stream.SafeDataOutput;
|
||||||
|
import it.unimi.dsi.fastutil.bytes.ByteArrayList;
|
||||||
|
import it.unimi.dsi.fastutil.bytes.ByteList;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.RandomAccess;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.annotations.VisibleForTesting;
|
||||||
|
|
||||||
|
public interface Buf extends ByteList, RandomAccess {
|
||||||
|
static Buf wrap(ByteList bytes) {
|
||||||
|
if (bytes instanceof Buf buf) {
|
||||||
|
return buf;
|
||||||
|
} else if (bytes instanceof ByteArrayList byteArrayList) {
|
||||||
|
return ByteListBuf.wrap(byteArrayList.elements(), byteArrayList.size());
|
||||||
|
} else {
|
||||||
|
return ByteListBuf.wrap(bytes.toByteArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static Buf wrap(ByteList bytes, int from, int to) {
|
||||||
|
if (bytes instanceof Buf buf) {
|
||||||
|
return buf.subList(from, to);
|
||||||
|
} else if (bytes instanceof ByteArrayList byteArrayList) {
|
||||||
|
return ByteListBuf.wrap(byteArrayList.elements(), byteArrayList.size()).subList(from, to);
|
||||||
|
} else {
|
||||||
|
return ByteListBuf.wrap(bytes.toByteArray()).subList(from, to);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Buf wrap(byte... bytes) {
|
||||||
|
return ByteListBuf.wrap(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Buf wrap(byte[] bytes, int from, int to) {
|
||||||
|
return ByteListBuf.wrap(bytes, to).subList(from, to);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Buf create(int initialCapacity) {
|
||||||
|
return new ByteListBuf(initialCapacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Buf copyOf(byte[] original) {
|
||||||
|
return new ByteListBuf(original);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Buf create() {
|
||||||
|
return new ByteListBuf();
|
||||||
|
}
|
||||||
|
|
||||||
|
static Buf wrap(byte[] array, int length) {
|
||||||
|
return ByteListBuf.wrap(array, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Buf createZeroes(int length) {
|
||||||
|
return ByteListBuf.wrap(new byte[length], length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get this element as an array, converting it if needed
|
||||||
|
*/
|
||||||
|
byte @NotNull[] asArray();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get this element as an array, only if it's already an array, otherwise return null
|
||||||
|
*/
|
||||||
|
byte @Nullable[] asArrayStrict();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get this element as an array with equal or bigger size, converting it if needed
|
||||||
|
* The returned array may be bigger than expected!
|
||||||
|
*/
|
||||||
|
byte[] asUnboundedArray();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get this element as an array with equal or bigger size, only if it's already an array, otherwise return null
|
||||||
|
* The returned array may be bigger than expected!
|
||||||
|
*/
|
||||||
|
byte @Nullable[] asUnboundedArrayStrict();
|
||||||
|
|
||||||
|
boolean isMutable();
|
||||||
|
|
||||||
|
Buf freeze();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Buf subList(int from, int to);
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
Buf subListForced(int from, int to);
|
||||||
|
|
||||||
|
Buf copyOfRange(int from, int to);
|
||||||
|
|
||||||
|
Buf copy();
|
||||||
|
|
||||||
|
SafeByteArrayInputStream binaryInputStream();
|
||||||
|
|
||||||
|
void writeTo(SafeDataOutput dataOutput);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param i byte offset
|
||||||
|
*/
|
||||||
|
default float getFloat(int i) {
|
||||||
|
return Float.intBitsToFloat(getInt(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param i byte offset
|
||||||
|
*/
|
||||||
|
default double getDouble(int i) {
|
||||||
|
return Double.longBitsToDouble(getLong(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param i byte offset
|
||||||
|
*/
|
||||||
|
default char getChar(int i) {
|
||||||
|
byte b1 = getByte(i);
|
||||||
|
byte b2 = getByte(i + 1);
|
||||||
|
return (char) ((b1 & 0xFF) << 8 | (b2 & 0xFF));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param i byte offset
|
||||||
|
*/
|
||||||
|
default short getShort(int i) {
|
||||||
|
byte b1 = getByte(i);
|
||||||
|
byte b2 = getByte(i + 1);
|
||||||
|
return (short) ((b1 & 0xFF) << 8 | (b2 & 0xFF));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param i byte offset
|
||||||
|
*/
|
||||||
|
default int getInt(int i) {
|
||||||
|
byte b1 = getByte(i);
|
||||||
|
byte b2 = getByte(i + 1);
|
||||||
|
byte b3 = getByte(i + 2);
|
||||||
|
byte b4 = getByte(i + 3);
|
||||||
|
return b1 << 24 | (b2 & 0xFF) << 16 | (b3 & 0xFF) << 8 | (b4 & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param i byte offset
|
||||||
|
*/
|
||||||
|
default long getLong(int i) {
|
||||||
|
byte b1 = getByte(i);
|
||||||
|
byte b2 = getByte(i + 1);
|
||||||
|
byte b3 = getByte(i + 2);
|
||||||
|
byte b4 = getByte(i + 3);
|
||||||
|
byte b5 = getByte(i + 4);
|
||||||
|
byte b6 = getByte(i + 5);
|
||||||
|
byte b7 = getByte(i + 6);
|
||||||
|
byte b8 = getByte(i + 7);
|
||||||
|
return (b1 & 0xFFL) << 56
|
||||||
|
| (b2 & 0xFFL) << 48
|
||||||
|
| (b3 & 0xFFL) << 40
|
||||||
|
| (b4 & 0xFFL) << 32
|
||||||
|
| (b5 & 0xFFL) << 24
|
||||||
|
| (b6 & 0xFFL) << 16
|
||||||
|
| (b7 & 0xFFL) << 8
|
||||||
|
| (b8 & 0xFFL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param i byte offset
|
||||||
|
*/
|
||||||
|
default long getInt52(int i) {
|
||||||
|
byte b1 = getByte(i);
|
||||||
|
byte b2 = getByte(i + 1);
|
||||||
|
byte b3 = getByte(i + 2);
|
||||||
|
byte b4 = getByte(i + 3);
|
||||||
|
byte b5 = getByte(i + 4);
|
||||||
|
byte b6 = getByte(i + 5);
|
||||||
|
byte b7 = getByte(i + 6);
|
||||||
|
return (b1 & 0xFFL) << 48
|
||||||
|
| (b2 & 0xFFL) << 40
|
||||||
|
| (b3 & 0xFFL) << 32
|
||||||
|
| (b4 & 0xFFL) << 24
|
||||||
|
| (b5 & 0xFFL) << 16
|
||||||
|
| (b6 & 0xFFL) << 8
|
||||||
|
| (b7 & 0xFFL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param i byte offset
|
||||||
|
*/
|
||||||
|
default boolean getBoolean(int i) {
|
||||||
|
return getByte(i) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param i byte offset
|
||||||
|
*/
|
||||||
|
default String getShortText(int i, Charset charset) {
|
||||||
|
var len = getShort(i);
|
||||||
|
return getString(i + Short.BYTES, len, charset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param i byte offset
|
||||||
|
*/
|
||||||
|
default String getMediumText(int i, Charset charset) {
|
||||||
|
var len = getInt(i);
|
||||||
|
return getString(i + Integer.BYTES, len, charset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param i byte offset
|
||||||
|
*/
|
||||||
|
String getString(int i, int length, Charset charset);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param i byte offset
|
||||||
|
*/
|
||||||
|
default void setBoolean(int i, boolean val) {
|
||||||
|
set(i, val ? (byte) 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param i byte offset
|
||||||
|
*/
|
||||||
|
default void setByte(int i, byte val) {
|
||||||
|
set(i, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param i byte offset
|
||||||
|
*/
|
||||||
|
default void setChar(int i, char val) {
|
||||||
|
set(i, (byte) (val >> 8));
|
||||||
|
set(i + 1, (byte) val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param i byte offset
|
||||||
|
*/
|
||||||
|
default void setShort(int i, short val) {
|
||||||
|
set(i, (byte) (val >> 8));
|
||||||
|
set(i + 1, (byte) val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param i byte offset
|
||||||
|
*/
|
||||||
|
default void setInt(int i, int val) {
|
||||||
|
set(i, (byte) (val >> 24));
|
||||||
|
set(i + 1, (byte) (val >> 16));
|
||||||
|
set(i + 2, (byte) (val >> 8));
|
||||||
|
set(i + 3, (byte) val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param i byte offset
|
||||||
|
*/
|
||||||
|
default void setLong(int i, long val) {
|
||||||
|
set(i, (byte) (val >> 56));
|
||||||
|
set(i + 1, (byte) (val >> 48));
|
||||||
|
set(i + 2, (byte) (val >> 40));
|
||||||
|
set(i + 3, (byte) (val >> 32));
|
||||||
|
set(i + 4, (byte) (val >> 24));
|
||||||
|
set(i + 5, (byte) (val >> 16));
|
||||||
|
set(i + 6, (byte) (val >> 8));
|
||||||
|
set(i + 7, (byte) val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param i byte offset
|
||||||
|
*/
|
||||||
|
default void setInt52(int i, long val) {
|
||||||
|
Int52.checkValidity(val);
|
||||||
|
set(i, (byte) (val >> 48));
|
||||||
|
set(i + 1, (byte) (val >> 40));
|
||||||
|
set(i + 2, (byte) (val >> 32));
|
||||||
|
set(i + 3, (byte) (val >> 24));
|
||||||
|
set(i + 4, (byte) (val >> 16));
|
||||||
|
set(i + 5, (byte) (val >> 8));
|
||||||
|
set(i + 6, (byte) val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param i byte offset
|
||||||
|
*/
|
||||||
|
default void setFloat(int i, float val) {
|
||||||
|
setInt(i, Float.floatToRawIntBits(val));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param i byte offset
|
||||||
|
*/
|
||||||
|
default void setDouble(int i, double val) {
|
||||||
|
setLong(i, Double.doubleToRawLongBits(val));
|
||||||
|
}
|
||||||
|
|
||||||
|
default SafeByteArrayOutputStream binaryOutputStream() {
|
||||||
|
return binaryOutputStream(0, size());
|
||||||
|
}
|
||||||
|
|
||||||
|
default SafeByteArrayOutputStream binaryOutputStream(int from) {
|
||||||
|
return binaryOutputStream(from, size());
|
||||||
|
}
|
||||||
|
|
||||||
|
SafeByteArrayOutputStream binaryOutputStream(int from, int to);
|
||||||
|
|
||||||
|
boolean equals(int aStartIndex, Buf b, int bStartIndex, int length);
|
||||||
|
|
||||||
|
boolean equals(int aStartIndex, byte[] b, int bStartIndex, int length);
|
||||||
|
|
||||||
|
String toString(Charset charset);
|
||||||
|
}
|
28
datagen/src/main/java/it/cavallium/buffer/BufDataInput.java
Normal file
28
datagen/src/main/java/it/cavallium/buffer/BufDataInput.java
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package it.cavallium.buffer;
|
||||||
|
|
||||||
|
import it.cavallium.stream.SafeByteArrayInputStream;
|
||||||
|
import it.cavallium.stream.SafeDataInputStream;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
|
||||||
|
public class BufDataInput extends SafeDataInputStream {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a DataInputStream that uses the specified underlying InputStream.
|
||||||
|
*
|
||||||
|
* @param in the specified input stream
|
||||||
|
*/
|
||||||
|
private BufDataInput(@NotNull SafeByteArrayInputStream in) {
|
||||||
|
super(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BufDataInput create(Buf byteList) {
|
||||||
|
return new BufDataInput(byteList.binaryInputStream());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
super.close();
|
||||||
|
}
|
||||||
|
}
|
328
datagen/src/main/java/it/cavallium/buffer/BufDataOutput.java
Normal file
328
datagen/src/main/java/it/cavallium/buffer/BufDataOutput.java
Normal file
@ -0,0 +1,328 @@
|
|||||||
|
package it.cavallium.buffer;
|
||||||
|
|
||||||
|
import static java.util.Objects.checkFromToIndex;
|
||||||
|
|
||||||
|
import it.cavallium.stream.SafeByteArrayOutputStream;
|
||||||
|
import it.cavallium.stream.SafeDataOutput;
|
||||||
|
import it.cavallium.stream.SafeDataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.VisibleForTesting;
|
||||||
|
|
||||||
|
public class BufDataOutput implements SafeDataOutput {
|
||||||
|
|
||||||
|
private final SafeByteArrayOutputStream buf;
|
||||||
|
private final SafeByteArrayDataOutputStream dOut;
|
||||||
|
private final int limit;
|
||||||
|
|
||||||
|
public BufDataOutput(SafeByteArrayOutputStream buf) {
|
||||||
|
this.buf = buf;
|
||||||
|
this.dOut = new SafeByteArrayDataOutputStream(buf);
|
||||||
|
limit = Integer.MAX_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BufDataOutput(SafeByteArrayOutputStream buf, int maxSize) {
|
||||||
|
this.buf = buf;
|
||||||
|
this.dOut = new SafeByteArrayDataOutputStream(buf);
|
||||||
|
this.limit = maxSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BufDataOutput createLimited(int maxSize, int hint) {
|
||||||
|
if (hint >= 0) {
|
||||||
|
if (maxSize < 0 || maxSize == Integer.MAX_VALUE) {
|
||||||
|
return create(hint);
|
||||||
|
} else {
|
||||||
|
return new BufDataOutput(new SafeByteArrayOutputStream(Math.min(maxSize, hint)), maxSize);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return createLimited(maxSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BufDataOutput createLimited(int maxSize) {
|
||||||
|
if (maxSize < 0 || maxSize == Integer.MAX_VALUE) {
|
||||||
|
return create();
|
||||||
|
} else {
|
||||||
|
return new BufDataOutput(new SafeByteArrayOutputStream(maxSize), maxSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BufDataOutput create() {
|
||||||
|
return new BufDataOutput(new SafeByteArrayOutputStream());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BufDataOutput create(int hint) {
|
||||||
|
if (hint >= 0) {
|
||||||
|
return new BufDataOutput(new SafeByteArrayOutputStream(hint));
|
||||||
|
} else {
|
||||||
|
return create();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
|
public static BufDataOutput wrap(Buf buf, int from, int to) {
|
||||||
|
checkFromToIndex(from, to, buf.size());
|
||||||
|
if (buf.isEmpty()) {
|
||||||
|
return createLimited(0);
|
||||||
|
} else {
|
||||||
|
return new BufDataOutput(buf.binaryOutputStream(from), to - from);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
|
public static BufDataOutput wrap(Buf buf) {
|
||||||
|
if (buf.isEmpty()) {
|
||||||
|
return createLimited(0);
|
||||||
|
} else {
|
||||||
|
return new BufDataOutput(buf.binaryOutputStream(), buf.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private IllegalStateException unreachable(IOException ex) {
|
||||||
|
return new IllegalStateException(ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(int b) {
|
||||||
|
// Fast inlined checkOutOfBounds
|
||||||
|
if (dOut.size() >= limit) {
|
||||||
|
throw new IndexOutOfBoundsException(limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
dOut.write(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkOutOfBounds(int delta) {
|
||||||
|
if (dOut.size() + delta > limit) {
|
||||||
|
throw new IndexOutOfBoundsException(limit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(byte @NotNull [] b) {
|
||||||
|
checkOutOfBounds(b.length);
|
||||||
|
dOut.write(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(byte @NotNull [] b, int off, int len) {
|
||||||
|
checkOutOfBounds(Math.max(0, Math.min(b.length - off, len)));
|
||||||
|
dOut.write(b, off, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeBoolean(boolean v) {
|
||||||
|
// Fast inlined checkOutOfBounds
|
||||||
|
if (dOut.size() >= limit) {
|
||||||
|
throw new IndexOutOfBoundsException(limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
dOut.writeBoolean(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeByte(int v) {
|
||||||
|
this.write(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeShort(int v) {
|
||||||
|
checkOutOfBounds(Short.BYTES);
|
||||||
|
dOut.writeShort(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeChar(int v) {
|
||||||
|
checkOutOfBounds(Character.BYTES);
|
||||||
|
dOut.writeChar(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeInt(int v) {
|
||||||
|
checkOutOfBounds(Integer.BYTES);
|
||||||
|
dOut.writeInt(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeLong(long v) {
|
||||||
|
checkOutOfBounds(Long.BYTES);
|
||||||
|
dOut.writeLong(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeInt52(long v) {
|
||||||
|
checkOutOfBounds(7);
|
||||||
|
dOut.writeInt52(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeFloat(float v) {
|
||||||
|
checkOutOfBounds(Float.BYTES);
|
||||||
|
dOut.writeFloat(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeDouble(double v) {
|
||||||
|
checkOutOfBounds(Double.BYTES);
|
||||||
|
dOut.writeDouble(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ensureWritable(int size) {
|
||||||
|
dOut.flush();
|
||||||
|
buf.ensureWritable(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeBytes(@NotNull String s) {
|
||||||
|
checkOutOfBounds(s.length() * Byte.BYTES);
|
||||||
|
dOut.writeBytes(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo: check
|
||||||
|
public void writeBytes(Buf deserialized) {
|
||||||
|
checkOutOfBounds(deserialized.size());
|
||||||
|
deserialized.writeTo(dOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeBytes(byte[] b, int off, int len) {
|
||||||
|
write(b, off, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeChars(@NotNull String s) {
|
||||||
|
checkOutOfBounds(Character.BYTES * s.length());
|
||||||
|
dOut.writeChars(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String tooLongMsg(String s, int bits32) {
|
||||||
|
int slen = s.length();
|
||||||
|
String head = s.substring(0, 8);
|
||||||
|
String tail = s.substring(slen - 8, slen);
|
||||||
|
// handle int overflow with max 3x expansion
|
||||||
|
long actualLength = (long)slen + Integer.toUnsignedLong(bits32 - slen);
|
||||||
|
return "encoded string (" + head + "..." + tail + ") too long: "
|
||||||
|
+ actualLength + " bytes";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
public void writeUTF(@NotNull String str) {
|
||||||
|
writeShortText(str, StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeShortText(String s, Charset charset) {
|
||||||
|
if (charset == StandardCharsets.UTF_8) {
|
||||||
|
var beforeWrite = (int) this.position();
|
||||||
|
this.advancePosition(Short.BYTES);
|
||||||
|
ZeroAllocationEncoder.INSTANCE.encodeTo(s, this);
|
||||||
|
var afterWrite = (int) this.position();
|
||||||
|
this.rewindPosition(afterWrite - beforeWrite);
|
||||||
|
var len = Math.toIntExact(afterWrite - beforeWrite - Short.BYTES);
|
||||||
|
if (len > Short.MAX_VALUE) {
|
||||||
|
throw new IndexOutOfBoundsException("String too long: " + len + " bytes");
|
||||||
|
}
|
||||||
|
dOut.writeShort(len);
|
||||||
|
dOut.advancePosition(len);
|
||||||
|
} else {
|
||||||
|
var out = s.getBytes(charset);
|
||||||
|
if (out.length > Short.MAX_VALUE) {
|
||||||
|
throw new IndexOutOfBoundsException("String too long: " + out.length + " bytes");
|
||||||
|
}
|
||||||
|
checkOutOfBounds(Short.BYTES + out.length);
|
||||||
|
dOut.writeShort(out.length);
|
||||||
|
dOut.write(out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeMediumText(String s, Charset charset) {
|
||||||
|
// todo: charbuffer is still slow, check in future java versions
|
||||||
|
// if (charset == StandardCharsets.UTF_8) {
|
||||||
|
// writeMediumTextZeroCopy(s);
|
||||||
|
// } else {
|
||||||
|
writeMediumTextLegacy(s, charset);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
public void writeMediumTextZeroCopy(String s) {
|
||||||
|
var beforeWrite = (int) this.position();
|
||||||
|
this.advancePosition(Integer.BYTES);
|
||||||
|
ZeroAllocationEncoder.INSTANCE.encodeTo(s, this);
|
||||||
|
var afterWrite = (int) this.position();
|
||||||
|
this.rewindPosition(afterWrite - beforeWrite);
|
||||||
|
var len = Math.toIntExact(afterWrite - beforeWrite - Integer.BYTES);
|
||||||
|
dOut.writeInt(len);
|
||||||
|
dOut.advancePosition(len);
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
public void writeMediumTextLegacy(String s, Charset charset) {
|
||||||
|
var out = s.getBytes(charset);
|
||||||
|
checkOutOfBounds(Integer.BYTES + out.length);
|
||||||
|
dOut.writeInt(out.length);
|
||||||
|
dOut.write(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetUnderlyingBuffer() {
|
||||||
|
dOut.resetUnderlyingBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void rewindPosition(int count) {
|
||||||
|
dOut.rewindPosition(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void advancePosition(int count) {
|
||||||
|
checkOutOfBounds(count);
|
||||||
|
dOut.advancePosition(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long position() {
|
||||||
|
return dOut.position();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Buf asList() {
|
||||||
|
dOut.flush();
|
||||||
|
return Buf.wrap(this.buf.array, this.buf.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Buf toList() {
|
||||||
|
dOut.flush();
|
||||||
|
return Buf.wrap(Arrays.copyOf(this.buf.array, this.buf.length));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return dOut.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return dOut.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (o == null || getClass() != o.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
BufDataOutput that = (BufDataOutput) o;
|
||||||
|
|
||||||
|
return Objects.equals(dOut, that.dOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return dOut.size();
|
||||||
|
}
|
||||||
|
}
|
941
datagen/src/main/java/it/cavallium/buffer/ByteListBuf.java
Normal file
941
datagen/src/main/java/it/cavallium/buffer/ByteListBuf.java
Normal file
@ -0,0 +1,941 @@
|
|||||||
|
package it.cavallium.buffer;
|
||||||
|
|
||||||
|
import static java.util.Objects.checkFromIndexSize;
|
||||||
|
import static java.util.Objects.checkFromToIndex;
|
||||||
|
|
||||||
|
import it.cavallium.stream.SafeByteArrayInputStream;
|
||||||
|
import it.cavallium.stream.SafeByteArrayOutputStream;
|
||||||
|
import it.cavallium.stream.SafeDataOutput;
|
||||||
|
import it.unimi.dsi.fastutil.bytes.AbstractByteList;
|
||||||
|
import it.unimi.dsi.fastutil.bytes.ByteArrayList;
|
||||||
|
import it.unimi.dsi.fastutil.bytes.ByteArrays;
|
||||||
|
import it.unimi.dsi.fastutil.bytes.ByteCollection;
|
||||||
|
import it.unimi.dsi.fastutil.bytes.ByteConsumer;
|
||||||
|
import it.unimi.dsi.fastutil.bytes.ByteIterator;
|
||||||
|
import it.unimi.dsi.fastutil.bytes.ByteIterators;
|
||||||
|
import it.unimi.dsi.fastutil.bytes.ByteList;
|
||||||
|
import it.unimi.dsi.fastutil.bytes.ByteListIterator;
|
||||||
|
import it.unimi.dsi.fastutil.bytes.BytePredicate;
|
||||||
|
import it.unimi.dsi.fastutil.bytes.ByteSpliterator;
|
||||||
|
import it.unimi.dsi.fastutil.bytes.ByteSpliterators;
|
||||||
|
import it.unimi.dsi.fastutil.bytes.ByteUnaryOperator;
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HexFormat;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
import java.util.function.IntPredicate;
|
||||||
|
import java.util.function.IntUnaryOperator;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.function.UnaryOperator;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.annotations.VisibleForTesting;
|
||||||
|
|
||||||
|
class ByteListBuf extends ByteArrayList implements Buf {
|
||||||
|
|
||||||
|
private static final HexFormat HEX_FORMAT = HexFormat.of().withUpperCase();
|
||||||
|
private static final String IMMUTABLE_ERROR = "The buffer is immutable";
|
||||||
|
private static final VariableLengthLexiconographicComparator VAR_LENGTH_LEX_COMP = new VariableLengthLexiconographicComparator();
|
||||||
|
|
||||||
|
private boolean immutable;
|
||||||
|
|
||||||
|
protected ByteListBuf(byte[] a, boolean wrapped) {
|
||||||
|
super(a, wrapped);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteListBuf(int capacity) {
|
||||||
|
super(capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteListBuf() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteListBuf(Collection<? extends Byte> c) {
|
||||||
|
super(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteListBuf(ByteCollection c) {
|
||||||
|
super(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteListBuf(ByteList l) {
|
||||||
|
super(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteListBuf(byte[] a) {
|
||||||
|
super(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteListBuf(byte[] a, int offset, int length) {
|
||||||
|
super(a, offset, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteListBuf(Iterator<? extends Byte> i) {
|
||||||
|
super(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteListBuf(ByteIterator i) {
|
||||||
|
super(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps a given array into an array list of given size.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Note it is guaranteed that the type of the array returned by {@link #elements()} will be the same
|
||||||
|
* (see the comments in the class documentation).
|
||||||
|
*
|
||||||
|
* @param a an array to wrap.
|
||||||
|
* @param length the length of the resulting array list.
|
||||||
|
* @return a new array list of the given size, wrapping the given array.
|
||||||
|
*/
|
||||||
|
public static ByteListBuf wrap(final byte[] a, final int length) {
|
||||||
|
ByteArrays.ensureFromTo(a, 0, length);
|
||||||
|
final ByteListBuf l = new ByteListBuf(a, true);
|
||||||
|
l.size = length;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps a given array into an array list.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Note it is guaranteed that the type of the array returned by {@link #elements()} will be the same
|
||||||
|
* (see the comments in the class documentation).
|
||||||
|
*
|
||||||
|
* @param a an array to wrap.
|
||||||
|
* @return a new array list wrapping the given array.
|
||||||
|
*/
|
||||||
|
public static ByteListBuf wrap(final byte[] a) {
|
||||||
|
return wrap(a, a.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new empty array list.
|
||||||
|
*
|
||||||
|
* @return a new empty array list.
|
||||||
|
*/
|
||||||
|
public static ByteListBuf of() {
|
||||||
|
return new ByteListBuf();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an array list using an array of elements.
|
||||||
|
*
|
||||||
|
* @param init a the array the will become the new backing array of the array list.
|
||||||
|
* @return a new array list backed by the given array.
|
||||||
|
* @see #wrap
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static ByteListBuf of(final byte... init) {
|
||||||
|
return wrap(init);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte @NotNull [] asArray() {
|
||||||
|
if (this.size() == a.length) {
|
||||||
|
return this.a;
|
||||||
|
} else {
|
||||||
|
return this.toByteArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte @Nullable [] asArrayStrict() {
|
||||||
|
if (this.size() == a.length) {
|
||||||
|
return a;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] asUnboundedArray() {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte @Nullable [] asUnboundedArrayStrict() {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isMutable() {
|
||||||
|
return !immutable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteListBuf freeze() {
|
||||||
|
immutable = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Buf subList(int from, int to) {
|
||||||
|
if (from == 0 && to == size()) return this;
|
||||||
|
return subListForced(from, to);
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
public Buf subListForced(int from, int to) {
|
||||||
|
checkFromToIndex(from, to, this.size());
|
||||||
|
return new SubList(from, to);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Buf copyOfRange(int from, int to) {
|
||||||
|
if (from == 0 && to == size()) {
|
||||||
|
return copy();
|
||||||
|
} else {
|
||||||
|
return ByteListBuf.wrap(Arrays.copyOfRange(this.a, from, to), to - from);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Buf copy() {
|
||||||
|
return ByteListBuf.wrap(this.a.clone(), this.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SafeByteArrayInputStream binaryInputStream() {
|
||||||
|
return new SafeByteArrayInputStream(this.a, 0, this.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeTo(SafeDataOutput dataOutput) {
|
||||||
|
dataOutput.write(this.a, 0, this.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SafeByteArrayOutputStream binaryOutputStream(int from, int to) {
|
||||||
|
checkFromToIndex(from, to, size);
|
||||||
|
return new SafeByteArrayOutputStream(a, from, to);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(int aStartIndex, Buf b, int bStartIndex, int length) {
|
||||||
|
if (aStartIndex + length > size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return b.equals(bStartIndex, this.a, aStartIndex, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(int aStartIndex, byte[] b, int bStartIndex, int length) {
|
||||||
|
if (aStartIndex < 0) return false;
|
||||||
|
if (aStartIndex + length > this.size) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (bStartIndex + length > b.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return Arrays.equals(a, aStartIndex, aStartIndex + length, b, bStartIndex, bStartIndex + length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString(Charset charset) {
|
||||||
|
return getString(0, size, charset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return HEX_FORMAT.formatHex(a, 0, size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getString(int i, int length, Charset charset) {
|
||||||
|
return new String(a, i, length, charset);
|
||||||
|
}
|
||||||
|
|
||||||
|
class SubList extends AbstractByteList.ByteRandomAccessSubList implements Buf {
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = -3185226345314976296L;
|
||||||
|
|
||||||
|
protected SubList(int from, int to) {
|
||||||
|
super(ByteListBuf.this, from, to);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Most of the inherited methods should be fine, but we can override a few of them for performance.
|
||||||
|
// Needed because we can't access the parent class' instance variables directly in a different
|
||||||
|
// instance of SubList.
|
||||||
|
@IgnoreCoverage
|
||||||
|
private byte[] getParentArray() {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Buf subList(int from, int to) {
|
||||||
|
// Sadly we have to rewrap this, because if there is a sublist of a sublist, and the
|
||||||
|
// subsublist adds, both sublists need to update their "to" value.
|
||||||
|
return subListForced(from, to);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Buf subListForced(int from, int to) {
|
||||||
|
checkFromToIndex(from, to, this.to);
|
||||||
|
var fromAbs = this.from + from;
|
||||||
|
var toAbs = this.from + to;
|
||||||
|
// Sadly we have to rewrap this, because if there is a sublist of a sublist, and the
|
||||||
|
// subsublist adds, both sublists need to update their "to" value.
|
||||||
|
return new SubList(fromAbs, toAbs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Buf copyOfRange(int from, int to) {
|
||||||
|
if (from == 0 && to == size()) {
|
||||||
|
return copy();
|
||||||
|
} else {
|
||||||
|
return Buf.wrap(Arrays.copyOfRange(a, this.from + from, this.from + to));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Buf copy() {
|
||||||
|
return Buf.wrap(Arrays.copyOfRange(a, from, to));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SafeByteArrayInputStream binaryInputStream() {
|
||||||
|
return new SafeByteArrayInputStream(a, from, size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeTo(SafeDataOutput dataOutput) {
|
||||||
|
dataOutput.write(a, from, size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SafeByteArrayOutputStream binaryOutputStream(int from, int to) {
|
||||||
|
checkFromToIndex(from, to, size());
|
||||||
|
return new SafeByteArrayOutputStream(a, from + this.from, to + this.from);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(int aStartIndex, Buf b, int bStartIndex, int length) {
|
||||||
|
if (aStartIndex + length > size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return b.equals(bStartIndex, a, aStartIndex + from, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(int aStartIndex, byte[] b, int bStartIndex, int length) {
|
||||||
|
var aFrom = from + aStartIndex;
|
||||||
|
var aTo = from + aStartIndex + length;
|
||||||
|
var bTo = bStartIndex + length;
|
||||||
|
if (aFrom < from) return false;
|
||||||
|
if (aTo > to) return false;
|
||||||
|
if (bTo > b.length) return false;
|
||||||
|
return Arrays.equals(a, aFrom, aTo, b, bStartIndex, bTo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte getByte(int i) {
|
||||||
|
ensureRestrictedIndex(i);
|
||||||
|
return a[i + from];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte @NotNull [] asArray() {
|
||||||
|
if (this.from == 0 && this.to == a.length) {
|
||||||
|
return a;
|
||||||
|
} else {
|
||||||
|
return SubList.this.toByteArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte @Nullable [] asArrayStrict() {
|
||||||
|
if (this.from == 0 && this.to == a.length) {
|
||||||
|
return a;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] asUnboundedArray() {
|
||||||
|
if (from == 0) {
|
||||||
|
return a;
|
||||||
|
} else {
|
||||||
|
return toByteArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte @Nullable [] asUnboundedArrayStrict() {
|
||||||
|
if (from == 0) {
|
||||||
|
return a;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isMutable() {
|
||||||
|
return ByteListBuf.this.isMutable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SubList freeze() {
|
||||||
|
immutable = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class SubListIterator extends ByteIterators.AbstractIndexBasedListIterator {
|
||||||
|
// We are using pos == 0 to be 0 relative to SubList.from (meaning you need to do a[from + i] when
|
||||||
|
// accessing array).
|
||||||
|
SubListIterator(int index) {
|
||||||
|
super(0, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
protected byte get(int i) {
|
||||||
|
return ByteListBuf.SubList.this.getByte(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
protected void add(int i, byte k) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
ByteListBuf.SubList.this.add(i, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
protected void set(int i, byte k) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
ByteListBuf.SubList.this.set(i, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
protected void remove(int i) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
ByteListBuf.SubList.this.removeByte(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getMaxPos() {
|
||||||
|
return to - from;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte nextByte() {
|
||||||
|
if (!hasNext()) throw new NoSuchElementException();
|
||||||
|
return a[from + (lastReturned = pos++)];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte previousByte() {
|
||||||
|
if (!hasPrevious()) throw new NoSuchElementException();
|
||||||
|
return a[from + (lastReturned = --pos)];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void forEachRemaining(final ByteConsumer action) {
|
||||||
|
final int max = to - from;
|
||||||
|
while (pos < max) {
|
||||||
|
action.accept(a[from + (lastReturned = pos++)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull ByteListIterator listIterator(int index) {
|
||||||
|
return new ByteListBuf.SubList.SubListIterator(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class SubListSpliterator extends ByteSpliterators.LateBindingSizeIndexBasedSpliterator {
|
||||||
|
// We are using pos == 0 to be 0 relative to real array 0
|
||||||
|
SubListSpliterator() {
|
||||||
|
super(from);
|
||||||
|
}
|
||||||
|
|
||||||
|
private SubListSpliterator(int pos, int maxPos) {
|
||||||
|
super(pos, maxPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getMaxPosFromBackingStore() {
|
||||||
|
return to;
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
protected byte get(int i) {
|
||||||
|
return a[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ByteListBuf.SubList.SubListSpliterator makeForSplit(int pos, int maxPos) {
|
||||||
|
return new ByteListBuf.SubList.SubListSpliterator(pos, maxPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean tryAdvance(final ByteConsumer action) {
|
||||||
|
if (pos >= getMaxPos()) return false;
|
||||||
|
action.accept(a[pos++]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void forEachRemaining(final ByteConsumer action) {
|
||||||
|
final int max = getMaxPos();
|
||||||
|
while (pos < max) {
|
||||||
|
action.accept(a[pos++]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteSpliterator spliterator() {
|
||||||
|
return new ByteListBuf.SubList.SubListSpliterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean contentsEquals(byte[] otherA, int otherAFrom, int otherATo) {
|
||||||
|
if (a == otherA && from == otherAFrom && to == otherATo) return true;
|
||||||
|
return Arrays.equals(a, from, to, otherA, otherAFrom, otherATo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (o == this) return true;
|
||||||
|
if (o == null) return false;
|
||||||
|
if (!(o instanceof java.util.List)) return false;
|
||||||
|
if (o instanceof ByteListBuf other) {
|
||||||
|
return contentsEquals(other.a, 0, other.size());
|
||||||
|
}
|
||||||
|
if (o instanceof SubList other) {
|
||||||
|
return contentsEquals(other.getParentArray(), other.from, other.to);
|
||||||
|
}
|
||||||
|
return super.equals(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
int contentsCompareTo(byte[] otherA, int otherAFrom, int otherATo) {
|
||||||
|
if (a == otherA && from == otherAFrom && to == otherATo) return 0;
|
||||||
|
return VAR_LENGTH_LEX_COMP.compare(a, from, to, otherA, otherAFrom, otherATo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(final java.util.@NotNull List<? extends Byte> l) {
|
||||||
|
if (l instanceof ByteListBuf other) {
|
||||||
|
return contentsCompareTo(other.a, 0, other.size());
|
||||||
|
}
|
||||||
|
if (l instanceof ByteListBuf.SubList other) {
|
||||||
|
return contentsCompareTo(other.getParentArray(), other.from, other.to);
|
||||||
|
}
|
||||||
|
return super.compareTo(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString(Charset charset) {
|
||||||
|
return new String(a, from, size(), charset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return HEX_FORMAT.formatHex(a, from, from + size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getString(int i, int length, Charset charset) {
|
||||||
|
checkFromIndexSize(i, length, to - from);
|
||||||
|
return new String(a, from + i, length, charset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
public void add(int index, byte k) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
super.add(index, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
public boolean add(byte k) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
return super.add(k);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
public byte removeByte(int index) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
return super.removeByte(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
public boolean rem(byte k) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
return super.rem(k);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
public byte set(int index, byte k) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
return super.set(index, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
super.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
public void trim() {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
super.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
public void trim(int n) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
super.trim(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
public void removeElements(int from, int to) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
super.removeElements(from, to);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
public void addElements(int index, byte[] a, int offset, int length) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
super.addElements(index, a, offset, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
public void setElements(int index, byte[] a, int offset, int length) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
super.setElements(index, a, offset, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
public boolean addAll(int index, ByteCollection c) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
return super.addAll(index, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
public boolean addAll(int index, ByteList l) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
return super.addAll(index, l);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
public boolean removeAll(ByteCollection c) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
return super.removeAll(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
public boolean addAll(int index, @NotNull Collection<? extends Byte> c) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
return super.addAll(index, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
public boolean addAll(@NotNull Collection<? extends Byte> c) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
return super.addAll(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
public void addElements(int index, byte[] a) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
super.addElements(index, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
public void push(byte o) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
super.push(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
public byte popByte() {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
return super.popByte();
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
public byte topByte() {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
return super.topByte();
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
public boolean addAll(ByteCollection c) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
return super.addAll(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
public boolean add(Byte key) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
return super.add(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
public boolean remove(Object key) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
return super.remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
public boolean removeAll(@NotNull Collection<?> c) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
return super.removeAll(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
public boolean retainAll(ByteCollection c) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
return super.retainAll(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
public boolean retainAll(@NotNull Collection<?> c) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
return super.retainAll(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
public void setElements(byte[] a) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
super.setElements(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
public void setElements(int index, byte[] a) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
super.setElements(index, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
public void add(int index, Byte key) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
super.add(index, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
public void replaceAll(ByteUnaryOperator operator) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
super.replaceAll(operator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
public void replaceAll(IntUnaryOperator operator) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
super.replaceAll(operator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
public void replaceAll(UnaryOperator<Byte> operator) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
super.replaceAll(operator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
public Byte remove(int index) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
return super.remove(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
public Byte set(int index, Byte k) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
return super.set(index, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
public boolean addAll(ByteList l) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
return super.addAll(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
public void sort(Comparator<? super Byte> comparator) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
super.sort(comparator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
public void unstableSort(Comparator<? super Byte> comparator) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
super.unstableSort(comparator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
public boolean removeIf(Predicate<? super Byte> filter) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
return super.removeIf(filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
public boolean removeIf(BytePredicate filter) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
return super.removeIf(filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@Override
|
||||||
|
public boolean removeIf(IntPredicate filter) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
return super.removeIf(filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
public void push(Byte o) {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
super.push(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
public Byte pop() {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
return super.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
public Byte top() {
|
||||||
|
assert isMutable() : IMMUTABLE_ERROR;
|
||||||
|
return super.top();
|
||||||
|
}
|
||||||
|
|
||||||
|
@IgnoreCoverage
|
||||||
|
private void ensureMutable() {
|
||||||
|
if (!isMutable()) {
|
||||||
|
throw new UnsupportedOperationException(IMMUTABLE_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(List<? extends Byte> l) {
|
||||||
|
if (l instanceof ByteArrayList) {
|
||||||
|
return compareTo((ByteArrayList)l);
|
||||||
|
}
|
||||||
|
if (l instanceof SubList) {
|
||||||
|
// Must negate because we are inverting the order of the comparison.
|
||||||
|
return -((SubList)l).compareTo(this);
|
||||||
|
}
|
||||||
|
return super.compareTo(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(ByteArrayList l) {
|
||||||
|
final int s1 = size(), s2 = l.size();
|
||||||
|
final byte[] a1 = a, a2 = l.elements();
|
||||||
|
if (a1 == a2 && s1 == s2) return 0;
|
||||||
|
return VAR_LENGTH_LEX_COMP.compare(a, 0, s1, a2, 0, s2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares this type-specific array list to another one.
|
||||||
|
*
|
||||||
|
* @apiNote This method exists only for sake of efficiency. The implementation inherited from the
|
||||||
|
* abstract implementation would already work.
|
||||||
|
*
|
||||||
|
* @param l a type-specific array list.
|
||||||
|
* @return true if the argument contains the same elements of this type-specific array list.
|
||||||
|
*/
|
||||||
|
public boolean equals(final ByteArrayList l) {
|
||||||
|
if (l == this) return true;
|
||||||
|
int s = size();
|
||||||
|
if (s != l.size()) return false;
|
||||||
|
final byte[] a1 = a, a2 = l.elements();
|
||||||
|
final int s1 = this.size(), s2 = l.size();
|
||||||
|
return Arrays.equals(a1, 0, s1, a2, 0, s2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unlikely-arg-type")
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object o) {
|
||||||
|
if (o == this) return true;
|
||||||
|
if (o == null) return false;
|
||||||
|
if (!(o instanceof java.util.List)) return false;
|
||||||
|
if (o instanceof ByteArrayList) {
|
||||||
|
// Safe cast because we are only going to take elements from other list, never give them
|
||||||
|
return equals((ByteArrayList) o);
|
||||||
|
}
|
||||||
|
if (o instanceof SubList subList) {
|
||||||
|
// Safe cast because we are only going to take elements from other list, never give them
|
||||||
|
// Sublist has an optimized sub-array based comparison, reuse that.
|
||||||
|
return subList.equals(this);
|
||||||
|
}
|
||||||
|
return super.equals(o);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
package it.cavallium.buffer;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.CLASS)
|
||||||
|
public @interface IgnoreCoverage {
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package it.cavallium.buffer;
|
||||||
|
|
||||||
|
import it.cavallium.stream.SafeByteArrayOutputStream;
|
||||||
|
import it.cavallium.stream.SafeDataOutputStream;
|
||||||
|
|
||||||
|
public class SafeByteArrayDataOutputStream extends SafeDataOutputStream {
|
||||||
|
private final SafeByteArrayOutputStream bOut;
|
||||||
|
|
||||||
|
public SafeByteArrayDataOutputStream(SafeByteArrayOutputStream out) {
|
||||||
|
super(out);
|
||||||
|
this.bOut = out;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetUnderlyingBuffer() {
|
||||||
|
bOut.reset();
|
||||||
|
this.written = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void rewindPosition(int count) {
|
||||||
|
var currentPosition = bOut.position();
|
||||||
|
if (count > written) {
|
||||||
|
throw new IndexOutOfBoundsException(count + " > " + written);
|
||||||
|
}
|
||||||
|
bOut.position(currentPosition - count);
|
||||||
|
decCount(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void advancePosition(int count) {
|
||||||
|
bOut.ensureWritable(count);
|
||||||
|
bOut.position(bOut.position() + count);
|
||||||
|
incCount(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long position() {
|
||||||
|
return bOut.position();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package it.cavallium.buffer;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public class VariableLengthLexiconographicComparator implements ArraysComparator {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(byte[] a, byte[] b) {
|
||||||
|
return a.length != b.length ? Integer.compare(a.length, b.length) : Arrays.compareUnsigned(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(byte[] a, int aFrom, int aTo, byte[] b, int bFrom, int bTo) {
|
||||||
|
return (aTo - aFrom) != (bTo - bFrom) ? Integer.compare(aTo - aFrom, bTo - bFrom)
|
||||||
|
: Arrays.compareUnsigned(a, aFrom, aTo, b, bFrom, bTo);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,133 @@
|
|||||||
|
package it.cavallium.buffer;
|
||||||
|
|
||||||
|
import it.cavallium.stream.SafeDataInput;
|
||||||
|
import it.cavallium.stream.SafeDataOutput;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.CharBuffer;
|
||||||
|
import java.nio.charset.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
public class ZeroAllocationEncoder {
|
||||||
|
|
||||||
|
public static final ZeroAllocationEncoder INSTANCE = new ZeroAllocationEncoder(8192);
|
||||||
|
|
||||||
|
private static final ThreadLocal<CharsetEncoder> CHARSET_ENCODER_UTF8 = ThreadLocal.withInitial(() ->
|
||||||
|
StandardCharsets.UTF_8.newEncoder()
|
||||||
|
.onMalformedInput(CodingErrorAction.REPLACE)
|
||||||
|
.onUnmappableCharacter(CodingErrorAction.REPLACE));
|
||||||
|
|
||||||
|
private static final ThreadLocal<CharsetDecoder> CHARSET_DECODER_UTF8 = ThreadLocal.withInitial(() ->
|
||||||
|
StandardCharsets.UTF_8.newDecoder()
|
||||||
|
.onMalformedInput(CodingErrorAction.REPLACE)
|
||||||
|
.onUnmappableCharacter(CodingErrorAction.REPLACE));
|
||||||
|
|
||||||
|
private final ThreadLocal<ByteBuffer> bufferThreadLocal;
|
||||||
|
|
||||||
|
private final ThreadLocal<AtomicReference<CharBuffer>> charBufferRefThreadLocal;
|
||||||
|
|
||||||
|
private final ThreadLocal<AtomicReference<ByteBuffer>> byteBufferRefThreadLocal;
|
||||||
|
|
||||||
|
public ZeroAllocationEncoder(int outBufferSize) {
|
||||||
|
var maxBytesPerChar = (int) Math.ceil(StandardCharsets.UTF_8.newEncoder().maxBytesPerChar());
|
||||||
|
bufferThreadLocal = ThreadLocal.withInitial(() -> ByteBuffer.allocate(outBufferSize * maxBytesPerChar));
|
||||||
|
charBufferRefThreadLocal = ThreadLocal.withInitial(() -> new AtomicReference<>(CharBuffer.allocate(outBufferSize)));
|
||||||
|
byteBufferRefThreadLocal = ThreadLocal.withInitial(() -> new AtomicReference<>(ByteBuffer.allocate(outBufferSize * maxBytesPerChar)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void encodeTo(String s, SafeDataOutput bufDataOutput) {
|
||||||
|
var encoder = CHARSET_ENCODER_UTF8.get();
|
||||||
|
encoder.reset();
|
||||||
|
var buf = bufferThreadLocal.get();
|
||||||
|
var charBuffer = CharBuffer.wrap(s);
|
||||||
|
boolean endOfInput = false;
|
||||||
|
CoderResult result;
|
||||||
|
do {
|
||||||
|
buf.clear();
|
||||||
|
result = encoder.encode(charBuffer, buf, endOfInput);
|
||||||
|
buf.flip();
|
||||||
|
bufDataOutput.write(buf.array(), buf.arrayOffset() + buf.position(), buf.remaining());
|
||||||
|
if (result.isUnderflow()) {
|
||||||
|
if (endOfInput) {
|
||||||
|
buf.clear();
|
||||||
|
encoder.flush(buf);
|
||||||
|
buf.flip();
|
||||||
|
bufDataOutput.write(buf.array(), buf.arrayOffset() + buf.position(), buf.remaining());
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
endOfInput = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else if (result.isOverflow()) {
|
||||||
|
continue;
|
||||||
|
} else if (result.isError()) {
|
||||||
|
try {
|
||||||
|
result.throwException();
|
||||||
|
} catch (CharacterCodingException e) {
|
||||||
|
// This should not happen
|
||||||
|
throw new Error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String decodeFrom(SafeDataInput bufDataInput, int bytesLength) {
|
||||||
|
var decoder = CHARSET_DECODER_UTF8.get();
|
||||||
|
decoder.reset();
|
||||||
|
var bufRef = byteBufferRefThreadLocal.get();
|
||||||
|
var charBufRef = charBufferRefThreadLocal.get();
|
||||||
|
var buf = bufRef.get();
|
||||||
|
var charBuf = charBufRef.get();
|
||||||
|
assert decoder.maxCharsPerByte() == 1.0f
|
||||||
|
: "UTF8 max chars per byte is 1.0f, but the decoder got a value of " + decoder.maxCharsPerByte();
|
||||||
|
if (charBuf.capacity() < bytesLength) {
|
||||||
|
charBuf = CharBuffer.allocate(bytesLength);
|
||||||
|
charBufRef.set(charBuf);
|
||||||
|
} else {
|
||||||
|
charBuf.clear();
|
||||||
|
}
|
||||||
|
if (buf.capacity() < bytesLength) {
|
||||||
|
buf = ByteBuffer.allocate(bytesLength);
|
||||||
|
bufRef.set(buf);
|
||||||
|
} else {
|
||||||
|
buf.clear();
|
||||||
|
}
|
||||||
|
CoderResult result;
|
||||||
|
do {
|
||||||
|
buf.clear();
|
||||||
|
assert buf.capacity() >= bytesLength;
|
||||||
|
bufDataInput.readFully(buf, bytesLength);
|
||||||
|
buf.flip();
|
||||||
|
result = decoder.decode(buf, charBuf, true);
|
||||||
|
if (result.isUnderflow()) {
|
||||||
|
result = decoder.flush(charBuf);
|
||||||
|
if (result.isOverflow()) {
|
||||||
|
throw new IllegalStateException("Unexpected overflow");
|
||||||
|
}
|
||||||
|
charBuf.flip();
|
||||||
|
return charBuf.toString();
|
||||||
|
} else if (result.isOverflow()) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
} else if (result.isError()) {
|
||||||
|
try {
|
||||||
|
result.throwException();
|
||||||
|
} catch (CharacterCodingException e) {
|
||||||
|
// This should not happen
|
||||||
|
throw new Error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CharBuffer getNextCharBuf(ArrayList<CharBuffer> charBufs, int charBufIndex) {
|
||||||
|
if (charBufIndex == 0) return charBufs.getFirst();
|
||||||
|
if (charBufIndex >= charBufs.size()) {
|
||||||
|
var b = charBufs.getFirst().duplicate();
|
||||||
|
charBufs.add(b);
|
||||||
|
return b;
|
||||||
|
} else {
|
||||||
|
return charBufs.get(charBufIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package it.cavallium.data.generator;
|
package it.cavallium.datagen;
|
||||||
|
|
||||||
public class CommonField {
|
public class CommonField {
|
||||||
public final String fieldName;
|
public final String fieldName;
|
@ -0,0 +1,4 @@
|
|||||||
|
package it.cavallium.datagen;
|
||||||
|
|
||||||
|
public interface DataContext {
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package it.cavallium.datagen;
|
||||||
|
|
||||||
|
public final class DataContextNone implements DataContext {
|
||||||
|
|
||||||
|
public static final DataContextNone INSTANCE = new DataContextNone();
|
||||||
|
|
||||||
|
private DataContextNone() {}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
package it.cavallium.datagen;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public interface DataInitializer<C extends DataContext, T> {
|
||||||
|
|
||||||
|
@NotNull T initialize(C context);
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package it.cavallium.datagen;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public abstract class DataInitializerSimple<T> implements DataInitializer<DataContextNone, T> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final @NotNull T initialize(DataContextNone context) {
|
||||||
|
return initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract @NotNull T initialize();
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user