#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.Generic;
using System.IO;
using Google.ProtocolBuffers.Descriptors;

namespace Google.ProtocolBuffers
{
    /// <summary>
    /// An implementation of IMessage that can represent arbitrary types, given a MessageaDescriptor.
    /// </summary>
    public sealed partial class DynamicMessage : AbstractMessage<DynamicMessage, DynamicMessage.Builder>
    {
        private readonly MessageDescriptor type;
        private readonly FieldSet fields;
        private readonly FieldDescriptor[] oneofCase;
        private readonly UnknownFieldSet unknownFields;
        private int memoizedSize = -1;

        /// <summary>
        /// Creates a DynamicMessage with the given FieldSet.
        /// </summary>
        /// <param name="type"></param>
        /// <param name="fields"></param>
        /// <param name="unknownFields"></param>
        private DynamicMessage(MessageDescriptor type, FieldSet fields,
            FieldDescriptor[] oneofCase, UnknownFieldSet unknownFields)
        {
            this.type = type;
            this.fields = fields;
            this.oneofCase = oneofCase;
            this.unknownFields = unknownFields;
        }

        /// <summary>
        /// Returns a DynamicMessage representing the default instance of the given type.
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static DynamicMessage GetDefaultInstance(MessageDescriptor type)
        {
            int oneofDescriptorCount = type.Proto.OneofDeclCount;
            FieldDescriptor[] oneofCase = new FieldDescriptor[oneofDescriptorCount];
            return new DynamicMessage(type, FieldSet.DefaultInstance, oneofCase, UnknownFieldSet.DefaultInstance);
        }

        /// <summary>
        /// Parses a message of the given type from the given stream.
        /// </summary>
        public static DynamicMessage ParseFrom(MessageDescriptor type, ICodedInputStream input)
        {
            Builder builder = CreateBuilder(type);
            Builder dynamicBuilder = builder.MergeFrom(input);
            return dynamicBuilder.BuildParsed();
        }

        /// <summary>
        /// Parse a message of the given type from the given stream and extension registry.
        /// </summary>
        /// <param name="type"></param>
        /// <param name="input"></param>
        /// <param name="extensionRegistry"></param>
        /// <returns></returns>
        public static DynamicMessage ParseFrom(MessageDescriptor type, ICodedInputStream input,
                                               ExtensionRegistry extensionRegistry)
        {
            Builder builder = CreateBuilder(type);
            Builder dynamicBuilder = builder.MergeFrom(input, extensionRegistry);
            return dynamicBuilder.BuildParsed();
        }

        /// <summary>
        /// Parses a message of the given type from the given stream.
        /// </summary>
        public static DynamicMessage ParseFrom(MessageDescriptor type, Stream input)
        {
            Builder builder = CreateBuilder(type);
            Builder dynamicBuilder = builder.MergeFrom(input);
            return dynamicBuilder.BuildParsed();
        }

        /// <summary>
        /// Parse a message of the given type from the given stream and extension registry.
        /// </summary>
        /// <param name="type"></param>
        /// <param name="input"></param>
        /// <param name="extensionRegistry"></param>
        /// <returns></returns>
        public static DynamicMessage ParseFrom(MessageDescriptor type, Stream input, ExtensionRegistry extensionRegistry)
        {
            Builder builder = CreateBuilder(type);
            Builder dynamicBuilder = builder.MergeFrom(input, extensionRegistry);
            return dynamicBuilder.BuildParsed();
        }

        /// <summary>
        /// Parse <paramref name="data"/> as a message of the given type and return it.
        /// </summary>
        public static DynamicMessage ParseFrom(MessageDescriptor type, ByteString data)
        {
            Builder builder = CreateBuilder(type);
            Builder dynamicBuilder = builder.MergeFrom(data);
            return dynamicBuilder.BuildParsed();
        }

        /// <summary>
        /// Parse <paramref name="data"/> as a message of the given type and return it.
        /// </summary>
        public static DynamicMessage ParseFrom(MessageDescriptor type, ByteString data,
                                               ExtensionRegistry extensionRegistry)
        {
            Builder builder = CreateBuilder(type);
            Builder dynamicBuilder = builder.MergeFrom(data, extensionRegistry);
            return dynamicBuilder.BuildParsed();
        }

