#region Copyright notice and license

// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// http://github.com/jskeet/dotnet-protobufs/
// Original C++/Java/Python code:
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#endregion

using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;
using Google.ProtocolBuffers.Descriptors;

namespace Google.ProtocolBuffers
{
    /// <summary>
    /// Provides ASCII text formatting support for messages.
    /// TODO(jonskeet): Support for alternative line endings.
    /// (Easy to print, via TextGenerator. Not sure about parsing.)
    /// </summary>
    public static class TextFormat
    {
        /// <summary>
        /// Outputs a textual representation of the Protocol Message supplied into
        /// the parameter output.
        /// </summary>
        public static void Print(IMessage message, TextWriter output)
        {
            TextGenerator generator = new TextGenerator(output, "\n");
            Print(message, generator);
        }

        /// <summary>
        /// Outputs a textual representation of the Protocol Message builder supplied into
        /// the parameter output.
        /// </summary>
        public static void Print(IBuilder builder, TextWriter output)
        {
            TextGenerator generator = new TextGenerator(output, "\n");
            Print(builder, generator);
        }

        /// <summary>
        /// Outputs a textual representation of <paramref name="fields" /> to <paramref name="output"/>.
        /// </summary>
        public static void Print(UnknownFieldSet fields, TextWriter output)
        {
            TextGenerator generator = new TextGenerator(output, "\n");
            PrintUnknownFields(fields, generator);
        }

        public static string PrintToString(IMessage message)
        {
            StringWriter text = new StringWriter();
            Print(message, text);
            return text.ToString();
        }

        public static string PrintToString(IBuilder builder)
        {
            StringWriter text = new StringWriter();
            Print(builder, text);
            return text.ToString();
        }

        public static string PrintToString(UnknownFieldSet fields)
        {
            StringWriter text = new StringWriter();
            Print(fields, text);
            return text.ToString();
        }

        private static void Print(IMessage message, TextGenerator generator)
        {
            foreach (KeyValuePair<FieldDescriptor, object> entry in message.AllFields)
            {
                PrintField(entry.Key, entry.Value, generator);
            }
            PrintUnknownFields(message.UnknownFields, generator);
        }

        private static void Print(IBuilder message, TextGenerator generator)
        {
            foreach (KeyValuePair<FieldDescriptor, object> entry in message.AllFields)
            {
                PrintField(entry.Key, entry.Value, generator);
            }
            PrintUnknownFields(message.UnknownFields, generator);
        }

        internal static void PrintField(FieldDescriptor field, object value, TextGenerator generator)
        {
            if (field.IsRepeated)
            {
                // Repeated field.  Print each element.
                foreach (object element in (IEnumerable) value)
                {
                    PrintSingleField(field, element, generator);
                }
            }
            else
            {
                PrintSingleField(field, value, generator);
            }
        }

        private static void PrintSingleField(FieldDescriptor field, Object value, TextGenerator generator)
        {
            if (field.IsExtension)
            {
                generator.Print("[");
                // We special-case MessageSet elements for compatibility with proto1.
                if (field.ContainingType.Options.MessageSetWireFormat
                    && field.FieldType == FieldType.Message
                    && field.IsOptional
                    // object equality (TODO(jonskeet): Work out what this comment means!)
                    && field.ExtensionScope == field.MessageType)
                {
                    generator.Print(field.MessageType.FullName);
                }
                else
                {
                    generator.Print(field.FullName);
                }
                generator.Print("]");
            }
            else
            {
                if (field.FieldType == FieldType.Group)
                {
                    // Groups must be serialized with their original capitalization.
                    generator.Print(field.MessageType.Name);
                }
                else
                {
                    generator.Print(field.Name);
                }
            }

            if (field.MappedType == MappedType.Message)
            {
                generator.Print(" {\n");
                generator.Indent();
            }
            else
            {
                generator.Print(": ");
            }

            PrintFieldValue(field, value, generator);

            if (field.MappedType == MappedType.Message)
            {
                generator.Outdent();
                generator.Print("}");
            }
            generator.Print("\n");
        }

