.class file format: PHP parsing library

File extension

class

KS implementation details

License: CC0-1.0

References

This page hosts a formal specification of .class file format using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.

PHP source code to parse .class file format

JavaClass.php

<?php
// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild

namespace {
    class JavaClass extends \Kaitai\Struct\Struct {
        public function __construct(\Kaitai\Struct\Stream $_io, \Kaitai\Struct\Struct $_parent = null, \JavaClass $_root = null) {
            parent::__construct($_io, $_parent, $_root);
            $this->_read();
        }

        private function _read() {
            $this->_m_magic = $this->_io->readBytes(4);
            if (!($this->magic() == "\xCA\xFE\xBA\xBE")) {
                throw new \Kaitai\Struct\Error\ValidationNotEqualError("\xCA\xFE\xBA\xBE", $this->magic(), $this->_io(), "/seq/0");
            }
            $this->_m_versionMinor = $this->_io->readU2be();
            $this->_m_versionMajor = $this->_io->readU2be();
            if (!($this->versionMajor() >= 43)) {
                throw new \Kaitai\Struct\Error\ValidationLessThanError(43, $this->versionMajor(), $this->_io(), "/seq/2");
            }
            $this->_m_constantPoolCount = $this->_io->readU2be();
            $this->_m_constantPool = [];
            $n = ($this->constantPoolCount() - 1);
            for ($i = 0; $i < $n; $i++) {
                $this->_m_constantPool[] = new \JavaClass\ConstantPoolEntry(($i != 0 ? $this->constantPool()[($i - 1)]->isTwoEntries() : false), $this->_io, $this, $this->_root);
            }
            $this->_m_accessFlags = $this->_io->readU2be();
            $this->_m_thisClass = $this->_io->readU2be();
            $this->_m_superClass = $this->_io->readU2be();
            $this->_m_interfacesCount = $this->_io->readU2be();
            $this->_m_interfaces = [];
            $n = $this->interfacesCount();
            for ($i = 0; $i < $n; $i++) {
                $this->_m_interfaces[] = $this->_io->readU2be();
            }
            $this->_m_fieldsCount = $this->_io->readU2be();
            $this->_m_fields = [];
            $n = $this->fieldsCount();
            for ($i = 0; $i < $n; $i++) {
                $this->_m_fields[] = new \JavaClass\FieldInfo($this->_io, $this, $this->_root);
            }
            $this->_m_methodsCount = $this->_io->readU2be();
            $this->_m_methods = [];
            $n = $this->methodsCount();
            for ($i = 0; $i < $n; $i++) {
                $this->_m_methods[] = new \JavaClass\MethodInfo($this->_io, $this, $this->_root);
            }
            $this->_m_attributesCount = $this->_io->readU2be();
            $this->_m_attributes = [];
            $n = $this->attributesCount();
            for ($i = 0; $i < $n; $i++) {
                $this->_m_attributes[] = new \JavaClass\AttributeInfo($this->_io, $this, $this->_root);
            }
        }
        protected $_m_magic;
        protected $_m_versionMinor;
        protected $_m_versionMajor;
        protected $_m_constantPoolCount;
        protected $_m_constantPool;
        protected $_m_accessFlags;
        protected $_m_thisClass;
        protected $_m_superClass;
        protected $_m_interfacesCount;
        protected $_m_interfaces;
        protected $_m_fieldsCount;
        protected $_m_fields;
        protected $_m_methodsCount;
        protected $_m_methods;
        protected $_m_attributesCount;
        protected $_m_attributes;
        public function magic() { return $this->_m_magic; }
        public function versionMinor() { return $this->_m_versionMinor; }
        public function versionMajor() { return $this->_m_versionMajor; }
        public function constantPoolCount() { return $this->_m_constantPoolCount; }
        public function constantPool() { return $this->_m_constantPool; }
        public function accessFlags() { return $this->_m_accessFlags; }
        public function thisClass() { return $this->_m_thisClass; }
        public function superClass() { return $this->_m_superClass; }
        public function interfacesCount() { return $this->_m_interfacesCount; }
        public function interfaces() { return $this->_m_interfaces; }
        public function fieldsCount() { return $this->_m_fieldsCount; }
        public function fields() { return $this->_m_fields; }
        public function methodsCount() { return $this->_m_methodsCount; }
        public function methods() { return $this->_m_methods; }
        public function attributesCount() { return $this->_m_attributesCount; }
        public function attributes() { return $this->_m_attributes; }
    }
}

/**
 * `class` file format version 45.3 (appeared in the very first publicly
 * known release of Java SE AND JDK 1.0.2, released 23th January 1996) is so
 * ancient that it's taken for granted. Earlier formats seem to be
 * undocumented. Changes of `version_minor` don't change `class` format.
 * Earlier `version_major`s likely belong to Oak programming language, the
 * proprietary predecessor of Java.
 */

namespace JavaClass {
    class VersionGuard extends \Kaitai\Struct\Struct {
        public function __construct(int $major, \Kaitai\Struct\Stream $_io, \Kaitai\Struct\Struct $_parent = null, \JavaClass $_root = null) {
            parent::__construct($_io, $_parent, $_root);
            $this->_m_major = $major;
            $this->_read();
        }

