kaitai_struct_compiler icon indicating copy to clipboard operation
kaitai_struct_compiler copied to clipboard

Generate annotations for Java classes

Open Mingun opened this issue 4 years ago • 9 comments

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.

Mingun avatar Jan 11 '20 15:01 Mingun

I finish work on the feature. Now

  • each generated class has Generated annotation,
  • each field and getter, that represents attribute from seq element has SeqItem annotation,
  • each field and getter, that represents instance from instances element has Instance 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): Docstrings java

Mingun avatar Jan 14 '20 18:01 Mingun

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

Mingun avatar Feb 02 '20 19:02 Mingun

@GreyCat, can you look at this? I didn't miss anything?

Mingun avatar Feb 06 '20 14:02 Mingun

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

Mingun avatar Feb 29 '20 14:02 Mingun

@GreyCat , please do not bury the project. Can you give feedback for my PRs?

Mingun avatar Mar 07 '20 08:03 Mingun

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.

GreyCat avatar Mar 07 '20 10:03 GreyCat

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?

GreyCat avatar Mar 08 '20 22:03 GreyCat

Actually, I plan to make a rebase to keep history linear as much as possible

Mingun avatar Mar 18 '20 09:03 Mingun

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; }
}

annotations

Mingun avatar Aug 14 '20 07:08 Mingun