        private static void PrintFieldValue(FieldDescriptor field, object value, TextGenerator generator)
        {
            switch (field.FieldType)
            {
                    // The Float and Double types must specify the "r" format to preserve their precision, otherwise,
                    // the double to/from string will trim the precision to 6 places.  As with other numeric formats
                    // below, always use the invariant culture so it's predictable.
                case FieldType.Float:
                    generator.Print(((float)value).ToString("r", FrameworkPortability.InvariantCulture));
                    break;
                case FieldType.Double:
                    generator.Print(((double)value).ToString("r", FrameworkPortability.InvariantCulture));
                    break;

                case FieldType.Int32:
                case FieldType.Int64:
                case FieldType.SInt32:
                case FieldType.SInt64:
                case FieldType.SFixed32:
                case FieldType.SFixed64:
                case FieldType.UInt32:
                case FieldType.UInt64:
                case FieldType.Fixed32:
                case FieldType.Fixed64:
                    // The simple Object.ToString converts using the current culture.
                    // We want to always use the invariant culture so it's predictable.
                    generator.Print(((IConvertible)value).ToString(FrameworkPortability.InvariantCulture));
                    break;
                case FieldType.Bool:
                    // Explicitly use the Java true/false
                    generator.Print((bool) value ? "true" : "false");
                    break;

                case FieldType.String:
                    generator.Print("\"");
                    generator.Print(EscapeText((string) value));
                    generator.Print("\"");
                    break;

                case FieldType.Bytes:
                    {
                        generator.Print("\"");
                        generator.Print(EscapeBytes((ByteString) value));
                        generator.Print("\"");
                        break;
                    }

                case FieldType.Enum:
                    {
                        if (value is IEnumLite && !(value is EnumValueDescriptor))
                        {
                            throw new NotSupportedException("Lite enumerations are not supported.");
                        }
                        generator.Print(((EnumValueDescriptor) value).Name);
                        break;
                    }

                case FieldType.Message:
                case FieldType.Group:
                    if (value is IMessageLite && !(value is IMessage))
                    {
                        throw new NotSupportedException("Lite messages are not supported.");
                    }
                    Print((IMessage) value, generator);
                    break;
            }
        }

        private static void PrintUnknownFields(UnknownFieldSet unknownFields, TextGenerator generator)
        {
            foreach (KeyValuePair<int, UnknownField> entry in unknownFields.FieldDictionary)
            {
                String prefix = entry.Key.ToString() + ": ";
                UnknownField field = entry.Value;

                foreach (ulong value in field.VarintList)
                {
                    generator.Print(prefix);
                    generator.Print(value.ToString());
                    generator.Print("\n");
                }
                foreach (uint value in field.Fixed32List)
                {
                    generator.Print(prefix);
                    generator.Print(string.Format("0x{0:x8}", value));
                    generator.Print("\n");
                }
                foreach (ulong value in field.Fixed64List)
                {
                    generator.Print(prefix);
                    generator.Print(string.Format("0x{0:x16}", value));
                    generator.Print("\n");
                }
                foreach (ByteString value in field.LengthDelimitedList)
                {
                    generator.Print(entry.Key.ToString());
                    generator.Print(": \"");
                    generator.Print(EscapeBytes(value));
                    generator.Print("\"\n");
                }
                foreach (UnknownFieldSet value in field.GroupList)
                {
                    generator.Print(entry.Key.ToString());
                    generator.Print(" {\n");
                    generator.Indent();
                    PrintUnknownFields(value, generator);
                    generator.Outdent();
                    generator.Print("}\n");
                }
            }
        }

        public static ulong ParseUInt64(string text)
        {
            return (ulong) ParseInteger(text, false, true);
        }

        public static long ParseInt64(string text)
        {
            return ParseInteger(text, true, true);
        }