        private function _read() {
            $this->_m__unnamed0 = $this->_io->readBytes(0);
            $_ = $this->_unnamed0();
            if (!($this->_root()->versionMajor() >= $this->major())) {
                throw new \Kaitai\Struct\Error\ValidationExprError($this->_unnamed0(), $this->_io(), "/types/version_guard/seq/0");
            }
        }
        protected $_m__unnamed0;
        protected $_m_major;
        public function _unnamed0() { return $this->_m__unnamed0; }
        public function major() { return $this->_m_major; }
    }
}

namespace JavaClass {
    class FloatCpInfo extends \Kaitai\Struct\Struct {
        public function __construct(\Kaitai\Struct\Stream $_io, \JavaClass\ConstantPoolEntry $_parent = null, \JavaClass $_root = null) {
            parent::__construct($_io, $_parent, $_root);
            $this->_read();
        }

        private function _read() {
            $this->_m_value = $this->_io->readF4be();
        }
        protected $_m_value;
        public function value() { return $this->_m_value; }
    }
}

namespace JavaClass {
    class AttributeInfo extends \Kaitai\Struct\Struct {
        public function __construct(\Kaitai\Struct\Stream $_io, \Kaitai\Struct\Struct $_parent = null, \JavaClass $_root = null) {
            parent::__construct($_io, $_parent, $_root);
            $this->_read();
        }

        private function _read() {
            $this->_m_nameIndex = $this->_io->readU2be();
            $this->_m_attributeLength = $this->_io->readU4be();
            switch ($this->nameAsStr()) {
                case "SourceFile":
                    $this->_m__raw_info = $this->_io->readBytes($this->attributeLength());
                    $_io__raw_info = new \Kaitai\Struct\Stream($this->_m__raw_info);
                    $this->_m_info = new \JavaClass\AttributeInfo\AttrBodySourceFile($_io__raw_info, $this, $this->_root);
                    break;
                case "LineNumberTable":
                    $this->_m__raw_info = $this->_io->readBytes($this->attributeLength());
                    $_io__raw_info = new \Kaitai\Struct\Stream($this->_m__raw_info);
                    $this->_m_info = new \JavaClass\AttributeInfo\AttrBodyLineNumberTable($_io__raw_info, $this, $this->_root);
                    break;
                case "Exceptions":
                    $this->_m__raw_info = $this->_io->readBytes($this->attributeLength());
                    $_io__raw_info = new \Kaitai\Struct\Stream($this->_m__raw_info);
                    $this->_m_info = new \JavaClass\AttributeInfo\AttrBodyExceptions($_io__raw_info, $this, $this->_root);
                    break;
                case "Code":
                    $this->_m__raw_info = $this->_io->readBytes($this->attributeLength());
                    $_io__raw_info = new \Kaitai\Struct\Stream($this->_m__raw_info);
                    $this->_m_info = new \JavaClass\AttributeInfo\AttrBodyCode($_io__raw_info, $this, $this->_root);
                    break;
                default:
                    $this->_m_info = $this->_io->readBytes($this->attributeLength());
                    break;
            }
        }
        protected $_m_nameAsStr;
        public function nameAsStr() {
            if ($this->_m_nameAsStr !== null)
                return $this->_m_nameAsStr;
            $this->_m_nameAsStr = $this->_root()->constantPool()[($this->nameIndex() - 1)]->cpInfo()->value();
            return $this->_m_nameAsStr;
        }
        protected $_m_nameIndex;
        protected $_m_attributeLength;
        protected $_m_info;
        protected $_m__raw_info;
        public function nameIndex() { return $this->_m_nameIndex; }
        public function attributeLength() { return $this->_m_attributeLength; }
        public function info() { return $this->_m_info; }
        public function _raw_info() { return $this->_m__raw_info; }
    }
}

namespace JavaClass\AttributeInfo {
    class AttrBodyCode extends \Kaitai\Struct\Struct {
        public function __construct(\Kaitai\Struct\Stream $_io, \JavaClass\AttributeInfo $_parent = null, \JavaClass $_root = null) {
            parent::__construct($_io, $_parent, $_root);
            $this->_read();
        }

        private function _read() {
            $this->_m_maxStack = $this->_io->readU2be();
            $this->_m_maxLocals = $this->_io->readU2be();
            $this->_m_codeLength = $this->_io->readU4be();
            $this->_m_code = $this->_io->readBytes($this->codeLength());
            $this->_m_exceptionTableLength = $this->_io->readU2be();
            $this->_m_exceptionTable = [];
            $n = $this->exceptionTableLength();
            for ($i = 0; $i < $n; $i++) {
                $this->_m_exceptionTable[] = new \JavaClass\AttributeInfo\AttrBodyCode\ExceptionEntry($this->_io, $this, $this->_root);
            }
            $this->_m_attributesCount = $this->_io->readU2be();
            $this->_m_attributes = [];
            $n = $this->attributesCount();
            for ($i = 0; $i < $n; $i++) {
                $this->_m_attributes[] = new \JavaClass\AttributeInfo($this->_io, $this, $this->_root);
            }
        }
        protected $_m_maxStack;
        protected $_m_maxLocals;
        protected $_m_codeLength;
        protected $_m_code;
        protected $_m_exceptionTableLength;
        protected $_m_exceptionTable;
        protected $_m_attributesCount;
        protected $_m_attributes;
        public function maxStack() { return $this->_m_maxStack; }
        public function maxLocals() { return $this->_m_maxLocals; }
        public function codeLength() { return $this->_m_codeLength; }
        public function code() { return $this->_m_code; }
        public function exceptionTableLength() { return $this->_m_exceptionTableLength; }
        public function exceptionTable() { return $this->_m_exceptionTable; }
        public function attributesCount() { return $this->_m_attributesCount; }
        public function attributes() { return $this->_m_attributes; }
    }
}

