async function processTemplates()

in experimental/generation/generator/packages/library/src/dialogGenerator.ts [671:749]


async function processTemplates(
    schema: s.Schema,
    templateDirs: string[],
    transforms: Transform[],
    locales: string[],
    outDir: string,
    scope: any,
    force: boolean,
    feedback: Feedback): Promise<void> {
    await verifyExamples(schema.schema, feedback)
    scope.templates = {}
    // We expand each template in the context of a combination of locale, property, type (schema name) and entity.
    // Since we only generate each filename once this means property only templates don't care about the entity and entity templates will be expanded for each entity.
    // If a template author wants to do different things with different entities they will need explicit templates for each desired entity.
    for (const locale of locales) {
        scope.locale = locale
        for (const property of schema.schemaProperties()) {
            scope.property = property.path
            scope.template = property.schema.$template
            scope.propertySchema = property.schema
            const entities = property.schema.$entities
            const templates = property.schema.$templates
            if (!entities || !templates) {
                feedback(FeedbackType.error, `'${property.path}' does not define $template, $entities or $templates.`)
            } else if (scope.property.includes('-') || scope.property.includes(' ')) {
                feedback(FeedbackType.error, `'${property.path}' cannot include space or dash.`)
            } else {
                // Pick up examples from property schema if unique entity
                if (!property.schema.$examples && (property.schema.examples || property.schema.items?.examples)) {
                    const entity = entities.filter((e: string) => e !== 'utterance')
                    if (entity.length == 1) {
                        const entityExamples = {}
                        entityExamples[entity[0]] = property.schema.examples ?? property.schema.items?.examples
                        property.schema.$examples = {
                            '': entityExamples
                        }
                    } else {
                        feedback(FeedbackType.warning, `For property ${property.path} use $examples rather than examples.`)
                    }
                }

                // Assume non-array are expressions to be interpreted in expandSchema
                for (const entityName of entities) {
                    // If expression will get handled by expandSchema
                    if (!entityName.startsWith('$')) {
                        const entityTransforms = []
                        scope.entity = entityName
                        feedback(FeedbackType.debug, `=== ${scope.locale} ${scope.property} ${scope.entity} ===`)
                        scope.examples = verifyEnumAndGetExamples(schema.schema, property.path, locale, entityName, feedback)
                        for (const template of templates) {
                            await processTemplate(template, templateDirs, entityTransforms, transforms, outDir, scope, force, feedback, false)
                        }

                        delete scope.entity
                        delete scope.examples
                    }
                }
            }
            delete scope.property
            delete scope.type
            delete scope.propertySchema
        }

        // Process templates found at the top which should not depend on locale/property/entity
        if (schema.schema.$templates) {
            feedback(FeedbackType.debug, `=== Global templates ===`)
            scope.examples = await globalExamples(outDir, scope)
            for (const templateName of schema.schema.$templates) {
                await processTemplate(templateName, templateDirs, [], transforms, outDir, scope, force, feedback, false)
            }
        }

        // Reset locale specific files
        scope.templates.lu = []
        scope.templates.lg = []
        scope.templates.qna = []
    }
    delete scope.locale
}