11cb0ef41Sopenharmony_ci#!/usr/bin/env python 21cb0ef41Sopenharmony_ci# Copyright 2016 The Chromium Authors. All rights reserved. 31cb0ef41Sopenharmony_ci# Use of this source code is governed by a BSD-style license that can be 41cb0ef41Sopenharmony_ci# found in the LICENSE file. 51cb0ef41Sopenharmony_ci 61cb0ef41Sopenharmony_ciimport os.path 71cb0ef41Sopenharmony_ciimport sys 81cb0ef41Sopenharmony_ciimport argparse 91cb0ef41Sopenharmony_ciimport collections 101cb0ef41Sopenharmony_ciimport functools 111cb0ef41Sopenharmony_ciimport re 121cb0ef41Sopenharmony_ciimport copy 131cb0ef41Sopenharmony_citry: 141cb0ef41Sopenharmony_ci import json 151cb0ef41Sopenharmony_ciexcept ImportError: 161cb0ef41Sopenharmony_ci import simplejson as json 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_ciimport pdl 191cb0ef41Sopenharmony_ci 201cb0ef41Sopenharmony_citry: 211cb0ef41Sopenharmony_ci unicode 221cb0ef41Sopenharmony_ciexcept NameError: 231cb0ef41Sopenharmony_ci # Define unicode for Py3 241cb0ef41Sopenharmony_ci def unicode(s, *_): 251cb0ef41Sopenharmony_ci return s 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_ci# Path handling for libraries and templates 281cb0ef41Sopenharmony_ci# Paths have to be normalized because Jinja uses the exact template path to 291cb0ef41Sopenharmony_ci# determine the hash used in the cache filename, and we need a pre-caching step 301cb0ef41Sopenharmony_ci# to be concurrency-safe. Use absolute path because __file__ is absolute if 311cb0ef41Sopenharmony_ci# module is imported, and relative if executed directly. 321cb0ef41Sopenharmony_ci# If paths differ between pre-caching and individual file compilation, the cache 331cb0ef41Sopenharmony_ci# is regenerated, which causes a race condition and breaks concurrent build, 341cb0ef41Sopenharmony_ci# since some compile processes will try to read the partially written cache. 351cb0ef41Sopenharmony_cimodule_path, module_filename = os.path.split(os.path.realpath(__file__)) 361cb0ef41Sopenharmony_ci 371cb0ef41Sopenharmony_cidef read_config(): 381cb0ef41Sopenharmony_ci # pylint: disable=W0703 391cb0ef41Sopenharmony_ci def json_to_object(data, output_base): 401cb0ef41Sopenharmony_ci def json_object_hook(object_dict): 411cb0ef41Sopenharmony_ci items = [(k, os.path.join(output_base, v) if k == "path" else v) for (k, v) in object_dict.items()] 421cb0ef41Sopenharmony_ci items = [(k, os.path.join(output_base, v) if k == "output" else v) for (k, v) in items] 431cb0ef41Sopenharmony_ci keys, values = list(zip(*items)) 441cb0ef41Sopenharmony_ci # 'async' is a python 3.7 keyword. Don't use namedtuple(rename=True) 451cb0ef41Sopenharmony_ci # because that only renames it in python 3 but not python 2. 461cb0ef41Sopenharmony_ci keys = tuple('async_' if k == 'async' else k for k in keys) 471cb0ef41Sopenharmony_ci return collections.namedtuple('X', keys)(*values) 481cb0ef41Sopenharmony_ci return json.loads(data, object_hook=json_object_hook) 491cb0ef41Sopenharmony_ci 501cb0ef41Sopenharmony_ci def init_defaults(config_tuple, path, defaults): 511cb0ef41Sopenharmony_ci keys = list(config_tuple._fields) # pylint: disable=E1101 521cb0ef41Sopenharmony_ci values = [getattr(config_tuple, k) for k in keys] 531cb0ef41Sopenharmony_ci for i in range(len(keys)): 541cb0ef41Sopenharmony_ci if hasattr(values[i], "_fields"): 551cb0ef41Sopenharmony_ci values[i] = init_defaults(values[i], path + "." + keys[i], defaults) 561cb0ef41Sopenharmony_ci for optional in defaults: 571cb0ef41Sopenharmony_ci if optional.find(path + ".") != 0: 581cb0ef41Sopenharmony_ci continue 591cb0ef41Sopenharmony_ci optional_key = optional[len(path) + 1:] 601cb0ef41Sopenharmony_ci if optional_key.find(".") == -1 and optional_key not in keys: 611cb0ef41Sopenharmony_ci keys.append(optional_key) 621cb0ef41Sopenharmony_ci values.append(defaults[optional]) 631cb0ef41Sopenharmony_ci return collections.namedtuple('X', keys)(*values) 641cb0ef41Sopenharmony_ci 651cb0ef41Sopenharmony_ci try: 661cb0ef41Sopenharmony_ci cmdline_parser = argparse.ArgumentParser() 671cb0ef41Sopenharmony_ci cmdline_parser.add_argument("--output_base", type=unicode, required=True) 681cb0ef41Sopenharmony_ci cmdline_parser.add_argument("--jinja_dir", type=unicode, required=True) 691cb0ef41Sopenharmony_ci cmdline_parser.add_argument("--config", type=unicode, required=True) 701cb0ef41Sopenharmony_ci cmdline_parser.add_argument("--config_value", default=[], action="append") 711cb0ef41Sopenharmony_ci arg_options = cmdline_parser.parse_args() 721cb0ef41Sopenharmony_ci jinja_dir = arg_options.jinja_dir 731cb0ef41Sopenharmony_ci output_base = arg_options.output_base 741cb0ef41Sopenharmony_ci config_file = arg_options.config 751cb0ef41Sopenharmony_ci config_values = arg_options.config_value 761cb0ef41Sopenharmony_ci except Exception: 771cb0ef41Sopenharmony_ci # Work with python 2 and 3 http://docs.python.org/py3k/howto/pyporting.html 781cb0ef41Sopenharmony_ci exc = sys.exc_info()[1] 791cb0ef41Sopenharmony_ci sys.stderr.write("Failed to parse command-line arguments: %s\n\n" % exc) 801cb0ef41Sopenharmony_ci exit(1) 811cb0ef41Sopenharmony_ci 821cb0ef41Sopenharmony_ci try: 831cb0ef41Sopenharmony_ci config_json_file = open(config_file, "r") 841cb0ef41Sopenharmony_ci config_json_string = config_json_file.read() 851cb0ef41Sopenharmony_ci config_partial = json_to_object(config_json_string, output_base) 861cb0ef41Sopenharmony_ci config_json_file.close() 871cb0ef41Sopenharmony_ci defaults = { 881cb0ef41Sopenharmony_ci ".use_snake_file_names": False, 891cb0ef41Sopenharmony_ci ".use_title_case_methods": False, 901cb0ef41Sopenharmony_ci ".imported": False, 911cb0ef41Sopenharmony_ci ".imported.export_macro": "", 921cb0ef41Sopenharmony_ci ".imported.export_header": False, 931cb0ef41Sopenharmony_ci ".imported.header": False, 941cb0ef41Sopenharmony_ci ".imported.package": False, 951cb0ef41Sopenharmony_ci ".imported.options": False, 961cb0ef41Sopenharmony_ci ".protocol.export_macro": "", 971cb0ef41Sopenharmony_ci ".protocol.export_header": False, 981cb0ef41Sopenharmony_ci ".protocol.options": False, 991cb0ef41Sopenharmony_ci ".protocol.file_name_prefix": "", 1001cb0ef41Sopenharmony_ci ".exported": False, 1011cb0ef41Sopenharmony_ci ".exported.export_macro": "", 1021cb0ef41Sopenharmony_ci ".exported.export_header": False, 1031cb0ef41Sopenharmony_ci ".lib": False, 1041cb0ef41Sopenharmony_ci ".lib.export_macro": "", 1051cb0ef41Sopenharmony_ci ".lib.export_header": False, 1061cb0ef41Sopenharmony_ci # The encoding lib consists of encoding/encoding.h and 1071cb0ef41Sopenharmony_ci # encoding/encoding.cc in its subdirectory, which binaries 1081cb0ef41Sopenharmony_ci # may link / depend on, instead of relying on the 1091cb0ef41Sopenharmony_ci # JINJA2 templates lib/encoding_{h,cc}.template. 1101cb0ef41Sopenharmony_ci # In that case, |header| identifies the include file 1111cb0ef41Sopenharmony_ci # and |namespace| is the namespace it's using. Usually 1121cb0ef41Sopenharmony_ci # inspector_protocol_encoding but for v8's copy it's 1131cb0ef41Sopenharmony_ci # v8_inspector_protocol_encoding. 1141cb0ef41Sopenharmony_ci # TODO(johannes): Migrate away from lib/encoding_{h,cc}.template 1151cb0ef41Sopenharmony_ci # in favor of this. 1161cb0ef41Sopenharmony_ci ".encoding_lib": { "header": "", "namespace": []}, 1171cb0ef41Sopenharmony_ci } 1181cb0ef41Sopenharmony_ci for key_value in config_values: 1191cb0ef41Sopenharmony_ci parts = key_value.split("=") 1201cb0ef41Sopenharmony_ci if len(parts) == 2: 1211cb0ef41Sopenharmony_ci defaults["." + parts[0]] = parts[1] 1221cb0ef41Sopenharmony_ci return (jinja_dir, config_file, init_defaults(config_partial, "", defaults)) 1231cb0ef41Sopenharmony_ci except Exception: 1241cb0ef41Sopenharmony_ci # Work with python 2 and 3 http://docs.python.org/py3k/howto/pyporting.html 1251cb0ef41Sopenharmony_ci exc = sys.exc_info()[1] 1261cb0ef41Sopenharmony_ci sys.stderr.write("Failed to parse config file: %s\n\n" % exc) 1271cb0ef41Sopenharmony_ci exit(1) 1281cb0ef41Sopenharmony_ci 1291cb0ef41Sopenharmony_ci 1301cb0ef41Sopenharmony_ci# ---- Begin of utilities exposed to generator ---- 1311cb0ef41Sopenharmony_ci 1321cb0ef41Sopenharmony_ci 1331cb0ef41Sopenharmony_cidef to_title_case(name): 1341cb0ef41Sopenharmony_ci return name[:1].upper() + name[1:] 1351cb0ef41Sopenharmony_ci 1361cb0ef41Sopenharmony_ci 1371cb0ef41Sopenharmony_cidef dash_to_camelcase(word): 1381cb0ef41Sopenharmony_ci prefix = "" 1391cb0ef41Sopenharmony_ci if word[0] == "-": 1401cb0ef41Sopenharmony_ci prefix = "Negative" 1411cb0ef41Sopenharmony_ci word = word[1:] 1421cb0ef41Sopenharmony_ci return prefix + "".join(to_title_case(x) or "-" for x in word.split("-")) 1431cb0ef41Sopenharmony_ci 1441cb0ef41Sopenharmony_ci 1451cb0ef41Sopenharmony_cidef to_snake_case(name): 1461cb0ef41Sopenharmony_ci return re.sub(r"([a-z0-9])([A-Z])", r"\1_\2", name, sys.maxsize).lower() 1471cb0ef41Sopenharmony_ci 1481cb0ef41Sopenharmony_ci 1491cb0ef41Sopenharmony_cidef to_method_case(config, name): 1501cb0ef41Sopenharmony_ci if config.use_title_case_methods: 1511cb0ef41Sopenharmony_ci return to_title_case(name) 1521cb0ef41Sopenharmony_ci return name 1531cb0ef41Sopenharmony_ci 1541cb0ef41Sopenharmony_ci 1551cb0ef41Sopenharmony_cidef join_arrays(dict, keys): 1561cb0ef41Sopenharmony_ci result = [] 1571cb0ef41Sopenharmony_ci for key in keys: 1581cb0ef41Sopenharmony_ci if key in dict: 1591cb0ef41Sopenharmony_ci result += dict[key] 1601cb0ef41Sopenharmony_ci return result 1611cb0ef41Sopenharmony_ci 1621cb0ef41Sopenharmony_ci 1631cb0ef41Sopenharmony_cidef format_include(config, header, file_name=None): 1641cb0ef41Sopenharmony_ci if file_name is not None: 1651cb0ef41Sopenharmony_ci header = header + "/" + file_name + ".h" 1661cb0ef41Sopenharmony_ci header = "\"" + header + "\"" if header[0] not in "<\"" else header 1671cb0ef41Sopenharmony_ci if config.use_snake_file_names: 1681cb0ef41Sopenharmony_ci header = to_snake_case(header) 1691cb0ef41Sopenharmony_ci return header 1701cb0ef41Sopenharmony_ci 1711cb0ef41Sopenharmony_ci 1721cb0ef41Sopenharmony_cidef format_domain_include(config, header, file_name): 1731cb0ef41Sopenharmony_ci return format_include(config, header, config.protocol.file_name_prefix + file_name) 1741cb0ef41Sopenharmony_ci 1751cb0ef41Sopenharmony_ci 1761cb0ef41Sopenharmony_cidef to_file_name(config, file_name): 1771cb0ef41Sopenharmony_ci if config.use_snake_file_names: 1781cb0ef41Sopenharmony_ci return to_snake_case(file_name).replace(".cpp", ".cc") 1791cb0ef41Sopenharmony_ci return file_name 1801cb0ef41Sopenharmony_ci 1811cb0ef41Sopenharmony_ci 1821cb0ef41Sopenharmony_ci# ---- End of utilities exposed to generator ---- 1831cb0ef41Sopenharmony_ci 1841cb0ef41Sopenharmony_ci 1851cb0ef41Sopenharmony_cidef initialize_jinja_env(jinja_dir, cache_dir, config): 1861cb0ef41Sopenharmony_ci # pylint: disable=F0401 1871cb0ef41Sopenharmony_ci sys.path.insert(1, os.path.abspath(jinja_dir)) 1881cb0ef41Sopenharmony_ci import jinja2 1891cb0ef41Sopenharmony_ci 1901cb0ef41Sopenharmony_ci jinja_env = jinja2.Environment( 1911cb0ef41Sopenharmony_ci loader=jinja2.FileSystemLoader(module_path), 1921cb0ef41Sopenharmony_ci # Bytecode cache is not concurrency-safe unless pre-cached: 1931cb0ef41Sopenharmony_ci # if pre-cached this is read-only, but writing creates a race condition. 1941cb0ef41Sopenharmony_ci bytecode_cache=jinja2.FileSystemBytecodeCache(cache_dir), 1951cb0ef41Sopenharmony_ci keep_trailing_newline=True, # newline-terminate generated files 1961cb0ef41Sopenharmony_ci lstrip_blocks=True, # so can indent control flow tags 1971cb0ef41Sopenharmony_ci trim_blocks=True) 1981cb0ef41Sopenharmony_ci jinja_env.filters.update({"to_title_case": to_title_case, "dash_to_camelcase": dash_to_camelcase, "to_method_case": functools.partial(to_method_case, config)}) 1991cb0ef41Sopenharmony_ci jinja_env.add_extension("jinja2.ext.loopcontrols") 2001cb0ef41Sopenharmony_ci return jinja_env 2011cb0ef41Sopenharmony_ci 2021cb0ef41Sopenharmony_ci 2031cb0ef41Sopenharmony_cidef create_imported_type_definition(domain_name, type, imported_namespace): 2041cb0ef41Sopenharmony_ci # pylint: disable=W0622 2051cb0ef41Sopenharmony_ci return { 2061cb0ef41Sopenharmony_ci "return_type": "std::unique_ptr<%s::%s::API::%s>" % (imported_namespace, domain_name, type["id"]), 2071cb0ef41Sopenharmony_ci "pass_type": "std::unique_ptr<%s::%s::API::%s>" % (imported_namespace, domain_name, type["id"]), 2081cb0ef41Sopenharmony_ci "to_raw_type": "%s.get()", 2091cb0ef41Sopenharmony_ci "to_pass_type": "std::move(%s)", 2101cb0ef41Sopenharmony_ci "to_rvalue": "std::move(%s)", 2111cb0ef41Sopenharmony_ci "type": "std::unique_ptr<%s::%s::API::%s>" % (imported_namespace, domain_name, type["id"]), 2121cb0ef41Sopenharmony_ci "raw_type": "%s::%s::API::%s" % (imported_namespace, domain_name, type["id"]), 2131cb0ef41Sopenharmony_ci "raw_pass_type": "%s::%s::API::%s*" % (imported_namespace, domain_name, type["id"]), 2141cb0ef41Sopenharmony_ci "raw_return_type": "%s::%s::API::%s*" % (imported_namespace, domain_name, type["id"]), 2151cb0ef41Sopenharmony_ci } 2161cb0ef41Sopenharmony_ci 2171cb0ef41Sopenharmony_ci 2181cb0ef41Sopenharmony_cidef create_user_type_definition(domain_name, type): 2191cb0ef41Sopenharmony_ci # pylint: disable=W0622 2201cb0ef41Sopenharmony_ci return { 2211cb0ef41Sopenharmony_ci "return_type": "std::unique_ptr<protocol::%s::%s>" % (domain_name, type["id"]), 2221cb0ef41Sopenharmony_ci "pass_type": "std::unique_ptr<protocol::%s::%s>" % (domain_name, type["id"]), 2231cb0ef41Sopenharmony_ci "to_raw_type": "%s.get()", 2241cb0ef41Sopenharmony_ci "to_pass_type": "std::move(%s)", 2251cb0ef41Sopenharmony_ci "to_rvalue": "std::move(%s)", 2261cb0ef41Sopenharmony_ci "type": "std::unique_ptr<protocol::%s::%s>" % (domain_name, type["id"]), 2271cb0ef41Sopenharmony_ci "raw_type": "protocol::%s::%s" % (domain_name, type["id"]), 2281cb0ef41Sopenharmony_ci "raw_pass_type": "protocol::%s::%s*" % (domain_name, type["id"]), 2291cb0ef41Sopenharmony_ci "raw_return_type": "protocol::%s::%s*" % (domain_name, type["id"]), 2301cb0ef41Sopenharmony_ci } 2311cb0ef41Sopenharmony_ci 2321cb0ef41Sopenharmony_ci 2331cb0ef41Sopenharmony_cidef create_object_type_definition(): 2341cb0ef41Sopenharmony_ci # pylint: disable=W0622 2351cb0ef41Sopenharmony_ci return { 2361cb0ef41Sopenharmony_ci "return_type": "std::unique_ptr<protocol::DictionaryValue>", 2371cb0ef41Sopenharmony_ci "pass_type": "std::unique_ptr<protocol::DictionaryValue>", 2381cb0ef41Sopenharmony_ci "to_raw_type": "%s.get()", 2391cb0ef41Sopenharmony_ci "to_pass_type": "std::move(%s)", 2401cb0ef41Sopenharmony_ci "to_rvalue": "std::move(%s)", 2411cb0ef41Sopenharmony_ci "type": "std::unique_ptr<protocol::DictionaryValue>", 2421cb0ef41Sopenharmony_ci "raw_type": "protocol::DictionaryValue", 2431cb0ef41Sopenharmony_ci "raw_pass_type": "protocol::DictionaryValue*", 2441cb0ef41Sopenharmony_ci "raw_return_type": "protocol::DictionaryValue*", 2451cb0ef41Sopenharmony_ci } 2461cb0ef41Sopenharmony_ci 2471cb0ef41Sopenharmony_ci 2481cb0ef41Sopenharmony_cidef create_any_type_definition(): 2491cb0ef41Sopenharmony_ci # pylint: disable=W0622 2501cb0ef41Sopenharmony_ci return { 2511cb0ef41Sopenharmony_ci "return_type": "std::unique_ptr<protocol::Value>", 2521cb0ef41Sopenharmony_ci "pass_type": "std::unique_ptr<protocol::Value>", 2531cb0ef41Sopenharmony_ci "to_raw_type": "%s.get()", 2541cb0ef41Sopenharmony_ci "to_pass_type": "std::move(%s)", 2551cb0ef41Sopenharmony_ci "to_rvalue": "std::move(%s)", 2561cb0ef41Sopenharmony_ci "type": "std::unique_ptr<protocol::Value>", 2571cb0ef41Sopenharmony_ci "raw_type": "protocol::Value", 2581cb0ef41Sopenharmony_ci "raw_pass_type": "protocol::Value*", 2591cb0ef41Sopenharmony_ci "raw_return_type": "protocol::Value*", 2601cb0ef41Sopenharmony_ci } 2611cb0ef41Sopenharmony_ci 2621cb0ef41Sopenharmony_ci 2631cb0ef41Sopenharmony_cidef create_string_type_definition(): 2641cb0ef41Sopenharmony_ci # pylint: disable=W0622 2651cb0ef41Sopenharmony_ci return { 2661cb0ef41Sopenharmony_ci "return_type": "String", 2671cb0ef41Sopenharmony_ci "pass_type": "const String&", 2681cb0ef41Sopenharmony_ci "to_pass_type": "%s", 2691cb0ef41Sopenharmony_ci "to_raw_type": "%s", 2701cb0ef41Sopenharmony_ci "to_rvalue": "%s", 2711cb0ef41Sopenharmony_ci "type": "String", 2721cb0ef41Sopenharmony_ci "raw_type": "String", 2731cb0ef41Sopenharmony_ci "raw_pass_type": "const String&", 2741cb0ef41Sopenharmony_ci "raw_return_type": "String", 2751cb0ef41Sopenharmony_ci } 2761cb0ef41Sopenharmony_ci 2771cb0ef41Sopenharmony_ci 2781cb0ef41Sopenharmony_cidef create_binary_type_definition(): 2791cb0ef41Sopenharmony_ci # pylint: disable=W0622 2801cb0ef41Sopenharmony_ci return { 2811cb0ef41Sopenharmony_ci "return_type": "Binary", 2821cb0ef41Sopenharmony_ci "pass_type": "const Binary&", 2831cb0ef41Sopenharmony_ci "to_pass_type": "%s", 2841cb0ef41Sopenharmony_ci "to_raw_type": "%s", 2851cb0ef41Sopenharmony_ci "to_rvalue": "%s", 2861cb0ef41Sopenharmony_ci "type": "Binary", 2871cb0ef41Sopenharmony_ci "raw_type": "Binary", 2881cb0ef41Sopenharmony_ci "raw_pass_type": "const Binary&", 2891cb0ef41Sopenharmony_ci "raw_return_type": "Binary", 2901cb0ef41Sopenharmony_ci } 2911cb0ef41Sopenharmony_ci 2921cb0ef41Sopenharmony_ci 2931cb0ef41Sopenharmony_cidef create_primitive_type_definition(type): 2941cb0ef41Sopenharmony_ci # pylint: disable=W0622 2951cb0ef41Sopenharmony_ci typedefs = { 2961cb0ef41Sopenharmony_ci "number": "double", 2971cb0ef41Sopenharmony_ci "integer": "int", 2981cb0ef41Sopenharmony_ci "boolean": "bool" 2991cb0ef41Sopenharmony_ci } 3001cb0ef41Sopenharmony_ci defaults = { 3011cb0ef41Sopenharmony_ci "number": "0", 3021cb0ef41Sopenharmony_ci "integer": "0", 3031cb0ef41Sopenharmony_ci "boolean": "false" 3041cb0ef41Sopenharmony_ci } 3051cb0ef41Sopenharmony_ci jsontypes = { 3061cb0ef41Sopenharmony_ci "number": "TypeDouble", 3071cb0ef41Sopenharmony_ci "integer": "TypeInteger", 3081cb0ef41Sopenharmony_ci "boolean": "TypeBoolean", 3091cb0ef41Sopenharmony_ci } 3101cb0ef41Sopenharmony_ci return { 3111cb0ef41Sopenharmony_ci "return_type": typedefs[type], 3121cb0ef41Sopenharmony_ci "pass_type": typedefs[type], 3131cb0ef41Sopenharmony_ci "to_pass_type": "%s", 3141cb0ef41Sopenharmony_ci "to_raw_type": "%s", 3151cb0ef41Sopenharmony_ci "to_rvalue": "%s", 3161cb0ef41Sopenharmony_ci "type": typedefs[type], 3171cb0ef41Sopenharmony_ci "raw_type": typedefs[type], 3181cb0ef41Sopenharmony_ci "raw_pass_type": typedefs[type], 3191cb0ef41Sopenharmony_ci "raw_return_type": typedefs[type], 3201cb0ef41Sopenharmony_ci "default_value": defaults[type] 3211cb0ef41Sopenharmony_ci } 3221cb0ef41Sopenharmony_ci 3231cb0ef41Sopenharmony_ci 3241cb0ef41Sopenharmony_cidef wrap_array_definition(type): 3251cb0ef41Sopenharmony_ci # pylint: disable=W0622 3261cb0ef41Sopenharmony_ci return { 3271cb0ef41Sopenharmony_ci "return_type": "std::unique_ptr<protocol::Array<%s>>" % type["raw_type"], 3281cb0ef41Sopenharmony_ci "pass_type": "std::unique_ptr<protocol::Array<%s>>" % type["raw_type"], 3291cb0ef41Sopenharmony_ci "to_raw_type": "%s.get()", 3301cb0ef41Sopenharmony_ci "to_pass_type": "std::move(%s)", 3311cb0ef41Sopenharmony_ci "to_rvalue": "std::move(%s)", 3321cb0ef41Sopenharmony_ci "type": "std::unique_ptr<protocol::Array<%s>>" % type["raw_type"], 3331cb0ef41Sopenharmony_ci "raw_type": "protocol::Array<%s>" % type["raw_type"], 3341cb0ef41Sopenharmony_ci "raw_pass_type": "protocol::Array<%s>*" % type["raw_type"], 3351cb0ef41Sopenharmony_ci "raw_return_type": "protocol::Array<%s>*" % type["raw_type"], 3361cb0ef41Sopenharmony_ci "out_type": "protocol::Array<%s>&" % type["raw_type"], 3371cb0ef41Sopenharmony_ci } 3381cb0ef41Sopenharmony_ci 3391cb0ef41Sopenharmony_ci 3401cb0ef41Sopenharmony_ciclass Protocol(object): 3411cb0ef41Sopenharmony_ci def __init__(self, config): 3421cb0ef41Sopenharmony_ci self.config = config 3431cb0ef41Sopenharmony_ci self.json_api = {"domains": []} 3441cb0ef41Sopenharmony_ci self.imported_domains = [] 3451cb0ef41Sopenharmony_ci self.exported_domains = [] 3461cb0ef41Sopenharmony_ci self.generate_domains = self.read_protocol_file(config.protocol.path) 3471cb0ef41Sopenharmony_ci 3481cb0ef41Sopenharmony_ci if config.protocol.options: 3491cb0ef41Sopenharmony_ci self.generate_domains = [rule.domain for rule in config.protocol.options] 3501cb0ef41Sopenharmony_ci self.exported_domains = [rule.domain for rule in config.protocol.options if hasattr(rule, "exported")] 3511cb0ef41Sopenharmony_ci 3521cb0ef41Sopenharmony_ci if config.imported: 3531cb0ef41Sopenharmony_ci self.imported_domains = self.read_protocol_file(config.imported.path) 3541cb0ef41Sopenharmony_ci if config.imported.options: 3551cb0ef41Sopenharmony_ci self.imported_domains = [rule.domain for rule in config.imported.options] 3561cb0ef41Sopenharmony_ci 3571cb0ef41Sopenharmony_ci self.patch_full_qualified_refs() 3581cb0ef41Sopenharmony_ci self.create_notification_types() 3591cb0ef41Sopenharmony_ci self.create_type_definitions() 3601cb0ef41Sopenharmony_ci self.generate_used_types() 3611cb0ef41Sopenharmony_ci 3621cb0ef41Sopenharmony_ci 3631cb0ef41Sopenharmony_ci def read_protocol_file(self, file_name): 3641cb0ef41Sopenharmony_ci input_file = open(file_name, "r") 3651cb0ef41Sopenharmony_ci parsed_json = pdl.loads(input_file.read(), file_name) 3661cb0ef41Sopenharmony_ci input_file.close() 3671cb0ef41Sopenharmony_ci version = parsed_json["version"]["major"] + "." + parsed_json["version"]["minor"] 3681cb0ef41Sopenharmony_ci domains = [] 3691cb0ef41Sopenharmony_ci for domain in parsed_json["domains"]: 3701cb0ef41Sopenharmony_ci domains.append(domain["domain"]) 3711cb0ef41Sopenharmony_ci domain["version"] = version 3721cb0ef41Sopenharmony_ci self.json_api["domains"] += parsed_json["domains"] 3731cb0ef41Sopenharmony_ci return domains 3741cb0ef41Sopenharmony_ci 3751cb0ef41Sopenharmony_ci 3761cb0ef41Sopenharmony_ci def patch_full_qualified_refs(self): 3771cb0ef41Sopenharmony_ci def patch_full_qualified_refs_in_domain(json, domain_name): 3781cb0ef41Sopenharmony_ci if isinstance(json, list): 3791cb0ef41Sopenharmony_ci for item in json: 3801cb0ef41Sopenharmony_ci patch_full_qualified_refs_in_domain(item, domain_name) 3811cb0ef41Sopenharmony_ci if not isinstance(json, dict): 3821cb0ef41Sopenharmony_ci return 3831cb0ef41Sopenharmony_ci for key in json: 3841cb0ef41Sopenharmony_ci if key == "type" and json[key] == "string": 3851cb0ef41Sopenharmony_ci json[key] = domain_name + ".string" 3861cb0ef41Sopenharmony_ci if key != "$ref": 3871cb0ef41Sopenharmony_ci patch_full_qualified_refs_in_domain(json[key], domain_name) 3881cb0ef41Sopenharmony_ci continue 3891cb0ef41Sopenharmony_ci if json["$ref"].find(".") == -1: 3901cb0ef41Sopenharmony_ci json["$ref"] = domain_name + "." + json["$ref"] 3911cb0ef41Sopenharmony_ci return 3921cb0ef41Sopenharmony_ci 3931cb0ef41Sopenharmony_ci for domain in self.json_api["domains"]: 3941cb0ef41Sopenharmony_ci patch_full_qualified_refs_in_domain(domain, domain["domain"]) 3951cb0ef41Sopenharmony_ci 3961cb0ef41Sopenharmony_ci 3971cb0ef41Sopenharmony_ci def all_references(self, json): 3981cb0ef41Sopenharmony_ci refs = set() 3991cb0ef41Sopenharmony_ci if isinstance(json, list): 4001cb0ef41Sopenharmony_ci for item in json: 4011cb0ef41Sopenharmony_ci refs |= self.all_references(item) 4021cb0ef41Sopenharmony_ci if not isinstance(json, dict): 4031cb0ef41Sopenharmony_ci return refs 4041cb0ef41Sopenharmony_ci for key in json: 4051cb0ef41Sopenharmony_ci if key != "$ref": 4061cb0ef41Sopenharmony_ci refs |= self.all_references(json[key]) 4071cb0ef41Sopenharmony_ci else: 4081cb0ef41Sopenharmony_ci refs.add(json["$ref"]) 4091cb0ef41Sopenharmony_ci return refs 4101cb0ef41Sopenharmony_ci 4111cb0ef41Sopenharmony_ci def generate_used_types(self): 4121cb0ef41Sopenharmony_ci all_refs = set() 4131cb0ef41Sopenharmony_ci for domain in self.json_api["domains"]: 4141cb0ef41Sopenharmony_ci domain_name = domain["domain"] 4151cb0ef41Sopenharmony_ci if "commands" in domain: 4161cb0ef41Sopenharmony_ci for command in domain["commands"]: 4171cb0ef41Sopenharmony_ci if self.generate_command(domain_name, command["name"]): 4181cb0ef41Sopenharmony_ci all_refs |= self.all_references(command) 4191cb0ef41Sopenharmony_ci if "events" in domain: 4201cb0ef41Sopenharmony_ci for event in domain["events"]: 4211cb0ef41Sopenharmony_ci if self.generate_event(domain_name, event["name"]): 4221cb0ef41Sopenharmony_ci all_refs |= self.all_references(event) 4231cb0ef41Sopenharmony_ci all_refs.add(domain_name + "." + to_title_case(event["name"]) + "Notification") 4241cb0ef41Sopenharmony_ci 4251cb0ef41Sopenharmony_ci dependencies = self.generate_type_dependencies() 4261cb0ef41Sopenharmony_ci queue = set(all_refs) 4271cb0ef41Sopenharmony_ci while len(queue): 4281cb0ef41Sopenharmony_ci ref = queue.pop() 4291cb0ef41Sopenharmony_ci if ref in dependencies: 4301cb0ef41Sopenharmony_ci queue |= dependencies[ref] - all_refs 4311cb0ef41Sopenharmony_ci all_refs |= dependencies[ref] 4321cb0ef41Sopenharmony_ci self.used_types = all_refs 4331cb0ef41Sopenharmony_ci 4341cb0ef41Sopenharmony_ci 4351cb0ef41Sopenharmony_ci def generate_type_dependencies(self): 4361cb0ef41Sopenharmony_ci dependencies = dict() 4371cb0ef41Sopenharmony_ci domains_with_types = (x for x in self.json_api["domains"] if "types" in x) 4381cb0ef41Sopenharmony_ci for domain in domains_with_types: 4391cb0ef41Sopenharmony_ci domain_name = domain["domain"] 4401cb0ef41Sopenharmony_ci for type in domain["types"]: 4411cb0ef41Sopenharmony_ci related_types = self.all_references(type) 4421cb0ef41Sopenharmony_ci if len(related_types): 4431cb0ef41Sopenharmony_ci dependencies[domain_name + "." + type["id"]] = related_types 4441cb0ef41Sopenharmony_ci return dependencies 4451cb0ef41Sopenharmony_ci 4461cb0ef41Sopenharmony_ci 4471cb0ef41Sopenharmony_ci def create_notification_types(self): 4481cb0ef41Sopenharmony_ci for domain in self.json_api["domains"]: 4491cb0ef41Sopenharmony_ci if "events" in domain: 4501cb0ef41Sopenharmony_ci for event in domain["events"]: 4511cb0ef41Sopenharmony_ci event_type = dict() 4521cb0ef41Sopenharmony_ci event_type["description"] = "Wrapper for notification params" 4531cb0ef41Sopenharmony_ci event_type["type"] = "object" 4541cb0ef41Sopenharmony_ci event_type["id"] = to_title_case(event["name"]) + "Notification" 4551cb0ef41Sopenharmony_ci if "parameters" in event: 4561cb0ef41Sopenharmony_ci event_type["properties"] = copy.deepcopy(event["parameters"]) 4571cb0ef41Sopenharmony_ci if "types" not in domain: 4581cb0ef41Sopenharmony_ci domain["types"] = list() 4591cb0ef41Sopenharmony_ci domain["types"].append(event_type) 4601cb0ef41Sopenharmony_ci 4611cb0ef41Sopenharmony_ci 4621cb0ef41Sopenharmony_ci def create_type_definitions(self): 4631cb0ef41Sopenharmony_ci imported_namespace = "::".join(self.config.imported.namespace) if self.config.imported else "" 4641cb0ef41Sopenharmony_ci self.type_definitions = {} 4651cb0ef41Sopenharmony_ci self.type_definitions["number"] = create_primitive_type_definition("number") 4661cb0ef41Sopenharmony_ci self.type_definitions["integer"] = create_primitive_type_definition("integer") 4671cb0ef41Sopenharmony_ci self.type_definitions["boolean"] = create_primitive_type_definition("boolean") 4681cb0ef41Sopenharmony_ci self.type_definitions["object"] = create_object_type_definition() 4691cb0ef41Sopenharmony_ci self.type_definitions["any"] = create_any_type_definition() 4701cb0ef41Sopenharmony_ci self.type_definitions["binary"] = create_binary_type_definition() 4711cb0ef41Sopenharmony_ci for domain in self.json_api["domains"]: 4721cb0ef41Sopenharmony_ci self.type_definitions[domain["domain"] + ".string"] = create_string_type_definition() 4731cb0ef41Sopenharmony_ci self.type_definitions[domain["domain"] + ".binary"] = create_binary_type_definition() 4741cb0ef41Sopenharmony_ci if not ("types" in domain): 4751cb0ef41Sopenharmony_ci continue 4761cb0ef41Sopenharmony_ci for type in domain["types"]: 4771cb0ef41Sopenharmony_ci type_name = domain["domain"] + "." + type["id"] 4781cb0ef41Sopenharmony_ci if type["type"] == "object" and domain["domain"] in self.imported_domains: 4791cb0ef41Sopenharmony_ci self.type_definitions[type_name] = create_imported_type_definition(domain["domain"], type, imported_namespace) 4801cb0ef41Sopenharmony_ci elif type["type"] == "object": 4811cb0ef41Sopenharmony_ci self.type_definitions[type_name] = create_user_type_definition(domain["domain"], type) 4821cb0ef41Sopenharmony_ci elif type["type"] == "array": 4831cb0ef41Sopenharmony_ci self.type_definitions[type_name] = self.resolve_type(type) 4841cb0ef41Sopenharmony_ci elif type["type"] == domain["domain"] + ".string": 4851cb0ef41Sopenharmony_ci self.type_definitions[type_name] = create_string_type_definition() 4861cb0ef41Sopenharmony_ci elif type["type"] == domain["domain"] + ".binary": 4871cb0ef41Sopenharmony_ci self.type_definitions[type_name] = create_binary_type_definition() 4881cb0ef41Sopenharmony_ci else: 4891cb0ef41Sopenharmony_ci self.type_definitions[type_name] = create_primitive_type_definition(type["type"]) 4901cb0ef41Sopenharmony_ci 4911cb0ef41Sopenharmony_ci 4921cb0ef41Sopenharmony_ci def check_options(self, options, domain, name, include_attr, exclude_attr, default): 4931cb0ef41Sopenharmony_ci for rule in options: 4941cb0ef41Sopenharmony_ci if rule.domain != domain: 4951cb0ef41Sopenharmony_ci continue 4961cb0ef41Sopenharmony_ci if include_attr and hasattr(rule, include_attr): 4971cb0ef41Sopenharmony_ci return name in getattr(rule, include_attr) 4981cb0ef41Sopenharmony_ci if exclude_attr and hasattr(rule, exclude_attr): 4991cb0ef41Sopenharmony_ci return name not in getattr(rule, exclude_attr) 5001cb0ef41Sopenharmony_ci return default 5011cb0ef41Sopenharmony_ci return False 5021cb0ef41Sopenharmony_ci 5031cb0ef41Sopenharmony_ci 5041cb0ef41Sopenharmony_ci # ---- Begin of methods exposed to generator 5051cb0ef41Sopenharmony_ci 5061cb0ef41Sopenharmony_ci 5071cb0ef41Sopenharmony_ci def type_definition(self, name): 5081cb0ef41Sopenharmony_ci return self.type_definitions[name] 5091cb0ef41Sopenharmony_ci 5101cb0ef41Sopenharmony_ci 5111cb0ef41Sopenharmony_ci def resolve_type(self, prop): 5121cb0ef41Sopenharmony_ci if "$ref" in prop: 5131cb0ef41Sopenharmony_ci return self.type_definitions[prop["$ref"]] 5141cb0ef41Sopenharmony_ci if prop["type"] == "array": 5151cb0ef41Sopenharmony_ci return wrap_array_definition(self.resolve_type(prop["items"])) 5161cb0ef41Sopenharmony_ci return self.type_definitions[prop["type"]] 5171cb0ef41Sopenharmony_ci 5181cb0ef41Sopenharmony_ci 5191cb0ef41Sopenharmony_ci def generate_command(self, domain, command): 5201cb0ef41Sopenharmony_ci if not self.config.protocol.options: 5211cb0ef41Sopenharmony_ci return domain in self.generate_domains 5221cb0ef41Sopenharmony_ci return self.check_options(self.config.protocol.options, domain, command, "include", "exclude", True) 5231cb0ef41Sopenharmony_ci 5241cb0ef41Sopenharmony_ci 5251cb0ef41Sopenharmony_ci def generate_event(self, domain, event): 5261cb0ef41Sopenharmony_ci if not self.config.protocol.options: 5271cb0ef41Sopenharmony_ci return domain in self.generate_domains 5281cb0ef41Sopenharmony_ci return self.check_options(self.config.protocol.options, domain, event, "include_events", "exclude_events", True) 5291cb0ef41Sopenharmony_ci 5301cb0ef41Sopenharmony_ci 5311cb0ef41Sopenharmony_ci def generate_type(self, domain, typename): 5321cb0ef41Sopenharmony_ci return domain + "." + typename in self.used_types 5331cb0ef41Sopenharmony_ci 5341cb0ef41Sopenharmony_ci 5351cb0ef41Sopenharmony_ci def is_async_command(self, domain, command): 5361cb0ef41Sopenharmony_ci if not self.config.protocol.options: 5371cb0ef41Sopenharmony_ci return False 5381cb0ef41Sopenharmony_ci return self.check_options(self.config.protocol.options, domain, command, "async_", None, False) 5391cb0ef41Sopenharmony_ci 5401cb0ef41Sopenharmony_ci 5411cb0ef41Sopenharmony_ci def is_exported(self, domain, name): 5421cb0ef41Sopenharmony_ci if not self.config.protocol.options: 5431cb0ef41Sopenharmony_ci return False 5441cb0ef41Sopenharmony_ci return self.check_options(self.config.protocol.options, domain, name, "exported", None, False) 5451cb0ef41Sopenharmony_ci 5461cb0ef41Sopenharmony_ci 5471cb0ef41Sopenharmony_ci def is_imported(self, domain, name): 5481cb0ef41Sopenharmony_ci if not self.config.imported: 5491cb0ef41Sopenharmony_ci return False 5501cb0ef41Sopenharmony_ci if not self.config.imported.options: 5511cb0ef41Sopenharmony_ci return domain in self.imported_domains 5521cb0ef41Sopenharmony_ci return self.check_options(self.config.imported.options, domain, name, "imported", None, False) 5531cb0ef41Sopenharmony_ci 5541cb0ef41Sopenharmony_ci 5551cb0ef41Sopenharmony_ci def is_exported_domain(self, domain): 5561cb0ef41Sopenharmony_ci return domain in self.exported_domains 5571cb0ef41Sopenharmony_ci 5581cb0ef41Sopenharmony_ci 5591cb0ef41Sopenharmony_ci def generate_disable(self, domain): 5601cb0ef41Sopenharmony_ci if "commands" not in domain: 5611cb0ef41Sopenharmony_ci return True 5621cb0ef41Sopenharmony_ci for command in domain["commands"]: 5631cb0ef41Sopenharmony_ci if command["name"] == "disable" and self.generate_command(domain["domain"], "disable"): 5641cb0ef41Sopenharmony_ci return False 5651cb0ef41Sopenharmony_ci return True 5661cb0ef41Sopenharmony_ci 5671cb0ef41Sopenharmony_ci 5681cb0ef41Sopenharmony_ci def is_imported_dependency(self, domain): 5691cb0ef41Sopenharmony_ci return domain in self.generate_domains or domain in self.imported_domains 5701cb0ef41Sopenharmony_ci 5711cb0ef41Sopenharmony_ci 5721cb0ef41Sopenharmony_cidef main(): 5731cb0ef41Sopenharmony_ci jinja_dir, config_file, config = read_config() 5741cb0ef41Sopenharmony_ci 5751cb0ef41Sopenharmony_ci protocol = Protocol(config) 5761cb0ef41Sopenharmony_ci 5771cb0ef41Sopenharmony_ci if not config.exported and len(protocol.exported_domains): 5781cb0ef41Sopenharmony_ci sys.stderr.write("Domains [%s] are exported, but config is missing export entry\n\n" % ", ".join(protocol.exported_domains)) 5791cb0ef41Sopenharmony_ci exit(1) 5801cb0ef41Sopenharmony_ci 5811cb0ef41Sopenharmony_ci if not os.path.exists(config.protocol.output): 5821cb0ef41Sopenharmony_ci os.mkdir(config.protocol.output) 5831cb0ef41Sopenharmony_ci if len(protocol.exported_domains) and not os.path.exists(config.exported.output): 5841cb0ef41Sopenharmony_ci os.mkdir(config.exported.output) 5851cb0ef41Sopenharmony_ci jinja_env = initialize_jinja_env(jinja_dir, config.protocol.output, config) 5861cb0ef41Sopenharmony_ci 5871cb0ef41Sopenharmony_ci inputs = [] 5881cb0ef41Sopenharmony_ci inputs.append(__file__) 5891cb0ef41Sopenharmony_ci inputs.append(config_file) 5901cb0ef41Sopenharmony_ci inputs.append(config.protocol.path) 5911cb0ef41Sopenharmony_ci if config.imported: 5921cb0ef41Sopenharmony_ci inputs.append(config.imported.path) 5931cb0ef41Sopenharmony_ci templates_dir = os.path.join(module_path, "templates") 5941cb0ef41Sopenharmony_ci inputs.append(os.path.join(templates_dir, "TypeBuilder_h.template")) 5951cb0ef41Sopenharmony_ci inputs.append(os.path.join(templates_dir, "TypeBuilder_cpp.template")) 5961cb0ef41Sopenharmony_ci inputs.append(os.path.join(templates_dir, "Exported_h.template")) 5971cb0ef41Sopenharmony_ci inputs.append(os.path.join(templates_dir, "Imported_h.template")) 5981cb0ef41Sopenharmony_ci 5991cb0ef41Sopenharmony_ci h_template = jinja_env.get_template("templates/TypeBuilder_h.template") 6001cb0ef41Sopenharmony_ci cpp_template = jinja_env.get_template("templates/TypeBuilder_cpp.template") 6011cb0ef41Sopenharmony_ci exported_template = jinja_env.get_template("templates/Exported_h.template") 6021cb0ef41Sopenharmony_ci imported_template = jinja_env.get_template("templates/Imported_h.template") 6031cb0ef41Sopenharmony_ci 6041cb0ef41Sopenharmony_ci outputs = dict() 6051cb0ef41Sopenharmony_ci 6061cb0ef41Sopenharmony_ci for domain in protocol.json_api["domains"]: 6071cb0ef41Sopenharmony_ci class_name = domain["domain"] 6081cb0ef41Sopenharmony_ci file_name = config.protocol.file_name_prefix + class_name 6091cb0ef41Sopenharmony_ci template_context = { 6101cb0ef41Sopenharmony_ci "protocol": protocol, 6111cb0ef41Sopenharmony_ci "config": config, 6121cb0ef41Sopenharmony_ci "domain": domain, 6131cb0ef41Sopenharmony_ci "join_arrays": join_arrays, 6141cb0ef41Sopenharmony_ci "format_include": functools.partial(format_include, config), 6151cb0ef41Sopenharmony_ci "format_domain_include": functools.partial(format_domain_include, config), 6161cb0ef41Sopenharmony_ci } 6171cb0ef41Sopenharmony_ci 6181cb0ef41Sopenharmony_ci if domain["domain"] in protocol.generate_domains: 6191cb0ef41Sopenharmony_ci outputs[os.path.join(config.protocol.output, to_file_name(config, file_name + ".h"))] = h_template.render(template_context) 6201cb0ef41Sopenharmony_ci outputs[os.path.join(config.protocol.output, to_file_name(config, file_name + ".cpp"))] = cpp_template.render(template_context) 6211cb0ef41Sopenharmony_ci if domain["domain"] in protocol.exported_domains: 6221cb0ef41Sopenharmony_ci outputs[os.path.join(config.exported.output, to_file_name(config, file_name + ".h"))] = exported_template.render(template_context) 6231cb0ef41Sopenharmony_ci if domain["domain"] in protocol.imported_domains: 6241cb0ef41Sopenharmony_ci outputs[os.path.join(config.protocol.output, to_file_name(config, file_name + ".h"))] = imported_template.render(template_context) 6251cb0ef41Sopenharmony_ci 6261cb0ef41Sopenharmony_ci if config.lib: 6271cb0ef41Sopenharmony_ci template_context = { 6281cb0ef41Sopenharmony_ci "config": config, 6291cb0ef41Sopenharmony_ci "format_include": functools.partial(format_include, config), 6301cb0ef41Sopenharmony_ci } 6311cb0ef41Sopenharmony_ci 6321cb0ef41Sopenharmony_ci lib_templates_dir = os.path.join(module_path, "lib") 6331cb0ef41Sopenharmony_ci # Note these should be sorted in the right order. 6341cb0ef41Sopenharmony_ci # TODO(dgozman): sort them programmatically based on commented includes. 6351cb0ef41Sopenharmony_ci protocol_h_templates = [ 6361cb0ef41Sopenharmony_ci "ErrorSupport_h.template", 6371cb0ef41Sopenharmony_ci "Values_h.template", 6381cb0ef41Sopenharmony_ci "Object_h.template", 6391cb0ef41Sopenharmony_ci "ValueConversions_h.template", 6401cb0ef41Sopenharmony_ci "Maybe_h.template", 6411cb0ef41Sopenharmony_ci "Array_h.template", 6421cb0ef41Sopenharmony_ci "DispatcherBase_h.template", 6431cb0ef41Sopenharmony_ci "Parser_h.template", 6441cb0ef41Sopenharmony_ci "encoding_h.template", 6451cb0ef41Sopenharmony_ci ] 6461cb0ef41Sopenharmony_ci 6471cb0ef41Sopenharmony_ci protocol_cpp_templates = [ 6481cb0ef41Sopenharmony_ci "Protocol_cpp.template", 6491cb0ef41Sopenharmony_ci "ErrorSupport_cpp.template", 6501cb0ef41Sopenharmony_ci "Values_cpp.template", 6511cb0ef41Sopenharmony_ci "Object_cpp.template", 6521cb0ef41Sopenharmony_ci "DispatcherBase_cpp.template", 6531cb0ef41Sopenharmony_ci "Parser_cpp.template", 6541cb0ef41Sopenharmony_ci "encoding_cpp.template", 6551cb0ef41Sopenharmony_ci ] 6561cb0ef41Sopenharmony_ci 6571cb0ef41Sopenharmony_ci forward_h_templates = [ 6581cb0ef41Sopenharmony_ci "Forward_h.template", 6591cb0ef41Sopenharmony_ci "Allocator_h.template", 6601cb0ef41Sopenharmony_ci "FrontendChannel_h.template", 6611cb0ef41Sopenharmony_ci ] 6621cb0ef41Sopenharmony_ci 6631cb0ef41Sopenharmony_ci base_string_adapter_h_templates = [ 6641cb0ef41Sopenharmony_ci "base_string_adapter_h.template", 6651cb0ef41Sopenharmony_ci ] 6661cb0ef41Sopenharmony_ci 6671cb0ef41Sopenharmony_ci base_string_adapter_cc_templates = [ 6681cb0ef41Sopenharmony_ci "base_string_adapter_cc.template", 6691cb0ef41Sopenharmony_ci ] 6701cb0ef41Sopenharmony_ci 6711cb0ef41Sopenharmony_ci def generate_lib_file(file_name, template_files): 6721cb0ef41Sopenharmony_ci parts = [] 6731cb0ef41Sopenharmony_ci for template_file in template_files: 6741cb0ef41Sopenharmony_ci inputs.append(os.path.join(lib_templates_dir, template_file)) 6751cb0ef41Sopenharmony_ci template = jinja_env.get_template("lib/" + template_file) 6761cb0ef41Sopenharmony_ci parts.append(template.render(template_context)) 6771cb0ef41Sopenharmony_ci outputs[file_name] = "\n\n".join(parts) 6781cb0ef41Sopenharmony_ci 6791cb0ef41Sopenharmony_ci generate_lib_file(os.path.join(config.lib.output, to_file_name(config, "Forward.h")), forward_h_templates) 6801cb0ef41Sopenharmony_ci generate_lib_file(os.path.join(config.lib.output, to_file_name(config, "Protocol.h")), protocol_h_templates) 6811cb0ef41Sopenharmony_ci generate_lib_file(os.path.join(config.lib.output, to_file_name(config, "Protocol.cpp")), protocol_cpp_templates) 6821cb0ef41Sopenharmony_ci generate_lib_file(os.path.join(config.lib.output, to_file_name(config, "base_string_adapter.h")), base_string_adapter_h_templates) 6831cb0ef41Sopenharmony_ci generate_lib_file(os.path.join(config.lib.output, to_file_name(config, "base_string_adapter.cc")), base_string_adapter_cc_templates) 6841cb0ef41Sopenharmony_ci 6851cb0ef41Sopenharmony_ci # Make gyp / make generatos happy, otherwise make rebuilds world. 6861cb0ef41Sopenharmony_ci inputs_ts = max(map(os.path.getmtime, inputs)) 6871cb0ef41Sopenharmony_ci up_to_date = True 6881cb0ef41Sopenharmony_ci for output_file in outputs.keys(): 6891cb0ef41Sopenharmony_ci if not os.path.exists(output_file) or os.path.getmtime(output_file) < inputs_ts: 6901cb0ef41Sopenharmony_ci up_to_date = False 6911cb0ef41Sopenharmony_ci break 6921cb0ef41Sopenharmony_ci if up_to_date: 6931cb0ef41Sopenharmony_ci sys.exit() 6941cb0ef41Sopenharmony_ci 6951cb0ef41Sopenharmony_ci for file_name, content in outputs.items(): 6961cb0ef41Sopenharmony_ci out_file = open(file_name, "w") 6971cb0ef41Sopenharmony_ci out_file.write(content) 6981cb0ef41Sopenharmony_ci out_file.close() 6991cb0ef41Sopenharmony_ci 7001cb0ef41Sopenharmony_ci 7011cb0ef41Sopenharmony_cimain() 702