        public static uint ParseUInt32(string text)
        {
            return (uint) ParseInteger(text, false, false);
        }

        public static int ParseInt32(string text)
        {
            return (int) ParseInteger(text, true, false);
        }

        public static float ParseFloat(string text)
        {
            switch (text)
            {
                case "-inf":
                case "-infinity":
                case "-inff":
                case "-infinityf":
                    return float.NegativeInfinity;
                case "inf":
                case "infinity":
                case "inff":
                case "infinityf":
                    return float.PositiveInfinity;
                case "nan":
                case "nanf":
                    return float.NaN;
                default:
                    return float.Parse(text, FrameworkPortability.InvariantCulture);
            }
        }

        public static double ParseDouble(string text)
        {
            switch (text)
            {
                case "-inf":
                case "-infinity":
                    return double.NegativeInfinity;
                case "inf":
                case "infinity":
                    return double.PositiveInfinity;
                case "nan":
                    return double.NaN;
                default:
                    return double.Parse(text, FrameworkPortability.InvariantCulture);
            }
        }

        /// <summary>
        /// Parses an integer in hex (leading 0x), decimal (no prefix) or octal (leading 0).
        /// Only a negative sign is permitted, and it must come before the radix indicator.
        /// </summary>
        private static long ParseInteger(string text, bool isSigned, bool isLong)
        {
            string original = text;
            bool negative = false;
            if (text.StartsWith("-"))
            {
                if (!isSigned)
                {
                    throw new FormatException("Number must be positive: " + original);
                }
                negative = true;
                text = text.Substring(1);
            }

            int radix = 10;
            if (text.StartsWith("0x"))
            {
                radix = 16;
                text = text.Substring(2);
            }
            else if (text.StartsWith("0"))
            {
                radix = 8;
            }

            ulong result;
            try
            {
                // Workaround for https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=278448
                // We should be able to use Convert.ToUInt64 for all cases.
                result = radix == 10 ? ulong.Parse(text) : Convert.ToUInt64(text, radix);
            }
            catch (OverflowException)
            {
                // Convert OverflowException to FormatException so there's a single exception type this method can throw.
                string numberDescription = string.Format("{0}-bit {1}signed integer", isLong ? 64 : 32,
                                                         isSigned ? "" : "un");
                throw new FormatException("Number out of range for " + numberDescription + ": " + original);
            }

            if (negative)
            {
                ulong max = isLong ? 0x8000000000000000UL : 0x80000000L;
                if (result > max)
                {
                    string numberDescription = string.Format("{0}-bit signed integer", isLong ? 64 : 32);
                    throw new FormatException("Number out of range for " + numberDescription + ": " + original);
                }
                return -((long) result);
            }
            else
            {
                ulong max = isSigned
                                ? (isLong ? (ulong) long.MaxValue : int.MaxValue)
                                : (isLong ? ulong.MaxValue : uint.MaxValue);
                if (result > max)
                {
                    string numberDescription = string.Format("{0}-bit {1}signed integer", isLong ? 64 : 32,
                                                             isSigned ? "" : "un");
                    throw new FormatException("Number out of range for " + numberDescription + ": " + original);
                }
                return (long) result;
            }
        }

        /// <summary>
        /// Tests a character to see if it's an octal digit.
        /// </summary>
        private static bool IsOctal(char c)
        {
            return '0' <= c && c <= '7';
        }

        /// <summary>
        /// Tests a character to see if it's a hex digit.
        /// </summary>
        private static bool IsHex(char c)
        {
            return ('0' <= c && c <= '9') ||
                   ('a' <= c && c <= 'f') ||
                   ('A' <= c && c <= 'F');
        }

        /// <summary>
        /// Interprets a character as a digit (in any base up to 36) and returns the
        /// numeric value.
        /// </summary>
        private static int ParseDigit(char c)
        {
            if ('0' <= c && c <= '9')
            {
                return c - '0';
            }
            else if ('a' <= c && c <= 'z')
            {
                return c - 'a' + 10;
            }
            else
            {
                return c - 'A' + 10;
            }
        }

