<s> """<STR_LIT>""" <EOL> import re <EOL> SIMPLE_SCALAR = '<STR_LIT>' <EOL> DECIMAL_SCALAR = '<STR_LIT>' <EOL> DOUBLE_SCALAR = '<STR_LIT>' <EOL> def parse_column ( name , type_string , comment = None ) : <EOL> """<STR_LIT>""" <EOL> column = { <EOL> '<STR_LIT:name>' : name , <EOL> '<STR_LIT>' : comment or '<STR_LIT>' <EOL> } <EOL> simple_type , inner = _parse_type ( type_string ) <EOL> column [ '<STR_LIT:type>' ] = simple_type <EOL> if inner : <EOL> column . update ( _parse_complex ( simple_type , inner ) ) <EOL> return column <EOL> def is_scalar_type ( type_string ) : <EOL> return not ( type_string . startswith ( '<STR_LIT>' ) or type_string . startswith ( '<STR_LIT>' ) or type_string . startswith ( '<STR_LIT>' ) ) <EOL> def _parse_type ( type_string ) : <EOL> pattern = re . compile ( '<STR_LIT>' % { <EOL> '<STR_LIT>' : SIMPLE_SCALAR , <EOL> '<STR_LIT>' : DECIMAL_SCALAR , <EOL> '<STR_LIT>' : DOUBLE_SCALAR } , re . IGNORECASE ) <EOL> match = re . search ( pattern , type_string ) <EOL> return match . group ( <NUM_LIT:1> ) , match . group ( <NUM_LIT:3> ) <EOL> def _parse_complex ( simple_type , inner ) : <EOL> complex_type = { } <EOL> if simple_type == "<STR_LIT>" : <EOL> complex_type [ '<STR_LIT>' ] = _parse_array_item ( inner ) <EOL> elif simple_type == "<STR_LIT>" : <EOL> complex_type [ '<STR_LIT:key>' ] = _parse_map_key ( inner ) <EOL> complex_type [ '<STR_LIT:value>' ] = _parse_map_value ( inner ) <EOL> elif simple_type == "<STR_LIT>" : <EOL> complex_type [ '<STR_LIT>' ] = _parse_struct_fields ( inner ) <EOL> return complex_type <EOL> def _parse_array_item ( inner ) : <EOL> item = { } <EOL> simple_type , inner = _parse_type ( inner ) <EOL> item [ '<STR_LIT:type>' ] = simple_type <EOL> if inner : <EOL> item . update ( _parse_complex ( simple_type , inner ) ) <EOL> return item <EOL> def _parse_map_key ( inner ) : <EOL> key = { } <EOL> key_type = inner . split ( '<STR_LIT:U+002C>' , <NUM_LIT:1> ) [ <NUM_LIT:0> ] <EOL> key [ '<STR_LIT:type>' ] = key_type <EOL> return key <EOL> def _parse_map_value ( inner ) : <EOL> value = { } <EOL> value_type = inner . split ( '<STR_LIT:U+002C>' , <NUM_LIT:1> ) [ <NUM_LIT:1> ] <EOL> simple_type , inner = _parse_type ( value_type ) <EOL> value [ '<STR_LIT:type>' ] = simple_type <EOL> if inner : <EOL> value . update ( _parse_complex ( simple_type , inner ) ) <EOL> return value <EOL> def _parse_struct_fields ( inner ) : <EOL> fields = [ ] <EOL> field_tuples = _split_struct_fields ( inner ) <EOL> for ( name , value ) in field_tuples : <EOL> field = { } <EOL> field [ '<STR_LIT:name>' ] = name <EOL> simple_type , inner = _parse_type ( value ) <EOL> field [ '<STR_LIT:type>' ] = simple_type <EOL> if inner : <EOL> field . update ( _parse_complex ( simple_type , inner ) ) <EOL> fields . append ( field ) <EOL> return fields <EOL> def _split_struct_fields ( fields_string ) : <EOL> fields = [ ] <EOL> remaining = fields_string <EOL> while remaining : <EOL> ( fieldname , fieldvalue ) , remaining = _get_next_struct_field ( remaining ) <EOL> fields . append ( ( fieldname , fieldvalue ) ) <EOL> return fields <EOL> def _get_next_struct_field ( fields_string ) : <EOL> fieldname , rest = fields_string . split ( '<STR_LIT::>' , <NUM_LIT:1> ) <EOL> balanced = <NUM_LIT:0> <EOL> for pos , char in enumerate ( rest ) : <EOL> balanced += { '<STR_LIT:<>' : <NUM_LIT:1> , '<STR_LIT:>>' : - <NUM_LIT:1> , '<STR_LIT:(>' : <NUM_LIT:1> , '<STR_LIT:)>' : - <NUM_LIT:1> } . get ( char , <NUM_LIT:0> ) <EOL> if balanced == <NUM_LIT:0> and char in [ '<STR_LIT:>>' , '<STR_LIT:U+002C>' ] : <EOL> return ( fieldname , rest [ : pos + <NUM_LIT:1> ] . strip ( '<STR_LIT:U+002C>' ) ) , rest [ pos + <NUM_LIT:1> : ] <EOL> return ( fieldname , rest ) , None </s>