        /// <summary>
        /// Parse <paramref name="data"/> as a message of the given type and return it.
        /// </summary>
        public static DynamicMessage ParseFrom(MessageDescriptor type, byte[] data)
        {
            Builder builder = CreateBuilder(type);
            Builder dynamicBuilder = builder.MergeFrom(data);
            return dynamicBuilder.BuildParsed();
        }

        /// <summary>
        /// Parse <paramref name="data"/> as a message of the given type and return it.
        /// </summary>
        public static DynamicMessage ParseFrom(MessageDescriptor type, byte[] data, ExtensionRegistry extensionRegistry)
        {
            Builder builder = CreateBuilder(type);
            Builder dynamicBuilder = builder.MergeFrom(data, extensionRegistry);
            return dynamicBuilder.BuildParsed();
        }

        /// <summary>
        /// Constructs a builder for the given type.
        /// </summary>
        public static Builder CreateBuilder(MessageDescriptor type)
        {
            return new Builder(type);
        }

        /// <summary>
        /// Constructs a builder for a message of the same type as <paramref name="prototype"/>,
        /// and initializes it with the same contents.
        /// </summary>
        /// <param name="prototype"></param>
        /// <returns></returns>
        public static Builder CreateBuilder(IMessage prototype)
        {
            return new Builder(prototype.DescriptorForType).MergeFrom(prototype);
        }

        // -----------------------------------------------------------------
        // Implementation of IMessage interface.

        public override MessageDescriptor DescriptorForType
        {
            get { return type; }
        }

        public override DynamicMessage DefaultInstanceForType
        {
            get { return GetDefaultInstance(type); }
        }

        public override IDictionary<FieldDescriptor, object> AllFields
        {
            get { return fields.AllFieldDescriptors; }
        }

        public override bool HasOneof(OneofDescriptor oneof)
        {
            VerifyContainingOneofType(oneof);
            FieldDescriptor field = oneofCase[oneof.Index];
            if (field == null)
            {
                return false;
            }
            return true;
        }

        public override FieldDescriptor OneofFieldDescriptor(OneofDescriptor oneof)
        {
            VerifyContainingOneofType(oneof);
            return oneofCase[oneof.Index];
        }

        public override bool HasField(FieldDescriptor field)
        {
            VerifyContainingType(field);
            return fields.HasField(field);
        }

        public override object this[FieldDescriptor field]
        {
            get
            {
                VerifyContainingType(field);
                object result = fields[field];
                if (result == null)
                {
                    result = GetDefaultInstance(field.MessageType);
                }
                return result;
            }
        }

        public override int GetRepeatedFieldCount(FieldDescriptor field)
        {
            VerifyContainingType(field);
            return fields.GetRepeatedFieldCount(field);
        }

        public override object this[FieldDescriptor field, int index]
        {
            get
            {
                VerifyContainingType(field);
                return fields[field, index];
            }
        }

        public override UnknownFieldSet UnknownFields
        {
            get { return unknownFields; }
        }

        public bool Initialized
        {
            get { return fields.IsInitializedWithRespectTo(type.Fields); }
        }

        public override void WriteTo(ICodedOutputStream output)
        {
            fields.WriteTo(output);
            if (type.Options.MessageSetWireFormat)
            {
                unknownFields.WriteAsMessageSetTo(output);
            }
            else
            {
                unknownFields.WriteTo(output);
            }
        }

        public override int SerializedSize
        {
            get
            {
                int size = memoizedSize;
                if (size != -1)
                {
                    return size;
                }

                size = fields.SerializedSize;
                if (type.Options.MessageSetWireFormat)
                {
                    size += unknownFields.SerializedSizeAsMessageSet;
                }
                else
                {
                    size += unknownFields.SerializedSize;
                }

                memoizedSize = size;
                return size;
            }
        }

        public override Builder CreateBuilderForType()
        {
            return new Builder(type);
        }