        /// <summary>
        /// Unescapes a text string as escaped using <see cref="EscapeText(string)" />.
        /// Two-digit hex escapes (starting with "\x" are also recognised.
        /// </summary>
        public static string UnescapeText(string input)
        {
            return UnescapeBytes(input).ToStringUtf8();
        }

        /// <summary>
        /// Like <see cref="EscapeBytes" /> but escapes a text string.
        /// The string is first encoded as UTF-8, then each byte escaped individually.
        /// The returned value is guaranteed to be entirely ASCII.
        /// </summary>
        public static string EscapeText(string input)
        {
            return EscapeBytes(ByteString.CopyFromUtf8(input));
        }

        /// <summary>
        /// Escapes bytes in the format used in protocol buffer text format, which
        /// is the same as the format used for C string literals.  All bytes
        /// that are not printable 7-bit ASCII characters are escaped, as well as
        /// backslash, single-quote, and double-quote characters.  Characters for
        /// which no defined short-hand escape sequence is defined will be escaped
        /// using 3-digit octal sequences.
        /// The returned value is guaranteed to be entirely ASCII.
        /// </summary>
        public static String EscapeBytes(ByteString input)
        {
            StringBuilder builder = new StringBuilder(input.Length);
            foreach (byte b in input)
            {
                switch (b)
                {
                        // C# does not use \a or \v
                    case 0x07:
                        builder.Append("\\a");
                        break;
                    case (byte) '\b':
                        builder.Append("\\b");
                        break;
                    case (byte) '\f':
                        builder.Append("\\f");
                        break;
                    case (byte) '\n':
                        builder.Append("\\n");
                        break;
                    case (byte) '\r':
                        builder.Append("\\r");
                        break;
                    case (byte) '\t':
                        builder.Append("\\t");
                        break;
                    case 0x0b:
                        builder.Append("\\v");
                        break;
                    case (byte) '\\':
                        builder.Append("\\\\");
                        break;
                    case (byte) '\'':
                        builder.Append("\\\'");
                        break;
                    case (byte) '"':
                        builder.Append("\\\"");
                        break;
                    default:
                        if (b >= 0x20 && b < 128)
                        {
                            builder.Append((char) b);
                        }
                        else
                        {
                            builder.Append('\\');
                            builder.Append((char) ('0' + ((b >> 6) & 3)));
                            builder.Append((char) ('0' + ((b >> 3) & 7)));
                            builder.Append((char) ('0' + (b & 7)));
                        }
                        break;
                }
            }
            return builder.ToString();
        }