namespace JavaClass\AttributeInfo\AttrBodyCode {
    class ExceptionEntry extends \Kaitai\Struct\Struct {
        public function __construct(\Kaitai\Struct\Stream $_io, \JavaClass\AttributeInfo\AttrBodyCode $_parent = null, \JavaClass $_root = null) {
            parent::__construct($_io, $_parent, $_root);
            $this->_read();
        }

        private function _read() {
            $this->_m_startPc = $this->_io->readU2be();
            $this->_m_endPc = $this->_io->readU2be();
            $this->_m_handlerPc = $this->_io->readU2be();
            $this->_m_catchType = $this->_io->readU2be();
        }
        protected $_m_catchException;
        public function catchException() {
            if ($this->_m_catchException !== null)
                return $this->_m_catchException;
            if ($this->catchType() != 0) {
                $this->_m_catchException = $this->_root()->constantPool()[($this->catchType() - 1)];
            }
            return $this->_m_catchException;
        }
        protected $_m_startPc;
        protected $_m_endPc;
        protected $_m_handlerPc;
        protected $_m_catchType;

        /**
         * Start of a code region where exception handler is being
         * active, index in code array (inclusive)
         */
        public function startPc() { return $this->_m_startPc; }

        /**
         * End of a code region where exception handler is being
         * active, index in code array (exclusive)
         */
        public function endPc() { return $this->_m_endPc; }

        /**
         * Start of exception handler code, index in code array
         */
        public function handlerPc() { return $this->_m_handlerPc; }

        /**
         * Exception class that this handler catches, index in constant
         * pool, or 0 (catch all exceptions handler, used to implement
         * `finally`).
         */
        public function catchType() { return $this->_m_catchType; }
    }
}

namespace JavaClass\AttributeInfo {
    class AttrBodyExceptions extends \Kaitai\Struct\Struct {
        public function __construct(\Kaitai\Struct\Stream $_io, \JavaClass\AttributeInfo $_parent = null, \JavaClass $_root = null) {
            parent::__construct($_io, $_parent, $_root);
            $this->_read();
        }

        private function _read() {
            $this->_m_numberOfExceptions = $this->_io->readU2be();
            $this->_m_exceptions = [];
            $n = $this->numberOfExceptions();
            for ($i = 0; $i < $n; $i++) {
                $this->_m_exceptions[] = new \JavaClass\AttributeInfo\AttrBodyExceptions\ExceptionTableEntry($this->_io, $this, $this->_root);
            }
        }
        protected $_m_numberOfExceptions;
        protected $_m_exceptions;
        public function numberOfExceptions() { return $this->_m_numberOfExceptions; }
        public function exceptions() { return $this->_m_exceptions; }
    }
}

namespace JavaClass\AttributeInfo\AttrBodyExceptions {
    class ExceptionTableEntry extends \Kaitai\Struct\Struct {
        public function __construct(\Kaitai\Struct\Stream $_io, \JavaClass\AttributeInfo\AttrBodyExceptions $_parent = null, \JavaClass $_root = null) {
            parent::__construct($_io, $_parent, $_root);
            $this->_read();
        }

        private function _read() {
            $this->_m_index = $this->_io->readU2be();
        }
        protected $_m_asInfo;
        public function asInfo() {
            if ($this->_m_asInfo !== null)
                return $this->_m_asInfo;
            $this->_m_asInfo = $this->_root()->constantPool()[($this->index() - 1)]->cpInfo();
            return $this->_m_asInfo;
        }
        protected $_m_nameAsStr;
        public function nameAsStr() {
            if ($this->_m_nameAsStr !== null)
                return $this->_m_nameAsStr;
            $this->_m_nameAsStr = $this->asInfo()->nameAsStr();
            return $this->_m_nameAsStr;
        }
        protected $_m_index;
        public function index() { return $this->_m_index; }
    }
}

namespace JavaClass\AttributeInfo {
    class AttrBodySourceFile extends \Kaitai\Struct\Struct {
        public function __construct(\Kaitai\Struct\Stream $_io, \JavaClass\AttributeInfo $_parent = null, \JavaClass $_root = null) {
            parent::__construct($_io, $_parent, $_root);
            $this->_read();
        }

        private function _read() {
            $this->_m_sourcefileIndex = $this->_io->readU2be();
        }
        protected $_m_sourcefileAsStr;
        public function sourcefileAsStr() {
            if ($this->_m_sourcefileAsStr !== null)
                return $this->_m_sourcefileAsStr;
            $this->_m_sourcefileAsStr = $this->_root()->constantPool()[($this->sourcefileIndex() - 1)]->cpInfo()->value();
            return $this->_m_sourcefileAsStr;
        }
        protected $_m_sourcefileIndex;
        public function sourcefileIndex() { return $this->_m_sourcefileIndex; }
    }
}

namespace JavaClass\AttributeInfo {
    class AttrBodyLineNumberTable extends \Kaitai\Struct\Struct {
        public function __construct(\Kaitai\Struct\Stream $_io, \JavaClass\AttributeInfo $_parent = null, \JavaClass $_root = null) {
            parent::__construct($_io, $_parent, $_root);
            $this->_read();
        }

