<commit_before>#!/usr/bin/env python

import collections
import itertools
import os.path
import re
import string
import sys
import xml.etree.ElementTree

INDENT = '    '

ADJUSTED_VALUES = {
  ('276', 'f '): 'f',
}

SYMBOLIC_NAME_ALIASES = {
    ('434', '2'): [
        'OrderCancelReplaceRequest',
    ],
}

Enum = collections.namedtuple('Enum', ['tag', 'value', 'symbolic_name', 'sort'])

def read_enums(infile):
    def enum_with_aliases(elem):
        tag = elem.find('Tag').text
        value = elem.find('Value').text
        adjusted_value = ADJUSTED_VALUES.get((tag, value), value)
        symbolic_name = elem.find('SymbolicName').text
        sort = int(elem.find('Sort').text) if elem.find('Sort') is not None else None
        enum = Enum(tag, adjusted_value, symbolic_name, sort)
        return [enum] + [enum._replace(symbolic_name=symbolic_name_alias)
                for symbolic_name_alias in SYMBOLIC_NAME_ALIASES.get((tag, adjusted_value), [])]
    tree = xml.etree.ElementTree.parse(infile)
    enums = [enum_with_aliases(elem) for elem in tree.findall('Enum')]
    return [enum for aliases in enums for enum in aliases]

Field = collections.namedtuple('Field', ['tag', 'name', 'type'])

def read_fields(infile):
    def field(elem):
        tag = elem.find('Tag').text
        name = elem.find('Name').text
        type = elem.find('Type').text
        return Field(tag, name, type)
    tree = xml.etree.ElementTree.parse(infile)
    fields = [field(elem) for elem in tree.findall('Field')]
    return sorted(fields, key=lambda field: int(field.tag))

Message = collections.namedtuple('Message', ['msg_type', 'name'])

def read_messages(infile):
    def message(elem):
        msg_type = elem.find('MsgType').text
        name = elem.find('Name').text
        return Message(msg_type, name)
    tree = xml.etree.ElementTree.parse(infile)
    return [message(elem) for elem in tree.findall('Message')]

Version = collections.namedtuple('Version', ['protocol', 'major', 'minor', 'sp'])

def read_version(infile):
    version = xml.etree.ElementTree.parse(infile).getroot().get('version')
    match = re.match(r'(?P<protocol>.+)\.(?P<major>\d+)\.(?P<minor>\d+)(SP(?P<sp>\d+))?', version)
    return Version(match.group('protocol'), match.group('major'), match.group('minor'),
        match.group('sp'))

ENUMERATIONS_TEMPLATE = string.Template('''\
package com.paritytrading.philadelphia.${package_name};

/**
 * Enumerations for ${version_name}.
 */
public class ${class_name} {

${body}

    private ${class_name}() {
    }

}
''')

def format_enumerations(version, enumerations):
    body = '\n\n'.join(format_enumeration(enumeration) for enumeration in enumerations)
    return ENUMERATIONS_TEMPLATE.substitute({
            'package_name': package_name(version),
            'class_name': class_name(version, 'Enumerations'),
            'version_name': version_name(version),
            'body': body,
        })

ENUMERATION_TEMPLATE = string.Template('''\
    /**
     * Values for ${field_name}.
     */
    public static class ${class_name} {

${body}

        private ${class_name}() {
        }

    }\
''')

def format_char(value, value_width):
    return '\'{}\''.format(value)

def format_string(value, value_width):
    return '"{}"'.format(value)

def format_int(value, value_width):
    return '{:>{}}'.format(value, value_width)

FIELD_TYPES = {
    'Char': ('char', format_char),
    'char': ('char', format_char),
    'Int': ('int', format_int),
    'int': ('int', format_int),
    'MultipleCharValue': ('char', format_char),
    'MultipleStringValue': ('String', format_string),
    'MultipleValueString': ('String', format_string),
    'NumInGroup': ('int', format_int),
    'String': ('String', format_string),
}

def format_enumeration(enumeration):
    symbolic_name_width = max(len(enum.symbolic_name) for enum in enumeration.enums)
    value_width = max(len(enum.value) for enum in enumeration.enums)
    type, format_type = FIELD_TYPES[enumeration.field.type]
    if type == 'char' and value_width > 1:
        type, format_type = FIELD_TYPES['String']
    body = '\n'.join('{}{}'.format(2 * INDENT, format_enum(enum, type, symbolic_name_width,
      format_type, value_width)) for enum in enumeration.enums)
    return ENUMERATION_TEMPLATE.substitute({
            'field_name': field_name(enumeration.field),
            'class_name': '{}Values'.format(enumeration.field.name),
            'body': body,
        })

def format_enum(enum, type, symbolic_name_width, format_type, value_width):
    return 'public static final {} {:<{}} = {};'.format(type, enum.symbolic_name,
        symbolic_name_width, format_type(enum.value, value_width))

MSG_TYPES_TEMPLATE = string.Template('''\
package com.paritytrading.philadelphia.${package_name};

/**
 * Message types for ${version_name}.
 */
public class ${class_name} {

${body}

    private ${class_name}() {
    }

}
''')

def format_msg_types(version, messages):
    name_width = max(len(message.name) for message in messages)
    msg_type_width = max(len(message.msg_type) for message in messages)<commit_msg>scripts: Simplify enumeration formatting<commit_after>#!/usr/bin/env python