        /// <summary>
        /// Performs string unescaping from C style (octal, hex, form feeds, tab etc) into a byte string.
        /// </summary>
        public static ByteString UnescapeBytes(string input)
        {
            byte[] result = new byte[input.Length];
            int pos = 0;
            for (int i = 0; i < input.Length; i++)
            {
                char c = input[i];
                if (c > 127 || c < 32)
                {
                    throw new FormatException("Escaped string must only contain ASCII");
                }
                if (c != '\\')
                {
                    result[pos++] = (byte) c;
                    continue;
                }
                if (i + 1 >= input.Length)
                {
                    throw new FormatException("Invalid escape sequence: '\\' at end of string.");
                }

                i++;
                c = input[i];
                if (c >= '0' && c <= '7')
                {
                    // Octal escape. 
                    int code = ParseDigit(c);
                    if (i + 1 < input.Length && IsOctal(input[i + 1]))
                    {
                        i++;
                        code = code*8 + ParseDigit(input[i]);
                    }
                    if (i + 1 < input.Length && IsOctal(input[i + 1]))
                    {
                        i++;
                        code = code*8 + ParseDigit(input[i]);
                    }
                    result[pos++] = (byte) code;
                }
                else
                {
                    switch (c)
                    {
                        case 'a':
                            result[pos++] = 0x07;
                            break;
                        case 'b':
                            result[pos++] = (byte) '\b';
                            break;
                        case 'f':
                            result[pos++] = (byte) '\f';
                            break;
                        case 'n':
                            result[pos++] = (byte) '\n';
                            break;
                        case 'r':
                            result[pos++] = (byte) '\r';
                            break;
                        case 't':
                            result[pos++] = (byte) '\t';
                            break;
                        case 'v':
                            result[pos++] = 0x0b;
                            break;
                        case '\\':
                            result[pos++] = (byte) '\\';
                            break;
                        case '\'':
                            result[pos++] = (byte) '\'';
                            break;
                        case '"':
                            result[pos++] = (byte) '\"';
                            break;

                        case 'x':
                            // hex escape
                            int code;
                            if (i + 1 < input.Length && IsHex(input[i + 1]))
                            {
                                i++;
                                code = ParseDigit(input[i]);
                            }
                            else
                            {
                                throw new FormatException("Invalid escape sequence: '\\x' with no digits");
                            }
                            if (i + 1 < input.Length && IsHex(input[i + 1]))
                            {
                                ++i;
                                code = code*16 + ParseDigit(input[i]);
                            }
                            result[pos++] = (byte) code;
                            break;

                        default:
                            throw new FormatException("Invalid escape sequence: '\\" + c + "'");
                    }
                }
            }

            return ByteString.CopyFrom(result, 0, pos);
        }

        public static void Merge(string text, IBuilder builder)
        {
            Merge(text, ExtensionRegistry.Empty, builder);
        }

        public static void Merge(TextReader reader, IBuilder builder)
        {
            Merge(reader, ExtensionRegistry.Empty, builder);
        }

        public static void Merge(TextReader reader, ExtensionRegistry registry, IBuilder builder)
        {
            Merge(reader.ReadToEnd(), registry, builder);
        }

        public static void Merge(string text, ExtensionRegistry registry, IBuilder builder)
        {
            TextTokenizer tokenizer = new TextTokenizer(text);

            while (!tokenizer.AtEnd)
            {
                MergeField(tokenizer, registry, builder);
            }
        }