        public override Builder ToBuilder()
        {
            return CreateBuilderForType().MergeFrom(this);
        }

        /// <summary>
        /// Verifies that the field is a field of this message.
        /// </summary>
        private void VerifyContainingType(FieldDescriptor field)
        {
            if (field.ContainingType != type)
            {
                throw new ArgumentException("FieldDescriptor does not match message type.");
            }
        }

        /// <summary>
        /// Verifies that the oneof is an oneof of this message.
        /// </summary>
        private void VerifyContainingOneofType(OneofDescriptor oneof)
        {
            if (oneof.ContainingType != type)
            {
                throw new ArgumentException("OneofDescritpor does not match message type");
            }
        }

        /// <summary>
        /// Builder for dynamic messages. Instances are created with DynamicMessage.CreateBuilder.
        /// </summary>
        public sealed partial class Builder : AbstractBuilder<DynamicMessage, Builder>
        {
            private readonly MessageDescriptor type;
            private FieldSet fields;
            private FieldDescriptor[] oneofCase;
            private UnknownFieldSet unknownFields;

            internal Builder(MessageDescriptor type)
            {
                this.type = type;
                this.fields = FieldSet.CreateInstance();
                this.unknownFields = UnknownFieldSet.DefaultInstance;
                this.oneofCase = new FieldDescriptor[type.Proto.OneofDeclCount];
            }

            protected override Builder ThisBuilder
            {
                get { return this; }
            }

            public override Builder Clear()
            {
                fields.Clear();
                return this;
            }

            public override Builder MergeFrom(IMessage other)
            {
                if (other.DescriptorForType != type)
                {
                    throw new ArgumentException("MergeFrom(IMessage) can only merge messages of the same type.");
                }
                fields.MergeFrom(other);
                MergeUnknownFields(other.UnknownFields);
                for (int i = 0; i < oneofCase.Length; i++)
                {
                    if (other.HasOneof(type.Oneofs[i]))
                    {
                        if (oneofCase[i] == null)
                        {
                            oneofCase[i] = other.OneofFieldDescriptor(type.Oneofs[i]);
                        } else
                        {
                            if (oneofCase[i] != other.OneofFieldDescriptor(type.Oneofs[i]))
                            {
                                fields.ClearField(oneofCase[i]);
                                oneofCase[i] = other.OneofFieldDescriptor(type.Oneofs[i]);
                            }
                        }
                    }
                }
                return this;
            }

            public override Builder MergeFrom(DynamicMessage other)
            {
                IMessage downcast = other;
                return MergeFrom(downcast);
            }

            public override DynamicMessage Build()
            {
                if (fields != null && !IsInitialized)
                {
                    throw new UninitializedMessageException(new DynamicMessage(type, fields, oneofCase, unknownFields));
                }
                return BuildPartial();
            }

            /// <summary>
            /// Helper for DynamicMessage.ParseFrom() methods to call. Throws
            /// InvalidProtocolBufferException 
            /// </summary>
            /// <returns></returns>
            internal DynamicMessage BuildParsed()
            {
                if (!IsInitialized)
                {
                    throw new UninitializedMessageException(new DynamicMessage(type, fields, oneofCase, unknownFields)).
                        AsInvalidProtocolBufferException();
                }
                return BuildPartial();
            }

            public override DynamicMessage BuildPartial()
            {
                if (fields == null)
                {
                    throw new InvalidOperationException("Build() has already been called on this Builder.");
                }
                fields.MakeImmutable();
                DynamicMessage result = new DynamicMessage(type, fields, oneofCase, unknownFields);
                fields = null;
                unknownFields = null;
                return result;
            }

            public override Builder Clone()
            {
                Builder result = new Builder(type);
                result.fields.MergeFrom(fields);
                result.oneofCase = oneofCase;
                return result;
            }

            public override bool IsInitialized
            {
                get { return fields.IsInitializedWithRespectTo(type.Fields); }
            }

