def generate(models): types = set() for model in models.values(): for key, value in model.allitems(): if key == 'property': name = value.get('name') type = value.get('type') card = value.get('card') if (name != 'type') and (type != 'any') and (card == 'any'): types.add(type) elif key in ['class', 'obj_ref', 'class_ref', 'group_ref']: card = value.get('card') if card == 'any': type = 'any' if key == 'group_ref' else value.get('type') types.add(type) containers = [] for type in sorted(types): containers.append(f' typedef std::vector<{type}*> VectorOf{type};') containers.append(f' typedef std::vector<{type}*>::iterator VectorOf{type}Itr;') containers.append('') containers = '\n'.join(containers) with open(config.get_template_filepath('containers.h'), 'r+t') as strm: file_content = strm.read() file_content = file_content.replace('<CONTAINERS>', containers) file_utils.set_content_if_changed(config.get_output_header_filepath('containers.h'), file_content) return True
def generate(models): types = '\n'.join([f' {name} = {id},' for name, id in get_type_map(models).items()]) with open(config.get_template_filepath('uhdm_types.h'), 'r+t') as strm: file_content = strm.read() file_content = file_content.replace('<DEFINES>', types) file_utils.set_content_if_changed(config.get_output_header_filepath('uhdm_types.h'), file_content) return True
def generate(models): with open(config.get_template_filepath('clone_tree.cpp'), 'r+t') as strm: file_content = strm.read() file_content = file_content.replace('<CLONE_IMPLEMENTATIONS>', '') file_utils.set_content_if_changed( config.get_output_source_filepath('clone_tree.cpp'), file_content) return True
def generate(models): methods = get_methods(models, '', '') with open(config.get_template_filepath('VpiListener.h'), 'r+t') as strm: file_content = strm.read() file_content = file_content.replace('<VPI_LISTENER_METHODS>', '\n'.join(methods)) file_utils.set_content_if_changed( config.get_output_header_filepath('VpiListener.h'), file_content) return True
def generate(models): classnames = [model['name'] for model in models.values()] headers = '\n'.join( [f'#include "uhdm/{classname}.h"' for classname in classnames]) with open(config.get_template_filepath('uhdm.h'), 'r+t') as strm: file_content = strm.read() file_content = file_content.replace('<INCLUDE_FILES>', headers) file_utils.set_content_if_changed( config.get_output_header_filepath('uhdm.h'), file_content) return True
def generate(models): classnames = [ model['name'] for model in models.values() if model['type'] != 'group_def' ] declarations = '\n'.join([ f'class {classname};' for classname in sorted(classnames) if classname != 'BaseClass' ]) with open(config.get_template_filepath('uhdm_forward_decl.h'), 'r+t') as strm: file_content = strm.read() file_content = file_content.replace('<UHDM_FORWARD_DECL>', declarations) file_utils.set_content_if_changed( config.get_output_header_filepath('uhdm_forward_decl.h'), file_content) return True
def generate(models): module_listeners = _generate_module_listeners(models) class_listeners = _generate_class_listeners(models) with open(config.get_template_filepath('ElaboratorListener.cpp'), 'r+t') as strm: file_content = strm.read() file_content = file_content.replace( '<MODULE_ELABORATOR_LISTENER>', (' ' * 10) + ('\n' + (' ' * 10)).join(module_listeners)) file_content = file_content.replace( '<CLASS_ELABORATOR_LISTENER>', (' ' * 4) + ('\n' + (' ' * 4)).join(class_listeners)) file_utils.set_content_if_changed( config.get_output_source_filepath('ElaboratorListener.cpp'), file_content) return True
def generate(models): templates = {} for filename in [ 'class_header.h', 'class_source.cpp', 'group_header.h', 'group_header.cpp' ]: template_filepath = config.get_template_filepath(filename) with open(template_filepath, 'r+t') as strm: templates[filename] = strm.read() for model in models.values(): classname = model['name'] modeltype = model['type'] if modeltype == 'group_def': _generate_group_checker(model, models, templates) else: _generate_one_class(model, models, templates) return True
def generate(models): vpi_get_value_classes = set() vpi_get_delay_classes = set() for model in models.values(): modeltype = model['type'] if modeltype != 'obj_def': continue classname = model['name'] baseclass = classname while baseclass: for key, value in models[baseclass].allitems(): if key == 'property' and value.get('card') == '1': type = value.get('type') if type == 'value': vpi_get_value_classes.add(classname) if type == 'delay': vpi_get_delay_classes.add(classname) baseclass = models[baseclass]['extends'] # headers = [ f"#include <uhdm/{model['name']}.h>" for model in models.values() ] headers = [ f"#include <uhdm/{name}.h>" for name in sorted( set.union(vpi_get_value_classes, vpi_get_delay_classes)) ] vpi_handle_by_name_body = [ f' if (object->GetSerializer()->symbolMaker.GetId(name) == static_cast<SymbolFactory::ID>(-1)) {{', ' return nullptr;', ' }', ' const BaseClass *const ref = object->GetByVpiName(std::string_view(name));', ' return (ref != nullptr) ? NewVpiHandle(ref) : nullptr;' ] vpi_handle_body = [ ' auto [ref, ignored1, ignored2] = object->GetByVpiType(type);', ' return (ref != nullptr) ? NewHandle(ref->UhdmType(), ref) : nullptr;' ] vpi_iterate_body = [ ' auto [ignored, refType, refVector] = object->GetByVpiType(type);', ' return (refVector != nullptr) ? NewHandle(refType, refVector) : nullptr;' ] vpi_get_body = [ ' BaseClass::vpi_property_value_t value = obj->GetVpiPropertyValue(property);', ' return std::holds_alternative<int64_t>(value) ? std::get<int64_t>(value) : 0;' ] vpi_get_str_body = [ ' BaseClass::vpi_property_value_t value = obj->GetVpiPropertyValue(property);', ' return std::holds_alternative<const char *>(value) ? const_cast<char *>(std::get<const char *>(value)) : nullptr;' ] vpi_get_value_body = [ f' const s_vpi_value* v = nullptr;', f' switch (handle->type) {{' ] + [ f' case uhdm{classname}: v = String2VpiValue((({classname}*)obj)->VpiValue()); break;' for classname in sorted(vpi_get_value_classes) ] + [ ' default: break;', f' }}', f' if (v != nullptr) *value_p = *v;' ] if vpi_get_value_classes else [] vpi_get_delay_body = [ f' const s_vpi_delay* v = nullptr;', f' switch (handle->type) {{', ] + [ f' case uhdm{classname}: v = String2VpiDelays((({classname}*)obj)->VpiDelay()); break;' for classname in sorted(vpi_get_delay_classes) ] + [ ' default: break;', f' }}', f' if (v != nullptr) *delay_p = *v;' ] if vpi_get_delay_classes else [] # vpi_user.cpp with open(config.get_template_filepath('vpi_user.cpp'), 'r+t') as strm: file_content = strm.read() file_content = file_content.replace('<HEADERS>', '\n'.join(headers)) file_content = file_content.replace('<VPI_HANDLE_BY_NAME_BODY>', '\n'.join(vpi_handle_by_name_body)) file_content = file_content.replace('<VPI_HANDLE_BODY>', '\n'.join(vpi_handle_body)) file_content = file_content.replace('<VPI_ITERATE_BODY>', '\n'.join(vpi_iterate_body)) file_content = file_content.replace('<VPI_SCAN_BODY>', '') file_content = file_content.replace('<VPI_GET_BODY>', '\n'.join(vpi_get_body)) file_content = file_content.replace('<VPI_GET_STR_BODY>', '\n'.join(vpi_get_str_body)) file_content = file_content.replace('<VPI_GET_VALUE_BODY>', '\n'.join(vpi_get_value_body)) file_content = file_content.replace('<VPI_GET_DELAY_BODY>', '\n'.join(vpi_get_delay_body)) file_utils.set_content_if_changed( config.get_output_source_filepath('vpi_user.cpp'), file_content) return True
def generate(models): factory_declarations = [] factory_methods = [] factory_purge = [] factory_stats = [] factory_object_type_map = [] save_ids = [] save_objects = [] saves_adapters = [] restore_ids = [] restore_objects = [] restore_adapters = [] type_map = uhdm_types_h.get_type_map(models) for model in models.values(): modeltype = model['type'] if modeltype == 'group_def': continue classname = model['name'] Classname_ = classname[:1].upper() + classname[1:] Classname = Classname_.replace('_', '') baseclass = model.get('extends', 'BaseClass') or 'BaseClass' if modeltype != 'class_def': factory_declarations.append(f' {classname}Factory {classname}Maker;') factory_methods.append(f' {classname}* Make{Classname_}() {{ return Make<{classname}>(&{classname}Maker); }}') factory_object_type_map.append(f' case uhdm{classname} /* = {type_map["uhdm" + classname]} */: return {classname}Maker.objects_[index];') save_ids.append(f' SetSaveId_(&{classname}Maker);') save_objects.append(f' VectorOfanySaveAdapter<{classname}, {Classname}>()({classname}Maker.objects_, this, cap_root.initFactory{Classname}({classname}Maker.objects_.size()));') restore_ids.append(f' SetRestoreId_(&{classname}Maker, cap_root.getFactory{Classname}().size());') restore_objects.append(f' VectorOfanyRestoreAdapter<{classname}, {Classname}>()(cap_root.getFactory{Classname}(), this, {classname}Maker.objects_);') factory_purge.append(f' {classname}Maker.Purge();') factory_stats.append(f' stats.insert(std::make_pair("{classname}", {classname}Maker.objects_.size()));') factory_declarations.append(f' VectorOf{classname}Factory {classname}VectMaker;') factory_methods.append(f' std::vector<{classname}*>* Make{Classname_}Vec() {{ return Make<{classname}>(&{classname}VectMaker); }}') saves_adapters.append(f'template<typename U>') saves_adapters.append(f'struct Serializer::AnySaveAdapter<{classname}, U> {{') saves_adapters.append(f' void operator()(const {classname} *const obj, Serializer *const serializer, U builder) const {{') saves_adapters.append(f' AnySaveAdapter<{baseclass}, U>()(static_cast<const {baseclass}*>(obj), serializer, builder);') restore_adapters.append(f'template<typename U>') restore_adapters.append(f'struct Serializer::AnyRestoreAdapter<{classname}, U> {{') restore_adapters.append(f' void operator()(U reader, Serializer *const serializer, {classname} *const obj) const {{') restore_adapters.append(f' AnyRestoreAdapter<{baseclass}, U>()(reader, serializer, static_cast<{baseclass}*>(obj));') for key, value in model.allitems(): if key == 'property': name = value.get('name') vpi = value.get('vpi') type = value.get('type') card = value.get('card') if name == 'type': continue Vpi_ = vpi[:1].upper() + vpi[1:] Vpi = Vpi_.replace('_', '') if type in ['string', 'value', 'delay']: saves_adapters.append(f' builder.set{Vpi}(serializer->symbolMaker.Make(obj->{Vpi_}()));') restore_adapters.append(f' obj->{Vpi_}(serializer->symbolMaker.GetSymbol(reader.get{Vpi}()));') else: saves_adapters.append(f' builder.set{Vpi}(obj->{Vpi_}());') restore_adapters.append(f' obj->{Vpi_}(reader.get{Vpi}());') elif key in ['class', 'obj_ref', 'class_ref', 'group_ref']: name = value.get('name') type = value.get('type') card = value.get('card') id = value.get('id') Type_ = type[:1].upper() + type[1:] Type = Type_.replace('_', '') if (card == 'any') and not name.endswith('s'): name += 's' Name_ = name[:1].upper() + name[1:] Name = Name_.replace('_', '') real_type = type if key == 'group_ref': type = 'any' if card == '1': if key in ['class_ref', 'group_ref']: saves_adapters.append(f' if (obj->{Name_}() != nullptr) {{') saves_adapters.append(f' ::ObjIndexType::Builder tmp = builder.get{Name}();') saves_adapters.append(f' tmp.setIndex(serializer->GetId(obj->{Name_}()));') saves_adapters.append(f' tmp.setType((obj->{Name_}())->UhdmType());') saves_adapters.append( ' }') restore_adapters.append(f' obj->{Name_}(({type}*)serializer->GetObject(reader.get{Name}().getType(), reader.get{Name}().getIndex() - 1));') else: saves_adapters.append(f' builder.set{Name}(serializer->GetId(obj->{Name_}()));') restore_adapters.append(f' if (reader.get{Name}()) {{') restore_adapters.append(f' obj->{Name_}(serializer->{type}Maker.objects_[reader.get{Name}() - 1]);') restore_adapters.append( ' }') else: obj_key = '::ObjIndexType' if key in ['class_ref', 'group_ref'] else '::uint64_t' saves_adapters.append(f' if (obj->{Name_}() != nullptr) {{') saves_adapters.append(f' ::capnp::List<{obj_key}>::Builder {Name}s = builder.init{Name}(obj->{Name_}()->size());') saves_adapters.append(f' for (unsigned int i = 0, n = obj->{Name_}()->size(); i < n; ++i) {{') restore_adapters.append(f' if (reader.get{Name}().size() > 0) {{') restore_adapters.append(f' std::vector<{type}*>* vect = serializer->{type}VectMaker.Make();') restore_adapters.append(f' for (unsigned int i = 0, n = reader.get{Name}().size(); i < n; ++i) {{') if key in ['class_ref', 'group_ref']: saves_adapters.append(f' ::ObjIndexType::Builder tmp = {Name}s[i];') saves_adapters.append(f' tmp.setIndex(serializer->GetId((*obj->{Name_}())[i]));') saves_adapters.append(f' tmp.setType(((BaseClass*)((*obj->{Name_}())[i]))->UhdmType());') restore_adapters.append(f' vect->push_back(({type}*)serializer->GetObject(reader.get{Name}()[i].getType(), reader.get{Name}()[i].getIndex() - 1));') else: saves_adapters.append(f' {Name}s.set(i, serializer->GetId((*obj->{Name_}())[i]));') restore_adapters.append(f' vect->push_back(serializer->{type}Maker.objects_[reader.get{Name}()[i] - 1]);') saves_adapters.append(' }') saves_adapters.append(' }') restore_adapters.append( ' }') restore_adapters.append(f' obj->{Name_}(vect);') restore_adapters.append( ' }') saves_adapters.append(' }') saves_adapters.append('};') saves_adapters.append('') restore_adapters.append(' }') restore_adapters.append('};') restore_adapters.append('') uhdm_name_map = [ 'std::string UhdmName(UHDM_OBJECT_TYPE type) {', ' switch (type) {' ] uhdm_name_map.extend([ f' case {name} /* = {id} */: return "{name[4:]}";' for name, id in uhdm_types_h.get_type_map(models).items() ]) uhdm_name_map.append(' default: return "NO TYPE";') uhdm_name_map.append('}') uhdm_name_map.append('}') # Serializer.h with open(config.get_template_filepath('Serializer.h'), 'r+t') as strm: file_content = strm.read() file_content = file_content.replace('<FACTORIES>', '\n'.join(factory_declarations)) file_content = file_content.replace('<FACTORIES_METHODS>', '\n'.join(factory_methods)) file_utils.set_content_if_changed(config.get_output_header_filepath('Serializer.h'), file_content) # Serializer.cpp with open(config.get_template_filepath('Serializer.cpp'), 'r+t') as strm: file_content = strm.read() file_content = file_content.replace('<METHODS_CPP>', '') # Deprecated file_content = file_content.replace('<UHDM_NAME_MAP>', '\n'.join(uhdm_name_map)) file_content = file_content.replace('<FACTORY_PURGE>', '\n'.join(factory_purge)) file_content = file_content.replace('<FACTORY_STATS>', '\n'.join(factory_stats)) file_content = file_content.replace('<FACTORY_OBJECT_TYPE_MAP>', '\n'.join(factory_object_type_map)) file_utils.set_content_if_changed(config.get_output_source_filepath('Serializer.cpp'), file_content) # Serializer_save.cpp with open(config.get_template_filepath('Serializer_save.cpp'), 'r+t') as strm: file_content = strm.read() file_content = file_content.replace('<CAPNP_ID>', '\n'.join(save_ids)) file_content = file_content.replace('<CAPNP_SAVE>', '\n'.join(save_objects)) file_content = file_content.replace('<CAPNP_SAVE_ADAPTERS>', '\n'.join(saves_adapters)) file_utils.set_content_if_changed(config.get_output_source_filepath('Serializer_save.cpp'), file_content) # Serializer_restore.cpp with open(config.get_template_filepath('Serializer_restore.cpp'), 'r+t') as strm: file_content = strm.read() file_content = file_content.replace('<CAPNP_INIT_FACTORIES>', '\n'.join(restore_ids)) file_content = file_content.replace('<CAPNP_RESTORE_FACTORIES>', '\n'.join(restore_objects)) file_content = file_content.replace('<CAPNP_RESTORE_ADAPTERS>', '\n'.join(restore_adapters)) file_utils.set_content_if_changed(config.get_output_source_filepath('Serializer_restore.cpp'), file_content) return True
def _main(): parser = argparse.ArgumentParser() parser.add_argument('-output-dirpath', dest='output_dirpath', type=str, help='Output path') parser.add_argument('--parallel', dest='parallel', action='store_true', default=True) parser.add_argument('--source-dirpath', dest='source_dirpath', type=str, help='Path to UHDM source') args = parser.parse_args() config.configure(args) print('Generating UHDM models ...') print(' Loading models ...') models = loader.load_models() print(f' ... found {len(models)} models.') print(' Validating ordering ...') # Check validity index = 0 order = {} for name in models.keys(): order[name] = index index += 1 for name, model in models.items(): baseclass = model['extends'] if baseclass: thisIndex = order[name] baseIndex = order[baseclass] if baseIndex >= thisIndex: raise Exception( f'Model {name} should follow {baseclass} in listing.') print(' ... all good.') params = [ ('capnp', [models]), ('class_hierarchy', [models]), ('classes', [models]), ('clone_tree_cpp', [models]), ('containers_h', [models]), ('ElaboratorListener_cpp', [models]), ('Copier', [{ config.get_template_filepath('BaseClass.h'): config.get_output_header_filepath('BaseClass.h'), config.get_template_filepath('clone_tree.h'): config.get_output_header_filepath('clone_tree.h'), config.get_template_filepath('ElaboratorListener.h'): config.get_output_header_filepath('ElaboratorListener.h'), config.get_template_filepath('ExprEval.h'): config.get_output_header_filepath('ExprEval.h'), config.get_template_filepath('ExprEval.cpp'): config.get_output_source_filepath('ExprEval.cpp'), config.get_template_filepath('RTTI.h'): config.get_output_header_filepath('RTTI.h'), config.get_template_filepath('SymbolFactory.h'): config.get_output_header_filepath('SymbolFactory.h'), config.get_template_filepath('SymbolFactory.cpp'): config.get_output_source_filepath('SymbolFactory.cpp'), config.get_template_filepath('uhdm_vpi_user.h'): config.get_output_header_filepath('uhdm_vpi_user.h'), config.get_template_filepath('vpi_uhdm.h'): config.get_output_header_filepath('vpi_uhdm.h'), config.get_template_filepath('vpi_visitor.h'): config.get_output_header_filepath('vpi_visitor.h'), config.get_include_filepath('sv_vpi_user.h'): config.get_output_header_filepath('sv_vpi_user.h'), config.get_include_filepath('vhpi_user.h'): config.get_output_header_filepath('vhpi_user.h'), config.get_include_filepath('vpi_user.h'): config.get_output_header_filepath('vpi_user.h'), }]), ('serializer', [models]), ('uhdm_forward_decl_h', [models]), ('uhdm_h', [models]), ('uhdm_types_h', [models]), ('vpi_listener', [models]), ('vpi_user_cpp', [models]), ('vpi_visitor_cpp', [models]), ('VpiListener_h', [models]), ('VpiListenerTracer_h', [models]), ] if args.parallel: with concurrent.futures.ThreadPoolExecutor(max_workers=8) as executor: results = list(executor.map(_worker, params)) else: results = [_worker(args) for args in params] print('... all done!') result = sum([0 if r else 1 for r in results]) if result: print('ERROR: UHDM model generation FAILED!') else: print('UHDM Models generated successfully!.') return result
def generate(models): visit_object_body = [] private_visitor_bodies = [] ignored_objects = set(['vpiNet']) for model in models.values(): modeltype = model['type'] if modeltype == 'group_def': continue classname = model['name'] if classname in ['net_drivers', 'net_loads']: continue vpi_name = config.make_vpi_name(classname) if vpi_name not in ignored_objects: visit_object_body.append( f' case {vpi_name}: visit_{classname}(obj_h, indent, relation, visited, out, shallowVisit); break;' ) private_visitor_bodies.append( f'static void visit_{classname}(vpiHandle obj_h, int indent, const char *relation, VisitedContainer* visited, std::ostream& out, bool shallowVisit) {{' ) baseclass = model.get('extends', None) if baseclass: private_visitor_bodies.append( f' visit_{baseclass}(obj_h, indent, relation, visited, out, shallowVisit);' ) itr_required = False private_visitor_body = [] if classname == 'part_select': private_visitor_body.extend( _get_implementation(classname, 'vpiParent', '1')) itr_required = True if modeltype != 'class_def': private_visitor_body.extend( _get_vpi_xxx_visitor('string', 'vpiFile', '1')) type_specified = False for key, value in model.allitems(): if key == 'property': name = value.get('name') vpi = value.get('vpi') type = value.get('type') card = value.get('card') type_specified = name == 'type' or type_specified private_visitor_body.extend( _get_vpi_xxx_visitor(type, vpi, card)) elif key in ['class', 'obj_ref', 'class_ref', 'group_ref']: vpi = value.get('vpi') card = value.get('card') private_visitor_body.extend( _get_implementation(classname, vpi, card)) itr_required = True if not type_specified and (modeltype == 'obj_def'): private_visitor_body.extend( _get_vpi_xxx_visitor('unsigned int', 'vpiType', '1')) if private_visitor_body: if itr_required: private_visitor_bodies.append(f' vpiHandle itr;') private_visitor_bodies.extend(private_visitor_body) private_visitor_bodies.append(f'}}') private_visitor_bodies.append('') visitors = [f' switch (objectType) {{' ] + sorted(visit_object_body) + [f' }}'] # vpi_visitor.cpp with open(config.get_template_filepath('vpi_visitor.cpp'), 'r+t') as strm: file_content = strm.read() file_content = file_content.replace('<OBJECT_VISITORS>', '\n'.join(visitors)) file_content = file_content.replace('<PRIVATE_OBJECT_VISITORS>', '\n'.join(private_visitor_bodies)) file_utils.set_content_if_changed( config.get_output_source_filepath('vpi_visitor.cpp'), file_content) return True
def generate(models): individual_model_schemas = {} flattened_model_schemas = [] root_schema_index = 2 root_schema = [] for model in models.values(): modeltype = model['type'] if modeltype == 'group_def': continue classname = model['name'] individual_model_schemas[classname] = [] Classname_ = classname[:1].upper() + classname[1:] Classname = Classname_.replace('_', '') if modeltype != 'class_def': individual_model_schemas[classname].append(('uhdmId', 'UInt64')) individual_model_schemas[classname].append(('vpiParent', 'UInt64')) individual_model_schemas[classname].append(('uhdmParentType', 'UInt64')) individual_model_schemas[classname].append(('vpiFile', 'UInt64')) individual_model_schemas[classname].append(('vpiLineNo', 'UInt32')) individual_model_schemas[classname].append(('vpiEndLineNo', 'UInt32')) individual_model_schemas[classname].append(('vpiColumnNo', 'UInt16')) individual_model_schemas[classname].append(('vpiEndColumnNo', 'UInt16')) root_schema.append(f' factory{Classname} @{root_schema_index} :List({Classname});') root_schema_index += 1 for key, value in model.allitems(): if key == 'property': if value.get('name') != 'type': vpi = value.get('vpi') type = value.get('type') card = value.get('card') individual_model_schemas[classname].append(_get_schema(type, vpi, card)) elif key in ['class', 'obj_ref', 'class_ref', 'group_ref']: name = value.get('name') type = value.get('type') card = value.get('card') if (card == 'any') and not name.endswith('s'): name += 's' name = name.replace('_', '') obj_key = 'ObjIndexType' if key in ['class_ref', 'group_ref'] else 'UInt64' individual_model_schemas[classname].append(_get_schema(obj_key, name, card)) if modeltype != 'class_def': # Process the hierarchy tree top-down stack = [] baseclass = classname while (baseclass): stack.append(baseclass) baseclass = models[baseclass]['extends'] capnpIndex = 0 flattened_model_schemas.append(f'struct {Classname} {{') while stack: for name, type in individual_model_schemas[stack.pop()]: if name and type: flattened_model_schemas.append(f' {name} @{capnpIndex} :{type};') capnpIndex += 1 flattened_model_schemas.append('}') flattened_model_schemas.append('') with open(config.get_template_filepath('UHDM.capnp'), 'r+t') as strm: file_content = strm.read() file_content = file_content.replace('<CAPNP_SCHEMA>', '\n'.join(flattened_model_schemas)) file_content = file_content.replace('<CAPNP_ROOT_SCHEMA>', '\n'.join(root_schema)) file_utils.set_content_if_changed(config.get_output_source_filepath('UHDM.capnp'), file_content) return True