kaitai_struct_compiler
kaitai_struct_compiler copied to clipboard
Generate annotations for Java classes
Proposal for https://github.com/kaitai-io/kaitai_struct_java_runtime/issues/22. Annotations make it much easier to create a visualizer, especially, if input for visualizer is class, derived from kaitai-generated class and if https://github.com/kaitai-io/kaitai_struct/issues/672 will be implemented.
Right now I want to see, if it compiles and also receive some review comments.
I finish work on the feature. Now
- each generated class has
Generated
annotation, - each field and getter, that represents attribute from
seq
element hasSeqItem
annotation, - each field and getter, that represents instance from
instances
element hasInstance
annotation - each field and getter, that represents parameter has
Parameter
annotation
PR with adds annotations to runtime -- https://github.com/kaitai-io/kaitai_struct_java_runtime/pull/23.
I wasn't ran tests with kaitai_struct/tests/run-java
, because of lacking testng dependency (I don't known, why test script can not find it) but, because annotations do not change behavior of compiled class, I think, that nothing was break. I hope, CI do their work for me.
Result (docstrings.ksy
test):
I would be happy to see it merged, as it will allow to proceed the improvement of kaitai_struct_gui
. Runtime changes already merged, but their useless without support in compiler
@GreyCat, can you look at this? I didn't miss anything?
Can this be merged before another conflict occurred? There is no point in having support for annotation in the runtime without their support in the compiler
@GreyCat , please do not bury the project. Can you give feedback for my PRs?
Hi! Apologies for super late response. This PR changes a lot, and I'm not 100% with you in certain aspects of it. I'll try to highlight main points of concern.
I've took liberty to resolve the conflict which arisen due to recent changes. Please pull it first if you'll be contributing more stuff on top of this branch?
Actually, I plan to make a rebase to keep history linear as much as possible
I fully rework implementation:
- Remove generating
doc
- Generate annotations via separate methods in
LanguageCompiler
, which by default do nothing - Import annotation classes only when its used (annotations always generated though)
- Supply indexes (via
zipWithIndex
) only for that members for which its required
Because that includes also changes in runtime, I try to make PR for main repository: https://github.com/kaitai-io/kaitai_struct/pull/801. But as it my first experience with submodules PR, I don't know will it success or not. Therefore, if PR to the main repository fails to marge, tell me about it.
Generated file params_enum.ksy
Source: https://github.com/kaitai-io/kaitai_struct_tests/blob/master/formats/params_enum.ksy
// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild
package io.kaitai.struct.testformats;
import io.kaitai.struct.ByteBufferKaitaiStream;
import io.kaitai.struct.KaitaiStruct;
import io.kaitai.struct.KaitaiStream;
import java.io.IOException;
import io.kaitai.struct.annotations.Generated;
import java.util.Map;
import java.util.HashMap;
import io.kaitai.struct.annotations.Instance;
import io.kaitai.struct.annotations.Parameter;
import io.kaitai.struct.annotations.SeqItem;
@Generated(
id = "params_enum",
version = "0.9",
posInfo = false,
autoRead = true
)
public class ParamsEnum extends KaitaiStruct {
public static ParamsEnum fromFile(String fileName) throws IOException {
return new ParamsEnum(new ByteBufferKaitaiStream(fileName));
}
public enum Animal {
DOG(4),
CAT(7),
CHICKEN(12);
private final long id;
Animal(long id) { this.id = id; }
public long id() { return id; }
private static final Map<Long, Animal> byId = new HashMap<Long, Animal>(3);
static {
for (Animal e : Animal.values())
byId.put(e.id(), e);
}
public static Animal byId(long id) { return byId.get(id); }
}
public ParamsEnum(KaitaiStream _io) {
this(_io, null, null);
}
public ParamsEnum(KaitaiStream _io, KaitaiStruct _parent) {
this(_io, _parent, null);
}
public ParamsEnum(KaitaiStream _io, KaitaiStruct _parent, ParamsEnum _root) {
super(_io);
this._parent = _parent;
this._root = _root == null ? this : _root;
_read();
}
private void _read() {
this.one = Animal.byId(this._io.readU1());
this.invokeWithParam = new WithParam(this._io, this, _root, one());
}
public static class WithParam extends KaitaiStruct {
public WithParam(KaitaiStream _io, Animal enumeratedOne) {
this(_io, null, null, enumeratedOne);
}
public WithParam(KaitaiStream _io, ParamsEnum _parent, Animal enumeratedOne) {
this(_io, _parent, null, enumeratedOne);
}
public WithParam(KaitaiStream _io, ParamsEnum _parent, ParamsEnum _root, Animal enumeratedOne) {
super(_io);
this._parent = _parent;
this._root = _root;
this.enumeratedOne = enumeratedOne;
_read();
}
private void _read() {
}
@Instance(id = "is_cat")
private Boolean isCat;
@Instance(id = "is_cat")
public Boolean isCat() {
if (this.isCat != null)
return this.isCat;
boolean _tmp = (boolean) (enumeratedOne() == ParamsEnum.Animal.CAT);
this.isCat = _tmp;
return this.isCat;
}
@Parameter(index = 0, id = "enumerated_one")
private Animal enumeratedOne;
private ParamsEnum _root;
private ParamsEnum _parent;
@Parameter(index = 0, id = "enumerated_one")
public Animal enumeratedOne() { return enumeratedOne; }
public ParamsEnum _root() { return _root; }
public ParamsEnum _parent() { return _parent; }
}
@SeqItem(index = 0, id = "one")
private Animal one;
@SeqItem(index = 1, id = "invoke_with_param")
private WithParam invokeWithParam;
private ParamsEnum _root;
private KaitaiStruct _parent;
@SeqItem(index = 0, id = "one")
public Animal one() { return one; }
@SeqItem(index = 1, id = "invoke_with_param")
public WithParam invokeWithParam() { return invokeWithParam; }
public ParamsEnum _root() { return _root; }
public KaitaiStruct _parent() { return _parent; }
}