        private function _read() {
            $this->_m_lineNumberTableLength = $this->_io->readU2be();
            $this->_m_lineNumberTable = [];
            $n = $this->lineNumberTableLength();
            for ($i = 0; $i < $n; $i++) {
                $this->_m_lineNumberTable[] = new \JavaClass\AttributeInfo\AttrBodyLineNumberTable\LineNumberTableEntry($this->_io, $this, $this->_root);
            }
        }
        protected $_m_lineNumberTableLength;
        protected $_m_lineNumberTable;
        public function lineNumberTableLength() { return $this->_m_lineNumberTableLength; }
        public function lineNumberTable() { return $this->_m_lineNumberTable; }
    }
}

namespace JavaClass\AttributeInfo\AttrBodyLineNumberTable {
    class LineNumberTableEntry extends \Kaitai\Struct\Struct {
        public function __construct(\Kaitai\Struct\Stream $_io, \JavaClass\AttributeInfo\AttrBodyLineNumberTable $_parent = null, \JavaClass $_root = null) {
            parent::__construct($_io, $_parent, $_root);
            $this->_read();
        }

        private function _read() {
            $this->_m_startPc = $this->_io->readU2be();
            $this->_m_lineNumber = $this->_io->readU2be();
        }
        protected $_m_startPc;
        protected $_m_lineNumber;
        public function startPc() { return $this->_m_startPc; }
        public function lineNumber() { return $this->_m_lineNumber; }
    }
}

namespace JavaClass {
    class MethodRefCpInfo extends \Kaitai\Struct\Struct {
        public function __construct(\Kaitai\Struct\Stream $_io, \JavaClass\ConstantPoolEntry $_parent = null, \JavaClass $_root = null) {
            parent::__construct($_io, $_parent, $_root);
            $this->_read();
        }

        private function _read() {
            $this->_m_classIndex = $this->_io->readU2be();
            $this->_m_nameAndTypeIndex = $this->_io->readU2be();
        }
        protected $_m_classAsInfo;
        public function classAsInfo() {
            if ($this->_m_classAsInfo !== null)
                return $this->_m_classAsInfo;
            $this->_m_classAsInfo = $this->_root()->constantPool()[($this->classIndex() - 1)]->cpInfo();
            return $this->_m_classAsInfo;
        }
        protected $_m_nameAndTypeAsInfo;
        public function nameAndTypeAsInfo() {
            if ($this->_m_nameAndTypeAsInfo !== null)
                return $this->_m_nameAndTypeAsInfo;
            $this->_m_nameAndTypeAsInfo = $this->_root()->constantPool()[($this->nameAndTypeIndex() - 1)]->cpInfo();
            return $this->_m_nameAndTypeAsInfo;
        }
        protected $_m_classIndex;
        protected $_m_nameAndTypeIndex;
        public function classIndex() { return $this->_m_classIndex; }
        public function nameAndTypeIndex() { return $this->_m_nameAndTypeIndex; }
    }
}

namespace JavaClass {
    class FieldInfo extends \Kaitai\Struct\Struct {
        public function __construct(\Kaitai\Struct\Stream $_io, \JavaClass $_parent = null, \JavaClass $_root = null) {
            parent::__construct($_io, $_parent, $_root);
            $this->_read();
        }

        private function _read() {
            $this->_m_accessFlags = $this->_io->readU2be();
            $this->_m_nameIndex = $this->_io->readU2be();
            $this->_m_descriptorIndex = $this->_io->readU2be();
            $this->_m_attributesCount = $this->_io->readU2be();
            $this->_m_attributes = [];
            $n = $this->attributesCount();
            for ($i = 0; $i < $n; $i++) {
                $this->_m_attributes[] = new \JavaClass\AttributeInfo($this->_io, $this, $this->_root);
            }
        }
        protected $_m_nameAsStr;
        public function nameAsStr() {
            if ($this->_m_nameAsStr !== null)
                return $this->_m_nameAsStr;
            $this->_m_nameAsStr = $this->_root()->constantPool()[($this->nameIndex() - 1)]->cpInfo()->value();
            return $this->_m_nameAsStr;
        }
        protected $_m_accessFlags;
        protected $_m_nameIndex;
        protected $_m_descriptorIndex;
        protected $_m_attributesCount;
        protected $_m_attributes;
        public function accessFlags() { return $this->_m_accessFlags; }
        public function nameIndex() { return $this->_m_nameIndex; }
        public function descriptorIndex() { return $this->_m_descriptorIndex; }
        public function attributesCount() { return $this->_m_attributesCount; }
        public function attributes() { return $this->_m_attributes; }
    }
}

namespace JavaClass {
    class DoubleCpInfo extends \Kaitai\Struct\Struct {
        public function __construct(\Kaitai\Struct\Stream $_io, \JavaClass\ConstantPoolEntry $_parent = null, \JavaClass $_root = null) {
            parent::__construct($_io, $_parent, $_root);
            $this->_read();
        }

        private function _read() {
            $this->_m_value = $this->_io->readF8be();
        }
        protected $_m_value;
        public function value() { return $this->_m_value; }
    }
}

namespace JavaClass {
    class DynamicCpInfo extends \Kaitai\Struct\Struct {
        public function __construct(\Kaitai\Struct\Stream $_io, \JavaClass\ConstantPoolEntry $_parent = null, \JavaClass $_root = null) {
            parent::__construct($_io, $_parent, $_root);
            $this->_read();
        }