            public override Builder MergeFrom(ICodedInputStream input, ExtensionRegistry extensionRegistry)
            {
                UnknownFieldSet.Builder unknownFieldsBuilder = UnknownFieldSet.CreateBuilder(unknownFields);
                unknownFieldsBuilder.MergeFrom(input, extensionRegistry, this);
                unknownFields = unknownFieldsBuilder.Build();
                return this;
            }

            public override MessageDescriptor DescriptorForType
            {
                get { return type; }
            }

            public override DynamicMessage DefaultInstanceForType
            {
                get { return GetDefaultInstance(type); }
            }

            public override IDictionary<FieldDescriptor, object> AllFields
            {
                get { return fields.AllFieldDescriptors; }
            }

            public override IBuilder CreateBuilderForField(FieldDescriptor field)
            {
                VerifyContainingType(field);
                if (field.MappedType != MappedType.Message)
                {
                    throw new ArgumentException("CreateBuilderForField is only valid for fields with message type.");
                }
                return new Builder(field.MessageType);
            }

            public override bool HasOneof(OneofDescriptor oneof)
            {
                VerifyContainingOneofType(oneof);
                FieldDescriptor field = oneofCase[oneof.Index];
                if (field == null)
                {
                    return false;
                }
                return true;
            }

            public override FieldDescriptor OneofFieldDescriptor(OneofDescriptor oneof)
            {
                VerifyContainingOneofType(oneof);
                return oneofCase[oneof.Index];
            }

            public override bool HasField(FieldDescriptor field)
            {
                VerifyContainingType(field);
                return fields.HasField(field);
            }

            public override object this[FieldDescriptor field, int index]
            {
                get
                {
                    VerifyContainingType(field);
                    return fields[field, index];
                }
                set
                {
                    VerifyContainingType(field);
                    fields[field, index] = value;
                }
            }

            public override object this[FieldDescriptor field]
            {
                get
                {
                    VerifyContainingType(field);
                    object result = fields[field];
                    if (result == null)
                    {
                        result = GetDefaultInstance(field.MessageType);
                    }
                    return result;
                }
                set
                {
                    VerifyContainingType(field);
                    OneofDescriptor oneof = field.ContainingOneof;
                    if (oneof != null)
                    {
                        int index = oneof.Index;
                        FieldDescriptor oldField = oneofCase[index];
                        if ((oldField != null) && (oldField != field))
                        {
                            fields.ClearField(oldField);
                        }
                        oneofCase[index] = field;
                    }
                    fields[field] = value;
                }
            }

            public override Builder ClearField(FieldDescriptor field)
            {
                VerifyContainingType(field);
                OneofDescriptor oneof = field.ContainingOneof;
                if (oneof != null)
                {
                    int index = oneof.Index;
                    if (oneofCase[index] == field)
                    {
                        oneofCase[index] = null;
                    }
                }
                fields.ClearField(field);
                return this;
            }

            public override Builder ClearOneof(OneofDescriptor oneof)
            {
                VerifyContainingOneofType(oneof);
                FieldDescriptor field = oneofCase[oneof.Index];
                if (field != null)
                {
                    ClearField(field);
                }
                return this;
            }

            public override int GetRepeatedFieldCount(FieldDescriptor field)
            {
                VerifyContainingType(field);
                return fields.GetRepeatedFieldCount(field);
            }

            public override Builder AddRepeatedField(FieldDescriptor field, object value)
            {
                VerifyContainingType(field);
                fields.AddRepeatedField(field, value);
                return this;
            }

            public override UnknownFieldSet UnknownFields
            {
                get { return unknownFields; }
                set { unknownFields = value; }
            }

            /// <summary>
            /// Verifies that the field is a field of this message.
            /// </summary>
            /// <param name="field"></param>
            private void VerifyContainingType(FieldDescriptor field)
            {
                if (field.ContainingType != type)
                {
                    throw new ArgumentException("FieldDescriptor does not match message type.");
                }
            }

            /// <summary>
            /// Verifies that the oneof is an oneof of this message.
            /// </summary>
            private void VerifyContainingOneofType(OneofDescriptor oneof)
            {
                if (oneof.ContainingType != type)
                {
                    throw new ArgumentException("OneofDescriptor does not match message type");
                }
            }
        }
    }
}