import collections
import itertools
import os.path
import re
import string
import sys
import xml.etree.ElementTree

INDENT = '    '

ADJUSTED_VALUES = {
  ('276', 'f '): 'f',
}

SYMBOLIC_NAME_ALIASES = {
    ('434', '2'): [
        'OrderCancelReplaceRequest',
    ],
}

Enum = collections.namedtuple('Enum', ['tag', 'value', 'symbolic_name', 'sort'])

def read_enums(infile):
    def enum_with_aliases(elem):
        tag = elem.find('Tag').text
        value = elem.find('Value').text
        adjusted_value = ADJUSTED_VALUES.get((tag, value), value)
        symbolic_name = elem.find('SymbolicName').text
        sort = int(elem.find('Sort').text) if elem.find('Sort') is not None else None
        enum = Enum(tag, adjusted_value, symbolic_name, sort)
        return [enum] + [enum._replace(symbolic_name=symbolic_name_alias)
                for symbolic_name_alias in SYMBOLIC_NAME_ALIASES.get((tag, adjusted_value), [])]
    tree = xml.etree.ElementTree.parse(infile)
    enums = [enum_with_aliases(elem) for elem in tree.findall('Enum')]
    return [enum for aliases in enums for enum in aliases]

Field = collections.namedtuple('Field', ['tag', 'name', 'type'])

def read_fields(infile):
    def field(elem):
        tag = elem.find('Tag').text
        name = elem.find('Name').text
        type = elem.find('Type').text
        return Field(tag, name, type)
    tree = xml.etree.ElementTree.parse(infile)
    fields = [field(elem) for elem in tree.findall('Field')]
    return sorted(fields, key=lambda field: int(field.tag))

Message = collections.namedtuple('Message', ['msg_type', 'name'])

def read_messages(infile):
    def message(elem):
        msg_type = elem.find('MsgType').text
        name = elem.find('Name').text
        return Message(msg_type, name)
    tree = xml.etree.ElementTree.parse(infile)
    return [message(elem) for elem in tree.findall('Message')]

Version = collections.namedtuple('Version', ['protocol', 'major', 'minor', 'sp'])

def read_version(infile):
    version = xml.etree.ElementTree.parse(infile).getroot().get('version')
    match = re.match(r'(?P<protocol>.+)\.(?P<major>\d+)\.(?P<minor>\d+)(SP(?P<sp>\d+))?', version)
    return Version(match.group('protocol'), match.group('major'), match.group('minor'),
        match.group('sp'))

ENUMERATIONS_TEMPLATE = string.Template('''\
package com.paritytrading.philadelphia.${package_name};

/**
 * Enumerations for ${version_name}.
 */
public class ${class_name} {

${body}

    private ${class_name}() {
    }

}
''')

def format_enumerations(version, enumerations):
    body = '\n\n'.join(format_enumeration(enumeration) for enumeration in enumerations)
    return ENUMERATIONS_TEMPLATE.substitute({
            'package_name': package_name(version),
            'class_name': class_name(version, 'Enumerations'),
            'version_name': version_name(version),
            'body': body,
        })

ENUMERATION_TEMPLATE = string.Template('''\
    /**
     * Values for ${field_name}.
     */
    public static class ${class_name} {

${body}

        private ${class_name}() {
        }

    }\
''')

def format_char(value):
    return '\'{}\''.format(value)

def format_string(value):
    return '"{}"'.format(value)

def format_int(value):
    return '{}'.format(value)

FIELD_TYPES = {
    'Char': ('char', format_char),
    'char': ('char', format_char),
    'Int': ('int', format_int),
    'int': ('int', format_int),
    'MultipleCharValue': ('char', format_char),
    'MultipleStringValue': ('String', format_string),
    'MultipleValueString': ('String', format_string),
    'NumInGroup': ('int', format_int),
    'String': ('String', format_string),
}

def format_enumeration(enumeration):
    symbolic_name_width = max(len(enum.symbolic_name) for enum in enumeration.enums)
    value_width = max(len(enum.value) for enum in enumeration.enums)
    type, format_type = FIELD_TYPES[enumeration.field.type]
    if type == 'char' and value_width > 1:
        type, format_type = FIELD_TYPES['String']
    body = '\n'.join('{}{}'.format(2 * INDENT, format_enum(enum, type, symbolic_name_width,
      format_type)) for enum in enumeration.enums)
    return ENUMERATION_TEMPLATE.substitute({
            'field_name': field_name(enumeration.field),
            'class_name': '{}Values'.format(enumeration.field.name),
            'body': body,
        })

def format_enum(enum, type, symbolic_name_width, format_type):
    return 'public static final {} {:<{}} = {};'.format(type, enum.symbolic_name,
        symbolic_name_width, format_type(enum.value))

MSG_TYPES_TEMPLATE = string.Template('''\
package com.paritytrading.philadelphia.${package_name};

/**
 * Message types for ${version_name}.
 */
public class ${class_name} {

${body}

    private ${class_name}() {
    }

}
''')

def format_msg_types(version, messages):
    name_width = max(len(message.name) for message in messages)
    msg_type_width = max(len(message.msg_type) for message in messages)
{'fraction_non_alphanumeric': 0.15983445013795822, 'fraction_numerical': 0.0017737485218762318, 'mean_word_length': 3.835159599809433, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 10}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4184397', 'n_tokens_mistral': 3373, 'n_tokens_neox': 3322, 'n_words': 669}