        private function _read() {
            $this->_m__unnamed0 = new \JavaClass\VersionGuard(55, $this->_io, $this, $this->_root);
            $this->_m_bootstrapMethodAttrIndex = $this->_io->readU2be();
            $this->_m_nameAndTypeIndex = $this->_io->readU2be();
        }
        protected $_m__unnamed0;
        protected $_m_bootstrapMethodAttrIndex;
        protected $_m_nameAndTypeIndex;
        public function _unnamed0() { return $this->_m__unnamed0; }
        public function bootstrapMethodAttrIndex() { return $this->_m_bootstrapMethodAttrIndex; }
        public function nameAndTypeIndex() { return $this->_m_nameAndTypeIndex; }
    }
}

namespace JavaClass {
    class LongCpInfo extends \Kaitai\Struct\Struct {
        public function __construct(\Kaitai\Struct\Stream $_io, \JavaClass\ConstantPoolEntry $_parent = null, \JavaClass $_root = null) {
            parent::__construct($_io, $_parent, $_root);
            $this->_read();
        }

        private function _read() {
            $this->_m_value = $this->_io->readU8be();
        }
        protected $_m_value;
        public function value() { return $this->_m_value; }
    }
}

namespace JavaClass {
    class InvokeDynamicCpInfo extends \Kaitai\Struct\Struct {
        public function __construct(\Kaitai\Struct\Stream $_io, \JavaClass\ConstantPoolEntry $_parent = null, \JavaClass $_root = null) {
            parent::__construct($_io, $_parent, $_root);
            $this->_read();
        }

        private function _read() {
            $this->_m__unnamed0 = new \JavaClass\VersionGuard(51, $this->_io, $this, $this->_root);
            $this->_m_bootstrapMethodAttrIndex = $this->_io->readU2be();
            $this->_m_nameAndTypeIndex = $this->_io->readU2be();
        }
        protected $_m__unnamed0;
        protected $_m_bootstrapMethodAttrIndex;
        protected $_m_nameAndTypeIndex;
        public function _unnamed0() { return $this->_m__unnamed0; }
        public function bootstrapMethodAttrIndex() { return $this->_m_bootstrapMethodAttrIndex; }
        public function nameAndTypeIndex() { return $this->_m_nameAndTypeIndex; }
    }
}

namespace JavaClass {
    class MethodHandleCpInfo extends \Kaitai\Struct\Struct {
        public function __construct(\Kaitai\Struct\Stream $_io, \JavaClass\ConstantPoolEntry $_parent = null, \JavaClass $_root = null) {
            parent::__construct($_io, $_parent, $_root);
            $this->_read();
        }

        private function _read() {
            $this->_m__unnamed0 = new \JavaClass\VersionGuard(51, $this->_io, $this, $this->_root);
            $this->_m_referenceKind = $this->_io->readU1();
            $this->_m_referenceIndex = $this->_io->readU2be();
        }
        protected $_m__unnamed0;
        protected $_m_referenceKind;
        protected $_m_referenceIndex;
        public function _unnamed0() { return $this->_m__unnamed0; }
        public function referenceKind() { return $this->_m_referenceKind; }
        public function referenceIndex() { return $this->_m_referenceIndex; }
    }
}

namespace JavaClass\MethodHandleCpInfo {
    class ReferenceKindEnum {
        const GET_FIELD = 1;
        const GET_STATIC = 2;
        const PUT_FIELD = 3;
        const PUT_STATIC = 4;
        const INVOKE_VIRTUAL = 5;
        const INVOKE_STATIC = 6;
        const INVOKE_SPECIAL = 7;
        const NEW_INVOKE_SPECIAL = 8;
        const INVOKE_INTERFACE = 9;
    }
}

/**
 * Project Jigsaw modules introduced in Java 9
 */

namespace JavaClass {
    class ModulePackageCpInfo extends \Kaitai\Struct\Struct {
        public function __construct(\Kaitai\Struct\Stream $_io, \JavaClass\ConstantPoolEntry $_parent = null, \JavaClass $_root = null) {
            parent::__construct($_io, $_parent, $_root);
            $this->_read();
        }

        private function _read() {
            $this->_m__unnamed0 = new \JavaClass\VersionGuard(53, $this->_io, $this, $this->_root);
            $this->_m_nameIndex = $this->_io->readU2be();
        }
        protected $_m_nameAsInfo;
        public function nameAsInfo() {
            if ($this->_m_nameAsInfo !== null)
                return $this->_m_nameAsInfo;
            $this->_m_nameAsInfo = $this->_root()->constantPool()[($this->nameIndex() - 1)]->cpInfo();
            return $this->_m_nameAsInfo;
        }
        protected $_m_nameAsStr;
        public function nameAsStr() {
            if ($this->_m_nameAsStr !== null)
                return $this->_m_nameAsStr;
            $this->_m_nameAsStr = $this->nameAsInfo()->value();
            return $this->_m_nameAsStr;
        }
        protected $_m__unnamed0;
        protected $_m_nameIndex;
        public function _unnamed0() { return $this->_m__unnamed0; }
        public function nameIndex() { return $this->_m_nameIndex; }
    }
}

namespace JavaClass {
    class NameAndTypeCpInfo extends \Kaitai\Struct\Struct {
        public function __construct(\Kaitai\Struct\Stream $_io, \JavaClass\ConstantPoolEntry $_parent = null, \JavaClass $_root = null) {
            parent::__construct($_io, $_parent, $_root);
            $this->_read();
        }

