// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: google/protobuf/unittest_import_lite.proto
#pragma warning disable 1591, 0612, 3021
#region Designer generated code

using pb = global::Google.ProtocolBuffers;
using pbc = global::Google.ProtocolBuffers.Collections;
using pbd = global::Google.ProtocolBuffers.Descriptors;
using scg = global::System.Collections.Generic;
namespace Google.ProtocolBuffers.TestProtos {

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public static partial class UnittestImportLite {

    #region Extension registration
    public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {
    }
    #endregion
    #region Static variables
    #endregion
    #region Extensions
    internal static readonly object Descriptor;
    static UnittestImportLite() {
      Descriptor = null;
    }
    #endregion

  }
  #region Enums
  public enum ImportEnumLite {
    IMPORT_LITE_FOO = 7,
    IMPORT_LITE_BAR = 8,
    IMPORT_LITE_BAZ = 9,
  }

  #endregion

  #region Messages
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class ImportMessageLite : pb::GeneratedMessageLite<ImportMessageLite, ImportMessageLite.Builder> {
    private ImportMessageLite() { }
    private static readonly ImportMessageLite defaultInstance = new ImportMessageLite().MakeReadOnly();
    private static readonly string[] _importMessageLiteFieldNames = new string[] { "d" };
    private static readonly uint[] _importMessageLiteFieldTags = new uint[] { 8 };
    public static ImportMessageLite DefaultInstance {
      get { return defaultInstance; }
    }

    public override ImportMessageLite DefaultInstanceForType {
      get { return DefaultInstance; }
    }

    protected override ImportMessageLite ThisMessage {
      get { return this; }
    }

    public const int DFieldNumber = 1;
    private bool hasD;
    private int d_;
    public bool HasD {
      get { return hasD; }
    }
    public int D {
      get { return d_; }
    }

    public override bool IsInitialized {
      get {
        return true;
      }
    }

    public override void WriteTo(pb::ICodedOutputStream output) {
      CalcSerializedSize();
      string[] field_names = _importMessageLiteFieldNames;
      if (hasD) {
        output.WriteInt32(1, field_names[0], D);
      }
    }

    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        return CalcSerializedSize();
      }
    }

    private int CalcSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (hasD) {
        size += pb::CodedOutputStream.ComputeInt32Size(1, D);
      }
      memoizedSerializedSize = size;
      return size;
    }
    #region Lite runtime methods
    public override int GetHashCode() {
      int hash = GetType().GetHashCode();
      if (hasD) {
        hash ^= d_.GetHashCode();
      }
      return hash;
    }

    public override bool Equals(object obj) {
      ImportMessageLite other = obj as ImportMessageLite;
      if (other == null) return false;
      if (hasD != other.hasD || (hasD && !d_.Equals(other.d_))) return false;
      return true;
    }

    public override void PrintTo(global::System.IO.TextWriter writer) {
      PrintField("d", hasD, d_, writer);
    }
    #endregion

    public static ImportMessageLite ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static ImportMessageLite ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static ImportMessageLite ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static ImportMessageLite ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static ImportMessageLite ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static ImportMessageLite ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static ImportMessageLite ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static ImportMessageLite ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static ImportMessageLite ParseFrom(pb::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static ImportMessageLite ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private ImportMessageLite MakeReadOnly() {
      return this;
    }

    public static Builder CreateBuilder() { return new Builder(); }
    public override Builder ToBuilder() { return CreateBuilder(this); }
    public override Builder CreateBuilderForType() { return new Builder(); }
    public static Builder CreateBuilder(ImportMessageLite prototype) {
      return new Builder(prototype);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilderLite<ImportMessageLite, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(ImportMessageLite cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }

      private bool resultIsReadOnly;
      private ImportMessageLite result;

      private ImportMessageLite PrepareBuilder() {
        if (resultIsReadOnly) {
          ImportMessageLite original = result;
          result = new ImportMessageLite();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }

      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }

      protected override ImportMessageLite MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }

      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }

      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          return new Builder().MergeFrom(result);
        }
      }

      public override ImportMessageLite DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.ImportMessageLite.DefaultInstance; }
      }

      public override ImportMessageLite BuildPartial() {
        if (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }

      public override Builder MergeFrom(pb::IMessageLite other) {
        if (other is ImportMessageLite) {
          return MergeFrom((ImportMessageLite) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }

      public override Builder MergeFrom(ImportMessageLite other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.ImportMessageLite.DefaultInstance) return this;
        PrepareBuilder();
        if (other.HasD) {
          D = other.D;
        }
        return this;
      }

      public override Builder MergeFrom(pb::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }

      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_importMessageLiteFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _importMessageLiteFieldTags[field_ordinal];
            else {
              ParseUnknownField(input, extensionRegistry, tag, field_name);
              continue;
            }
          }
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            default: {
              if (pb::WireFormat.IsEndGroupTag(tag)) {
                return this;
              }
              ParseUnknownField(input, extensionRegistry, tag, field_name);
              break;
            }
            case 8: {
              result.hasD = input.ReadInt32(ref result.d_);
              break;
            }
          }
        }

        return this;
      }


      public bool HasD {
        get { return result.hasD; }
      }
      public int D {
        get { return result.D; }
        set { SetD(value); }
      }
      public Builder SetD(int value) {
        PrepareBuilder();
        result.hasD = true;
        result.d_ = value;
        return this;
      }
      public Builder ClearD() {
        PrepareBuilder();
        result.hasD = false;
        result.d_ = 0;
        return this;
      }
    }
    static ImportMessageLite() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnittestImportLite.Descriptor, null);
    }
  }

  #endregion

}

#endregion Designer generated code
