import os import sys from jinja2 import Environment, PackageLoader import capnp import schema_capnp def find_type(code, id): for node in code["nodes"]: if node["id"] == id: return node return None def main(): env = Environment(loader=PackageLoader("capnp", "templates")) env.filters["format_name"] = lambda name: name[name.find(":") + 1 :] 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"] = list(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 include_dir = os.path.abspath(os.path.join(os.path.dirname(capnp.__file__), "..")) module = env.get_template("module.pyx") for f in code["requestedFiles"]: filename = f["filename"].replace(".", "_") + "_cython.pyx" 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)) 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()