        private function _read() {
            $this->_m_nameIndex = $this->_io->readU2be();
            $this->_m_descriptorIndex = $this->_io->readU2be();
        }
        protected $_m_nameAsInfo;
        public function nameAsInfo() {
            if ($this->_m_nameAsInfo !== null)
                return $this->_m_nameAsInfo;
            $this->_m_nameAsInfo = $this->_root()->constantPool()[($this->nameIndex() - 1)]->cpInfo();
            return $this->_m_nameAsInfo;
        }
        protected $_m_nameAsStr;
        public function nameAsStr() {
            if ($this->_m_nameAsStr !== null)
                return $this->_m_nameAsStr;
            $this->_m_nameAsStr = $this->nameAsInfo()->value();
            return $this->_m_nameAsStr;
        }
        protected $_m_descriptorAsInfo;
        public function descriptorAsInfo() {
            if ($this->_m_descriptorAsInfo !== null)
                return $this->_m_descriptorAsInfo;
            $this->_m_descriptorAsInfo = $this->_root()->constantPool()[($this->descriptorIndex() - 1)]->cpInfo();
            return $this->_m_descriptorAsInfo;
        }
        protected $_m_descriptorAsStr;
        public function descriptorAsStr() {
            if ($this->_m_descriptorAsStr !== null)
                return $this->_m_descriptorAsStr;
            $this->_m_descriptorAsStr = $this->descriptorAsInfo()->value();
            return $this->_m_descriptorAsStr;
        }
        protected $_m_nameIndex;
        protected $_m_descriptorIndex;
        public function nameIndex() { return $this->_m_nameIndex; }
        public function descriptorIndex() { return $this->_m_descriptorIndex; }
    }
}

namespace JavaClass {
    class Utf8CpInfo extends \Kaitai\Struct\Struct {
        public function __construct(\Kaitai\Struct\Stream $_io, \JavaClass\ConstantPoolEntry $_parent = null, \JavaClass $_root = null) {
            parent::__construct($_io, $_parent, $_root);
            $this->_read();
        }

        private function _read() {
            $this->_m_strLen = $this->_io->readU2be();
            $this->_m_value = \Kaitai\Struct\Stream::bytesToStr($this->_io->readBytes($this->strLen()), "UTF-8");
        }
        protected $_m_strLen;
        protected $_m_value;
        public function strLen() { return $this->_m_strLen; }
        public function value() { return $this->_m_value; }
    }
}

namespace JavaClass {
    class StringCpInfo extends \Kaitai\Struct\Struct {
        public function __construct(\Kaitai\Struct\Stream $_io, \JavaClass\ConstantPoolEntry $_parent = null, \JavaClass $_root = null) {
            parent::__construct($_io, $_parent, $_root);
            $this->_read();
        }

        private function _read() {
            $this->_m_stringIndex = $this->_io->readU2be();
        }
        protected $_m_stringIndex;
        public function stringIndex() { return $this->_m_stringIndex; }
    }
}

namespace JavaClass {
    class MethodTypeCpInfo extends \Kaitai\Struct\Struct {
        public function __construct(\Kaitai\Struct\Stream $_io, \JavaClass\ConstantPoolEntry $_parent = null, \JavaClass $_root = null) {
            parent::__construct($_io, $_parent, $_root);
            $this->_read();
        }

        private function _read() {
            $this->_m__unnamed0 = new \JavaClass\VersionGuard(51, $this->_io, $this, $this->_root);
            $this->_m_descriptorIndex = $this->_io->readU2be();
        }
        protected $_m__unnamed0;
        protected $_m_descriptorIndex;
        public function _unnamed0() { return $this->_m__unnamed0; }
        public function descriptorIndex() { return $this->_m_descriptorIndex; }
    }
}

namespace JavaClass {
    class InterfaceMethodRefCpInfo extends \Kaitai\Struct\Struct {
        public function __construct(\Kaitai\Struct\Stream $_io, \JavaClass\ConstantPoolEntry $_parent = null, \JavaClass $_root = null) {
            parent::__construct($_io, $_parent, $_root);
            $this->_read();
        }

        private function _read() {
            $this->_m_classIndex = $this->_io->readU2be();
            $this->_m_nameAndTypeIndex = $this->_io->readU2be();
        }
        protected $_m_classAsInfo;
        public function classAsInfo() {
            if ($this->_m_classAsInfo !== null)
                return $this->_m_classAsInfo;
            $this->_m_classAsInfo = $this->_root()->constantPool()[($this->classIndex() - 1)]->cpInfo();
            return $this->_m_classAsInfo;
        }
        protected $_m_nameAndTypeAsInfo;
        public function nameAndTypeAsInfo() {
            if ($this->_m_nameAndTypeAsInfo !== null)
                return $this->_m_nameAndTypeAsInfo;
            $this->_m_nameAndTypeAsInfo = $this->_root()->constantPool()[($this->nameAndTypeIndex() - 1)]->cpInfo();
            return $this->_m_nameAndTypeAsInfo;
        }
        protected $_m_classIndex;
        protected $_m_nameAndTypeIndex;
        public function classIndex() { return $this->_m_classIndex; }
        public function nameAndTypeIndex() { return $this->_m_nameAndTypeIndex; }
    }
}

