const parseAndHandleEntityV2 = function()

in packages/lu/src/parser/lufile/parseFileContents.js [1345:1449]


const parseAndHandleEntityV2 = function (parsedContent, luResource, log, locale, config) {
    let featuresToProcess = [];
    // handle new entity definitions.
    let entities = luResource.Sections.filter(s => s.SectionType === SectionType.NEWENTITYSECTION);
    if (entities && entities.length > 0) {
        for (const entity of entities) {
            if (entity.Type !== INTENTTYPE) {
                if (entity.Name.endsWith(PLCONSTS.INTERCHANGEABLE)) {
                    entity.Name = entity.Name.slice(0, entity.Name.length - PLCONSTS.INTERCHANGEABLE.length).trim().replace(/^[\'\"]|[\'\"]$/g, "") + PLCONSTS.INTERCHANGEABLE
                } else {
                    entity.Name = entity.Name.replace(/^[\'\"]|[\'\"]$/g, "");
                }

                let entityName = entity.Name.endsWith('=') ? entity.Name.slice(0, entity.Name.length - 1) : entity.Name;
                let entityType = !entity.Type ? getEntityType(entity.Name, entities) : entity.Type;
                if (!entityType) {
                    let errorMsg = `No type definition found for entity "${entityName}". Supported types are ${Object.values(EntityTypeEnum).join(', ')}. Note: Type names are case sensitive.`;
                    throwDiagnosticError({
                        message: errorMsg,
                        range: entity.Range
                    });
                };

                if (entityType !== EntityTypeEnum.PHRASELIST && InvalidCharsInIntentOrEntityName.some(x => entityName.includes(x))) {
                    let errorMsg = `Invalid entity line, entity name ${entityName} cannot contain any of the following characters: [<, >, *, %, &, :, \\, $]`;
                    throwDiagnosticError({
                        message: errorMsg,
                        line: entity.Range.Start.Line
                    });
                }

                if (entityType === entityName) {
                    let errorMsg = `Entity name "${entityName}" cannot be the same as entity type "${entityType}"`;
                    throwDiagnosticError({
                        message: errorMsg,
                        range: entity.Range
                    });
                }
                let entityRoles = validateAndGetRoles(parsedContent, entity.Roles, entity.Range, entityName, entityType);
                let PAEntityRoles = RemoveDuplicatePatternAnyEntity(parsedContent, entityName, entityType, entity.Range);
                if (PAEntityRoles.length > 0) {
                    PAEntityRoles.forEach(role => {
                        if (!entityRoles.includes(role)) entityRoles.push(role);
                    })
                }
                switch(entityType) {
                    case EntityTypeEnum.ML:
                      if (!config.enableMLEntities) {
                        throwDiagnosticError({
                            message: 'Do not support ML entity. Please make sure enableMLEntities is set to true.',
                            range: entity.Range
                        });
                      }
                        handleNDepthEntity(parsedContent, entityName, entityRoles, entity.ListBody, entity.Range);
                        break;
                    case EntityTypeEnum.SIMPLE:
                        addItemOrRoleIfNotPresent(parsedContent.LUISJsonStructure, LUISObjNameEnum.ENTITIES, entityName, entityRoles);
                        break;
                    case EntityTypeEnum.COMPOSITE:
                        let candidateChildren = [];
                        if (entity.CompositeDefinition) {
                            entity.CompositeDefinition.replace(/[\[\]]/g, '').split(/[,;]/g).map(item => item.trim()).filter(s => s).forEach(item => candidateChildren.push(item));
                        }
                        if (entity.ListBody) {
                            entity.ListBody.forEach(line => {
                                line.trim().substr(1).trim().replace(/[\[\]]/g, '').split(/[,;]/g).map(item => item.trim()).filter(s => s).forEach(item => candidateChildren.push(item));
                            })
                        }
                        handleComposite(parsedContent, entityName,`[${candidateChildren.join(',')}]`, entityRoles, entity.Range, false, entity.Type !== undefined, config);
                        break;
                    case EntityTypeEnum.LIST:
                        handleClosedList(parsedContent, entityName, entity.ListBody.map(item => item.trim()), entityRoles, entity.Range, config);
                        break;
                    case EntityTypeEnum.PATTERNANY:
                        handlePatternAny(parsedContent, entityName, entityRoles, entity.Range, config);
                        break;
                    case EntityTypeEnum.PREBUILT:
                        handlePrebuiltEntity(parsedContent, 'prebuilt', entityName, entityRoles, locale, log, entity.Range, config);
                        break;
                    case EntityTypeEnum.REGEX:
                        if (entity.ListBody[0]) {
                            handleRegExEntity(parsedContent, entityName, entity.ListBody[0].trim().substr(1).trim(), entityRoles, entity.Range, config);
                        } else {
                            handleRegExEntity(parsedContent, entityName, entity.RegexDefinition, entityRoles, entity.Range, config);
                        }
                        break;
                    case EntityTypeEnum.ML:
                        break;
                    case EntityTypeEnum.PHRASELIST:
                        handlePhraseList(parsedContent, entityName, entity.Type, entityRoles, entity.ListBody.map(item => item.trim().substr(1).trim()), entity.Range, config);
                    default:
                        //Unknown entity type
                        break;
                }
                if (entity.Features !== undefined) {
                    featuresToProcess.push(entity);
                }
            } else {
                featuresToProcess.push(entity);
            }
        }
    }

    return featuresToProcess;
};