public string ApplyMessageProperties()

in Libraries/src/Amazon.Lambda.RuntimeSupport/Helpers/Logging/AbstractLogMessageFormatter.cs [131:236]


        public string ApplyMessageProperties(string messageTemplate, IReadOnlyList<MessageProperty> messageProperties, object[] messageArguments)
        {
            if(messageProperties.Count == 0 || messageArguments == null || messageArguments.Length == 0)
            {
                return messageTemplate;
            }

            // Check to see if the message template is using positions instead of names. For example
            // "User bought {0} of {1}" is positional as opposed to "User bought {count} of {product"}.
            var usePositional = UsingPositionalArguments(messageProperties);

            var state = LogFormatParserState.InMessage;

            // Builder used to create the message with the properties replaced. Set the initial capacity
            // to the size of the message template plus 10% to give room for the values of message properties 
            // to be larger then the message property in the message themselves.
            StringBuilder messageBuilder = new StringBuilder(capacity: (int)(messageTemplate.Length * 1.1));

            // Builder used store potential message properties as we parse through the message. If the 
            // it turns out the potential message property is not a message property the contents of this
            // builder are written back to the messageBuilder.
            StringBuilder propertyBuilder = new StringBuilder();

            int propertyIndex = 0;
            for (int i = 0, l = messageTemplate.Length; i < l; i++)
            {
                var c = messageTemplate[i];

                // If not using positional properties and we have hit the point there are more message properties then arguments
                // then just add the rest of the message template onto the messageBuilder.
                if (!usePositional && (messageProperties.Count <= propertyIndex || messageArguments.Length <= propertyIndex))
                {
                    messageBuilder.Append(c);
                    continue;
                }

                switch (c)
                {
                    case '{':
                        if (state == LogFormatParserState.InMessage)
                        {
                            // regardless of whether this is the opening of a parameter we'd still need to add {
                            propertyBuilder.Append(c);
                            state = LogFormatParserState.PossibleParameterOpen;
                        }
                        else if (state == LogFormatParserState.PossibleParameterOpen)
                        {
                            // We have hit an escaped "{" by the user using "{{". Since we now know we are
                            // not in a message properties write back the propertiesBuilder into 
                            // messageBuilder and reset the propertyBuilder.
                            messageBuilder.Append(propertyBuilder.ToString());
                            propertyBuilder.Clear();
                            messageBuilder.Append(c);
                            state = LogFormatParserState.InMessage;
                        }
                        else
                        {
                            propertyBuilder.Append(c);
                        }
                        break;
                    case '}':
                        if (state == LogFormatParserState.InMessage)
                        {
                            messageBuilder.Append(c);
                        }
                        else
                        {
                            var property = messageProperties[propertyIndex];
                            object argument = null;
                            if(usePositional)
                            {
                                // If usePositional is true then we have confirmed the `Name` property is an int
                                var index = int.Parse(property.Name, CultureInfo.InvariantCulture);
                                if (index < messageArguments.Length)
                                {
                                    argument = messageArguments[index];
                                }
                            }
                            else
                            {
                                argument = messageArguments[propertyIndex];
                            }
                            messageBuilder.Append(property.FormatForMessage(argument));

                            propertyIndex++;
                            propertyBuilder.Clear();
                            state = LogFormatParserState.InMessage;
                        }
                        break;
                    default:
                        if (state == LogFormatParserState.InMessage)
                        {
                            messageBuilder.Append(c);
                        }
                        else if (state == LogFormatParserState.PossibleParameterOpen)
                        {
                            // non-brace character after '{', transition to InParameter
                            propertyBuilder.Append(c);
                            state = LogFormatParserState.InParameter;
                        }
                        break;
                }
            }

            return messageBuilder.ToString();
        }