namespace JavaClass {
    class ClassCpInfo extends \Kaitai\Struct\Struct {
        public function __construct(\Kaitai\Struct\Stream $_io, \JavaClass\ConstantPoolEntry $_parent = null, \JavaClass $_root = null) {
            parent::__construct($_io, $_parent, $_root);
            $this->_read();
        }

        private function _read() {
            $this->_m_nameIndex = $this->_io->readU2be();
        }
        protected $_m_nameAsInfo;
        public function nameAsInfo() {
            if ($this->_m_nameAsInfo !== null)
                return $this->_m_nameAsInfo;
            $this->_m_nameAsInfo = $this->_root()->constantPool()[($this->nameIndex() - 1)]->cpInfo();
            return $this->_m_nameAsInfo;
        }
        protected $_m_nameAsStr;
        public function nameAsStr() {
            if ($this->_m_nameAsStr !== null)
                return $this->_m_nameAsStr;
            $this->_m_nameAsStr = $this->nameAsInfo()->value();
            return $this->_m_nameAsStr;
        }
        protected $_m_nameIndex;
        public function nameIndex() { return $this->_m_nameIndex; }
    }
}

namespace JavaClass {
    class ConstantPoolEntry extends \Kaitai\Struct\Struct {
        public function __construct(bool $isPrevTwoEntries, \Kaitai\Struct\Stream $_io, \JavaClass $_parent = null, \JavaClass $_root = null) {
            parent::__construct($_io, $_parent, $_root);
            $this->_m_isPrevTwoEntries = $isPrevTwoEntries;
            $this->_read();
        }

        private function _read() {
            if (!($this->isPrevTwoEntries())) {
                $this->_m_tag = $this->_io->readU1();
            }
            if (!($this->isPrevTwoEntries())) {
                switch ($this->tag()) {
                    case \JavaClass\ConstantPoolEntry\TagEnum::INTERFACE_METHOD_REF:
                        $this->_m_cpInfo = new \JavaClass\InterfaceMethodRefCpInfo($this->_io, $this, $this->_root);
                        break;
                    case \JavaClass\ConstantPoolEntry\TagEnum::CLASS_TYPE:
                        $this->_m_cpInfo = new \JavaClass\ClassCpInfo($this->_io, $this, $this->_root);
                        break;
                    case \JavaClass\ConstantPoolEntry\TagEnum::DYNAMIC:
                        $this->_m_cpInfo = new \JavaClass\DynamicCpInfo($this->_io, $this, $this->_root);
                        break;
                    case \JavaClass\ConstantPoolEntry\TagEnum::UTF8:
                        $this->_m_cpInfo = new \JavaClass\Utf8CpInfo($this->_io, $this, $this->_root);
                        break;
                    case \JavaClass\ConstantPoolEntry\TagEnum::METHOD_TYPE:
                        $this->_m_cpInfo = new \JavaClass\MethodTypeCpInfo($this->_io, $this, $this->_root);
                        break;
                    case \JavaClass\ConstantPoolEntry\TagEnum::INTEGER:
                        $this->_m_cpInfo = new \JavaClass\IntegerCpInfo($this->_io, $this, $this->_root);
                        break;
                    case \JavaClass\ConstantPoolEntry\TagEnum::STRING:
                        $this->_m_cpInfo = new \JavaClass\StringCpInfo($this->_io, $this, $this->_root);
                        break;
                    case \JavaClass\ConstantPoolEntry\TagEnum::FLOAT:
                        $this->_m_cpInfo = new \JavaClass\FloatCpInfo($this->_io, $this, $this->_root);
                        break;
                    case \JavaClass\ConstantPoolEntry\TagEnum::MODULE:
                        $this->_m_cpInfo = new \JavaClass\ModulePackageCpInfo($this->_io, $this, $this->_root);
                        break;
                    case \JavaClass\ConstantPoolEntry\TagEnum::LONG:
                        $this->_m_cpInfo = new \JavaClass\LongCpInfo($this->_io, $this, $this->_root);
                        break;
                    case \JavaClass\ConstantPoolEntry\TagEnum::METHOD_REF:
                        $this->_m_cpInfo = new \JavaClass\MethodRefCpInfo($this->_io, $this, $this->_root);
                        break;
                    case \JavaClass\ConstantPoolEntry\TagEnum::DOUBLE:
                        $this->_m_cpInfo = new \JavaClass\DoubleCpInfo($this->_io, $this, $this->_root);
                        break;
                    case \JavaClass\ConstantPoolEntry\TagEnum::INVOKE_DYNAMIC:
                        $this->_m_cpInfo = new \JavaClass\InvokeDynamicCpInfo($this->_io, $this, $this->_root);
                        break;
                    case \JavaClass\ConstantPoolEntry\TagEnum::FIELD_REF:
                        $this->_m_cpInfo = new \JavaClass\FieldRefCpInfo($this->_io, $this, $this->_root);
                        break;
                    case \JavaClass\ConstantPoolEntry\TagEnum::METHOD_HANDLE:
                        $this->_m_cpInfo = new \JavaClass\MethodHandleCpInfo($this->_io, $this, $this->_root);
                        break;
                    case \JavaClass\ConstantPoolEntry\TagEnum::PACKAGE:
                        $this->_m_cpInfo = new \JavaClass\ModulePackageCpInfo($this->_io, $this, $this->_root);
                        break;
                    case \JavaClass\ConstantPoolEntry\TagEnum::NAME_AND_TYPE:
                        $this->_m_cpInfo = new \JavaClass\NameAndTypeCpInfo($this->_io, $this, $this->_root);
                        break;
                }
            }
        }
        protected $_m_isTwoEntries;
        public function isTwoEntries() {
            if ($this->_m_isTwoEntries !== null)
                return $this->_m_isTwoEntries;
            $this->_m_isTwoEntries = ($this->isPrevTwoEntries() ? false :  (($this->tag() == \JavaClass\ConstantPoolEntry\TagEnum::LONG) || ($this->tag() == \JavaClass\ConstantPoolEntry\TagEnum::DOUBLE)) );
            return $this->_m_isTwoEntries;
        }
        protected $_m_tag;
        protected $_m_cpInfo;
        protected $_m_isPrevTwoEntries;
        public function tag() { return $this->_m_tag; }
        public function cpInfo() { return $this->_m_cpInfo; }
        public function isPrevTwoEntries() { return $this->_m_isPrevTwoEntries; }
    }
}

