private TypeSymbol NarrowStringAssignmentType()

in src/Bicep.Core/TypeSystem/TypeValidator.cs [500:571]


        private TypeSymbol NarrowStringAssignmentType(TypeValidatorConfig config, SyntaxBase expression, TypeSymbol expressionType, StringType targetType)
        {
            bool shouldWarn = config.IsResourceDeclaration || ShouldWarn(targetType);

            switch (expressionType)
            {
                case StringType expressionString:
                    if (expressionString.MinLength.HasValue && targetType.MaxLength.HasValue && expressionString.MinLength.Value > targetType.MaxLength.Value)
                    {
                        diagnosticWriter.Write(DiagnosticBuilder.ForPosition(expression)
                            .SourceValueLengthDomainDisjointFromTargetValueLengthDomain_SourceHigh(shouldWarn, expressionString.MinLength.Value, targetType.MaxLength.Value));
                        break;
                    }

                    if (expressionString.MaxLength.HasValue && targetType.MinLength.HasValue && expressionString.MaxLength.Value < targetType.MinLength.Value)
                    {
                        diagnosticWriter.Write(DiagnosticBuilder.ForPosition(expression)
                            .SourceValueLengthDomainDisjointFromTargetValueLengthDomain_SourceLow(shouldWarn, expressionString.MaxLength.Value, targetType.MinLength.Value));
                        break;
                    }

                    if (expressionString.MinLength.HasValue && targetType.MinLength.HasValue && expressionString.MinLength.Value < targetType.MinLength.Value)
                    {
                        diagnosticWriter.Write(DiagnosticBuilder.ForPosition(expression).SourceValueLengthDomainExtendsBelowTargetValueLengthDomain(expressionString.MinLength.Value, targetType.MinLength.Value));
                    }

                    if (expressionString.MaxLength.HasValue && targetType.MaxLength.HasValue && expressionString.MaxLength.Value > targetType.MaxLength.Value)
                    {
                        diagnosticWriter.Write(DiagnosticBuilder.ForPosition(expression).SourceValueLengthDomainExtendsAboveTargetValueLengthDomain(expressionString.MaxLength.Value, targetType.MaxLength.Value));
                    }

                    return TypeFactory.CreateStringType(
                        minLength: Math.Max(expressionString.MinLength ?? 0, targetType.MinLength ?? 0) switch
                        {
                            <= 0 => null,
                            long otherwise => otherwise,
                        },
                        maxLength: Math.Min(expressionString.MaxLength ?? long.MaxValue, targetType.MaxLength ?? long.MaxValue) switch
                        {
                            long.MaxValue => null,
                            long otherwise => otherwise,
                        },
                        validationFlags: targetType.ValidationFlags);
                case StringLiteralType expressionStringLiteral:
                    if (targetType.MaxLength.HasValue && expressionStringLiteral.RawStringValue.Length > targetType.MaxLength.Value)
                    {
                        diagnosticWriter.Write(DiagnosticBuilder.ForPosition(expression).SourceValueLengthDomainDisjointFromTargetValueLengthDomain_SourceHigh(
                            shouldWarn,
                            expressionStringLiteral.RawStringValue.Length,
                            targetType.MaxLength.Value));
                    }
                    else if (targetType.MinLength.HasValue && expressionStringLiteral.RawStringValue.Length < targetType.MinLength.Value)
                    {
                        diagnosticWriter.Write(DiagnosticBuilder.ForPosition(expression).SourceValueLengthDomainDisjointFromTargetValueLengthDomain_SourceLow(
                            shouldWarn,
                            expressionStringLiteral.RawStringValue.Length,
                            targetType.MinLength.Value));
                    }

                    if (targetType.Pattern is not null &&
                        TypeHelper.MatchesPattern(targetType.Pattern, expressionStringLiteral.RawStringValue) is false)
                    {
                        diagnosticWriter.Write(DiagnosticBuilder.ForPosition(expression)
                            .SuppliedStringDoesNotMatchExpectedPattern(shouldWarn, targetType.Pattern));
                    }

                    // if a literal was assignable to a string-typed target, the literal will always be the most narrow type
                    return expressionStringLiteral;
            }

            return expressionType;
        }