2020-06-08 23:51:07 -07:00
|
|
|
import os
|
2014-09-04 14:21:27 -07:00
|
|
|
import sys
|
2020-06-08 23:51:07 -07:00
|
|
|
|
2014-09-04 14:21:27 -07:00
|
|
|
from jinja2 import Environment, PackageLoader
|
|
|
|
|
2020-06-08 23:51:07 -07:00
|
|
|
import capnp
|
|
|
|
import schema_capnp
|
2019-12-11 22:44:44 -08:00
|
|
|
|
2014-10-19 20:06:00 -07:00
|
|
|
def find_type(code, id):
|
2019-09-26 22:18:28 -07:00
|
|
|
for node in code['nodes']:
|
|
|
|
if node['id'] == id:
|
|
|
|
return node
|
2014-10-19 20:06:00 -07:00
|
|
|
|
2019-09-26 22:18:28 -07:00
|
|
|
return None
|
2014-10-19 20:06:00 -07:00
|
|
|
|
2019-12-11 22:44:44 -08:00
|
|
|
|
2014-09-04 14:21:27 -07:00
|
|
|
def main():
|
2019-09-26 22:18:28 -07:00
|
|
|
env = Environment(loader=PackageLoader('capnp', 'templates'))
|
|
|
|
env.filters['format_name'] = lambda name: name[name.find(':') + 1:]
|
2014-09-04 14:21:27 -07:00
|
|
|
|
2019-09-26 22:18:28 -07:00
|
|
|
code = schema_capnp.CodeGeneratorRequest.read(sys.stdin)
|
|
|
|
code = code.to_dict()
|
|
|
|
code['nodes'] = [node for node in code['nodes'] if 'struct' in node and node['scopeId'] != 0]
|
|
|
|
for node in code['nodes']:
|
|
|
|
displayName = node['displayName']
|
|
|
|
parent, path = displayName.split(':')
|
|
|
|
node['module_path'] = parent.replace('.', '_') + '.' + '.'.join([x[0].upper() + x[1:] for x in path.split('.')])
|
|
|
|
node['module_name'] = path.replace('.', '_')
|
|
|
|
node['c_module_path'] = '::'.join([x[0].upper() + x[1:] for x in path.split('.')])
|
|
|
|
node['schema'] = '_{}_Schema'.format(node['module_name'])
|
|
|
|
is_union = False
|
|
|
|
for field in node['struct']['fields']:
|
|
|
|
if field['discriminantValue'] != 65535:
|
|
|
|
is_union = True
|
|
|
|
field['c_name'] = field['name'][0].upper() + field['name'][1:]
|
|
|
|
if 'slot' in field:
|
|
|
|
field['type'] = field['slot']['type'].keys()[0]
|
|
|
|
if not isinstance(field['slot']['type'][field['type']], dict):
|
|
|
|
continue
|
|
|
|
sub_type = field['slot']['type'][field['type']].get('typeId', None)
|
|
|
|
if sub_type:
|
|
|
|
field['sub_type'] = find_type(code, sub_type)
|
|
|
|
sub_type = field['slot']['type'][field['type']].get('elementType', None)
|
|
|
|
if sub_type:
|
|
|
|
field['sub_type'] = sub_type
|
|
|
|
else:
|
|
|
|
field['type'] = find_type(code, field['group']['typeId'])
|
|
|
|
node['is_union'] = is_union
|
2014-09-04 14:21:27 -07:00
|
|
|
|
2019-09-26 22:18:28 -07:00
|
|
|
include_dir = os.path.abspath(os.path.join(os.path.dirname(capnp.__file__), '..'))
|
|
|
|
module = env.get_template('module.pyx')
|
2014-09-04 18:04:52 -07:00
|
|
|
|
2019-09-26 22:18:28 -07:00
|
|
|
for f in code['requestedFiles']:
|
|
|
|
filename = f['filename'].replace('.', '_') + '_cython.pyx'
|
2014-09-04 18:04:52 -07:00
|
|
|
|
2019-09-26 22:18:28 -07:00
|
|
|
file_code = dict(code)
|
|
|
|
file_code['nodes'] = [node for node in file_code['nodes'] if node['displayName'].startswith(f['filename'])]
|
|
|
|
with open(filename, 'w') as out:
|
|
|
|
out.write(module.render(code=file_code, file=f, include_dir=include_dir))
|
2014-09-04 14:21:27 -07:00
|
|
|
|
2019-09-26 22:18:28 -07:00
|
|
|
setup = env.get_template('setup.py.tmpl')
|
|
|
|
with open('setup_capnp.py', 'w') as out:
|
|
|
|
out.write(setup.render(code=code))
|
|
|
|
print('You now need to build the cython module by running `python setup_capnp.py build_ext --inplace`.')
|
|
|
|
print()
|