output method

  1. @override
List<String> output()
override

Return resulting code, must be overridden.

Implementation

@override
List<String> output() {
    _minBufferSize = fields.where((Field f) => f.static).fold(_flagBytes, (int a, Field b) => a + b.size);

    /// Add 4 bytes for command ID and transaction ID if this node is used by message/request node
    if (id != null) _minBufferSize += 8;

    final Object? inheritedObject = inheritTag.isNotEmpty ? _getInheritedObject() : null;
    final List<Field> inheritedFields = _getInheritedFields();
    final Map<int, Object> childObjects = _getChildObjects();

    /// Add 4 bytes for specific inherited object class ID (to be able to unpack corresponding inherited object)
    if (inheritTag.isNotEmpty || childObjects.isNotEmpty) _minBufferSize += 4;

    return <String>[
        '',
        if (inheritTag.isEmpty) 'class $name extends PackMeMessage {'
        else 'class $name extends ${inheritedObject!.name} {',

        if (fields.isNotEmpty) ...<String>[
            '$name({',
            if (inheritTag.isNotEmpty) ...inheritedFields.map((Field f) => f.attribute),
            ...fields.map((Field f) => f.initializer),
            if (inheritTag.isEmpty) '});'
            else '}) : super(${inheritedFields.map((Field f) => '${f.name}: ${f.name}').join(', ')});'
        ]
        else '$name();',

        if (inheritTag.isEmpty) '$name.\$empty();\n'
        else '$name.\$empty() : super.\$empty();\n',

        if (inheritTag.isEmpty && childObjects.isNotEmpty) ...<String>[
            r'static Map<Type, int> $kinIds = <Type, int>{',
                '$name: 0,',
                ...childObjects.entries.map((MapEntry<int, Object> row) => '${row.value.name}: ${row.key},'),
            '};\n',
            'static $name \$emptyKin(int id) {',
                'switch (id) {',
                    ...childObjects.entries.map((MapEntry<int, Object> row) => 'case ${row.key}: return ${row.value.name}.\$empty();'),
                    'default: return $name.\$empty();',
                '}',
            '}\n'
        ],
        ...fields.map((Field field) => field.declaration),

        if (response != null) ...<String>[
            '',
            if (response!.fields.isNotEmpty) ...<String>[
                '${response!.name} \$response({',
                ...response!.fields.map((Field f) => f.attribute),
                '}) {'
            ]
            else '${response!.name} \$response() {',
                'final ${response!.name} message = ${response!.name}(${response!.fields.map((Field f) => '${f.name}: ${f.name}').join(', ')});',
                r'message.$request = this;',
                'return message;',
            '}',
        ],

        '',
        '@override',
        r'int $estimate() {',
            if (inheritTag.isEmpty) r'$reset();'
            else r'int _bytes = super.$estimate();',
            if (fields.where((Field f) => !f.static).isNotEmpty || inheritTag.isNotEmpty) ...<String>[
                if (inheritTag.isEmpty) 'int _bytes = $_minBufferSize;'
                else if (_minBufferSize > 0) '_bytes += $_minBufferSize;',
                ...fields.fold(<String>[], (Iterable<String> a, Field b) => a.toList() + b.estimate),
                'return _bytes;',
            ]
            else 'return $_minBufferSize;',
        '}',
        '',
        '@override',
        r'void $pack() {',
            if (id != null) '\$initPack($id);',
            if (inheritTag.isNotEmpty) r'super.$pack();'
            else if (childObjects.isNotEmpty) r'$packUint32($kinIds[runtimeType] ?? 0);',
            if (_flagBytes > 0) 'for (int i = 0; i < $_flagBytes; i++) \$packUint8(\$flags[i]);',
            ...fields.fold(<String>[], (Iterable<String> a, Field b) => a.toList() + b.pack),
        '}',
        '',
        '@override',
        r'void $unpack() {',
            if (id != null) r'$initUnpack();',
            if (inheritTag.isNotEmpty) r'super.$unpack();',
            if (_flagBytes > 0) 'for (int i = 0; i < $_flagBytes; i++) \$flags.add(\$unpackUint8());',
            ...fields.fold(<String>[], (Iterable<String> a, Field b) => a.toList() + b.unpack),
        '}',
        '',
        '@override',
            r'String toString() {',
            "return '$name\\x1b[0m(${<Field>[...inheritedFields, ...fields].map((Field f) => '${f.name}: \${PackMe.dye(${f.name})}').join(', ')})';",
        '}',
        '}',
    ];
}