namespace JavaClass\ConstantPoolEntry {
    class TagEnum {
        const UTF8 = 1;
        const INTEGER = 3;
        const FLOAT = 4;
        const LONG = 5;
        const DOUBLE = 6;
        const CLASS_TYPE = 7;
        const STRING = 8;
        const FIELD_REF = 9;
        const METHOD_REF = 10;
        const INTERFACE_METHOD_REF = 11;
        const NAME_AND_TYPE = 12;
        const METHOD_HANDLE = 15;
        const METHOD_TYPE = 16;
        const DYNAMIC = 17;
        const INVOKE_DYNAMIC = 18;
        const MODULE = 19;
        const PACKAGE = 20;
    }
}

namespace JavaClass {
    class MethodInfo extends \Kaitai\Struct\Struct {
        public function __construct(\Kaitai\Struct\Stream $_io, \JavaClass $_parent = null, \JavaClass $_root = null) {
            parent::__construct($_io, $_parent, $_root);
            $this->_read();
        }

        private function _read() {
            $this->_m_accessFlags = $this->_io->readU2be();
            $this->_m_nameIndex = $this->_io->readU2be();
            $this->_m_descriptorIndex = $this->_io->readU2be();
            $this->_m_attributesCount = $this->_io->readU2be();
            $this->_m_attributes = [];
            $n = $this->attributesCount();
            for ($i = 0; $i < $n; $i++) {
                $this->_m_attributes[] = new \JavaClass\AttributeInfo($this->_io, $this, $this->_root);
            }
        }
        protected $_m_nameAsStr;
        public function nameAsStr() {
            if ($this->_m_nameAsStr !== null)
                return $this->_m_nameAsStr;
            $this->_m_nameAsStr = $this->_root()->constantPool()[($this->nameIndex() - 1)]->cpInfo()->value();
            return $this->_m_nameAsStr;
        }
        protected $_m_accessFlags;
        protected $_m_nameIndex;
        protected $_m_descriptorIndex;
        protected $_m_attributesCount;
        protected $_m_attributes;
        public function accessFlags() { return $this->_m_accessFlags; }
        public function nameIndex() { return $this->_m_nameIndex; }
        public function descriptorIndex() { return $this->_m_descriptorIndex; }
        public function attributesCount() { return $this->_m_attributesCount; }
        public function attributes() { return $this->_m_attributes; }
    }
}

namespace JavaClass {
    class IntegerCpInfo extends \Kaitai\Struct\Struct {
        public function __construct(\Kaitai\Struct\Stream $_io, \JavaClass\ConstantPoolEntry $_parent = null, \JavaClass $_root = null) {
            parent::__construct($_io, $_parent, $_root);
            $this->_read();
        }

        private function _read() {
            $this->_m_value = $this->_io->readU4be();
        }
        protected $_m_value;
        public function value() { return $this->_m_value; }
    }
}

namespace JavaClass {
    class FieldRefCpInfo extends \Kaitai\Struct\Struct {
        public function __construct(\Kaitai\Struct\Stream $_io, \JavaClass\ConstantPoolEntry $_parent = null, \JavaClass $_root = null) {
            parent::__construct($_io, $_parent, $_root);
            $this->_read();
        }

        private function _read() {
            $this->_m_classIndex = $this->_io->readU2be();
            $this->_m_nameAndTypeIndex = $this->_io->readU2be();
        }
        protected $_m_classAsInfo;
        public function classAsInfo() {
            if ($this->_m_classAsInfo !== null)
                return $this->_m_classAsInfo;
            $this->_m_classAsInfo = $this->_root()->constantPool()[($this->classIndex() - 1)]->cpInfo();
            return $this->_m_classAsInfo;
        }
        protected $_m_nameAndTypeAsInfo;
        public function nameAndTypeAsInfo() {
            if ($this->_m_nameAndTypeAsInfo !== null)
                return $this->_m_nameAndTypeAsInfo;
            $this->_m_nameAndTypeAsInfo = $this->_root()->constantPool()[($this->nameAndTypeIndex() - 1)]->cpInfo();
            return $this->_m_nameAndTypeAsInfo;
        }
        protected $_m_classIndex;
        protected $_m_nameAndTypeIndex;
        public function classIndex() { return $this->_m_classIndex; }
        public function nameAndTypeIndex() { return $this->_m_nameAndTypeIndex; }
    }
}