diff --git a/shared/src/main/scala/io/kaitai/struct/languages/JavaCompiler.scala b/shared/src/main/scala/io/kaitai/struct/languages/JavaCompiler.scala index dea5aecba..bdfb5020f 100644 --- a/shared/src/main/scala/io/kaitai/struct/languages/JavaCompiler.scala +++ b/shared/src/main/scala/io/kaitai/struct/languages/JavaCompiler.scala @@ -60,6 +60,10 @@ class JavaCompiler(val typeProvider: ClassTypeProvider, config: RuntimeConfig) // Used in every class importList.add(s"io.kaitai.struct.$kstructName") importList.add(s"io.kaitai.struct.$kstreamName") + importList.add("io.kaitai.struct.annotations.Generated") + importList.add("io.kaitai.struct.annotations.Instance") + importList.add("io.kaitai.struct.annotations.Parameter") + importList.add("io.kaitai.struct.annotations.SeqItem") importList.add("java.io.IOException") out.puts @@ -72,6 +76,15 @@ class JavaCompiler(val typeProvider: ClassTypeProvider, config: RuntimeConfig) "" } + out.puts("@Generated(") + out.inc + out.puts(s"""id = "${name}",""") + out.puts(s"""version = "${KSVersion.current}",""") + out.puts(s"""posInfo = ${config.readStoresPos},""") + out.puts(s"""autoRead = ${config.autoRead},""") + out.puts(s"""doc = "${doc(typeProvider.nowClass.doc)}"""") + out.dec + out.puts(")") out.puts(s"public ${staticStr}class ${type2class(name)} extends $kstructName {") out.inc @@ -198,13 +211,56 @@ class JavaCompiler(val typeProvider: ClassTypeProvider, config: RuntimeConfig) override def readFooter(): Unit = universalFooter override def attributeDeclaration(attr: MemberSpec, index: Int, isNullable: Boolean): Unit = { + annotate(attr, index) out.puts(s"private ${kaitaiType2JavaType(attr.dataTypeComposite, isNullable)} ${idToStr(attr.id)};") } override def attributeReader(attr: MemberSpec, index: Int, isNullable: Boolean): Unit = { + annotate(attr, index) out.puts(s"public ${kaitaiType2JavaType(attr.dataTypeComposite, isNullable)} ${idToStr(attr.id)}() { return ${idToStr(attr.id)}; }") } + def doc(doc: DocSpec): String = { + doc.summary.map(summary => { + val sb = new StringBuilder + val len = summary.length + var pos = 0 + while (pos < len) { + summary.charAt(pos) match { + case '"' => sb.append("\\\"") + case '\b' => sb.append("\\b") + case '\f' => sb.append("\\f") + case '\n' => sb.append("\\n") + case '\t' => sb.append("\\t") + case '\r' => sb.append("\\r") + case '\\' => sb.append("\\\\") + case c => sb.append(c) + } + + pos += 1 + } + sb.toString + }).getOrElse("") + } + + def annotate(attr: MemberSpec, index: Int) = { + attr match { + case param : ParamDefSpec => { + out.puts(s"""@Parameter(id = "${param.id.humanReadable}", index = ${index}, doc = "${doc(param.doc)}")""") + } + case field : AttrSpec => { + field.id match { + case NamedIdentifier(name) => + out.puts(s"""@SeqItem(id = "${name}", index = ${index}, doc = "${doc(field.doc)}")""") + case NumberedIdentifier(_) => + out.puts(s"""@SeqItem(id = "", index = ${index}, doc = "${doc(field.doc)}")""") + case _ => {} + } + } + case _ => {} + } + } + override def universalDoc(doc: DocSpec): Unit = { out.puts out.puts( "/**") @@ -622,10 +678,12 @@ class JavaCompiler(val typeProvider: ClassTypeProvider, config: RuntimeConfig) // override def instanceDeclaration(instName: InstanceIdentifier, instSpec: InstanceSpec, isNullable: Boolean): Unit = { + out.puts(s"""@Instance(id = "${instName.name}", doc = "${doc(instSpec.doc)}")""") out.puts(s"private ${kaitaiType2JavaTypeBoxed(instSpec.dataTypeComposite)} ${idToStr(instName)};") } override def instanceHeader(className: String, instName: InstanceIdentifier, instSpec: InstanceSpec, isNullable: Boolean): Unit = { + out.puts(s"""@Instance(id = "${instName.name}", doc = "${doc(instSpec.doc)}")""") out.puts(s"public ${kaitaiType2JavaTypeBoxed(instSpec.dataTypeComposite)} ${idToStr(instName)}() {") out.inc }