        /// <summary>
        /// Parses a single field from the specified tokenizer and merges it into
        /// the builder.
        /// </summary>
        private static void MergeField(TextTokenizer tokenizer, ExtensionRegistry extensionRegistry,
                                       IBuilder builder)
        {
            FieldDescriptor field;
            MessageDescriptor type = builder.DescriptorForType;
            ExtensionInfo extension = null;

            if (tokenizer.TryConsume("["))
            {
                // An extension.
                StringBuilder name = new StringBuilder(tokenizer.ConsumeIdentifier());
                while (tokenizer.TryConsume("."))
                {
                    name.Append(".");
                    name.Append(tokenizer.ConsumeIdentifier());
                }

                extension = extensionRegistry.FindByName(type, name.ToString());

                if (extension == null)
                {
                    throw tokenizer.CreateFormatExceptionPreviousToken("Extension \"" + name +
                                                                       "\" not found in the ExtensionRegistry.");
                }
                else if (extension.Descriptor.ContainingType != type)
                {
                    throw tokenizer.CreateFormatExceptionPreviousToken("Extension \"" + name +
                                                                       "\" does not extend message type \"" +
                                                                       type.FullName + "\".");
                }

                tokenizer.Consume("]");

                field = extension.Descriptor;
            }
            else
            {
                String name = tokenizer.ConsumeIdentifier();
                field = type.FindDescriptor<FieldDescriptor>(name);

                // Group names are expected to be capitalized as they appear in the
                // .proto file, which actually matches their type names, not their field
                // names.
                if (field == null)
                {
                    // Explicitly specify the invariant culture so that this code does not break when
                    // executing in Turkey.
                    String lowerName = name.ToLowerInvariant();
                    field = type.FindDescriptor<FieldDescriptor>(lowerName);
                    // If the case-insensitive match worked but the field is NOT a group,
                    // TODO(jonskeet): What? Java comment ends here!
                    if (field != null && field.FieldType != FieldType.Group)
                    {
                        field = null;
                    }
                }
                // Again, special-case group names as described above.
                if (field != null && field.FieldType == FieldType.Group && field.MessageType.Name != name)
                {
                    field = null;
                }

                if (field == null)
                {
                    throw tokenizer.CreateFormatExceptionPreviousToken(
                        "Message type \"" + type.FullName + "\" has no field named \"" + name + "\".");
                }
            }

            object value = null;

            if (field.MappedType == MappedType.Message)
            {
                tokenizer.TryConsume(":"); // optional

                String endToken;
                if (tokenizer.TryConsume("<"))
                {
                    endToken = ">";
                }
                else
                {
                    tokenizer.Consume("{");
                    endToken = "}";
                }

                IBuilder subBuilder;
                if (extension == null)
                {
                    subBuilder = builder.CreateBuilderForField(field);
                }
                else
                {
                    subBuilder = extension.DefaultInstance.WeakCreateBuilderForType() as IBuilder;
                    if (subBuilder == null)
                    {
                        throw new NotSupportedException("Lite messages are not supported.");
                    }
                }

                while (!tokenizer.TryConsume(endToken))
                {
                    if (tokenizer.AtEnd)
                    {
                        throw tokenizer.CreateFormatException("Expected \"" + endToken + "\".");
                    }
                    MergeField(tokenizer, extensionRegistry, subBuilder);
                }

                value = subBuilder.WeakBuild();
            }
            else
            {
                tokenizer.Consume(":");

                switch (field.FieldType)
                {
                    case FieldType.Int32:
                    case FieldType.SInt32:
                    case FieldType.SFixed32:
                        value = tokenizer.ConsumeInt32();
                        break;

                    case FieldType.Int64:
                    case FieldType.SInt64:
                    case FieldType.SFixed64:
                        value = tokenizer.ConsumeInt64();
                        break;

                    case FieldType.UInt32:
                    case FieldType.Fixed32:
                        value = tokenizer.ConsumeUInt32();
                        break;

                    case FieldType.UInt64:
                    case FieldType.Fixed64:
                        value = tokenizer.ConsumeUInt64();
                        break;

                    case FieldType.Float:
                        value = tokenizer.ConsumeFloat();
                        break;

                    case FieldType.Double:
                        value = tokenizer.ConsumeDouble();
                        break;

                    case FieldType.Bool:
                        value = tokenizer.ConsumeBoolean();
                        break;

                    case FieldType.String:
                        value = tokenizer.ConsumeString();
                        break;

                    case FieldType.Bytes:
                        value = tokenizer.ConsumeByteString();
                        break;

                    case FieldType.Enum:
                        {
                            EnumDescriptor enumType = field.EnumType;

                            if (tokenizer.LookingAtInteger())
                            {
                                int number = tokenizer.ConsumeInt32();
                                value = enumType.FindValueByNumber(number);
                                if (value == null)
                                {
                                    throw tokenizer.CreateFormatExceptionPreviousToken(
                                        "Enum type \"" + enumType.FullName +
                                        "\" has no value with number " + number + ".");
                                }
                            }
                            else
                            {
                                String id = tokenizer.ConsumeIdentifier();
                                value = enumType.FindValueByName(id);
                                if (value == null)
                                {
                                    throw tokenizer.CreateFormatExceptionPreviousToken(
                                        "Enum type \"" + enumType.FullName +
                                        "\" has no value named \"" + id + "\".");
                                }
                            }

                            break;
                        }

                    case FieldType.Message:
                    case FieldType.Group:
                        throw new InvalidOperationException("Can't get here.");
                }
            }

            if (field.IsRepeated)
            {
                builder.WeakAddRepeatedField(field, value);
            }
            else
            {
                builder.SetField(field, value);
            }
        }
    }
}