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

using pb = global::Google.Protobuf;
using pbc = global::Google.Protobuf.Collections;
using pbr = global::Google.Protobuf.Reflection;
using scg = global::System.Collections.Generic;
namespace Google.Protobuf.TestProtos {

  /// <summary>Holder for reflection information generated from google/protobuf/unittest_proto3.proto</summary>
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public static partial class UnittestProto3 {

    #region Descriptor
    /// <summary>File descriptor for google/protobuf/unittest_proto3.proto</summary>
    public static pbr::FileDescriptor Descriptor {
      get { return descriptor; }
    }
    private static pbr::FileDescriptor descriptor;

    static UnittestProto3() {
      byte[] descriptorData = global::System.Convert.FromBase64String(
          string.Concat(
            "CiVnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJvdG8zLnByb3RvEhFwcm90",
            "b2J1Zl91bml0dGVzdBosZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2ltcG9y",
            "dF9wcm90bzMucHJvdG8i8A8KDFRlc3RBbGxUeXBlcxIUCgxzaW5nbGVfaW50",
            "MzIYASABKAUSFAoMc2luZ2xlX2ludDY0GAIgASgDEhUKDXNpbmdsZV91aW50",
            "MzIYAyABKA0SFQoNc2luZ2xlX3VpbnQ2NBgEIAEoBBIVCg1zaW5nbGVfc2lu",
            "dDMyGAUgASgREhUKDXNpbmdsZV9zaW50NjQYBiABKBISFgoOc2luZ2xlX2Zp",
            "eGVkMzIYByABKAcSFgoOc2luZ2xlX2ZpeGVkNjQYCCABKAYSFwoPc2luZ2xl",
            "X3NmaXhlZDMyGAkgASgPEhcKD3NpbmdsZV9zZml4ZWQ2NBgKIAEoEBIUCgxz",
            "aW5nbGVfZmxvYXQYCyABKAISFQoNc2luZ2xlX2RvdWJsZRgMIAEoARITCgtz",
            "aW5nbGVfYm9vbBgNIAEoCBIVCg1zaW5nbGVfc3RyaW5nGA4gASgJEhQKDHNp",
            "bmdsZV9ieXRlcxgPIAEoDBJMChVzaW5nbGVfbmVzdGVkX21lc3NhZ2UYEiAB",
            "KAsyLS5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVz",
            "c2FnZRJBChZzaW5nbGVfZm9yZWlnbl9tZXNzYWdlGBMgASgLMiEucHJvdG9i",
            "dWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2USRgoVc2luZ2xlX2ltcG9ydF9t",
            "ZXNzYWdlGBQgASgLMicucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9y",
            "dE1lc3NhZ2USRgoSc2luZ2xlX25lc3RlZF9lbnVtGBUgASgOMioucHJvdG9i",
            "dWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0SOwoTc2luZ2xl",
            "X2ZvcmVpZ25fZW51bRgWIAEoDjIeLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVp",
            "Z25FbnVtEkAKEnNpbmdsZV9pbXBvcnRfZW51bRgXIAEoDjIkLnByb3RvYnVm",
            "X3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtElMKHHNpbmdsZV9wdWJsaWNf",
            "aW1wb3J0X21lc3NhZ2UYGiABKAsyLS5wcm90b2J1Zl91bml0dGVzdF9pbXBv",
            "cnQuUHVibGljSW1wb3J0TWVzc2FnZRIWCg5yZXBlYXRlZF9pbnQzMhgfIAMo",
            "BRIWCg5yZXBlYXRlZF9pbnQ2NBggIAMoAxIXCg9yZXBlYXRlZF91aW50MzIY",
            "ISADKA0SFwoPcmVwZWF0ZWRfdWludDY0GCIgAygEEhcKD3JlcGVhdGVkX3Np",
            "bnQzMhgjIAMoERIXCg9yZXBlYXRlZF9zaW50NjQYJCADKBISGAoQcmVwZWF0",
            "ZWRfZml4ZWQzMhglIAMoBxIYChByZXBlYXRlZF9maXhlZDY0GCYgAygGEhkK",
            "EXJlcGVhdGVkX3NmaXhlZDMyGCcgAygPEhkKEXJlcGVhdGVkX3NmaXhlZDY0",
            "GCggAygQEhYKDnJlcGVhdGVkX2Zsb2F0GCkgAygCEhcKD3JlcGVhdGVkX2Rv",
            "dWJsZRgqIAMoARIVCg1yZXBlYXRlZF9ib29sGCsgAygIEhcKD3JlcGVhdGVk",
            "X3N0cmluZxgsIAMoCRIWCg5yZXBlYXRlZF9ieXRlcxgtIAMoDBJOChdyZXBl",
            "YXRlZF9uZXN0ZWRfbWVzc2FnZRgwIAMoCzItLnByb3RvYnVmX3VuaXR0ZXN0",
            "LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlEkMKGHJlcGVhdGVkX2ZvcmVp",
            "Z25fbWVzc2FnZRgxIAMoCzIhLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25N",
            "ZXNzYWdlEkgKF3JlcGVhdGVkX2ltcG9ydF9tZXNzYWdlGDIgAygLMicucHJv",
            "dG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2USSAoUcmVwZWF0",
            "ZWRfbmVzdGVkX2VudW0YMyADKA4yKi5wcm90b2J1Zl91bml0dGVzdC5UZXN0",
            "QWxsVHlwZXMuTmVzdGVkRW51bRI9ChVyZXBlYXRlZF9mb3JlaWduX2VudW0Y",
            "NCADKA4yHi5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bRJCChRyZXBl",
            "YXRlZF9pbXBvcnRfZW51bRg1IAMoDjIkLnByb3RvYnVmX3VuaXR0ZXN0X2lt",
            "cG9ydC5JbXBvcnRFbnVtElUKHnJlcGVhdGVkX3B1YmxpY19pbXBvcnRfbWVz",
            "c2FnZRg2IAMoCzItLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5QdWJsaWNJ",
            "bXBvcnRNZXNzYWdlEhYKDG9uZW9mX3VpbnQzMhhvIAEoDUgAEk0KFG9uZW9m",
            "X25lc3RlZF9tZXNzYWdlGHAgASgLMi0ucHJvdG9idWZfdW5pdHRlc3QuVGVz",
            "dEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VIABIWCgxvbmVvZl9zdHJpbmcYcSAB",
            "KAlIABIVCgtvbmVvZl9ieXRlcxhyIAEoDEgAGhsKDU5lc3RlZE1lc3NhZ2US",
            "CgoCYmIYASABKAUiVgoKTmVzdGVkRW51bRIbChdORVNURURfRU5VTV9VTlNQ",
            "RUNJRklFRBAAEgcKA0ZPTxABEgcKA0JBUhACEgcKA0JBWhADEhAKA05FRxD/",
            "//////////8BQg0KC29uZW9mX2ZpZWxkIrsBChJOZXN0ZWRUZXN0QWxsVHlw",
            "ZXMSNAoFY2hpbGQYASABKAsyJS5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRU",
            "ZXN0QWxsVHlwZXMSMAoHcGF5bG9hZBgCIAEoCzIfLnByb3RvYnVmX3VuaXR0",
            "ZXN0LlRlc3RBbGxUeXBlcxI9Cg5yZXBlYXRlZF9jaGlsZBgDIAMoCzIlLnBy",
            "b3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyI0ChRUZXN0RGVw",
            "cmVjYXRlZEZpZWxkcxIcChBkZXByZWNhdGVkX2ludDMyGAEgASgFQgIYASIb",
            "Cg5Gb3JlaWduTWVzc2FnZRIJCgFjGAEgASgFIjAKElRlc3RSZXNlcnZlZEZp",
            "ZWxkc0oECAIQA0oECA8QEEoECAkQDFIDYmFyUgNiYXoiWgoRVGVzdEZvcmVp",
            "Z25OZXN0ZWQSRQoOZm9yZWlnbl9uZXN0ZWQYASABKAsyLS5wcm90b2J1Zl91",
            "bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSI0ChhUZXN0UmVh",
            "bGx5TGFyZ2VUYWdOdW1iZXISCQoBYRgBIAEoBRINCgJiYhj///9/IAEoBSJV",
            "ChRUZXN0UmVjdXJzaXZlTWVzc2FnZRIyCgFhGAEgASgLMicucHJvdG9idWZf",
            "dW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1lc3NhZ2USCQoBaRgCIAEoBSJLChRU",
            "ZXN0TXV0dWFsUmVjdXJzaW9uQRIzCgJiYhgBIAEoCzInLnByb3RvYnVmX3Vu",
            "aXR0ZXN0LlRlc3RNdXR1YWxSZWN1cnNpb25CImIKFFRlc3RNdXR1YWxSZWN1",
            "cnNpb25CEjIKAWEYASABKAsyJy5wcm90b2J1Zl91bml0dGVzdC5UZXN0TXV0",
            "dWFsUmVjdXJzaW9uQRIWCg5vcHRpb25hbF9pbnQzMhgCIAEoBSLrAgoXVGVz",
            "dENhbWVsQ2FzZUZpZWxkTmFtZXMSFgoOUHJpbWl0aXZlRmllbGQYASABKAUS",
            "EwoLU3RyaW5nRmllbGQYAiABKAkSMQoJRW51bUZpZWxkGAMgASgOMh4ucHJv",
            "dG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0SNwoMTWVzc2FnZUZpZWxkGAQg",
            "ASgLMiEucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2USHgoWUmVw",
            "ZWF0ZWRQcmltaXRpdmVGaWVsZBgHIAMoBRIbChNSZXBlYXRlZFN0cmluZ0Zp",
            "ZWxkGAggAygJEjkKEVJlcGVhdGVkRW51bUZpZWxkGAkgAygOMh4ucHJvdG9i",
            "dWZfdW5pdHRlc3QuRm9yZWlnbkVudW0SPwoUUmVwZWF0ZWRNZXNzYWdlRmll",
            "bGQYCiADKAsyIS5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSLH",
            "AQoSVGVzdEZpZWxkT3JkZXJpbmdzEhEKCW15X3N0cmluZxgLIAEoCRIOCgZt",
            "eV9pbnQYASABKAMSEAoIbXlfZmxvYXQYZSABKAISUwoVc2luZ2xlX25lc3Rl",
            "ZF9tZXNzYWdlGMgBIAEoCzIzLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RGaWVs",
            "ZE9yZGVyaW5ncy5OZXN0ZWRNZXNzYWdlGicKDU5lc3RlZE1lc3NhZ2USCgoC",
            "b28YAiABKAMSCgoCYmIYASABKAUiSwoRU3BhcnNlRW51bU1lc3NhZ2USNgoL",
            "c3BhcnNlX2VudW0YASABKA4yIS5wcm90b2J1Zl91bml0dGVzdC5UZXN0U3Bh",
            "cnNlRW51bSIZCglPbmVTdHJpbmcSDAoEZGF0YRgBIAEoCSIaCgpNb3JlU3Ry",
            "aW5nEgwKBGRhdGEYASADKAkiGAoIT25lQnl0ZXMSDAoEZGF0YRgBIAEoDCIZ",
            "CglNb3JlQnl0ZXMSDAoEZGF0YRgBIAEoDCIcCgxJbnQzMk1lc3NhZ2USDAoE",
            "ZGF0YRgBIAEoBSIdCg1VaW50MzJNZXNzYWdlEgwKBGRhdGEYASABKA0iHAoM",
            "SW50NjRNZXNzYWdlEgwKBGRhdGEYASABKAMiHQoNVWludDY0TWVzc2FnZRIM",
            "CgRkYXRhGAEgASgEIhsKC0Jvb2xNZXNzYWdlEgwKBGRhdGEYASABKAgicwoJ",
            "VGVzdE9uZW9mEhEKB2Zvb19pbnQYASABKAVIABIUCgpmb29fc3RyaW5nGAIg",
            "ASgJSAASNgoLZm9vX21lc3NhZ2UYAyABKAsyHy5wcm90b2J1Zl91bml0dGVz",
            "dC5UZXN0QWxsVHlwZXNIAEIFCgNmb28iqgMKD1Rlc3RQYWNrZWRUeXBlcxIY",
            "CgxwYWNrZWRfaW50MzIYWiADKAVCAhABEhgKDHBhY2tlZF9pbnQ2NBhbIAMo",
            "A0ICEAESGQoNcGFja2VkX3VpbnQzMhhcIAMoDUICEAESGQoNcGFja2VkX3Vp",
            "bnQ2NBhdIAMoBEICEAESGQoNcGFja2VkX3NpbnQzMhheIAMoEUICEAESGQoN",
            "cGFja2VkX3NpbnQ2NBhfIAMoEkICEAESGgoOcGFja2VkX2ZpeGVkMzIYYCAD",
            "KAdCAhABEhoKDnBhY2tlZF9maXhlZDY0GGEgAygGQgIQARIbCg9wYWNrZWRf",
            "c2ZpeGVkMzIYYiADKA9CAhABEhsKD3BhY2tlZF9zZml4ZWQ2NBhjIAMoEEIC",
            "EAESGAoMcGFja2VkX2Zsb2F0GGQgAygCQgIQARIZCg1wYWNrZWRfZG91Ymxl",
            "GGUgAygBQgIQARIXCgtwYWNrZWRfYm9vbBhmIAMoCEICEAESNwoLcGFja2Vk",
            "X2VudW0YZyADKA4yHi5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bUIC",
            "EAEiyAMKEVRlc3RVbnBhY2tlZFR5cGVzEhoKDnVucGFja2VkX2ludDMyGFog",
            "AygFQgIQABIaCg51bnBhY2tlZF9pbnQ2NBhbIAMoA0ICEAASGwoPdW5wYWNr",
            "ZWRfdWludDMyGFwgAygNQgIQABIbCg91bnBhY2tlZF91aW50NjQYXSADKARC",
            "AhAAEhsKD3VucGFja2VkX3NpbnQzMhheIAMoEUICEAASGwoPdW5wYWNrZWRf",
            "c2ludDY0GF8gAygSQgIQABIcChB1bnBhY2tlZF9maXhlZDMyGGAgAygHQgIQ",
            "ABIcChB1bnBhY2tlZF9maXhlZDY0GGEgAygGQgIQABIdChF1bnBhY2tlZF9z",
            "Zml4ZWQzMhhiIAMoD0ICEAASHQoRdW5wYWNrZWRfc2ZpeGVkNjQYYyADKBBC",
            "AhAAEhoKDnVucGFja2VkX2Zsb2F0GGQgAygCQgIQABIbCg91bnBhY2tlZF9k",
            "b3VibGUYZSADKAFCAhAAEhkKDXVucGFja2VkX2Jvb2wYZiADKAhCAhAAEjkK",
            "DXVucGFja2VkX2VudW0YZyADKA4yHi5wcm90b2J1Zl91bml0dGVzdC5Gb3Jl",
            "aWduRW51bUICEAAiwAEKI1Rlc3RSZXBlYXRlZFNjYWxhckRpZmZlcmVudFRh",
            "Z1NpemVzEhgKEHJlcGVhdGVkX2ZpeGVkMzIYDCADKAcSFgoOcmVwZWF0ZWRf",
            "aW50MzIYDSADKAUSGQoQcmVwZWF0ZWRfZml4ZWQ2NBj+DyADKAYSFwoOcmVw",
            "ZWF0ZWRfaW50NjQY/w8gAygDEhgKDnJlcGVhdGVkX2Zsb2F0GP7/DyADKAIS",
            "GQoPcmVwZWF0ZWRfdWludDY0GP//DyADKAQiKAobVGVzdENvbW1lbnRJbmpl",
            "Y3Rpb25NZXNzYWdlEgkKAWEYASABKAkiDAoKRm9vUmVxdWVzdCINCgtGb29S",
            "ZXNwb25zZSISChBGb29DbGllbnRNZXNzYWdlIhIKEEZvb1NlcnZlck1lc3Nh",
            "Z2UiDAoKQmFyUmVxdWVzdCINCgtCYXJSZXNwb25zZSpZCgtGb3JlaWduRW51",
            "bRIXChNGT1JFSUdOX1VOU1BFQ0lGSUVEEAASDwoLRk9SRUlHTl9GT08QBBIP",
            "CgtGT1JFSUdOX0JBUhAFEg8KC0ZPUkVJR05fQkFaEAYqdQoUVGVzdEVudW1X",
            "aXRoRHVwVmFsdWUSKAokVEVTVF9FTlVNX1dJVEhfRFVQX1ZBTFVFX1VOU1BF",
            "Q0lGSUVEEAASCAoERk9PMRABEggKBEJBUjEQAhIHCgNCQVoQAxIICgRGT08y",
            "EAESCAoEQkFSMhACGgIQASqdAQoOVGVzdFNwYXJzZUVudW0SIAocVEVTVF9T",
            "UEFSU0VfRU5VTV9VTlNQRUNJRklFRBAAEgwKCFNQQVJTRV9BEHsSDgoIU1BB",
            "UlNFX0IQpucDEg8KCFNQQVJTRV9DELKxgAYSFQoIU1BBUlNFX0QQ8f//////",
            "////ARIVCghTUEFSU0VfRRC03vz///////8BEgwKCFNQQVJTRV9HEAIymQEK",
            "C1Rlc3RTZXJ2aWNlEkQKA0ZvbxIdLnByb3RvYnVmX3VuaXR0ZXN0LkZvb1Jl",
            "cXVlc3QaHi5wcm90b2J1Zl91bml0dGVzdC5Gb29SZXNwb25zZRJECgNCYXIS",
            "HS5wcm90b2J1Zl91bml0dGVzdC5CYXJSZXF1ZXN0Gh4ucHJvdG9idWZfdW5p",
            "dHRlc3QuQmFyUmVzcG9uc2VCOkINVW5pdHRlc3RQcm90b0gBgAEBiAEBkAEB",
            "+AEBqgIaR29vZ2xlLlByb3RvYnVmLlRlc3RQcm90b3NiBnByb3RvMw=="));
      descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
          new pbr::FileDescriptor[] { global::Google.Protobuf.TestProtos.UnittestImportProto3.Descriptor, },
          new pbr::GeneratedCodeInfo(new[] {typeof(global::Google.Protobuf.TestProtos.ForeignEnum), typeof(global::Google.Protobuf.TestProtos.TestEnumWithDupValue), typeof(global::Google.Protobuf.TestProtos.TestSparseEnum), }, new pbr::GeneratedCodeInfo[] {
            new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestAllTypes), new[]{ "SingleInt32", "SingleInt64", "SingleUint32", "SingleUint64", "SingleSint32", "SingleSint64", "SingleFixed32", "SingleFixed64", "SingleSfixed32", "SingleSfixed64", "SingleFloat", "SingleDouble", "SingleBool", "SingleString", "SingleBytes", "SingleNestedMessage", "SingleForeignMessage", "SingleImportMessage", "SingleNestedEnum", "SingleForeignEnum", "SingleImportEnum", "SinglePublicImportMessage", "RepeatedInt32", "RepeatedInt64", "RepeatedUint32", "RepeatedUint64", "RepeatedSint32", "RepeatedSint64", "RepeatedFixed32", "RepeatedFixed64", "RepeatedSfixed32", "RepeatedSfixed64", "RepeatedFloat", "RepeatedDouble", "RepeatedBool", "RepeatedString", "RepeatedBytes", "RepeatedNestedMessage", "RepeatedForeignMessage", "RepeatedImportMessage", "RepeatedNestedEnum", "RepeatedForeignEnum", "RepeatedImportEnum", "RepeatedPublicImportMessage", "OneofUint32", "OneofNestedMessage", "OneofString", "OneofBytes" }, new[]{ "OneofField" }, new[]{ typeof(global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum) }, new pbr::GeneratedCodeInfo[] { new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage), new[]{ "Bb" }, null, null, null)}),
            new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.NestedTestAllTypes), new[]{ "Child", "Payload", "RepeatedChild" }, null, null, null),
            new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestDeprecatedFields), new[]{ "DeprecatedInt32" }, null, null, null),
            new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.ForeignMessage), new[]{ "C" }, null, null, null),
            new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestReservedFields), null, null, null, null),
            new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestForeignNested), new[]{ "ForeignNested" }, null, null, null),
            new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestReallyLargeTagNumber), new[]{ "A", "Bb" }, null, null, null),
            new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestRecursiveMessage), new[]{ "A", "I" }, null, null, null),
            new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestMutualRecursionA), new[]{ "Bb" }, null, null, null),
            new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestMutualRecursionB), new[]{ "A", "OptionalInt32" }, null, null, null),
            new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestCamelCaseFieldNames), new[]{ "PrimitiveField", "StringField", "EnumField", "MessageField", "RepeatedPrimitiveField", "RepeatedStringField", "RepeatedEnumField", "RepeatedMessageField" }, null, null, null),
            new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestFieldOrderings), new[]{ "MyString", "MyInt", "MyFloat", "SingleNestedMessage" }, null, null, new pbr::GeneratedCodeInfo[] { new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestFieldOrderings.Types.NestedMessage), new[]{ "Oo", "Bb" }, null, null, null)}),
            new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.SparseEnumMessage), new[]{ "SparseEnum" }, null, null, null),
            new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.OneString), new[]{ "Data" }, null, null, null),
            new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.MoreString), new[]{ "Data" }, null, null, null),
            new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.OneBytes), new[]{ "Data" }, null, null, null),
            new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.MoreBytes), new[]{ "Data" }, null, null, null),
            new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.Int32Message), new[]{ "Data" }, null, null, null),
            new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.Uint32Message), new[]{ "Data" }, null, null, null),
            new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.Int64Message), new[]{ "Data" }, null, null, null),
            new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.Uint64Message), new[]{ "Data" }, null, null, null),
            new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.BoolMessage), new[]{ "Data" }, null, null, null),
            new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestOneof), new[]{ "FooInt", "FooString", "FooMessage" }, new[]{ "Foo" }, null, null),
            new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestPackedTypes), new[]{ "PackedInt32", "PackedInt64", "PackedUint32", "PackedUint64", "PackedSint32", "PackedSint64", "PackedFixed32", "PackedFixed64", "PackedSfixed32", "PackedSfixed64", "PackedFloat", "PackedDouble", "PackedBool", "PackedEnum" }, null, null, null),
            new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestUnpackedTypes), new[]{ "UnpackedInt32", "UnpackedInt64", "UnpackedUint32", "UnpackedUint64", "UnpackedSint32", "UnpackedSint64", "UnpackedFixed32", "UnpackedFixed64", "UnpackedSfixed32", "UnpackedSfixed64", "UnpackedFloat", "UnpackedDouble", "UnpackedBool", "UnpackedEnum" }, null, null, null),
            new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestRepeatedScalarDifferentTagSizes), new[]{ "RepeatedFixed32", "RepeatedInt32", "RepeatedFixed64", "RepeatedInt64", "RepeatedFloat", "RepeatedUint64" }, null, null, null),
            new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestCommentInjectionMessage), new[]{ "A" }, null, null, null),
            new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.FooRequest), null, null, null, null),
            new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.FooResponse), null, null, null, null),
            new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.FooClientMessage), null, null, null, null),
            new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.FooServerMessage), null, null, null, null),
            new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.BarRequest), null, null, null, null),
            new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.BarResponse), null, null, null, null)
          }));
    }
    #endregion

  }
  #region Enums
  public enum ForeignEnum {
    FOREIGN_UNSPECIFIED = 0,
    FOREIGN_FOO = 4,
    FOREIGN_BAR = 5,
    FOREIGN_BAZ = 6,
  }

  /// <summary>
  ///  Test an enum that has multiple values with the same number.
  /// </summary>
  public enum TestEnumWithDupValue {
    TEST_ENUM_WITH_DUP_VALUE_UNSPECIFIED = 0,
    FOO1 = 1,
    BAR1 = 2,
    BAZ = 3,
    FOO2 = 1,
    BAR2 = 2,
  }

  /// <summary>
  ///  Test an enum with large, unordered values.
  /// </summary>
  public enum TestSparseEnum {
    TEST_SPARSE_ENUM_UNSPECIFIED = 0,
    SPARSE_A = 123,
    SPARSE_B = 62374,
    SPARSE_C = 12589234,
    SPARSE_D = -15,
    SPARSE_E = -53452,
    /// <summary>
    ///  In proto3, value 0 must be the first one specified
    ///  SPARSE_F = 0;
    /// </summary>
    SPARSE_G = 2,
  }

  #endregion

  #region Messages
  /// <summary>
  ///  This proto includes every type of field in both singular and repeated
  ///  forms.
  /// </summary>
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestAllTypes : pb::IMessage<TestAllTypes> {
    private static readonly pb::MessageParser<TestAllTypes> _parser = new pb::MessageParser<TestAllTypes>(() => new TestAllTypes());
    public static pb::MessageParser<TestAllTypes> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[0]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public TestAllTypes() {
      OnConstruction();
    }

    partial void OnConstruction();

    public TestAllTypes(TestAllTypes other) : this() {
      singleInt32_ = other.singleInt32_;
      singleInt64_ = other.singleInt64_;
      singleUint32_ = other.singleUint32_;
      singleUint64_ = other.singleUint64_;
      singleSint32_ = other.singleSint32_;
      singleSint64_ = other.singleSint64_;
      singleFixed32_ = other.singleFixed32_;
      singleFixed64_ = other.singleFixed64_;
      singleSfixed32_ = other.singleSfixed32_;
      singleSfixed64_ = other.singleSfixed64_;
      singleFloat_ = other.singleFloat_;
      singleDouble_ = other.singleDouble_;
      singleBool_ = other.singleBool_;
      singleString_ = other.singleString_;
      singleBytes_ = other.singleBytes_;
      SingleNestedMessage = other.singleNestedMessage_ != null ? other.SingleNestedMessage.Clone() : null;
      SingleForeignMessage = other.singleForeignMessage_ != null ? other.SingleForeignMessage.Clone() : null;
      SingleImportMessage = other.singleImportMessage_ != null ? other.SingleImportMessage.Clone() : null;
      singleNestedEnum_ = other.singleNestedEnum_;
      singleForeignEnum_ = other.singleForeignEnum_;
      singleImportEnum_ = other.singleImportEnum_;
      SinglePublicImportMessage = other.singlePublicImportMessage_ != null ? other.SinglePublicImportMessage.Clone() : null;
      repeatedInt32_ = other.repeatedInt32_.Clone();
      repeatedInt64_ = other.repeatedInt64_.Clone();
      repeatedUint32_ = other.repeatedUint32_.Clone();
      repeatedUint64_ = other.repeatedUint64_.Clone();
      repeatedSint32_ = other.repeatedSint32_.Clone();
      repeatedSint64_ = other.repeatedSint64_.Clone();
      repeatedFixed32_ = other.repeatedFixed32_.Clone();
      repeatedFixed64_ = other.repeatedFixed64_.Clone();
      repeatedSfixed32_ = other.repeatedSfixed32_.Clone();
      repeatedSfixed64_ = other.repeatedSfixed64_.Clone();
      repeatedFloat_ = other.repeatedFloat_.Clone();
      repeatedDouble_ = other.repeatedDouble_.Clone();
      repeatedBool_ = other.repeatedBool_.Clone();
      repeatedString_ = other.repeatedString_.Clone();
      repeatedBytes_ = other.repeatedBytes_.Clone();
      repeatedNestedMessage_ = other.repeatedNestedMessage_.Clone();
      repeatedForeignMessage_ = other.repeatedForeignMessage_.Clone();
      repeatedImportMessage_ = other.repeatedImportMessage_.Clone();
      repeatedNestedEnum_ = other.repeatedNestedEnum_.Clone();
      repeatedForeignEnum_ = other.repeatedForeignEnum_.Clone();
      repeatedImportEnum_ = other.repeatedImportEnum_.Clone();
      repeatedPublicImportMessage_ = other.repeatedPublicImportMessage_.Clone();
      switch (other.OneofFieldCase) {
        case OneofFieldOneofCase.OneofUint32:
          OneofUint32 = other.OneofUint32;
          break;
        case OneofFieldOneofCase.OneofNestedMessage:
          OneofNestedMessage = other.OneofNestedMessage.Clone();
          break;
        case OneofFieldOneofCase.OneofString:
          OneofString = other.OneofString;
          break;
        case OneofFieldOneofCase.OneofBytes:
          OneofBytes = other.OneofBytes;
          break;
      }

    }

    public TestAllTypes Clone() {
      return new TestAllTypes(this);
    }

    /// <summary>Field number for the "single_int32" field.</summary>
    public const int SingleInt32FieldNumber = 1;
    private int singleInt32_;
    /// <summary>
    ///  Singular
    /// </summary>
    public int SingleInt32 {
      get { return singleInt32_; }
      set {
        singleInt32_ = value;
      }
    }

    /// <summary>Field number for the "single_int64" field.</summary>
    public const int SingleInt64FieldNumber = 2;
    private long singleInt64_;
    public long SingleInt64 {
      get { return singleInt64_; }
      set {
        singleInt64_ = value;
      }
    }

    /// <summary>Field number for the "single_uint32" field.</summary>
    public const int SingleUint32FieldNumber = 3;
    private uint singleUint32_;
    public uint SingleUint32 {
      get { return singleUint32_; }
      set {
        singleUint32_ = value;
      }
    }

    /// <summary>Field number for the "single_uint64" field.</summary>
    public const int SingleUint64FieldNumber = 4;
    private ulong singleUint64_;
    public ulong SingleUint64 {
      get { return singleUint64_; }
      set {
        singleUint64_ = value;
      }
    }

    /// <summary>Field number for the "single_sint32" field.</summary>
    public const int SingleSint32FieldNumber = 5;
    private int singleSint32_;
    public int SingleSint32 {
      get { return singleSint32_; }
      set {
        singleSint32_ = value;
      }
    }

    /// <summary>Field number for the "single_sint64" field.</summary>
    public const int SingleSint64FieldNumber = 6;
    private long singleSint64_;
    public long SingleSint64 {
      get { return singleSint64_; }
      set {
        singleSint64_ = value;
      }
    }

    /// <summary>Field number for the "single_fixed32" field.</summary>
    public const int SingleFixed32FieldNumber = 7;
    private uint singleFixed32_;
    public uint SingleFixed32 {
      get { return singleFixed32_; }
      set {
        singleFixed32_ = value;
      }
    }

    /// <summary>Field number for the "single_fixed64" field.</summary>
    public const int SingleFixed64FieldNumber = 8;
    private ulong singleFixed64_;
    public ulong SingleFixed64 {
      get { return singleFixed64_; }
      set {
        singleFixed64_ = value;
      }
    }

    /// <summary>Field number for the "single_sfixed32" field.</summary>
    public const int SingleSfixed32FieldNumber = 9;
    private int singleSfixed32_;
    public int SingleSfixed32 {
      get { return singleSfixed32_; }
      set {
        singleSfixed32_ = value;
      }
    }

    /// <summary>Field number for the "single_sfixed64" field.</summary>
    public const int SingleSfixed64FieldNumber = 10;
    private long singleSfixed64_;
    public long SingleSfixed64 {
      get { return singleSfixed64_; }
      set {
        singleSfixed64_ = value;
      }
    }

    /// <summary>Field number for the "single_float" field.</summary>
    public const int SingleFloatFieldNumber = 11;
    private float singleFloat_;
    public float SingleFloat {
      get { return singleFloat_; }
      set {
        singleFloat_ = value;
      }
    }

    /// <summary>Field number for the "single_double" field.</summary>
    public const int SingleDoubleFieldNumber = 12;
    private double singleDouble_;
    public double SingleDouble {
      get { return singleDouble_; }
      set {
        singleDouble_ = value;
      }
    }

    /// <summary>Field number for the "single_bool" field.</summary>
    public const int SingleBoolFieldNumber = 13;
    private bool singleBool_;
    public bool SingleBool {
      get { return singleBool_; }
      set {
        singleBool_ = value;
      }
    }

    /// <summary>Field number for the "single_string" field.</summary>
    public const int SingleStringFieldNumber = 14;
    private string singleString_ = "";
    public string SingleString {
      get { return singleString_; }
      set {
        singleString_ = pb::Preconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "single_bytes" field.</summary>
    public const int SingleBytesFieldNumber = 15;
    private pb::ByteString singleBytes_ = pb::ByteString.Empty;
    public pb::ByteString SingleBytes {
      get { return singleBytes_; }
      set {
        singleBytes_ = pb::Preconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "single_nested_message" field.</summary>
    public const int SingleNestedMessageFieldNumber = 18;
    private global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage singleNestedMessage_;
    public global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage SingleNestedMessage {
      get { return singleNestedMessage_; }
      set {
        singleNestedMessage_ = value;
      }
    }

    /// <summary>Field number for the "single_foreign_message" field.</summary>
    public const int SingleForeignMessageFieldNumber = 19;
    private global::Google.Protobuf.TestProtos.ForeignMessage singleForeignMessage_;
    public global::Google.Protobuf.TestProtos.ForeignMessage SingleForeignMessage {
      get { return singleForeignMessage_; }
      set {
        singleForeignMessage_ = value;
      }
    }

    /// <summary>Field number for the "single_import_message" field.</summary>
    public const int SingleImportMessageFieldNumber = 20;
    private global::Google.Protobuf.TestProtos.ImportMessage singleImportMessage_;
    public global::Google.Protobuf.TestProtos.ImportMessage SingleImportMessage {
      get { return singleImportMessage_; }
      set {
        singleImportMessage_ = value;
      }
    }

    /// <summary>Field number for the "single_nested_enum" field.</summary>
    public const int SingleNestedEnumFieldNumber = 21;
    private global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum singleNestedEnum_ = global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum.NESTED_ENUM_UNSPECIFIED;
    public global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum SingleNestedEnum {
      get { return singleNestedEnum_; }
      set {
        singleNestedEnum_ = value;
      }
    }

    /// <summary>Field number for the "single_foreign_enum" field.</summary>
    public const int SingleForeignEnumFieldNumber = 22;
    private global::Google.Protobuf.TestProtos.ForeignEnum singleForeignEnum_ = global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED;
    public global::Google.Protobuf.TestProtos.ForeignEnum SingleForeignEnum {
      get { return singleForeignEnum_; }
      set {
        singleForeignEnum_ = value;
      }
    }

    /// <summary>Field number for the "single_import_enum" field.</summary>
    public const int SingleImportEnumFieldNumber = 23;
    private global::Google.Protobuf.TestProtos.ImportEnum singleImportEnum_ = global::Google.Protobuf.TestProtos.ImportEnum.IMPORT_ENUM_UNSPECIFIED;
    public global::Google.Protobuf.TestProtos.ImportEnum SingleImportEnum {
      get { return singleImportEnum_; }
      set {
        singleImportEnum_ = value;
      }
    }

    /// <summary>Field number for the "single_public_import_message" field.</summary>
    public const int SinglePublicImportMessageFieldNumber = 26;
    private global::Google.Protobuf.TestProtos.PublicImportMessage singlePublicImportMessage_;
    /// <summary>
    ///  Defined in unittest_import_public.proto
    /// </summary>
    public global::Google.Protobuf.TestProtos.PublicImportMessage SinglePublicImportMessage {
      get { return singlePublicImportMessage_; }
      set {
        singlePublicImportMessage_ = value;
      }
    }

    /// <summary>Field number for the "repeated_int32" field.</summary>
    public const int RepeatedInt32FieldNumber = 31;
    private static readonly pb::FieldCodec<int> _repeated_repeatedInt32_codec
        = pb::FieldCodec.ForInt32(250);
    private readonly pbc::RepeatedField<int> repeatedInt32_ = new pbc::RepeatedField<int>();
    /// <summary>
    ///  Repeated
    /// </summary>
    public pbc::RepeatedField<int> RepeatedInt32 {
      get { return repeatedInt32_; }
    }

    /// <summary>Field number for the "repeated_int64" field.</summary>
    public const int RepeatedInt64FieldNumber = 32;
    private static readonly pb::FieldCodec<long> _repeated_repeatedInt64_codec
        = pb::FieldCodec.ForInt64(258);
    private readonly pbc::RepeatedField<long> repeatedInt64_ = new pbc::RepeatedField<long>();
    public pbc::RepeatedField<long> RepeatedInt64 {
      get { return repeatedInt64_; }
    }

    /// <summary>Field number for the "repeated_uint32" field.</summary>
    public const int RepeatedUint32FieldNumber = 33;
    private static readonly pb::FieldCodec<uint> _repeated_repeatedUint32_codec
        = pb::FieldCodec.ForUInt32(266);
    private readonly pbc::RepeatedField<uint> repeatedUint32_ = new pbc::RepeatedField<uint>();
    public pbc::RepeatedField<uint> RepeatedUint32 {
      get { return repeatedUint32_; }
    }

    /// <summary>Field number for the "repeated_uint64" field.</summary>
    public const int RepeatedUint64FieldNumber = 34;
    private static readonly pb::FieldCodec<ulong> _repeated_repeatedUint64_codec
        = pb::FieldCodec.ForUInt64(274);
    private readonly pbc::RepeatedField<ulong> repeatedUint64_ = new pbc::RepeatedField<ulong>();
    public pbc::RepeatedField<ulong> RepeatedUint64 {
      get { return repeatedUint64_; }
    }

    /// <summary>Field number for the "repeated_sint32" field.</summary>
    public const int RepeatedSint32FieldNumber = 35;
    private static readonly pb::FieldCodec<int> _repeated_repeatedSint32_codec
        = pb::FieldCodec.ForSInt32(282);
    private readonly pbc::RepeatedField<int> repeatedSint32_ = new pbc::RepeatedField<int>();
    public pbc::RepeatedField<int> RepeatedSint32 {
      get { return repeatedSint32_; }
    }

    /// <summary>Field number for the "repeated_sint64" field.</summary>
    public const int RepeatedSint64FieldNumber = 36;
    private static readonly pb::FieldCodec<long> _repeated_repeatedSint64_codec
        = pb::FieldCodec.ForSInt64(290);
    private readonly pbc::RepeatedField<long> repeatedSint64_ = new pbc::RepeatedField<long>();
    public pbc::RepeatedField<long> RepeatedSint64 {
      get { return repeatedSint64_; }
    }

    /// <summary>Field number for the "repeated_fixed32" field.</summary>
    public const int RepeatedFixed32FieldNumber = 37;
    private static readonly pb::FieldCodec<uint> _repeated_repeatedFixed32_codec
        = pb::FieldCodec.ForFixed32(298);
    private readonly pbc::RepeatedField<uint> repeatedFixed32_ = new pbc::RepeatedField<uint>();
    public pbc::RepeatedField<uint> RepeatedFixed32 {
      get { return repeatedFixed32_; }
    }

    /// <summary>Field number for the "repeated_fixed64" field.</summary>
    public const int RepeatedFixed64FieldNumber = 38;
    private static readonly pb::FieldCodec<ulong> _repeated_repeatedFixed64_codec
        = pb::FieldCodec.ForFixed64(306);
    private readonly pbc::RepeatedField<ulong> repeatedFixed64_ = new pbc::RepeatedField<ulong>();
    public pbc::RepeatedField<ulong> RepeatedFixed64 {
      get { return repeatedFixed64_; }
    }

    /// <summary>Field number for the "repeated_sfixed32" field.</summary>
    public const int RepeatedSfixed32FieldNumber = 39;
    private static readonly pb::FieldCodec<int> _repeated_repeatedSfixed32_codec
        = pb::FieldCodec.ForSFixed32(314);
    private readonly pbc::RepeatedField<int> repeatedSfixed32_ = new pbc::RepeatedField<int>();
    public pbc::RepeatedField<int> RepeatedSfixed32 {
      get { return repeatedSfixed32_; }
    }

    /// <summary>Field number for the "repeated_sfixed64" field.</summary>
    public const int RepeatedSfixed64FieldNumber = 40;
    private static readonly pb::FieldCodec<long> _repeated_repeatedSfixed64_codec
        = pb::FieldCodec.ForSFixed64(322);
    private readonly pbc::RepeatedField<long> repeatedSfixed64_ = new pbc::RepeatedField<long>();
    public pbc::RepeatedField<long> RepeatedSfixed64 {
      get { return repeatedSfixed64_; }
    }

    /// <summary>Field number for the "repeated_float" field.</summary>
    public const int RepeatedFloatFieldNumber = 41;
    private static readonly pb::FieldCodec<float> _repeated_repeatedFloat_codec
        = pb::FieldCodec.ForFloat(330);
    private readonly pbc::RepeatedField<float> repeatedFloat_ = new pbc::RepeatedField<float>();
    public pbc::RepeatedField<float> RepeatedFloat {
      get { return repeatedFloat_; }
    }

    /// <summary>Field number for the "repeated_double" field.</summary>
    public const int RepeatedDoubleFieldNumber = 42;
    private static readonly pb::FieldCodec<double> _repeated_repeatedDouble_codec
        = pb::FieldCodec.ForDouble(338);
    private readonly pbc::RepeatedField<double> repeatedDouble_ = new pbc::RepeatedField<double>();
    public pbc::RepeatedField<double> RepeatedDouble {
      get { return repeatedDouble_; }
    }

    /// <summary>Field number for the "repeated_bool" field.</summary>
    public const int RepeatedBoolFieldNumber = 43;
    private static readonly pb::FieldCodec<bool> _repeated_repeatedBool_codec
        = pb::FieldCodec.ForBool(346);
    private readonly pbc::RepeatedField<bool> repeatedBool_ = new pbc::RepeatedField<bool>();
    public pbc::RepeatedField<bool> RepeatedBool {
      get { return repeatedBool_; }
    }

    /// <summary>Field number for the "repeated_string" field.</summary>
    public const int RepeatedStringFieldNumber = 44;
    private static readonly pb::FieldCodec<string> _repeated_repeatedString_codec
        = pb::FieldCodec.ForString(354);
    private readonly pbc::RepeatedField<string> repeatedString_ = new pbc::RepeatedField<string>();
    public pbc::RepeatedField<string> RepeatedString {
      get { return repeatedString_; }
    }

    /// <summary>Field number for the "repeated_bytes" field.</summary>
    public const int RepeatedBytesFieldNumber = 45;
    private static readonly pb::FieldCodec<pb::ByteString> _repeated_repeatedBytes_codec
        = pb::FieldCodec.ForBytes(362);
    private readonly pbc::RepeatedField<pb::ByteString> repeatedBytes_ = new pbc::RepeatedField<pb::ByteString>();
    public pbc::RepeatedField<pb::ByteString> RepeatedBytes {
      get { return repeatedBytes_; }
    }

    /// <summary>Field number for the "repeated_nested_message" field.</summary>
    public const int RepeatedNestedMessageFieldNumber = 48;
    private static readonly pb::FieldCodec<global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage> _repeated_repeatedNestedMessage_codec
        = pb::FieldCodec.ForMessage(386, global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage> repeatedNestedMessage_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage>();
    public pbc::RepeatedField<global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage> RepeatedNestedMessage {
      get { return repeatedNestedMessage_; }
    }

    /// <summary>Field number for the "repeated_foreign_message" field.</summary>
    public const int RepeatedForeignMessageFieldNumber = 49;
    private static readonly pb::FieldCodec<global::Google.Protobuf.TestProtos.ForeignMessage> _repeated_repeatedForeignMessage_codec
        = pb::FieldCodec.ForMessage(394, global::Google.Protobuf.TestProtos.ForeignMessage.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignMessage> repeatedForeignMessage_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignMessage>();
    public pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignMessage> RepeatedForeignMessage {
      get { return repeatedForeignMessage_; }
    }

    /// <summary>Field number for the "repeated_import_message" field.</summary>
    public const int RepeatedImportMessageFieldNumber = 50;
    private static readonly pb::FieldCodec<global::Google.Protobuf.TestProtos.ImportMessage> _repeated_repeatedImportMessage_codec
        = pb::FieldCodec.ForMessage(402, global::Google.Protobuf.TestProtos.ImportMessage.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.ImportMessage> repeatedImportMessage_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.ImportMessage>();
    public pbc::RepeatedField<global::Google.Protobuf.TestProtos.ImportMessage> RepeatedImportMessage {
      get { return repeatedImportMessage_; }
    }

    /// <summary>Field number for the "repeated_nested_enum" field.</summary>
    public const int RepeatedNestedEnumFieldNumber = 51;
    private static readonly pb::FieldCodec<global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum> _repeated_repeatedNestedEnum_codec
        = pb::FieldCodec.ForEnum(410, x => (int) x, x => (global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum) x);
    private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum> repeatedNestedEnum_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum>();
    public pbc::RepeatedField<global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum> RepeatedNestedEnum {
      get { return repeatedNestedEnum_; }
    }

    /// <summary>Field number for the "repeated_foreign_enum" field.</summary>
    public const int RepeatedForeignEnumFieldNumber = 52;
    private static readonly pb::FieldCodec<global::Google.Protobuf.TestProtos.ForeignEnum> _repeated_repeatedForeignEnum_codec
        = pb::FieldCodec.ForEnum(418, x => (int) x, x => (global::Google.Protobuf.TestProtos.ForeignEnum) x);
    private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum> repeatedForeignEnum_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum>();
    public pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum> RepeatedForeignEnum {
      get { return repeatedForeignEnum_; }
    }

    /// <summary>Field number for the "repeated_import_enum" field.</summary>
    public const int RepeatedImportEnumFieldNumber = 53;
    private static readonly pb::FieldCodec<global::Google.Protobuf.TestProtos.ImportEnum> _repeated_repeatedImportEnum_codec
        = pb::FieldCodec.ForEnum(426, x => (int) x, x => (global::Google.Protobuf.TestProtos.ImportEnum) x);
    private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.ImportEnum> repeatedImportEnum_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.ImportEnum>();
    public pbc::RepeatedField<global::Google.Protobuf.TestProtos.ImportEnum> RepeatedImportEnum {
      get { return repeatedImportEnum_; }
    }

    /// <summary>Field number for the "repeated_public_import_message" field.</summary>
    public const int RepeatedPublicImportMessageFieldNumber = 54;
    private static readonly pb::FieldCodec<global::Google.Protobuf.TestProtos.PublicImportMessage> _repeated_repeatedPublicImportMessage_codec
        = pb::FieldCodec.ForMessage(434, global::Google.Protobuf.TestProtos.PublicImportMessage.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.PublicImportMessage> repeatedPublicImportMessage_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.PublicImportMessage>();
    /// <summary>
    ///  Defined in unittest_import_public.proto
    /// </summary>
    public pbc::RepeatedField<global::Google.Protobuf.TestProtos.PublicImportMessage> RepeatedPublicImportMessage {
      get { return repeatedPublicImportMessage_; }
    }

    /// <summary>Field number for the "oneof_uint32" field.</summary>
    public const int OneofUint32FieldNumber = 111;
    public uint OneofUint32 {
      get { return oneofFieldCase_ == OneofFieldOneofCase.OneofUint32 ? (uint) oneofField_ : 0; }
      set {
        oneofField_ = value;
        oneofFieldCase_ = OneofFieldOneofCase.OneofUint32;
      }
    }

    /// <summary>Field number for the "oneof_nested_message" field.</summary>
    public const int OneofNestedMessageFieldNumber = 112;
    public global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage OneofNestedMessage {
      get { return oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage ? (global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage) oneofField_ : null; }
      set {
        oneofField_ = value;
        oneofFieldCase_ = value == null ? OneofFieldOneofCase.None : OneofFieldOneofCase.OneofNestedMessage;
      }
    }

    /// <summary>Field number for the "oneof_string" field.</summary>
    public const int OneofStringFieldNumber = 113;
    public string OneofString {
      get { return oneofFieldCase_ == OneofFieldOneofCase.OneofString ? (string) oneofField_ : ""; }
      set {
        oneofField_ = pb::Preconditions.CheckNotNull(value, "value");
        oneofFieldCase_ = OneofFieldOneofCase.OneofString;
      }
    }

    /// <summary>Field number for the "oneof_bytes" field.</summary>
    public const int OneofBytesFieldNumber = 114;
    public pb::ByteString OneofBytes {
      get { return oneofFieldCase_ == OneofFieldOneofCase.OneofBytes ? (pb::ByteString) oneofField_ : pb::ByteString.Empty; }
      set {
        oneofField_ = pb::Preconditions.CheckNotNull(value, "value");
        oneofFieldCase_ = OneofFieldOneofCase.OneofBytes;
      }
    }

    private object oneofField_;
    /// <summary>Enum of possible cases for the "oneof_field" oneof.</summary>
    public enum OneofFieldOneofCase {
      None = 0,
      OneofUint32 = 111,
      OneofNestedMessage = 112,
      OneofString = 113,
      OneofBytes = 114,
    }
    private OneofFieldOneofCase oneofFieldCase_ = OneofFieldOneofCase.None;
    public OneofFieldOneofCase OneofFieldCase {
      get { return oneofFieldCase_; }
    }

    public void ClearOneofField() {
      oneofFieldCase_ = OneofFieldOneofCase.None;
      oneofField_ = null;
    }

    public override bool Equals(object other) {
      return Equals(other as TestAllTypes);
    }

    public bool Equals(TestAllTypes other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (SingleInt32 != other.SingleInt32) return false;
      if (SingleInt64 != other.SingleInt64) return false;
      if (SingleUint32 != other.SingleUint32) return false;
      if (SingleUint64 != other.SingleUint64) return false;
      if (SingleSint32 != other.SingleSint32) return false;
      if (SingleSint64 != other.SingleSint64) return false;
      if (SingleFixed32 != other.SingleFixed32) return false;
      if (SingleFixed64 != other.SingleFixed64) return false;
      if (SingleSfixed32 != other.SingleSfixed32) return false;
      if (SingleSfixed64 != other.SingleSfixed64) return false;
      if (SingleFloat != other.SingleFloat) return false;
      if (SingleDouble != other.SingleDouble) return false;
      if (SingleBool != other.SingleBool) return false;
      if (SingleString != other.SingleString) return false;
      if (SingleBytes != other.SingleBytes) return false;
      if (!object.Equals(SingleNestedMessage, other.SingleNestedMessage)) return false;
      if (!object.Equals(SingleForeignMessage, other.SingleForeignMessage)) return false;
      if (!object.Equals(SingleImportMessage, other.SingleImportMessage)) return false;
      if (SingleNestedEnum != other.SingleNestedEnum) return false;
      if (SingleForeignEnum != other.SingleForeignEnum) return false;
      if (SingleImportEnum != other.SingleImportEnum) return false;
      if (!object.Equals(SinglePublicImportMessage, other.SinglePublicImportMessage)) return false;
      if(!repeatedInt32_.Equals(other.repeatedInt32_)) return false;
      if(!repeatedInt64_.Equals(other.repeatedInt64_)) return false;
      if(!repeatedUint32_.Equals(other.repeatedUint32_)) return false;
      if(!repeatedUint64_.Equals(other.repeatedUint64_)) return false;
      if(!repeatedSint32_.Equals(other.repeatedSint32_)) return false;
      if(!repeatedSint64_.Equals(other.repeatedSint64_)) return false;
      if(!repeatedFixed32_.Equals(other.repeatedFixed32_)) return false;
      if(!repeatedFixed64_.Equals(other.repeatedFixed64_)) return false;
      if(!repeatedSfixed32_.Equals(other.repeatedSfixed32_)) return false;
      if(!repeatedSfixed64_.Equals(other.repeatedSfixed64_)) return false;
      if(!repeatedFloat_.Equals(other.repeatedFloat_)) return false;
      if(!repeatedDouble_.Equals(other.repeatedDouble_)) return false;
      if(!repeatedBool_.Equals(other.repeatedBool_)) return false;
      if(!repeatedString_.Equals(other.repeatedString_)) return false;
      if(!repeatedBytes_.Equals(other.repeatedBytes_)) return false;
      if(!repeatedNestedMessage_.Equals(other.repeatedNestedMessage_)) return false;
      if(!repeatedForeignMessage_.Equals(other.repeatedForeignMessage_)) return false;
      if(!repeatedImportMessage_.Equals(other.repeatedImportMessage_)) return false;
      if(!repeatedNestedEnum_.Equals(other.repeatedNestedEnum_)) return false;
      if(!repeatedForeignEnum_.Equals(other.repeatedForeignEnum_)) return false;
      if(!repeatedImportEnum_.Equals(other.repeatedImportEnum_)) return false;
      if(!repeatedPublicImportMessage_.Equals(other.repeatedPublicImportMessage_)) return false;
      if (OneofUint32 != other.OneofUint32) return false;
      if (!object.Equals(OneofNestedMessage, other.OneofNestedMessage)) return false;
      if (OneofString != other.OneofString) return false;
      if (OneofBytes != other.OneofBytes) return false;
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      if (SingleInt32 != 0) hash ^= SingleInt32.GetHashCode();
      if (SingleInt64 != 0L) hash ^= SingleInt64.GetHashCode();
      if (SingleUint32 != 0) hash ^= SingleUint32.GetHashCode();
      if (SingleUint64 != 0UL) hash ^= SingleUint64.GetHashCode();
      if (SingleSint32 != 0) hash ^= SingleSint32.GetHashCode();
      if (SingleSint64 != 0L) hash ^= SingleSint64.GetHashCode();
      if (SingleFixed32 != 0) hash ^= SingleFixed32.GetHashCode();
      if (SingleFixed64 != 0UL) hash ^= SingleFixed64.GetHashCode();
      if (SingleSfixed32 != 0) hash ^= SingleSfixed32.GetHashCode();
      if (SingleSfixed64 != 0L) hash ^= SingleSfixed64.GetHashCode();
      if (SingleFloat != 0F) hash ^= SingleFloat.GetHashCode();
      if (SingleDouble != 0D) hash ^= SingleDouble.GetHashCode();
      if (SingleBool != false) hash ^= SingleBool.GetHashCode();
      if (SingleString.Length != 0) hash ^= SingleString.GetHashCode();
      if (SingleBytes.Length != 0) hash ^= SingleBytes.GetHashCode();
      if (singleNestedMessage_ != null) hash ^= SingleNestedMessage.GetHashCode();
      if (singleForeignMessage_ != null) hash ^= SingleForeignMessage.GetHashCode();
      if (singleImportMessage_ != null) hash ^= SingleImportMessage.GetHashCode();
      if (SingleNestedEnum != global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum.NESTED_ENUM_UNSPECIFIED) hash ^= SingleNestedEnum.GetHashCode();
      if (SingleForeignEnum != global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED) hash ^= SingleForeignEnum.GetHashCode();
      if (SingleImportEnum != global::Google.Protobuf.TestProtos.ImportEnum.IMPORT_ENUM_UNSPECIFIED) hash ^= SingleImportEnum.GetHashCode();
      if (singlePublicImportMessage_ != null) hash ^= SinglePublicImportMessage.GetHashCode();
      hash ^= repeatedInt32_.GetHashCode();
      hash ^= repeatedInt64_.GetHashCode();
      hash ^= repeatedUint32_.GetHashCode();
      hash ^= repeatedUint64_.GetHashCode();
      hash ^= repeatedSint32_.GetHashCode();
      hash ^= repeatedSint64_.GetHashCode();
      hash ^= repeatedFixed32_.GetHashCode();
      hash ^= repeatedFixed64_.GetHashCode();
      hash ^= repeatedSfixed32_.GetHashCode();
      hash ^= repeatedSfixed64_.GetHashCode();
      hash ^= repeatedFloat_.GetHashCode();
      hash ^= repeatedDouble_.GetHashCode();
      hash ^= repeatedBool_.GetHashCode();
      hash ^= repeatedString_.GetHashCode();
      hash ^= repeatedBytes_.GetHashCode();
      hash ^= repeatedNestedMessage_.GetHashCode();
      hash ^= repeatedForeignMessage_.GetHashCode();
      hash ^= repeatedImportMessage_.GetHashCode();
      hash ^= repeatedNestedEnum_.GetHashCode();
      hash ^= repeatedForeignEnum_.GetHashCode();
      hash ^= repeatedImportEnum_.GetHashCode();
      hash ^= repeatedPublicImportMessage_.GetHashCode();
      if (oneofFieldCase_ == OneofFieldOneofCase.OneofUint32) hash ^= OneofUint32.GetHashCode();
      if (oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage) hash ^= OneofNestedMessage.GetHashCode();
      if (oneofFieldCase_ == OneofFieldOneofCase.OneofString) hash ^= OneofString.GetHashCode();
      if (oneofFieldCase_ == OneofFieldOneofCase.OneofBytes) hash ^= OneofBytes.GetHashCode();
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
      if (SingleInt32 != 0) {
        output.WriteRawTag(8);
        output.WriteInt32(SingleInt32);
      }
      if (SingleInt64 != 0L) {
        output.WriteRawTag(16);
        output.WriteInt64(SingleInt64);
      }
      if (SingleUint32 != 0) {
        output.WriteRawTag(24);
        output.WriteUInt32(SingleUint32);
      }
      if (SingleUint64 != 0UL) {
        output.WriteRawTag(32);
        output.WriteUInt64(SingleUint64);
      }
      if (SingleSint32 != 0) {
        output.WriteRawTag(40);
        output.WriteSInt32(SingleSint32);
      }
      if (SingleSint64 != 0L) {
        output.WriteRawTag(48);
        output.WriteSInt64(SingleSint64);
      }
      if (SingleFixed32 != 0) {
        output.WriteRawTag(61);
        output.WriteFixed32(SingleFixed32);
      }
      if (SingleFixed64 != 0UL) {
        output.WriteRawTag(65);
        output.WriteFixed64(SingleFixed64);
      }
      if (SingleSfixed32 != 0) {
        output.WriteRawTag(77);
        output.WriteSFixed32(SingleSfixed32);
      }
      if (SingleSfixed64 != 0L) {
        output.WriteRawTag(81);
        output.WriteSFixed64(SingleSfixed64);
      }
      if (SingleFloat != 0F) {
        output.WriteRawTag(93);
        output.WriteFloat(SingleFloat);
      }
      if (SingleDouble != 0D) {
        output.WriteRawTag(97);
        output.WriteDouble(SingleDouble);
      }
      if (SingleBool != false) {
        output.WriteRawTag(104);
        output.WriteBool(SingleBool);
      }
      if (SingleString.Length != 0) {
        output.WriteRawTag(114);
        output.WriteString(SingleString);
      }
      if (SingleBytes.Length != 0) {
        output.WriteRawTag(122);
        output.WriteBytes(SingleBytes);
      }
      if (singleNestedMessage_ != null) {
        output.WriteRawTag(146, 1);
        output.WriteMessage(SingleNestedMessage);
      }
      if (singleForeignMessage_ != null) {
        output.WriteRawTag(154, 1);
        output.WriteMessage(SingleForeignMessage);
      }
      if (singleImportMessage_ != null) {
        output.WriteRawTag(162, 1);
        output.WriteMessage(SingleImportMessage);
      }
      if (SingleNestedEnum != global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum.NESTED_ENUM_UNSPECIFIED) {
        output.WriteRawTag(168, 1);
        output.WriteEnum((int) SingleNestedEnum);
      }
      if (SingleForeignEnum != global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED) {
        output.WriteRawTag(176, 1);
        output.WriteEnum((int) SingleForeignEnum);
      }
      if (SingleImportEnum != global::Google.Protobuf.TestProtos.ImportEnum.IMPORT_ENUM_UNSPECIFIED) {
        output.WriteRawTag(184, 1);
        output.WriteEnum((int) SingleImportEnum);
      }
      if (singlePublicImportMessage_ != null) {
        output.WriteRawTag(210, 1);
        output.WriteMessage(SinglePublicImportMessage);
      }
      repeatedInt32_.WriteTo(output, _repeated_repeatedInt32_codec);
      repeatedInt64_.WriteTo(output, _repeated_repeatedInt64_codec);
      repeatedUint32_.WriteTo(output, _repeated_repeatedUint32_codec);
      repeatedUint64_.WriteTo(output, _repeated_repeatedUint64_codec);
      repeatedSint32_.WriteTo(output, _repeated_repeatedSint32_codec);
      repeatedSint64_.WriteTo(output, _repeated_repeatedSint64_codec);
      repeatedFixed32_.WriteTo(output, _repeated_repeatedFixed32_codec);
      repeatedFixed64_.WriteTo(output, _repeated_repeatedFixed64_codec);
      repeatedSfixed32_.WriteTo(output, _repeated_repeatedSfixed32_codec);
      repeatedSfixed64_.WriteTo(output, _repeated_repeatedSfixed64_codec);
      repeatedFloat_.WriteTo(output, _repeated_repeatedFloat_codec);
      repeatedDouble_.WriteTo(output, _repeated_repeatedDouble_codec);
      repeatedBool_.WriteTo(output, _repeated_repeatedBool_codec);
      repeatedString_.WriteTo(output, _repeated_repeatedString_codec);
      repeatedBytes_.WriteTo(output, _repeated_repeatedBytes_codec);
      repeatedNestedMessage_.WriteTo(output, _repeated_repeatedNestedMessage_codec);
      repeatedForeignMessage_.WriteTo(output, _repeated_repeatedForeignMessage_codec);
      repeatedImportMessage_.WriteTo(output, _repeated_repeatedImportMessage_codec);
      repeatedNestedEnum_.WriteTo(output, _repeated_repeatedNestedEnum_codec);
      repeatedForeignEnum_.WriteTo(output, _repeated_repeatedForeignEnum_codec);
      repeatedImportEnum_.WriteTo(output, _repeated_repeatedImportEnum_codec);
      repeatedPublicImportMessage_.WriteTo(output, _repeated_repeatedPublicImportMessage_codec);
      if (oneofFieldCase_ == OneofFieldOneofCase.OneofUint32) {
        output.WriteRawTag(248, 6);
        output.WriteUInt32(OneofUint32);
      }
      if (oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage) {
        output.WriteRawTag(130, 7);
        output.WriteMessage(OneofNestedMessage);
      }
      if (oneofFieldCase_ == OneofFieldOneofCase.OneofString) {
        output.WriteRawTag(138, 7);
        output.WriteString(OneofString);
      }
      if (oneofFieldCase_ == OneofFieldOneofCase.OneofBytes) {
        output.WriteRawTag(146, 7);
        output.WriteBytes(OneofBytes);
      }
    }

    public int CalculateSize() {
      int size = 0;
      if (SingleInt32 != 0) {
        size += 1 + pb::CodedOutputStream.ComputeInt32Size(SingleInt32);
      }
      if (SingleInt64 != 0L) {
        size += 1 + pb::CodedOutputStream.ComputeInt64Size(SingleInt64);
      }
      if (SingleUint32 != 0) {
        size += 1 + pb::CodedOutputStream.ComputeUInt32Size(SingleUint32);
      }
      if (SingleUint64 != 0UL) {
        size += 1 + pb::CodedOutputStream.ComputeUInt64Size(SingleUint64);
      }
      if (SingleSint32 != 0) {
        size += 1 + pb::CodedOutputStream.ComputeSInt32Size(SingleSint32);
      }
      if (SingleSint64 != 0L) {
        size += 1 + pb::CodedOutputStream.ComputeSInt64Size(SingleSint64);
      }
      if (SingleFixed32 != 0) {
        size += 1 + 4;
      }
      if (SingleFixed64 != 0UL) {
        size += 1 + 8;
      }
      if (SingleSfixed32 != 0) {
        size += 1 + 4;
      }
      if (SingleSfixed64 != 0L) {
        size += 1 + 8;
      }
      if (SingleFloat != 0F) {
        size += 1 + 4;
      }
      if (SingleDouble != 0D) {
        size += 1 + 8;
      }
      if (SingleBool != false) {
        size += 1 + 1;
      }
      if (SingleString.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(SingleString);
      }
      if (SingleBytes.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeBytesSize(SingleBytes);
      }
      if (singleNestedMessage_ != null) {
        size += 2 + pb::CodedOutputStream.ComputeMessageSize(SingleNestedMessage);
      }
      if (singleForeignMessage_ != null) {
        size += 2 + pb::CodedOutputStream.ComputeMessageSize(SingleForeignMessage);
      }
      if (singleImportMessage_ != null) {
        size += 2 + pb::CodedOutputStream.ComputeMessageSize(SingleImportMessage);
      }
      if (SingleNestedEnum != global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum.NESTED_ENUM_UNSPECIFIED) {
        size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) SingleNestedEnum);
      }
      if (SingleForeignEnum != global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED) {
        size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) SingleForeignEnum);
      }
      if (SingleImportEnum != global::Google.Protobuf.TestProtos.ImportEnum.IMPORT_ENUM_UNSPECIFIED) {
        size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) SingleImportEnum);
      }
      if (singlePublicImportMessage_ != null) {
        size += 2 + pb::CodedOutputStream.ComputeMessageSize(SinglePublicImportMessage);
      }
      size += repeatedInt32_.CalculateSize(_repeated_repeatedInt32_codec);
      size += repeatedInt64_.CalculateSize(_repeated_repeatedInt64_codec);
      size += repeatedUint32_.CalculateSize(_repeated_repeatedUint32_codec);
      size += repeatedUint64_.CalculateSize(_repeated_repeatedUint64_codec);
      size += repeatedSint32_.CalculateSize(_repeated_repeatedSint32_codec);
      size += repeatedSint64_.CalculateSize(_repeated_repeatedSint64_codec);
      size += repeatedFixed32_.CalculateSize(_repeated_repeatedFixed32_codec);
      size += repeatedFixed64_.CalculateSize(_repeated_repeatedFixed64_codec);
      size += repeatedSfixed32_.CalculateSize(_repeated_repeatedSfixed32_codec);
      size += repeatedSfixed64_.CalculateSize(_repeated_repeatedSfixed64_codec);
      size += repeatedFloat_.CalculateSize(_repeated_repeatedFloat_codec);
      size += repeatedDouble_.CalculateSize(_repeated_repeatedDouble_codec);
      size += repeatedBool_.CalculateSize(_repeated_repeatedBool_codec);
      size += repeatedString_.CalculateSize(_repeated_repeatedString_codec);
      size += repeatedBytes_.CalculateSize(_repeated_repeatedBytes_codec);
      size += repeatedNestedMessage_.CalculateSize(_repeated_repeatedNestedMessage_codec);
      size += repeatedForeignMessage_.CalculateSize(_repeated_repeatedForeignMessage_codec);
      size += repeatedImportMessage_.CalculateSize(_repeated_repeatedImportMessage_codec);
      size += repeatedNestedEnum_.CalculateSize(_repeated_repeatedNestedEnum_codec);
      size += repeatedForeignEnum_.CalculateSize(_repeated_repeatedForeignEnum_codec);
      size += repeatedImportEnum_.CalculateSize(_repeated_repeatedImportEnum_codec);
      size += repeatedPublicImportMessage_.CalculateSize(_repeated_repeatedPublicImportMessage_codec);
      if (oneofFieldCase_ == OneofFieldOneofCase.OneofUint32) {
        size += 2 + pb::CodedOutputStream.ComputeUInt32Size(OneofUint32);
      }
      if (oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage) {
        size += 2 + pb::CodedOutputStream.ComputeMessageSize(OneofNestedMessage);
      }
      if (oneofFieldCase_ == OneofFieldOneofCase.OneofString) {
        size += 2 + pb::CodedOutputStream.ComputeStringSize(OneofString);
      }
      if (oneofFieldCase_ == OneofFieldOneofCase.OneofBytes) {
        size += 2 + pb::CodedOutputStream.ComputeBytesSize(OneofBytes);
      }
      return size;
    }

    public void MergeFrom(TestAllTypes other) {
      if (other == null) {
        return;
      }
      if (other.SingleInt32 != 0) {
        SingleInt32 = other.SingleInt32;
      }
      if (other.SingleInt64 != 0L) {
        SingleInt64 = other.SingleInt64;
      }
      if (other.SingleUint32 != 0) {
        SingleUint32 = other.SingleUint32;
      }
      if (other.SingleUint64 != 0UL) {
        SingleUint64 = other.SingleUint64;
      }
      if (other.SingleSint32 != 0) {
        SingleSint32 = other.SingleSint32;
      }
      if (other.SingleSint64 != 0L) {
        SingleSint64 = other.SingleSint64;
      }
      if (other.SingleFixed32 != 0) {
        SingleFixed32 = other.SingleFixed32;
      }
      if (other.SingleFixed64 != 0UL) {
        SingleFixed64 = other.SingleFixed64;
      }
      if (other.SingleSfixed32 != 0) {
        SingleSfixed32 = other.SingleSfixed32;
      }
      if (other.SingleSfixed64 != 0L) {
        SingleSfixed64 = other.SingleSfixed64;
      }
      if (other.SingleFloat != 0F) {
        SingleFloat = other.SingleFloat;
      }
      if (other.SingleDouble != 0D) {
        SingleDouble = other.SingleDouble;
      }
      if (other.SingleBool != false) {
        SingleBool = other.SingleBool;
      }
      if (other.SingleString.Length != 0) {
        SingleString = other.SingleString;
      }
      if (other.SingleBytes.Length != 0) {
        SingleBytes = other.SingleBytes;
      }
      if (other.singleNestedMessage_ != null) {
        if (singleNestedMessage_ == null) {
          singleNestedMessage_ = new global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage();
        }
        SingleNestedMessage.MergeFrom(other.SingleNestedMessage);
      }
      if (other.singleForeignMessage_ != null) {
        if (singleForeignMessage_ == null) {
          singleForeignMessage_ = new global::Google.Protobuf.TestProtos.ForeignMessage();
        }
        SingleForeignMessage.MergeFrom(other.SingleForeignMessage);
      }
      if (other.singleImportMessage_ != null) {
        if (singleImportMessage_ == null) {
          singleImportMessage_ = new global::Google.Protobuf.TestProtos.ImportMessage();
        }
        SingleImportMessage.MergeFrom(other.SingleImportMessage);
      }
      if (other.SingleNestedEnum != global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum.NESTED_ENUM_UNSPECIFIED) {
        SingleNestedEnum = other.SingleNestedEnum;
      }
      if (other.SingleForeignEnum != global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED) {
        SingleForeignEnum = other.SingleForeignEnum;
      }
      if (other.SingleImportEnum != global::Google.Protobuf.TestProtos.ImportEnum.IMPORT_ENUM_UNSPECIFIED) {
        SingleImportEnum = other.SingleImportEnum;
      }
      if (other.singlePublicImportMessage_ != null) {
        if (singlePublicImportMessage_ == null) {
          singlePublicImportMessage_ = new global::Google.Protobuf.TestProtos.PublicImportMessage();
        }
        SinglePublicImportMessage.MergeFrom(other.SinglePublicImportMessage);
      }
      repeatedInt32_.Add(other.repeatedInt32_);
      repeatedInt64_.Add(other.repeatedInt64_);
      repeatedUint32_.Add(other.repeatedUint32_);
      repeatedUint64_.Add(other.repeatedUint64_);
      repeatedSint32_.Add(other.repeatedSint32_);
      repeatedSint64_.Add(other.repeatedSint64_);
      repeatedFixed32_.Add(other.repeatedFixed32_);
      repeatedFixed64_.Add(other.repeatedFixed64_);
      repeatedSfixed32_.Add(other.repeatedSfixed32_);
      repeatedSfixed64_.Add(other.repeatedSfixed64_);
      repeatedFloat_.Add(other.repeatedFloat_);
      repeatedDouble_.Add(other.repeatedDouble_);
      repeatedBool_.Add(other.repeatedBool_);
      repeatedString_.Add(other.repeatedString_);
      repeatedBytes_.Add(other.repeatedBytes_);
      repeatedNestedMessage_.Add(other.repeatedNestedMessage_);
      repeatedForeignMessage_.Add(other.repeatedForeignMessage_);
      repeatedImportMessage_.Add(other.repeatedImportMessage_);
      repeatedNestedEnum_.Add(other.repeatedNestedEnum_);
      repeatedForeignEnum_.Add(other.repeatedForeignEnum_);
      repeatedImportEnum_.Add(other.repeatedImportEnum_);
      repeatedPublicImportMessage_.Add(other.repeatedPublicImportMessage_);
      switch (other.OneofFieldCase) {
        case OneofFieldOneofCase.OneofUint32:
          OneofUint32 = other.OneofUint32;
          break;
        case OneofFieldOneofCase.OneofNestedMessage:
          OneofNestedMessage = other.OneofNestedMessage;
          break;
        case OneofFieldOneofCase.OneofString:
          OneofString = other.OneofString;
          break;
        case OneofFieldOneofCase.OneofBytes:
          OneofBytes = other.OneofBytes;
          break;
      }

    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 8: {
            SingleInt32 = input.ReadInt32();
            break;
          }
          case 16: {
            SingleInt64 = input.ReadInt64();
            break;
          }
          case 24: {
            SingleUint32 = input.ReadUInt32();
            break;
          }
          case 32: {
            SingleUint64 = input.ReadUInt64();
            break;
          }
          case 40: {
            SingleSint32 = input.ReadSInt32();
            break;
          }
          case 48: {
            SingleSint64 = input.ReadSInt64();
            break;
          }
          case 61: {
            SingleFixed32 = input.ReadFixed32();
            break;
          }
          case 65: {
            SingleFixed64 = input.ReadFixed64();
            break;
          }
          case 77: {
            SingleSfixed32 = input.ReadSFixed32();
            break;
          }
          case 81: {
            SingleSfixed64 = input.ReadSFixed64();
            break;
          }
          case 93: {
            SingleFloat = input.ReadFloat();
            break;
          }
          case 97: {
            SingleDouble = input.ReadDouble();
            break;
          }
          case 104: {
            SingleBool = input.ReadBool();
            break;
          }
          case 114: {
            SingleString = input.ReadString();
            break;
          }
          case 122: {
            SingleBytes = input.ReadBytes();
            break;
          }
          case 146: {
            if (singleNestedMessage_ == null) {
              singleNestedMessage_ = new global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage();
            }
            input.ReadMessage(singleNestedMessage_);
            break;
          }
          case 154: {
            if (singleForeignMessage_ == null) {
              singleForeignMessage_ = new global::Google.Protobuf.TestProtos.ForeignMessage();
            }
            input.ReadMessage(singleForeignMessage_);
            break;
          }
          case 162: {
            if (singleImportMessage_ == null) {
              singleImportMessage_ = new global::Google.Protobuf.TestProtos.ImportMessage();
            }
            input.ReadMessage(singleImportMessage_);
            break;
          }
          case 168: {
            singleNestedEnum_ = (global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum) input.ReadEnum();
            break;
          }
          case 176: {
            singleForeignEnum_ = (global::Google.Protobuf.TestProtos.ForeignEnum) input.ReadEnum();
            break;
          }
          case 184: {
            singleImportEnum_ = (global::Google.Protobuf.TestProtos.ImportEnum) input.ReadEnum();
            break;
          }
          case 210: {
            if (singlePublicImportMessage_ == null) {
              singlePublicImportMessage_ = new global::Google.Protobuf.TestProtos.PublicImportMessage();
            }
            input.ReadMessage(singlePublicImportMessage_);
            break;
          }
          case 250:
          case 248: {
            repeatedInt32_.AddEntriesFrom(input, _repeated_repeatedInt32_codec);
            break;
          }
          case 258:
          case 256: {
            repeatedInt64_.AddEntriesFrom(input, _repeated_repeatedInt64_codec);
            break;
          }
          case 266:
          case 264: {
            repeatedUint32_.AddEntriesFrom(input, _repeated_repeatedUint32_codec);
            break;
          }
          case 274:
          case 272: {
            repeatedUint64_.AddEntriesFrom(input, _repeated_repeatedUint64_codec);
            break;
          }
          case 282:
          case 280: {
            repeatedSint32_.AddEntriesFrom(input, _repeated_repeatedSint32_codec);
            break;
          }
          case 290:
          case 288: {
            repeatedSint64_.AddEntriesFrom(input, _repeated_repeatedSint64_codec);
            break;
          }
          case 298:
          case 301: {
            repeatedFixed32_.AddEntriesFrom(input, _repeated_repeatedFixed32_codec);
            break;
          }
          case 306:
          case 305: {
            repeatedFixed64_.AddEntriesFrom(input, _repeated_repeatedFixed64_codec);
            break;
          }
          case 314:
          case 317: {
            repeatedSfixed32_.AddEntriesFrom(input, _repeated_repeatedSfixed32_codec);
            break;
          }
          case 322:
          case 321: {
            repeatedSfixed64_.AddEntriesFrom(input, _repeated_repeatedSfixed64_codec);
            break;
          }
          case 330:
          case 333: {
            repeatedFloat_.AddEntriesFrom(input, _repeated_repeatedFloat_codec);
            break;
          }
          case 338:
          case 337: {
            repeatedDouble_.AddEntriesFrom(input, _repeated_repeatedDouble_codec);
            break;
          }
          case 346:
          case 344: {
            repeatedBool_.AddEntriesFrom(input, _repeated_repeatedBool_codec);
            break;
          }
          case 354: {
            repeatedString_.AddEntriesFrom(input, _repeated_repeatedString_codec);
            break;
          }
          case 362: {
            repeatedBytes_.AddEntriesFrom(input, _repeated_repeatedBytes_codec);
            break;
          }
          case 386: {
            repeatedNestedMessage_.AddEntriesFrom(input, _repeated_repeatedNestedMessage_codec);
            break;
          }
          case 394: {
            repeatedForeignMessage_.AddEntriesFrom(input, _repeated_repeatedForeignMessage_codec);
            break;
          }
          case 402: {
            repeatedImportMessage_.AddEntriesFrom(input, _repeated_repeatedImportMessage_codec);
            break;
          }
          case 410:
          case 408: {
            repeatedNestedEnum_.AddEntriesFrom(input, _repeated_repeatedNestedEnum_codec);
            break;
          }
          case 418:
          case 416: {
            repeatedForeignEnum_.AddEntriesFrom(input, _repeated_repeatedForeignEnum_codec);
            break;
          }
          case 426:
          case 424: {
            repeatedImportEnum_.AddEntriesFrom(input, _repeated_repeatedImportEnum_codec);
            break;
          }
          case 434: {
            repeatedPublicImportMessage_.AddEntriesFrom(input, _repeated_repeatedPublicImportMessage_codec);
            break;
          }
          case 888: {
            OneofUint32 = input.ReadUInt32();
            break;
          }
          case 898: {
            global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage subBuilder = new global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage();
            if (oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage) {
              subBuilder.MergeFrom(OneofNestedMessage);
            }
            input.ReadMessage(subBuilder);
            OneofNestedMessage = subBuilder;
            break;
          }
          case 906: {
            OneofString = input.ReadString();
            break;
          }
          case 914: {
            OneofBytes = input.ReadBytes();
            break;
          }
        }
      }
    }

    #region Nested types
    /// <summary>Container for nested types declared in the TestAllTypes message type.</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public static partial class Types {
      public enum NestedEnum {
        NESTED_ENUM_UNSPECIFIED = 0,
        FOO = 1,
        BAR = 2,
        BAZ = 3,
        /// <summary>
        ///  Intentionally negative.
        /// </summary>
        NEG = -1,
      }

      [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
      public sealed partial class NestedMessage : pb::IMessage<NestedMessage> {
        private static readonly pb::MessageParser<NestedMessage> _parser = new pb::MessageParser<NestedMessage>(() => new NestedMessage());
        public static pb::MessageParser<NestedMessage> Parser { get { return _parser; } }

        public static pbr::MessageDescriptor Descriptor {
          get { return global::Google.Protobuf.TestProtos.TestAllTypes.Descriptor.NestedTypes[0]; }
        }

        pbr::MessageDescriptor pb::IMessage.Descriptor {
          get { return Descriptor; }
        }

        public NestedMessage() {
          OnConstruction();
        }

        partial void OnConstruction();

        public NestedMessage(NestedMessage other) : this() {
          bb_ = other.bb_;
        }

        public NestedMessage Clone() {
          return new NestedMessage(this);
        }

        /// <summary>Field number for the "bb" field.</summary>
        public const int BbFieldNumber = 1;
        private int bb_;
        /// <summary>
        ///  The field name "b" fails to compile in proto1 because it conflicts with
        ///  a local variable named "b" in one of the generated methods.  Doh.
        ///  This file needs to compile in proto1 to test backwards-compatibility.
        /// </summary>
        public int Bb {
          get { return bb_; }
          set {
            bb_ = value;
          }
        }

        public override bool Equals(object other) {
          return Equals(other as NestedMessage);
        }

        public bool Equals(NestedMessage other) {
          if (ReferenceEquals(other, null)) {
            return false;
          }
          if (ReferenceEquals(other, this)) {
            return true;
          }
          if (Bb != other.Bb) return false;
          return true;
        }

        public override int GetHashCode() {
          int hash = 1;
          if (Bb != 0) hash ^= Bb.GetHashCode();
          return hash;
        }

        public override string ToString() {
          return pb::JsonFormatter.Default.Format(this);
        }

        public void WriteTo(pb::CodedOutputStream output) {
          if (Bb != 0) {
            output.WriteRawTag(8);
            output.WriteInt32(Bb);
          }
        }

        public int CalculateSize() {
          int size = 0;
          if (Bb != 0) {
            size += 1 + pb::CodedOutputStream.ComputeInt32Size(Bb);
          }
          return size;
        }

        public void MergeFrom(NestedMessage other) {
          if (other == null) {
            return;
          }
          if (other.Bb != 0) {
            Bb = other.Bb;
          }
        }

        public void MergeFrom(pb::CodedInputStream input) {
          uint tag;
          while ((tag = input.ReadTag()) != 0) {
            switch(tag) {
              default:
                input.SkipLastField();
                break;
              case 8: {
                Bb = input.ReadInt32();
                break;
              }
            }
          }
        }

      }

    }
    #endregion

  }

  /// <summary>
  ///  This proto includes a recusively nested message.
  /// </summary>
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class NestedTestAllTypes : pb::IMessage<NestedTestAllTypes> {
    private static readonly pb::MessageParser<NestedTestAllTypes> _parser = new pb::MessageParser<NestedTestAllTypes>(() => new NestedTestAllTypes());
    public static pb::MessageParser<NestedTestAllTypes> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[1]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public NestedTestAllTypes() {
      OnConstruction();
    }

    partial void OnConstruction();

    public NestedTestAllTypes(NestedTestAllTypes other) : this() {
      Child = other.child_ != null ? other.Child.Clone() : null;
      Payload = other.payload_ != null ? other.Payload.Clone() : null;
      repeatedChild_ = other.repeatedChild_.Clone();
    }

    public NestedTestAllTypes Clone() {
      return new NestedTestAllTypes(this);
    }

    /// <summary>Field number for the "child" field.</summary>
    public const int ChildFieldNumber = 1;
    private global::Google.Protobuf.TestProtos.NestedTestAllTypes child_;
    public global::Google.Protobuf.TestProtos.NestedTestAllTypes Child {
      get { return child_; }
      set {
        child_ = value;
      }
    }

    /// <summary>Field number for the "payload" field.</summary>
    public const int PayloadFieldNumber = 2;
    private global::Google.Protobuf.TestProtos.TestAllTypes payload_;
    public global::Google.Protobuf.TestProtos.TestAllTypes Payload {
      get { return payload_; }
      set {
        payload_ = value;
      }
    }

    /// <summary>Field number for the "repeated_child" field.</summary>
    public const int RepeatedChildFieldNumber = 3;
    private static readonly pb::FieldCodec<global::Google.Protobuf.TestProtos.NestedTestAllTypes> _repeated_repeatedChild_codec
        = pb::FieldCodec.ForMessage(26, global::Google.Protobuf.TestProtos.NestedTestAllTypes.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.NestedTestAllTypes> repeatedChild_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.NestedTestAllTypes>();
    public pbc::RepeatedField<global::Google.Protobuf.TestProtos.NestedTestAllTypes> RepeatedChild {
      get { return repeatedChild_; }
    }

    public override bool Equals(object other) {
      return Equals(other as NestedTestAllTypes);
    }

    public bool Equals(NestedTestAllTypes other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (!object.Equals(Child, other.Child)) return false;
      if (!object.Equals(Payload, other.Payload)) return false;
      if(!repeatedChild_.Equals(other.repeatedChild_)) return false;
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      if (child_ != null) hash ^= Child.GetHashCode();
      if (payload_ != null) hash ^= Payload.GetHashCode();
      hash ^= repeatedChild_.GetHashCode();
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
      if (child_ != null) {
        output.WriteRawTag(10);
        output.WriteMessage(Child);
      }
      if (payload_ != null) {
        output.WriteRawTag(18);
        output.WriteMessage(Payload);
      }
      repeatedChild_.WriteTo(output, _repeated_repeatedChild_codec);
    }

    public int CalculateSize() {
      int size = 0;
      if (child_ != null) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Child);
      }
      if (payload_ != null) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Payload);
      }
      size += repeatedChild_.CalculateSize(_repeated_repeatedChild_codec);
      return size;
    }

    public void MergeFrom(NestedTestAllTypes other) {
      if (other == null) {
        return;
      }
      if (other.child_ != null) {
        if (child_ == null) {
          child_ = new global::Google.Protobuf.TestProtos.NestedTestAllTypes();
        }
        Child.MergeFrom(other.Child);
      }
      if (other.payload_ != null) {
        if (payload_ == null) {
          payload_ = new global::Google.Protobuf.TestProtos.TestAllTypes();
        }
        Payload.MergeFrom(other.Payload);
      }
      repeatedChild_.Add(other.repeatedChild_);
    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 10: {
            if (child_ == null) {
              child_ = new global::Google.Protobuf.TestProtos.NestedTestAllTypes();
            }
            input.ReadMessage(child_);
            break;
          }
          case 18: {
            if (payload_ == null) {
              payload_ = new global::Google.Protobuf.TestProtos.TestAllTypes();
            }
            input.ReadMessage(payload_);
            break;
          }
          case 26: {
            repeatedChild_.AddEntriesFrom(input, _repeated_repeatedChild_codec);
            break;
          }
        }
      }
    }

  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestDeprecatedFields : pb::IMessage<TestDeprecatedFields> {
    private static readonly pb::MessageParser<TestDeprecatedFields> _parser = new pb::MessageParser<TestDeprecatedFields>(() => new TestDeprecatedFields());
    public static pb::MessageParser<TestDeprecatedFields> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[2]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public TestDeprecatedFields() {
      OnConstruction();
    }

    partial void OnConstruction();

    public TestDeprecatedFields(TestDeprecatedFields other) : this() {
      deprecatedInt32_ = other.deprecatedInt32_;
    }

    public TestDeprecatedFields Clone() {
      return new TestDeprecatedFields(this);
    }

    /// <summary>Field number for the "deprecated_int32" field.</summary>
    public const int DeprecatedInt32FieldNumber = 1;
    private int deprecatedInt32_;
    [global::System.ObsoleteAttribute()]
    public int DeprecatedInt32 {
      get { return deprecatedInt32_; }
      set {
        deprecatedInt32_ = value;
      }
    }

    public override bool Equals(object other) {
      return Equals(other as TestDeprecatedFields);
    }

    public bool Equals(TestDeprecatedFields other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (DeprecatedInt32 != other.DeprecatedInt32) return false;
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      if (DeprecatedInt32 != 0) hash ^= DeprecatedInt32.GetHashCode();
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
      if (DeprecatedInt32 != 0) {
        output.WriteRawTag(8);
        output.WriteInt32(DeprecatedInt32);
      }
    }

    public int CalculateSize() {
      int size = 0;
      if (DeprecatedInt32 != 0) {
        size += 1 + pb::CodedOutputStream.ComputeInt32Size(DeprecatedInt32);
      }
      return size;
    }

    public void MergeFrom(TestDeprecatedFields other) {
      if (other == null) {
        return;
      }
      if (other.DeprecatedInt32 != 0) {
        DeprecatedInt32 = other.DeprecatedInt32;
      }
    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 8: {
            DeprecatedInt32 = input.ReadInt32();
            break;
          }
        }
      }
    }

  }

  /// <summary>
  ///  Define these after TestAllTypes to make sure the compiler can handle
  ///  that.
  /// </summary>
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class ForeignMessage : pb::IMessage<ForeignMessage> {
    private static readonly pb::MessageParser<ForeignMessage> _parser = new pb::MessageParser<ForeignMessage>(() => new ForeignMessage());
    public static pb::MessageParser<ForeignMessage> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[3]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public ForeignMessage() {
      OnConstruction();
    }

    partial void OnConstruction();

    public ForeignMessage(ForeignMessage other) : this() {
      c_ = other.c_;
    }

    public ForeignMessage Clone() {
      return new ForeignMessage(this);
    }

    /// <summary>Field number for the "c" field.</summary>
    public const int CFieldNumber = 1;
    private int c_;
    public int C {
      get { return c_; }
      set {
        c_ = value;
      }
    }

    public override bool Equals(object other) {
      return Equals(other as ForeignMessage);
    }

    public bool Equals(ForeignMessage other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (C != other.C) return false;
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      if (C != 0) hash ^= C.GetHashCode();
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
      if (C != 0) {
        output.WriteRawTag(8);
        output.WriteInt32(C);
      }
    }

    public int CalculateSize() {
      int size = 0;
      if (C != 0) {
        size += 1 + pb::CodedOutputStream.ComputeInt32Size(C);
      }
      return size;
    }

    public void MergeFrom(ForeignMessage other) {
      if (other == null) {
        return;
      }
      if (other.C != 0) {
        C = other.C;
      }
    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 8: {
            C = input.ReadInt32();
            break;
          }
        }
      }
    }

  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestReservedFields : pb::IMessage<TestReservedFields> {
    private static readonly pb::MessageParser<TestReservedFields> _parser = new pb::MessageParser<TestReservedFields>(() => new TestReservedFields());
    public static pb::MessageParser<TestReservedFields> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[4]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public TestReservedFields() {
      OnConstruction();
    }

    partial void OnConstruction();

    public TestReservedFields(TestReservedFields other) : this() {
    }

    public TestReservedFields Clone() {
      return new TestReservedFields(this);
    }

    public override bool Equals(object other) {
      return Equals(other as TestReservedFields);
    }

    public bool Equals(TestReservedFields other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
    }

    public int CalculateSize() {
      int size = 0;
      return size;
    }

    public void MergeFrom(TestReservedFields other) {
      if (other == null) {
        return;
      }
    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
        }
      }
    }

  }

  /// <summary>
  ///  Test that we can use NestedMessage from outside TestAllTypes.
  /// </summary>
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestForeignNested : pb::IMessage<TestForeignNested> {
    private static readonly pb::MessageParser<TestForeignNested> _parser = new pb::MessageParser<TestForeignNested>(() => new TestForeignNested());
    public static pb::MessageParser<TestForeignNested> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[5]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public TestForeignNested() {
      OnConstruction();
    }

    partial void OnConstruction();

    public TestForeignNested(TestForeignNested other) : this() {
      ForeignNested = other.foreignNested_ != null ? other.ForeignNested.Clone() : null;
    }

    public TestForeignNested Clone() {
      return new TestForeignNested(this);
    }

    /// <summary>Field number for the "foreign_nested" field.</summary>
    public const int ForeignNestedFieldNumber = 1;
    private global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage foreignNested_;
    public global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage ForeignNested {
      get { return foreignNested_; }
      set {
        foreignNested_ = value;
      }
    }

    public override bool Equals(object other) {
      return Equals(other as TestForeignNested);
    }

    public bool Equals(TestForeignNested other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (!object.Equals(ForeignNested, other.ForeignNested)) return false;
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      if (foreignNested_ != null) hash ^= ForeignNested.GetHashCode();
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
      if (foreignNested_ != null) {
        output.WriteRawTag(10);
        output.WriteMessage(ForeignNested);
      }
    }

    public int CalculateSize() {
      int size = 0;
      if (foreignNested_ != null) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(ForeignNested);
      }
      return size;
    }

    public void MergeFrom(TestForeignNested other) {
      if (other == null) {
        return;
      }
      if (other.foreignNested_ != null) {
        if (foreignNested_ == null) {
          foreignNested_ = new global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage();
        }
        ForeignNested.MergeFrom(other.ForeignNested);
      }
    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 10: {
            if (foreignNested_ == null) {
              foreignNested_ = new global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage();
            }
            input.ReadMessage(foreignNested_);
            break;
          }
        }
      }
    }

  }

  /// <summary>
  ///  Test that really large tag numbers don't break anything.
  /// </summary>
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestReallyLargeTagNumber : pb::IMessage<TestReallyLargeTagNumber> {
    private static readonly pb::MessageParser<TestReallyLargeTagNumber> _parser = new pb::MessageParser<TestReallyLargeTagNumber>(() => new TestReallyLargeTagNumber());
    public static pb::MessageParser<TestReallyLargeTagNumber> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[6]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public TestReallyLargeTagNumber() {
      OnConstruction();
    }

    partial void OnConstruction();

    public TestReallyLargeTagNumber(TestReallyLargeTagNumber other) : this() {
      a_ = other.a_;
      bb_ = other.bb_;
    }

    public TestReallyLargeTagNumber Clone() {
      return new TestReallyLargeTagNumber(this);
    }

    /// <summary>Field number for the "a" field.</summary>
    public const int AFieldNumber = 1;
    private int a_;
    /// <summary>
    ///  The largest possible tag number is 2^28 - 1, since the wire format uses
    ///  three bits to communicate wire type.
    /// </summary>
    public int A {
      get { return a_; }
      set {
        a_ = value;
      }
    }

    /// <summary>Field number for the "bb" field.</summary>
    public const int BbFieldNumber = 268435455;
    private int bb_;
    public int Bb {
      get { return bb_; }
      set {
        bb_ = value;
      }
    }

    public override bool Equals(object other) {
      return Equals(other as TestReallyLargeTagNumber);
    }

    public bool Equals(TestReallyLargeTagNumber other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (A != other.A) return false;
      if (Bb != other.Bb) return false;
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      if (A != 0) hash ^= A.GetHashCode();
      if (Bb != 0) hash ^= Bb.GetHashCode();
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
      if (A != 0) {
        output.WriteRawTag(8);
        output.WriteInt32(A);
      }
      if (Bb != 0) {
        output.WriteRawTag(248, 255, 255, 255, 7);
        output.WriteInt32(Bb);
      }
    }

    public int CalculateSize() {
      int size = 0;
      if (A != 0) {
        size += 1 + pb::CodedOutputStream.ComputeInt32Size(A);
      }
      if (Bb != 0) {
        size += 5 + pb::CodedOutputStream.ComputeInt32Size(Bb);
      }
      return size;
    }

    public void MergeFrom(TestReallyLargeTagNumber other) {
      if (other == null) {
        return;
      }
      if (other.A != 0) {
        A = other.A;
      }
      if (other.Bb != 0) {
        Bb = other.Bb;
      }
    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 8: {
            A = input.ReadInt32();
            break;
          }
          case 2147483640: {
            Bb = input.ReadInt32();
            break;
          }
        }
      }
    }

  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestRecursiveMessage : pb::IMessage<TestRecursiveMessage> {
    private static readonly pb::MessageParser<TestRecursiveMessage> _parser = new pb::MessageParser<TestRecursiveMessage>(() => new TestRecursiveMessage());
    public static pb::MessageParser<TestRecursiveMessage> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[7]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public TestRecursiveMessage() {
      OnConstruction();
    }

    partial void OnConstruction();

    public TestRecursiveMessage(TestRecursiveMessage other) : this() {
      A = other.a_ != null ? other.A.Clone() : null;
      i_ = other.i_;
    }

    public TestRecursiveMessage Clone() {
      return new TestRecursiveMessage(this);
    }

    /// <summary>Field number for the "a" field.</summary>
    public const int AFieldNumber = 1;
    private global::Google.Protobuf.TestProtos.TestRecursiveMessage a_;
    public global::Google.Protobuf.TestProtos.TestRecursiveMessage A {
      get { return a_; }
      set {
        a_ = value;
      }
    }

    /// <summary>Field number for the "i" field.</summary>
    public const int IFieldNumber = 2;
    private int i_;
    public int I {
      get { return i_; }
      set {
        i_ = value;
      }
    }

    public override bool Equals(object other) {
      return Equals(other as TestRecursiveMessage);
    }

    public bool Equals(TestRecursiveMessage other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (!object.Equals(A, other.A)) return false;
      if (I != other.I) return false;
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      if (a_ != null) hash ^= A.GetHashCode();
      if (I != 0) hash ^= I.GetHashCode();
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
      if (a_ != null) {
        output.WriteRawTag(10);
        output.WriteMessage(A);
      }
      if (I != 0) {
        output.WriteRawTag(16);
        output.WriteInt32(I);
      }
    }

    public int CalculateSize() {
      int size = 0;
      if (a_ != null) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(A);
      }
      if (I != 0) {
        size += 1 + pb::CodedOutputStream.ComputeInt32Size(I);
      }
      return size;
    }

    public void MergeFrom(TestRecursiveMessage other) {
      if (other == null) {
        return;
      }
      if (other.a_ != null) {
        if (a_ == null) {
          a_ = new global::Google.Protobuf.TestProtos.TestRecursiveMessage();
        }
        A.MergeFrom(other.A);
      }
      if (other.I != 0) {
        I = other.I;
      }
    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 10: {
            if (a_ == null) {
              a_ = new global::Google.Protobuf.TestProtos.TestRecursiveMessage();
            }
            input.ReadMessage(a_);
            break;
          }
          case 16: {
            I = input.ReadInt32();
            break;
          }
        }
      }
    }

  }

  /// <summary>
  ///  Test that mutual recursion works.
  /// </summary>
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestMutualRecursionA : pb::IMessage<TestMutualRecursionA> {
    private static readonly pb::MessageParser<TestMutualRecursionA> _parser = new pb::MessageParser<TestMutualRecursionA>(() => new TestMutualRecursionA());
    public static pb::MessageParser<TestMutualRecursionA> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[8]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public TestMutualRecursionA() {
      OnConstruction();
    }

    partial void OnConstruction();

    public TestMutualRecursionA(TestMutualRecursionA other) : this() {
      Bb = other.bb_ != null ? other.Bb.Clone() : null;
    }

    public TestMutualRecursionA Clone() {
      return new TestMutualRecursionA(this);
    }

    /// <summary>Field number for the "bb" field.</summary>
    public const int BbFieldNumber = 1;
    private global::Google.Protobuf.TestProtos.TestMutualRecursionB bb_;
    public global::Google.Protobuf.TestProtos.TestMutualRecursionB Bb {
      get { return bb_; }
      set {
        bb_ = value;
      }
    }

    public override bool Equals(object other) {
      return Equals(other as TestMutualRecursionA);
    }

    public bool Equals(TestMutualRecursionA other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (!object.Equals(Bb, other.Bb)) return false;
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      if (bb_ != null) hash ^= Bb.GetHashCode();
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
      if (bb_ != null) {
        output.WriteRawTag(10);
        output.WriteMessage(Bb);
      }
    }

    public int CalculateSize() {
      int size = 0;
      if (bb_ != null) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Bb);
      }
      return size;
    }

    public void MergeFrom(TestMutualRecursionA other) {
      if (other == null) {
        return;
      }
      if (other.bb_ != null) {
        if (bb_ == null) {
          bb_ = new global::Google.Protobuf.TestProtos.TestMutualRecursionB();
        }
        Bb.MergeFrom(other.Bb);
      }
    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 10: {
            if (bb_ == null) {
              bb_ = new global::Google.Protobuf.TestProtos.TestMutualRecursionB();
            }
            input.ReadMessage(bb_);
            break;
          }
        }
      }
    }

  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestMutualRecursionB : pb::IMessage<TestMutualRecursionB> {
    private static readonly pb::MessageParser<TestMutualRecursionB> _parser = new pb::MessageParser<TestMutualRecursionB>(() => new TestMutualRecursionB());
    public static pb::MessageParser<TestMutualRecursionB> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[9]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public TestMutualRecursionB() {
      OnConstruction();
    }

    partial void OnConstruction();

    public TestMutualRecursionB(TestMutualRecursionB other) : this() {
      A = other.a_ != null ? other.A.Clone() : null;
      optionalInt32_ = other.optionalInt32_;
    }

    public TestMutualRecursionB Clone() {
      return new TestMutualRecursionB(this);
    }

    /// <summary>Field number for the "a" field.</summary>
    public const int AFieldNumber = 1;
    private global::Google.Protobuf.TestProtos.TestMutualRecursionA a_;
    public global::Google.Protobuf.TestProtos.TestMutualRecursionA A {
      get { return a_; }
      set {
        a_ = value;
      }
    }

    /// <summary>Field number for the "optional_int32" field.</summary>
    public const int OptionalInt32FieldNumber = 2;
    private int optionalInt32_;
    public int OptionalInt32 {
      get { return optionalInt32_; }
      set {
        optionalInt32_ = value;
      }
    }

    public override bool Equals(object other) {
      return Equals(other as TestMutualRecursionB);
    }

    public bool Equals(TestMutualRecursionB other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (!object.Equals(A, other.A)) return false;
      if (OptionalInt32 != other.OptionalInt32) return false;
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      if (a_ != null) hash ^= A.GetHashCode();
      if (OptionalInt32 != 0) hash ^= OptionalInt32.GetHashCode();
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
      if (a_ != null) {
        output.WriteRawTag(10);
        output.WriteMessage(A);
      }
      if (OptionalInt32 != 0) {
        output.WriteRawTag(16);
        output.WriteInt32(OptionalInt32);
      }
    }

    public int CalculateSize() {
      int size = 0;
      if (a_ != null) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(A);
      }
      if (OptionalInt32 != 0) {
        size += 1 + pb::CodedOutputStream.ComputeInt32Size(OptionalInt32);
      }
      return size;
    }

    public void MergeFrom(TestMutualRecursionB other) {
      if (other == null) {
        return;
      }
      if (other.a_ != null) {
        if (a_ == null) {
          a_ = new global::Google.Protobuf.TestProtos.TestMutualRecursionA();
        }
        A.MergeFrom(other.A);
      }
      if (other.OptionalInt32 != 0) {
        OptionalInt32 = other.OptionalInt32;
      }
    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 10: {
            if (a_ == null) {
              a_ = new global::Google.Protobuf.TestProtos.TestMutualRecursionA();
            }
            input.ReadMessage(a_);
            break;
          }
          case 16: {
            OptionalInt32 = input.ReadInt32();
            break;
          }
        }
      }
    }

  }

  /// <summary>
  ///  Test message with CamelCase field names.  This violates Protocol Buffer
  ///  standard style.
  /// </summary>
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestCamelCaseFieldNames : pb::IMessage<TestCamelCaseFieldNames> {
    private static readonly pb::MessageParser<TestCamelCaseFieldNames> _parser = new pb::MessageParser<TestCamelCaseFieldNames>(() => new TestCamelCaseFieldNames());
    public static pb::MessageParser<TestCamelCaseFieldNames> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[10]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public TestCamelCaseFieldNames() {
      OnConstruction();
    }

    partial void OnConstruction();

    public TestCamelCaseFieldNames(TestCamelCaseFieldNames other) : this() {
      primitiveField_ = other.primitiveField_;
      stringField_ = other.stringField_;
      enumField_ = other.enumField_;
      MessageField = other.messageField_ != null ? other.MessageField.Clone() : null;
      repeatedPrimitiveField_ = other.repeatedPrimitiveField_.Clone();
      repeatedStringField_ = other.repeatedStringField_.Clone();
      repeatedEnumField_ = other.repeatedEnumField_.Clone();
      repeatedMessageField_ = other.repeatedMessageField_.Clone();
    }

    public TestCamelCaseFieldNames Clone() {
      return new TestCamelCaseFieldNames(this);
    }

    /// <summary>Field number for the "PrimitiveField" field.</summary>
    public const int PrimitiveFieldFieldNumber = 1;
    private int primitiveField_;
    public int PrimitiveField {
      get { return primitiveField_; }
      set {
        primitiveField_ = value;
      }
    }

    /// <summary>Field number for the "StringField" field.</summary>
    public const int StringFieldFieldNumber = 2;
    private string stringField_ = "";
    public string StringField {
      get { return stringField_; }
      set {
        stringField_ = pb::Preconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "EnumField" field.</summary>
    public const int EnumFieldFieldNumber = 3;
    private global::Google.Protobuf.TestProtos.ForeignEnum enumField_ = global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED;
    public global::Google.Protobuf.TestProtos.ForeignEnum EnumField {
      get { return enumField_; }
      set {
        enumField_ = value;
      }
    }

    /// <summary>Field number for the "MessageField" field.</summary>
    public const int MessageFieldFieldNumber = 4;
    private global::Google.Protobuf.TestProtos.ForeignMessage messageField_;
    public global::Google.Protobuf.TestProtos.ForeignMessage MessageField {
      get { return messageField_; }
      set {
        messageField_ = value;
      }
    }

    /// <summary>Field number for the "RepeatedPrimitiveField" field.</summary>
    public const int RepeatedPrimitiveFieldFieldNumber = 7;
    private static readonly pb::FieldCodec<int> _repeated_repeatedPrimitiveField_codec
        = pb::FieldCodec.ForInt32(58);
    private readonly pbc::RepeatedField<int> repeatedPrimitiveField_ = new pbc::RepeatedField<int>();
    public pbc::RepeatedField<int> RepeatedPrimitiveField {
      get { return repeatedPrimitiveField_; }
    }

    /// <summary>Field number for the "RepeatedStringField" field.</summary>
    public const int RepeatedStringFieldFieldNumber = 8;
    private static readonly pb::FieldCodec<string> _repeated_repeatedStringField_codec
        = pb::FieldCodec.ForString(66);
    private readonly pbc::RepeatedField<string> repeatedStringField_ = new pbc::RepeatedField<string>();
    public pbc::RepeatedField<string> RepeatedStringField {
      get { return repeatedStringField_; }
    }

    /// <summary>Field number for the "RepeatedEnumField" field.</summary>
    public const int RepeatedEnumFieldFieldNumber = 9;
    private static readonly pb::FieldCodec<global::Google.Protobuf.TestProtos.ForeignEnum> _repeated_repeatedEnumField_codec
        = pb::FieldCodec.ForEnum(74, x => (int) x, x => (global::Google.Protobuf.TestProtos.ForeignEnum) x);
    private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum> repeatedEnumField_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum>();
    public pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum> RepeatedEnumField {
      get { return repeatedEnumField_; }
    }

    /// <summary>Field number for the "RepeatedMessageField" field.</summary>
    public const int RepeatedMessageFieldFieldNumber = 10;
    private static readonly pb::FieldCodec<global::Google.Protobuf.TestProtos.ForeignMessage> _repeated_repeatedMessageField_codec
        = pb::FieldCodec.ForMessage(82, global::Google.Protobuf.TestProtos.ForeignMessage.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignMessage> repeatedMessageField_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignMessage>();
    public pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignMessage> RepeatedMessageField {
      get { return repeatedMessageField_; }
    }

    public override bool Equals(object other) {
      return Equals(other as TestCamelCaseFieldNames);
    }

    public bool Equals(TestCamelCaseFieldNames other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (PrimitiveField != other.PrimitiveField) return false;
      if (StringField != other.StringField) return false;
      if (EnumField != other.EnumField) return false;
      if (!object.Equals(MessageField, other.MessageField)) return false;
      if(!repeatedPrimitiveField_.Equals(other.repeatedPrimitiveField_)) return false;
      if(!repeatedStringField_.Equals(other.repeatedStringField_)) return false;
      if(!repeatedEnumField_.Equals(other.repeatedEnumField_)) return false;
      if(!repeatedMessageField_.Equals(other.repeatedMessageField_)) return false;
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      if (PrimitiveField != 0) hash ^= PrimitiveField.GetHashCode();
      if (StringField.Length != 0) hash ^= StringField.GetHashCode();
      if (EnumField != global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED) hash ^= EnumField.GetHashCode();
      if (messageField_ != null) hash ^= MessageField.GetHashCode();
      hash ^= repeatedPrimitiveField_.GetHashCode();
      hash ^= repeatedStringField_.GetHashCode();
      hash ^= repeatedEnumField_.GetHashCode();
      hash ^= repeatedMessageField_.GetHashCode();
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
      if (PrimitiveField != 0) {
        output.WriteRawTag(8);
        output.WriteInt32(PrimitiveField);
      }
      if (StringField.Length != 0) {
        output.WriteRawTag(18);
        output.WriteString(StringField);
      }
      if (EnumField != global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED) {
        output.WriteRawTag(24);
        output.WriteEnum((int) EnumField);
      }
      if (messageField_ != null) {
        output.WriteRawTag(34);
        output.WriteMessage(MessageField);
      }
      repeatedPrimitiveField_.WriteTo(output, _repeated_repeatedPrimitiveField_codec);
      repeatedStringField_.WriteTo(output, _repeated_repeatedStringField_codec);
      repeatedEnumField_.WriteTo(output, _repeated_repeatedEnumField_codec);
      repeatedMessageField_.WriteTo(output, _repeated_repeatedMessageField_codec);
    }

    public int CalculateSize() {
      int size = 0;
      if (PrimitiveField != 0) {
        size += 1 + pb::CodedOutputStream.ComputeInt32Size(PrimitiveField);
      }
      if (StringField.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(StringField);
      }
      if (EnumField != global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED) {
        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) EnumField);
      }
      if (messageField_ != null) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(MessageField);
      }
      size += repeatedPrimitiveField_.CalculateSize(_repeated_repeatedPrimitiveField_codec);
      size += repeatedStringField_.CalculateSize(_repeated_repeatedStringField_codec);
      size += repeatedEnumField_.CalculateSize(_repeated_repeatedEnumField_codec);
      size += repeatedMessageField_.CalculateSize(_repeated_repeatedMessageField_codec);
      return size;
    }

    public void MergeFrom(TestCamelCaseFieldNames other) {
      if (other == null) {
        return;
      }
      if (other.PrimitiveField != 0) {
        PrimitiveField = other.PrimitiveField;
      }
      if (other.StringField.Length != 0) {
        StringField = other.StringField;
      }
      if (other.EnumField != global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED) {
        EnumField = other.EnumField;
      }
      if (other.messageField_ != null) {
        if (messageField_ == null) {
          messageField_ = new global::Google.Protobuf.TestProtos.ForeignMessage();
        }
        MessageField.MergeFrom(other.MessageField);
      }
      repeatedPrimitiveField_.Add(other.repeatedPrimitiveField_);
      repeatedStringField_.Add(other.repeatedStringField_);
      repeatedEnumField_.Add(other.repeatedEnumField_);
      repeatedMessageField_.Add(other.repeatedMessageField_);
    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 8: {
            PrimitiveField = input.ReadInt32();
            break;
          }
          case 18: {
            StringField = input.ReadString();
            break;
          }
          case 24: {
            enumField_ = (global::Google.Protobuf.TestProtos.ForeignEnum) input.ReadEnum();
            break;
          }
          case 34: {
            if (messageField_ == null) {
              messageField_ = new global::Google.Protobuf.TestProtos.ForeignMessage();
            }
            input.ReadMessage(messageField_);
            break;
          }
          case 58:
          case 56: {
            repeatedPrimitiveField_.AddEntriesFrom(input, _repeated_repeatedPrimitiveField_codec);
            break;
          }
          case 66: {
            repeatedStringField_.AddEntriesFrom(input, _repeated_repeatedStringField_codec);
            break;
          }
          case 74:
          case 72: {
            repeatedEnumField_.AddEntriesFrom(input, _repeated_repeatedEnumField_codec);
            break;
          }
          case 82: {
            repeatedMessageField_.AddEntriesFrom(input, _repeated_repeatedMessageField_codec);
            break;
          }
        }
      }
    }

  }

  /// <summary>
  ///  We list fields out of order, to ensure that we're using field number and not
  ///  field index to determine serialization order.
  /// </summary>
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestFieldOrderings : pb::IMessage<TestFieldOrderings> {
    private static readonly pb::MessageParser<TestFieldOrderings> _parser = new pb::MessageParser<TestFieldOrderings>(() => new TestFieldOrderings());
    public static pb::MessageParser<TestFieldOrderings> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[11]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public TestFieldOrderings() {
      OnConstruction();
    }

    partial void OnConstruction();

    public TestFieldOrderings(TestFieldOrderings other) : this() {
      myString_ = other.myString_;
      myInt_ = other.myInt_;
      myFloat_ = other.myFloat_;
      SingleNestedMessage = other.singleNestedMessage_ != null ? other.SingleNestedMessage.Clone() : null;
    }

    public TestFieldOrderings Clone() {
      return new TestFieldOrderings(this);
    }

    /// <summary>Field number for the "my_string" field.</summary>
    public const int MyStringFieldNumber = 11;
    private string myString_ = "";
    public string MyString {
      get { return myString_; }
      set {
        myString_ = pb::Preconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "my_int" field.</summary>
    public const int MyIntFieldNumber = 1;
    private long myInt_;
    public long MyInt {
      get { return myInt_; }
      set {
        myInt_ = value;
      }
    }

    /// <summary>Field number for the "my_float" field.</summary>
    public const int MyFloatFieldNumber = 101;
    private float myFloat_;
    public float MyFloat {
      get { return myFloat_; }
      set {
        myFloat_ = value;
      }
    }

    /// <summary>Field number for the "single_nested_message" field.</summary>
    public const int SingleNestedMessageFieldNumber = 200;
    private global::Google.Protobuf.TestProtos.TestFieldOrderings.Types.NestedMessage singleNestedMessage_;
    public global::Google.Protobuf.TestProtos.TestFieldOrderings.Types.NestedMessage SingleNestedMessage {
      get { return singleNestedMessage_; }
      set {
        singleNestedMessage_ = value;
      }
    }

    public override bool Equals(object other) {
      return Equals(other as TestFieldOrderings);
    }

    public bool Equals(TestFieldOrderings other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (MyString != other.MyString) return false;
      if (MyInt != other.MyInt) return false;
      if (MyFloat != other.MyFloat) return false;
      if (!object.Equals(SingleNestedMessage, other.SingleNestedMessage)) return false;
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      if (MyString.Length != 0) hash ^= MyString.GetHashCode();
      if (MyInt != 0L) hash ^= MyInt.GetHashCode();
      if (MyFloat != 0F) hash ^= MyFloat.GetHashCode();
      if (singleNestedMessage_ != null) hash ^= SingleNestedMessage.GetHashCode();
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
      if (MyInt != 0L) {
        output.WriteRawTag(8);
        output.WriteInt64(MyInt);
      }
      if (MyString.Length != 0) {
        output.WriteRawTag(90);
        output.WriteString(MyString);
      }
      if (MyFloat != 0F) {
        output.WriteRawTag(173, 6);
        output.WriteFloat(MyFloat);
      }
      if (singleNestedMessage_ != null) {
        output.WriteRawTag(194, 12);
        output.WriteMessage(SingleNestedMessage);
      }
    }

    public int CalculateSize() {
      int size = 0;
      if (MyString.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(MyString);
      }
      if (MyInt != 0L) {
        size += 1 + pb::CodedOutputStream.ComputeInt64Size(MyInt);
      }
      if (MyFloat != 0F) {
        size += 2 + 4;
      }
      if (singleNestedMessage_ != null) {
        size += 2 + pb::CodedOutputStream.ComputeMessageSize(SingleNestedMessage);
      }
      return size;
    }

    public void MergeFrom(TestFieldOrderings other) {
      if (other == null) {
        return;
      }
      if (other.MyString.Length != 0) {
        MyString = other.MyString;
      }
      if (other.MyInt != 0L) {
        MyInt = other.MyInt;
      }
      if (other.MyFloat != 0F) {
        MyFloat = other.MyFloat;
      }
      if (other.singleNestedMessage_ != null) {
        if (singleNestedMessage_ == null) {
          singleNestedMessage_ = new global::Google.Protobuf.TestProtos.TestFieldOrderings.Types.NestedMessage();
        }
        SingleNestedMessage.MergeFrom(other.SingleNestedMessage);
      }
    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 8: {
            MyInt = input.ReadInt64();
            break;
          }
          case 90: {
            MyString = input.ReadString();
            break;
          }
          case 813: {
            MyFloat = input.ReadFloat();
            break;
          }
          case 1602: {
            if (singleNestedMessage_ == null) {
              singleNestedMessage_ = new global::Google.Protobuf.TestProtos.TestFieldOrderings.Types.NestedMessage();
            }
            input.ReadMessage(singleNestedMessage_);
            break;
          }
        }
      }
    }

    #region Nested types
    /// <summary>Container for nested types declared in the TestFieldOrderings message type.</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public static partial class Types {
      [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
      public sealed partial class NestedMessage : pb::IMessage<NestedMessage> {
        private static readonly pb::MessageParser<NestedMessage> _parser = new pb::MessageParser<NestedMessage>(() => new NestedMessage());
        public static pb::MessageParser<NestedMessage> Parser { get { return _parser; } }

        public static pbr::MessageDescriptor Descriptor {
          get { return global::Google.Protobuf.TestProtos.TestFieldOrderings.Descriptor.NestedTypes[0]; }
        }

        pbr::MessageDescriptor pb::IMessage.Descriptor {
          get { return Descriptor; }
        }

        public NestedMessage() {
          OnConstruction();
        }

        partial void OnConstruction();

        public NestedMessage(NestedMessage other) : this() {
          oo_ = other.oo_;
          bb_ = other.bb_;
        }

        public NestedMessage Clone() {
          return new NestedMessage(this);
        }

        /// <summary>Field number for the "oo" field.</summary>
        public const int OoFieldNumber = 2;
        private long oo_;
        public long Oo {
          get { return oo_; }
          set {
            oo_ = value;
          }
        }

        /// <summary>Field number for the "bb" field.</summary>
        public const int BbFieldNumber = 1;
        private int bb_;
        /// <summary>
        ///  The field name "b" fails to compile in proto1 because it conflicts with
        ///  a local variable named "b" in one of the generated methods.  Doh.
        ///  This file needs to compile in proto1 to test backwards-compatibility.
        /// </summary>
        public int Bb {
          get { return bb_; }
          set {
            bb_ = value;
          }
        }

        public override bool Equals(object other) {
          return Equals(other as NestedMessage);
        }

        public bool Equals(NestedMessage other) {
          if (ReferenceEquals(other, null)) {
            return false;
          }
          if (ReferenceEquals(other, this)) {
            return true;
          }
          if (Oo != other.Oo) return false;
          if (Bb != other.Bb) return false;
          return true;
        }

        public override int GetHashCode() {
          int hash = 1;
          if (Oo != 0L) hash ^= Oo.GetHashCode();
          if (Bb != 0) hash ^= Bb.GetHashCode();
          return hash;
        }

        public override string ToString() {
          return pb::JsonFormatter.Default.Format(this);
        }

        public void WriteTo(pb::CodedOutputStream output) {
          if (Bb != 0) {
            output.WriteRawTag(8);
            output.WriteInt32(Bb);
          }
          if (Oo != 0L) {
            output.WriteRawTag(16);
            output.WriteInt64(Oo);
          }
        }

        public int CalculateSize() {
          int size = 0;
          if (Oo != 0L) {
            size += 1 + pb::CodedOutputStream.ComputeInt64Size(Oo);
          }
          if (Bb != 0) {
            size += 1 + pb::CodedOutputStream.ComputeInt32Size(Bb);
          }
          return size;
        }

        public void MergeFrom(NestedMessage other) {
          if (other == null) {
            return;
          }
          if (other.Oo != 0L) {
            Oo = other.Oo;
          }
          if (other.Bb != 0) {
            Bb = other.Bb;
          }
        }

        public void MergeFrom(pb::CodedInputStream input) {
          uint tag;
          while ((tag = input.ReadTag()) != 0) {
            switch(tag) {
              default:
                input.SkipLastField();
                break;
              case 8: {
                Bb = input.ReadInt32();
                break;
              }
              case 16: {
                Oo = input.ReadInt64();
                break;
              }
            }
          }
        }

      }

    }
    #endregion

  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class SparseEnumMessage : pb::IMessage<SparseEnumMessage> {
    private static readonly pb::MessageParser<SparseEnumMessage> _parser = new pb::MessageParser<SparseEnumMessage>(() => new SparseEnumMessage());
    public static pb::MessageParser<SparseEnumMessage> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[12]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public SparseEnumMessage() {
      OnConstruction();
    }

    partial void OnConstruction();

    public SparseEnumMessage(SparseEnumMessage other) : this() {
      sparseEnum_ = other.sparseEnum_;
    }

    public SparseEnumMessage Clone() {
      return new SparseEnumMessage(this);
    }

    /// <summary>Field number for the "sparse_enum" field.</summary>
    public const int SparseEnumFieldNumber = 1;
    private global::Google.Protobuf.TestProtos.TestSparseEnum sparseEnum_ = global::Google.Protobuf.TestProtos.TestSparseEnum.TEST_SPARSE_ENUM_UNSPECIFIED;
    public global::Google.Protobuf.TestProtos.TestSparseEnum SparseEnum {
      get { return sparseEnum_; }
      set {
        sparseEnum_ = value;
      }
    }

    public override bool Equals(object other) {
      return Equals(other as SparseEnumMessage);
    }

    public bool Equals(SparseEnumMessage other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (SparseEnum != other.SparseEnum) return false;
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      if (SparseEnum != global::Google.Protobuf.TestProtos.TestSparseEnum.TEST_SPARSE_ENUM_UNSPECIFIED) hash ^= SparseEnum.GetHashCode();
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
      if (SparseEnum != global::Google.Protobuf.TestProtos.TestSparseEnum.TEST_SPARSE_ENUM_UNSPECIFIED) {
        output.WriteRawTag(8);
        output.WriteEnum((int) SparseEnum);
      }
    }

    public int CalculateSize() {
      int size = 0;
      if (SparseEnum != global::Google.Protobuf.TestProtos.TestSparseEnum.TEST_SPARSE_ENUM_UNSPECIFIED) {
        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) SparseEnum);
      }
      return size;
    }

    public void MergeFrom(SparseEnumMessage other) {
      if (other == null) {
        return;
      }
      if (other.SparseEnum != global::Google.Protobuf.TestProtos.TestSparseEnum.TEST_SPARSE_ENUM_UNSPECIFIED) {
        SparseEnum = other.SparseEnum;
      }
    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 8: {
            sparseEnum_ = (global::Google.Protobuf.TestProtos.TestSparseEnum) input.ReadEnum();
            break;
          }
        }
      }
    }

  }

  /// <summary>
  ///  Test String and Bytes: string is for valid UTF-8 strings
  /// </summary>
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class OneString : pb::IMessage<OneString> {
    private static readonly pb::MessageParser<OneString> _parser = new pb::MessageParser<OneString>(() => new OneString());
    public static pb::MessageParser<OneString> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[13]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public OneString() {
      OnConstruction();
    }

    partial void OnConstruction();

    public OneString(OneString other) : this() {
      data_ = other.data_;
    }

    public OneString Clone() {
      return new OneString(this);
    }

    /// <summary>Field number for the "data" field.</summary>
    public const int DataFieldNumber = 1;
    private string data_ = "";
    public string Data {
      get { return data_; }
      set {
        data_ = pb::Preconditions.CheckNotNull(value, "value");
      }
    }

    public override bool Equals(object other) {
      return Equals(other as OneString);
    }

    public bool Equals(OneString other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (Data != other.Data) return false;
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      if (Data.Length != 0) hash ^= Data.GetHashCode();
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
      if (Data.Length != 0) {
        output.WriteRawTag(10);
        output.WriteString(Data);
      }
    }

    public int CalculateSize() {
      int size = 0;
      if (Data.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(Data);
      }
      return size;
    }

    public void MergeFrom(OneString other) {
      if (other == null) {
        return;
      }
      if (other.Data.Length != 0) {
        Data = other.Data;
      }
    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 10: {
            Data = input.ReadString();
            break;
          }
        }
      }
    }

  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class MoreString : pb::IMessage<MoreString> {
    private static readonly pb::MessageParser<MoreString> _parser = new pb::MessageParser<MoreString>(() => new MoreString());
    public static pb::MessageParser<MoreString> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[14]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public MoreString() {
      OnConstruction();
    }

    partial void OnConstruction();

    public MoreString(MoreString other) : this() {
      data_ = other.data_.Clone();
    }

    public MoreString Clone() {
      return new MoreString(this);
    }

    /// <summary>Field number for the "data" field.</summary>
    public const int DataFieldNumber = 1;
    private static readonly pb::FieldCodec<string> _repeated_data_codec
        = pb::FieldCodec.ForString(10);
    private readonly pbc::RepeatedField<string> data_ = new pbc::RepeatedField<string>();
    public pbc::RepeatedField<string> Data {
      get { return data_; }
    }

    public override bool Equals(object other) {
      return Equals(other as MoreString);
    }

    public bool Equals(MoreString other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if(!data_.Equals(other.data_)) return false;
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      hash ^= data_.GetHashCode();
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
      data_.WriteTo(output, _repeated_data_codec);
    }

    public int CalculateSize() {
      int size = 0;
      size += data_.CalculateSize(_repeated_data_codec);
      return size;
    }

    public void MergeFrom(MoreString other) {
      if (other == null) {
        return;
      }
      data_.Add(other.data_);
    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 10: {
            data_.AddEntriesFrom(input, _repeated_data_codec);
            break;
          }
        }
      }
    }

  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class OneBytes : pb::IMessage<OneBytes> {
    private static readonly pb::MessageParser<OneBytes> _parser = new pb::MessageParser<OneBytes>(() => new OneBytes());
    public static pb::MessageParser<OneBytes> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[15]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public OneBytes() {
      OnConstruction();
    }

    partial void OnConstruction();

    public OneBytes(OneBytes other) : this() {
      data_ = other.data_;
    }

    public OneBytes Clone() {
      return new OneBytes(this);
    }

    /// <summary>Field number for the "data" field.</summary>
    public const int DataFieldNumber = 1;
    private pb::ByteString data_ = pb::ByteString.Empty;
    public pb::ByteString Data {
      get { return data_; }
      set {
        data_ = pb::Preconditions.CheckNotNull(value, "value");
      }
    }

    public override bool Equals(object other) {
      return Equals(other as OneBytes);
    }

    public bool Equals(OneBytes other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (Data != other.Data) return false;
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      if (Data.Length != 0) hash ^= Data.GetHashCode();
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
      if (Data.Length != 0) {
        output.WriteRawTag(10);
        output.WriteBytes(Data);
      }
    }

    public int CalculateSize() {
      int size = 0;
      if (Data.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeBytesSize(Data);
      }
      return size;
    }

    public void MergeFrom(OneBytes other) {
      if (other == null) {
        return;
      }
      if (other.Data.Length != 0) {
        Data = other.Data;
      }
    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 10: {
            Data = input.ReadBytes();
            break;
          }
        }
      }
    }

  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class MoreBytes : pb::IMessage<MoreBytes> {
    private static readonly pb::MessageParser<MoreBytes> _parser = new pb::MessageParser<MoreBytes>(() => new MoreBytes());
    public static pb::MessageParser<MoreBytes> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[16]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public MoreBytes() {
      OnConstruction();
    }

    partial void OnConstruction();

    public MoreBytes(MoreBytes other) : this() {
      data_ = other.data_;
    }

    public MoreBytes Clone() {
      return new MoreBytes(this);
    }

    /// <summary>Field number for the "data" field.</summary>
    public const int DataFieldNumber = 1;
    private pb::ByteString data_ = pb::ByteString.Empty;
    public pb::ByteString Data {
      get { return data_; }
      set {
        data_ = pb::Preconditions.CheckNotNull(value, "value");
      }
    }

    public override bool Equals(object other) {
      return Equals(other as MoreBytes);
    }

    public bool Equals(MoreBytes other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (Data != other.Data) return false;
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      if (Data.Length != 0) hash ^= Data.GetHashCode();
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
      if (Data.Length != 0) {
        output.WriteRawTag(10);
        output.WriteBytes(Data);
      }
    }

    public int CalculateSize() {
      int size = 0;
      if (Data.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeBytesSize(Data);
      }
      return size;
    }

    public void MergeFrom(MoreBytes other) {
      if (other == null) {
        return;
      }
      if (other.Data.Length != 0) {
        Data = other.Data;
      }
    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 10: {
            Data = input.ReadBytes();
            break;
          }
        }
      }
    }

  }

  /// <summary>
  ///  Test int32, uint32, int64, uint64, and bool are all compatible
  /// </summary>
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class Int32Message : pb::IMessage<Int32Message> {
    private static readonly pb::MessageParser<Int32Message> _parser = new pb::MessageParser<Int32Message>(() => new Int32Message());
    public static pb::MessageParser<Int32Message> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[17]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public Int32Message() {
      OnConstruction();
    }

    partial void OnConstruction();

    public Int32Message(Int32Message other) : this() {
      data_ = other.data_;
    }

    public Int32Message Clone() {
      return new Int32Message(this);
    }

    /// <summary>Field number for the "data" field.</summary>
    public const int DataFieldNumber = 1;
    private int data_;
    public int Data {
      get { return data_; }
      set {
        data_ = value;
      }
    }

    public override bool Equals(object other) {
      return Equals(other as Int32Message);
    }

    public bool Equals(Int32Message other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (Data != other.Data) return false;
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      if (Data != 0) hash ^= Data.GetHashCode();
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
      if (Data != 0) {
        output.WriteRawTag(8);
        output.WriteInt32(Data);
      }
    }

    public int CalculateSize() {
      int size = 0;
      if (Data != 0) {
        size += 1 + pb::CodedOutputStream.ComputeInt32Size(Data);
      }
      return size;
    }

    public void MergeFrom(Int32Message other) {
      if (other == null) {
        return;
      }
      if (other.Data != 0) {
        Data = other.Data;
      }
    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 8: {
            Data = input.ReadInt32();
            break;
          }
        }
      }
    }

  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class Uint32Message : pb::IMessage<Uint32Message> {
    private static readonly pb::MessageParser<Uint32Message> _parser = new pb::MessageParser<Uint32Message>(() => new Uint32Message());
    public static pb::MessageParser<Uint32Message> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[18]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public Uint32Message() {
      OnConstruction();
    }

    partial void OnConstruction();

    public Uint32Message(Uint32Message other) : this() {
      data_ = other.data_;
    }

    public Uint32Message Clone() {
      return new Uint32Message(this);
    }

    /// <summary>Field number for the "data" field.</summary>
    public const int DataFieldNumber = 1;
    private uint data_;
    public uint Data {
      get { return data_; }
      set {
        data_ = value;
      }
    }

    public override bool Equals(object other) {
      return Equals(other as Uint32Message);
    }

    public bool Equals(Uint32Message other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (Data != other.Data) return false;
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      if (Data != 0) hash ^= Data.GetHashCode();
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
      if (Data != 0) {
        output.WriteRawTag(8);
        output.WriteUInt32(Data);
      }
    }

    public int CalculateSize() {
      int size = 0;
      if (Data != 0) {
        size += 1 + pb::CodedOutputStream.ComputeUInt32Size(Data);
      }
      return size;
    }

    public void MergeFrom(Uint32Message other) {
      if (other == null) {
        return;
      }
      if (other.Data != 0) {
        Data = other.Data;
      }
    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 8: {
            Data = input.ReadUInt32();
            break;
          }
        }
      }
    }

  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class Int64Message : pb::IMessage<Int64Message> {
    private static readonly pb::MessageParser<Int64Message> _parser = new pb::MessageParser<Int64Message>(() => new Int64Message());
    public static pb::MessageParser<Int64Message> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[19]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public Int64Message() {
      OnConstruction();
    }

    partial void OnConstruction();

    public Int64Message(Int64Message other) : this() {
      data_ = other.data_;
    }

    public Int64Message Clone() {
      return new Int64Message(this);
    }

    /// <summary>Field number for the "data" field.</summary>
    public const int DataFieldNumber = 1;
    private long data_;
    public long Data {
      get { return data_; }
      set {
        data_ = value;
      }
    }

    public override bool Equals(object other) {
      return Equals(other as Int64Message);
    }

    public bool Equals(Int64Message other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (Data != other.Data) return false;
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      if (Data != 0L) hash ^= Data.GetHashCode();
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
      if (Data != 0L) {
        output.WriteRawTag(8);
        output.WriteInt64(Data);
      }
    }

    public int CalculateSize() {
      int size = 0;
      if (Data != 0L) {
        size += 1 + pb::CodedOutputStream.ComputeInt64Size(Data);
      }
      return size;
    }

    public void MergeFrom(Int64Message other) {
      if (other == null) {
        return;
      }
      if (other.Data != 0L) {
        Data = other.Data;
      }
    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 8: {
            Data = input.ReadInt64();
            break;
          }
        }
      }
    }

  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class Uint64Message : pb::IMessage<Uint64Message> {
    private static readonly pb::MessageParser<Uint64Message> _parser = new pb::MessageParser<Uint64Message>(() => new Uint64Message());
    public static pb::MessageParser<Uint64Message> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[20]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public Uint64Message() {
      OnConstruction();
    }

    partial void OnConstruction();

    public Uint64Message(Uint64Message other) : this() {
      data_ = other.data_;
    }

    public Uint64Message Clone() {
      return new Uint64Message(this);
    }

    /// <summary>Field number for the "data" field.</summary>
    public const int DataFieldNumber = 1;
    private ulong data_;
    public ulong Data {
      get { return data_; }
      set {
        data_ = value;
      }
    }

    public override bool Equals(object other) {
      return Equals(other as Uint64Message);
    }

    public bool Equals(Uint64Message other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (Data != other.Data) return false;
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      if (Data != 0UL) hash ^= Data.GetHashCode();
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
      if (Data != 0UL) {
        output.WriteRawTag(8);
        output.WriteUInt64(Data);
      }
    }

    public int CalculateSize() {
      int size = 0;
      if (Data != 0UL) {
        size += 1 + pb::CodedOutputStream.ComputeUInt64Size(Data);
      }
      return size;
    }

    public void MergeFrom(Uint64Message other) {
      if (other == null) {
        return;
      }
      if (other.Data != 0UL) {
        Data = other.Data;
      }
    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 8: {
            Data = input.ReadUInt64();
            break;
          }
        }
      }
    }

  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class BoolMessage : pb::IMessage<BoolMessage> {
    private static readonly pb::MessageParser<BoolMessage> _parser = new pb::MessageParser<BoolMessage>(() => new BoolMessage());
    public static pb::MessageParser<BoolMessage> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[21]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public BoolMessage() {
      OnConstruction();
    }

    partial void OnConstruction();

    public BoolMessage(BoolMessage other) : this() {
      data_ = other.data_;
    }

    public BoolMessage Clone() {
      return new BoolMessage(this);
    }

    /// <summary>Field number for the "data" field.</summary>
    public const int DataFieldNumber = 1;
    private bool data_;
    public bool Data {
      get { return data_; }
      set {
        data_ = value;
      }
    }

    public override bool Equals(object other) {
      return Equals(other as BoolMessage);
    }

    public bool Equals(BoolMessage other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (Data != other.Data) return false;
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      if (Data != false) hash ^= Data.GetHashCode();
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
      if (Data != false) {
        output.WriteRawTag(8);
        output.WriteBool(Data);
      }
    }

    public int CalculateSize() {
      int size = 0;
      if (Data != false) {
        size += 1 + 1;
      }
      return size;
    }

    public void MergeFrom(BoolMessage other) {
      if (other == null) {
        return;
      }
      if (other.Data != false) {
        Data = other.Data;
      }
    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 8: {
            Data = input.ReadBool();
            break;
          }
        }
      }
    }

  }

  /// <summary>
  ///  Test oneofs.
  /// </summary>
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestOneof : pb::IMessage<TestOneof> {
    private static readonly pb::MessageParser<TestOneof> _parser = new pb::MessageParser<TestOneof>(() => new TestOneof());
    public static pb::MessageParser<TestOneof> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[22]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public TestOneof() {
      OnConstruction();
    }

    partial void OnConstruction();

    public TestOneof(TestOneof other) : this() {
      switch (other.FooCase) {
        case FooOneofCase.FooInt:
          FooInt = other.FooInt;
          break;
        case FooOneofCase.FooString:
          FooString = other.FooString;
          break;
        case FooOneofCase.FooMessage:
          FooMessage = other.FooMessage.Clone();
          break;
      }

    }

    public TestOneof Clone() {
      return new TestOneof(this);
    }

    /// <summary>Field number for the "foo_int" field.</summary>
    public const int FooIntFieldNumber = 1;
    public int FooInt {
      get { return fooCase_ == FooOneofCase.FooInt ? (int) foo_ : 0; }
      set {
        foo_ = value;
        fooCase_ = FooOneofCase.FooInt;
      }
    }

    /// <summary>Field number for the "foo_string" field.</summary>
    public const int FooStringFieldNumber = 2;
    public string FooString {
      get { return fooCase_ == FooOneofCase.FooString ? (string) foo_ : ""; }
      set {
        foo_ = pb::Preconditions.CheckNotNull(value, "value");
        fooCase_ = FooOneofCase.FooString;
      }
    }

    /// <summary>Field number for the "foo_message" field.</summary>
    public const int FooMessageFieldNumber = 3;
    public global::Google.Protobuf.TestProtos.TestAllTypes FooMessage {
      get { return fooCase_ == FooOneofCase.FooMessage ? (global::Google.Protobuf.TestProtos.TestAllTypes) foo_ : null; }
      set {
        foo_ = value;
        fooCase_ = value == null ? FooOneofCase.None : FooOneofCase.FooMessage;
      }
    }

    private object foo_;
    /// <summary>Enum of possible cases for the "foo" oneof.</summary>
    public enum FooOneofCase {
      None = 0,
      FooInt = 1,
      FooString = 2,
      FooMessage = 3,
    }
    private FooOneofCase fooCase_ = FooOneofCase.None;
    public FooOneofCase FooCase {
      get { return fooCase_; }
    }

    public void ClearFoo() {
      fooCase_ = FooOneofCase.None;
      foo_ = null;
    }

    public override bool Equals(object other) {
      return Equals(other as TestOneof);
    }

    public bool Equals(TestOneof other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (FooInt != other.FooInt) return false;
      if (FooString != other.FooString) return false;
      if (!object.Equals(FooMessage, other.FooMessage)) return false;
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      if (fooCase_ == FooOneofCase.FooInt) hash ^= FooInt.GetHashCode();
      if (fooCase_ == FooOneofCase.FooString) hash ^= FooString.GetHashCode();
      if (fooCase_ == FooOneofCase.FooMessage) hash ^= FooMessage.GetHashCode();
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
      if (fooCase_ == FooOneofCase.FooInt) {
        output.WriteRawTag(8);
        output.WriteInt32(FooInt);
      }
      if (fooCase_ == FooOneofCase.FooString) {
        output.WriteRawTag(18);
        output.WriteString(FooString);
      }
      if (fooCase_ == FooOneofCase.FooMessage) {
        output.WriteRawTag(26);
        output.WriteMessage(FooMessage);
      }
    }

    public int CalculateSize() {
      int size = 0;
      if (fooCase_ == FooOneofCase.FooInt) {
        size += 1 + pb::CodedOutputStream.ComputeInt32Size(FooInt);
      }
      if (fooCase_ == FooOneofCase.FooString) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(FooString);
      }
      if (fooCase_ == FooOneofCase.FooMessage) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(FooMessage);
      }
      return size;
    }

    public void MergeFrom(TestOneof other) {
      if (other == null) {
        return;
      }
      switch (other.FooCase) {
        case FooOneofCase.FooInt:
          FooInt = other.FooInt;
          break;
        case FooOneofCase.FooString:
          FooString = other.FooString;
          break;
        case FooOneofCase.FooMessage:
          FooMessage = other.FooMessage;
          break;
      }

    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 8: {
            FooInt = input.ReadInt32();
            break;
          }
          case 18: {
            FooString = input.ReadString();
            break;
          }
          case 26: {
            global::Google.Protobuf.TestProtos.TestAllTypes subBuilder = new global::Google.Protobuf.TestProtos.TestAllTypes();
            if (fooCase_ == FooOneofCase.FooMessage) {
              subBuilder.MergeFrom(FooMessage);
            }
            input.ReadMessage(subBuilder);
            FooMessage = subBuilder;
            break;
          }
        }
      }
    }

  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestPackedTypes : pb::IMessage<TestPackedTypes> {
    private static readonly pb::MessageParser<TestPackedTypes> _parser = new pb::MessageParser<TestPackedTypes>(() => new TestPackedTypes());
    public static pb::MessageParser<TestPackedTypes> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[23]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public TestPackedTypes() {
      OnConstruction();
    }

    partial void OnConstruction();

    public TestPackedTypes(TestPackedTypes other) : this() {
      packedInt32_ = other.packedInt32_.Clone();
      packedInt64_ = other.packedInt64_.Clone();
      packedUint32_ = other.packedUint32_.Clone();
      packedUint64_ = other.packedUint64_.Clone();
      packedSint32_ = other.packedSint32_.Clone();
      packedSint64_ = other.packedSint64_.Clone();
      packedFixed32_ = other.packedFixed32_.Clone();
      packedFixed64_ = other.packedFixed64_.Clone();
      packedSfixed32_ = other.packedSfixed32_.Clone();
      packedSfixed64_ = other.packedSfixed64_.Clone();
      packedFloat_ = other.packedFloat_.Clone();
      packedDouble_ = other.packedDouble_.Clone();
      packedBool_ = other.packedBool_.Clone();
      packedEnum_ = other.packedEnum_.Clone();
    }

    public TestPackedTypes Clone() {
      return new TestPackedTypes(this);
    }

    /// <summary>Field number for the "packed_int32" field.</summary>
    public const int PackedInt32FieldNumber = 90;
    private static readonly pb::FieldCodec<int> _repeated_packedInt32_codec
        = pb::FieldCodec.ForInt32(722);
    private readonly pbc::RepeatedField<int> packedInt32_ = new pbc::RepeatedField<int>();
    public pbc::RepeatedField<int> PackedInt32 {
      get { return packedInt32_; }
    }

    /// <summary>Field number for the "packed_int64" field.</summary>
    public const int PackedInt64FieldNumber = 91;
    private static readonly pb::FieldCodec<long> _repeated_packedInt64_codec
        = pb::FieldCodec.ForInt64(730);
    private readonly pbc::RepeatedField<long> packedInt64_ = new pbc::RepeatedField<long>();
    public pbc::RepeatedField<long> PackedInt64 {
      get { return packedInt64_; }
    }

    /// <summary>Field number for the "packed_uint32" field.</summary>
    public const int PackedUint32FieldNumber = 92;
    private static readonly pb::FieldCodec<uint> _repeated_packedUint32_codec
        = pb::FieldCodec.ForUInt32(738);
    private readonly pbc::RepeatedField<uint> packedUint32_ = new pbc::RepeatedField<uint>();
    public pbc::RepeatedField<uint> PackedUint32 {
      get { return packedUint32_; }
    }

    /// <summary>Field number for the "packed_uint64" field.</summary>
    public const int PackedUint64FieldNumber = 93;
    private static readonly pb::FieldCodec<ulong> _repeated_packedUint64_codec
        = pb::FieldCodec.ForUInt64(746);
    private readonly pbc::RepeatedField<ulong> packedUint64_ = new pbc::RepeatedField<ulong>();
    public pbc::RepeatedField<ulong> PackedUint64 {
      get { return packedUint64_; }
    }

    /// <summary>Field number for the "packed_sint32" field.</summary>
    public const int PackedSint32FieldNumber = 94;
    private static readonly pb::FieldCodec<int> _repeated_packedSint32_codec
        = pb::FieldCodec.ForSInt32(754);
    private readonly pbc::RepeatedField<int> packedSint32_ = new pbc::RepeatedField<int>();
    public pbc::RepeatedField<int> PackedSint32 {
      get { return packedSint32_; }
    }

    /// <summary>Field number for the "packed_sint64" field.</summary>
    public const int PackedSint64FieldNumber = 95;
    private static readonly pb::FieldCodec<long> _repeated_packedSint64_codec
        = pb::FieldCodec.ForSInt64(762);
    private readonly pbc::RepeatedField<long> packedSint64_ = new pbc::RepeatedField<long>();
    public pbc::RepeatedField<long> PackedSint64 {
      get { return packedSint64_; }
    }

    /// <summary>Field number for the "packed_fixed32" field.</summary>
    public const int PackedFixed32FieldNumber = 96;
    private static readonly pb::FieldCodec<uint> _repeated_packedFixed32_codec
        = pb::FieldCodec.ForFixed32(770);
    private readonly pbc::RepeatedField<uint> packedFixed32_ = new pbc::RepeatedField<uint>();
    public pbc::RepeatedField<uint> PackedFixed32 {
      get { return packedFixed32_; }
    }

    /// <summary>Field number for the "packed_fixed64" field.</summary>
    public const int PackedFixed64FieldNumber = 97;
    private static readonly pb::FieldCodec<ulong> _repeated_packedFixed64_codec
        = pb::FieldCodec.ForFixed64(778);
    private readonly pbc::RepeatedField<ulong> packedFixed64_ = new pbc::RepeatedField<ulong>();
    public pbc::RepeatedField<ulong> PackedFixed64 {
      get { return packedFixed64_; }
    }

    /// <summary>Field number for the "packed_sfixed32" field.</summary>
    public const int PackedSfixed32FieldNumber = 98;
    private static readonly pb::FieldCodec<int> _repeated_packedSfixed32_codec
        = pb::FieldCodec.ForSFixed32(786);
    private readonly pbc::RepeatedField<int> packedSfixed32_ = new pbc::RepeatedField<int>();
    public pbc::RepeatedField<int> PackedSfixed32 {
      get { return packedSfixed32_; }
    }

    /// <summary>Field number for the "packed_sfixed64" field.</summary>
    public const int PackedSfixed64FieldNumber = 99;
    private static readonly pb::FieldCodec<long> _repeated_packedSfixed64_codec
        = pb::FieldCodec.ForSFixed64(794);
    private readonly pbc::RepeatedField<long> packedSfixed64_ = new pbc::RepeatedField<long>();
    public pbc::RepeatedField<long> PackedSfixed64 {
      get { return packedSfixed64_; }
    }

    /// <summary>Field number for the "packed_float" field.</summary>
    public const int PackedFloatFieldNumber = 100;
    private static readonly pb::FieldCodec<float> _repeated_packedFloat_codec
        = pb::FieldCodec.ForFloat(802);
    private readonly pbc::RepeatedField<float> packedFloat_ = new pbc::RepeatedField<float>();
    public pbc::RepeatedField<float> PackedFloat {
      get { return packedFloat_; }
    }

    /// <summary>Field number for the "packed_double" field.</summary>
    public const int PackedDoubleFieldNumber = 101;
    private static readonly pb::FieldCodec<double> _repeated_packedDouble_codec
        = pb::FieldCodec.ForDouble(810);
    private readonly pbc::RepeatedField<double> packedDouble_ = new pbc::RepeatedField<double>();
    public pbc::RepeatedField<double> PackedDouble {
      get { return packedDouble_; }
    }

    /// <summary>Field number for the "packed_bool" field.</summary>
    public const int PackedBoolFieldNumber = 102;
    private static readonly pb::FieldCodec<bool> _repeated_packedBool_codec
        = pb::FieldCodec.ForBool(818);
    private readonly pbc::RepeatedField<bool> packedBool_ = new pbc::RepeatedField<bool>();
    public pbc::RepeatedField<bool> PackedBool {
      get { return packedBool_; }
    }

    /// <summary>Field number for the "packed_enum" field.</summary>
    public const int PackedEnumFieldNumber = 103;
    private static readonly pb::FieldCodec<global::Google.Protobuf.TestProtos.ForeignEnum> _repeated_packedEnum_codec
        = pb::FieldCodec.ForEnum(826, x => (int) x, x => (global::Google.Protobuf.TestProtos.ForeignEnum) x);
    private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum> packedEnum_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum>();
    public pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum> PackedEnum {
      get { return packedEnum_; }
    }

    public override bool Equals(object other) {
      return Equals(other as TestPackedTypes);
    }

    public bool Equals(TestPackedTypes other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if(!packedInt32_.Equals(other.packedInt32_)) return false;
      if(!packedInt64_.Equals(other.packedInt64_)) return false;
      if(!packedUint32_.Equals(other.packedUint32_)) return false;
      if(!packedUint64_.Equals(other.packedUint64_)) return false;
      if(!packedSint32_.Equals(other.packedSint32_)) return false;
      if(!packedSint64_.Equals(other.packedSint64_)) return false;
      if(!packedFixed32_.Equals(other.packedFixed32_)) return false;
      if(!packedFixed64_.Equals(other.packedFixed64_)) return false;
      if(!packedSfixed32_.Equals(other.packedSfixed32_)) return false;
      if(!packedSfixed64_.Equals(other.packedSfixed64_)) return false;
      if(!packedFloat_.Equals(other.packedFloat_)) return false;
      if(!packedDouble_.Equals(other.packedDouble_)) return false;
      if(!packedBool_.Equals(other.packedBool_)) return false;
      if(!packedEnum_.Equals(other.packedEnum_)) return false;
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      hash ^= packedInt32_.GetHashCode();
      hash ^= packedInt64_.GetHashCode();
      hash ^= packedUint32_.GetHashCode();
      hash ^= packedUint64_.GetHashCode();
      hash ^= packedSint32_.GetHashCode();
      hash ^= packedSint64_.GetHashCode();
      hash ^= packedFixed32_.GetHashCode();
      hash ^= packedFixed64_.GetHashCode();
      hash ^= packedSfixed32_.GetHashCode();
      hash ^= packedSfixed64_.GetHashCode();
      hash ^= packedFloat_.GetHashCode();
      hash ^= packedDouble_.GetHashCode();
      hash ^= packedBool_.GetHashCode();
      hash ^= packedEnum_.GetHashCode();
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
      packedInt32_.WriteTo(output, _repeated_packedInt32_codec);
      packedInt64_.WriteTo(output, _repeated_packedInt64_codec);
      packedUint32_.WriteTo(output, _repeated_packedUint32_codec);
      packedUint64_.WriteTo(output, _repeated_packedUint64_codec);
      packedSint32_.WriteTo(output, _repeated_packedSint32_codec);
      packedSint64_.WriteTo(output, _repeated_packedSint64_codec);
      packedFixed32_.WriteTo(output, _repeated_packedFixed32_codec);
      packedFixed64_.WriteTo(output, _repeated_packedFixed64_codec);
      packedSfixed32_.WriteTo(output, _repeated_packedSfixed32_codec);
      packedSfixed64_.WriteTo(output, _repeated_packedSfixed64_codec);
      packedFloat_.WriteTo(output, _repeated_packedFloat_codec);
      packedDouble_.WriteTo(output, _repeated_packedDouble_codec);
      packedBool_.WriteTo(output, _repeated_packedBool_codec);
      packedEnum_.WriteTo(output, _repeated_packedEnum_codec);
    }

    public int CalculateSize() {
      int size = 0;
      size += packedInt32_.CalculateSize(_repeated_packedInt32_codec);
      size += packedInt64_.CalculateSize(_repeated_packedInt64_codec);
      size += packedUint32_.CalculateSize(_repeated_packedUint32_codec);
      size += packedUint64_.CalculateSize(_repeated_packedUint64_codec);
      size += packedSint32_.CalculateSize(_repeated_packedSint32_codec);
      size += packedSint64_.CalculateSize(_repeated_packedSint64_codec);
      size += packedFixed32_.CalculateSize(_repeated_packedFixed32_codec);
      size += packedFixed64_.CalculateSize(_repeated_packedFixed64_codec);
      size += packedSfixed32_.CalculateSize(_repeated_packedSfixed32_codec);
      size += packedSfixed64_.CalculateSize(_repeated_packedSfixed64_codec);
      size += packedFloat_.CalculateSize(_repeated_packedFloat_codec);
      size += packedDouble_.CalculateSize(_repeated_packedDouble_codec);
      size += packedBool_.CalculateSize(_repeated_packedBool_codec);
      size += packedEnum_.CalculateSize(_repeated_packedEnum_codec);
      return size;
    }

    public void MergeFrom(TestPackedTypes other) {
      if (other == null) {
        return;
      }
      packedInt32_.Add(other.packedInt32_);
      packedInt64_.Add(other.packedInt64_);
      packedUint32_.Add(other.packedUint32_);
      packedUint64_.Add(other.packedUint64_);
      packedSint32_.Add(other.packedSint32_);
      packedSint64_.Add(other.packedSint64_);
      packedFixed32_.Add(other.packedFixed32_);
      packedFixed64_.Add(other.packedFixed64_);
      packedSfixed32_.Add(other.packedSfixed32_);
      packedSfixed64_.Add(other.packedSfixed64_);
      packedFloat_.Add(other.packedFloat_);
      packedDouble_.Add(other.packedDouble_);
      packedBool_.Add(other.packedBool_);
      packedEnum_.Add(other.packedEnum_);
    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 722:
          case 720: {
            packedInt32_.AddEntriesFrom(input, _repeated_packedInt32_codec);
            break;
          }
          case 730:
          case 728: {
            packedInt64_.AddEntriesFrom(input, _repeated_packedInt64_codec);
            break;
          }
          case 738:
          case 736: {
            packedUint32_.AddEntriesFrom(input, _repeated_packedUint32_codec);
            break;
          }
          case 746:
          case 744: {
            packedUint64_.AddEntriesFrom(input, _repeated_packedUint64_codec);
            break;
          }
          case 754:
          case 752: {
            packedSint32_.AddEntriesFrom(input, _repeated_packedSint32_codec);
            break;
          }
          case 762:
          case 760: {
            packedSint64_.AddEntriesFrom(input, _repeated_packedSint64_codec);
            break;
          }
          case 770:
          case 773: {
            packedFixed32_.AddEntriesFrom(input, _repeated_packedFixed32_codec);
            break;
          }
          case 778:
          case 777: {
            packedFixed64_.AddEntriesFrom(input, _repeated_packedFixed64_codec);
            break;
          }
          case 786:
          case 789: {
            packedSfixed32_.AddEntriesFrom(input, _repeated_packedSfixed32_codec);
            break;
          }
          case 794:
          case 793: {
            packedSfixed64_.AddEntriesFrom(input, _repeated_packedSfixed64_codec);
            break;
          }
          case 802:
          case 805: {
            packedFloat_.AddEntriesFrom(input, _repeated_packedFloat_codec);
            break;
          }
          case 810:
          case 809: {
            packedDouble_.AddEntriesFrom(input, _repeated_packedDouble_codec);
            break;
          }
          case 818:
          case 816: {
            packedBool_.AddEntriesFrom(input, _repeated_packedBool_codec);
            break;
          }
          case 826:
          case 824: {
            packedEnum_.AddEntriesFrom(input, _repeated_packedEnum_codec);
            break;
          }
        }
      }
    }

  }

  /// <summary>
  ///  A message with the same fields as TestPackedTypes, but without packing. Used
  ///  to test packed &lt;-> unpacked wire compatibility.
  /// </summary>
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestUnpackedTypes : pb::IMessage<TestUnpackedTypes> {
    private static readonly pb::MessageParser<TestUnpackedTypes> _parser = new pb::MessageParser<TestUnpackedTypes>(() => new TestUnpackedTypes());
    public static pb::MessageParser<TestUnpackedTypes> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[24]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public TestUnpackedTypes() {
      OnConstruction();
    }

    partial void OnConstruction();

    public TestUnpackedTypes(TestUnpackedTypes other) : this() {
      unpackedInt32_ = other.unpackedInt32_.Clone();
      unpackedInt64_ = other.unpackedInt64_.Clone();
      unpackedUint32_ = other.unpackedUint32_.Clone();
      unpackedUint64_ = other.unpackedUint64_.Clone();
      unpackedSint32_ = other.unpackedSint32_.Clone();
      unpackedSint64_ = other.unpackedSint64_.Clone();
      unpackedFixed32_ = other.unpackedFixed32_.Clone();
      unpackedFixed64_ = other.unpackedFixed64_.Clone();
      unpackedSfixed32_ = other.unpackedSfixed32_.Clone();
      unpackedSfixed64_ = other.unpackedSfixed64_.Clone();
      unpackedFloat_ = other.unpackedFloat_.Clone();
      unpackedDouble_ = other.unpackedDouble_.Clone();
      unpackedBool_ = other.unpackedBool_.Clone();
      unpackedEnum_ = other.unpackedEnum_.Clone();
    }

    public TestUnpackedTypes Clone() {
      return new TestUnpackedTypes(this);
    }

    /// <summary>Field number for the "unpacked_int32" field.</summary>
    public const int UnpackedInt32FieldNumber = 90;
    private static readonly pb::FieldCodec<int> _repeated_unpackedInt32_codec
        = pb::FieldCodec.ForInt32(720);
    private readonly pbc::RepeatedField<int> unpackedInt32_ = new pbc::RepeatedField<int>();
    public pbc::RepeatedField<int> UnpackedInt32 {
      get { return unpackedInt32_; }
    }

    /// <summary>Field number for the "unpacked_int64" field.</summary>
    public const int UnpackedInt64FieldNumber = 91;
    private static readonly pb::FieldCodec<long> _repeated_unpackedInt64_codec
        = pb::FieldCodec.ForInt64(728);
    private readonly pbc::RepeatedField<long> unpackedInt64_ = new pbc::RepeatedField<long>();
    public pbc::RepeatedField<long> UnpackedInt64 {
      get { return unpackedInt64_; }
    }

    /// <summary>Field number for the "unpacked_uint32" field.</summary>
    public const int UnpackedUint32FieldNumber = 92;
    private static readonly pb::FieldCodec<uint> _repeated_unpackedUint32_codec
        = pb::FieldCodec.ForUInt32(736);
    private readonly pbc::RepeatedField<uint> unpackedUint32_ = new pbc::RepeatedField<uint>();
    public pbc::RepeatedField<uint> UnpackedUint32 {
      get { return unpackedUint32_; }
    }

    /// <summary>Field number for the "unpacked_uint64" field.</summary>
    public const int UnpackedUint64FieldNumber = 93;
    private static readonly pb::FieldCodec<ulong> _repeated_unpackedUint64_codec
        = pb::FieldCodec.ForUInt64(744);
    private readonly pbc::RepeatedField<ulong> unpackedUint64_ = new pbc::RepeatedField<ulong>();
    public pbc::RepeatedField<ulong> UnpackedUint64 {
      get { return unpackedUint64_; }
    }

    /// <summary>Field number for the "unpacked_sint32" field.</summary>
    public const int UnpackedSint32FieldNumber = 94;
    private static readonly pb::FieldCodec<int> _repeated_unpackedSint32_codec
        = pb::FieldCodec.ForSInt32(752);
    private readonly pbc::RepeatedField<int> unpackedSint32_ = new pbc::RepeatedField<int>();
    public pbc::RepeatedField<int> UnpackedSint32 {
      get { return unpackedSint32_; }
    }

    /// <summary>Field number for the "unpacked_sint64" field.</summary>
    public const int UnpackedSint64FieldNumber = 95;
    private static readonly pb::FieldCodec<long> _repeated_unpackedSint64_codec
        = pb::FieldCodec.ForSInt64(760);
    private readonly pbc::RepeatedField<long> unpackedSint64_ = new pbc::RepeatedField<long>();
    public pbc::RepeatedField<long> UnpackedSint64 {
      get { return unpackedSint64_; }
    }

    /// <summary>Field number for the "unpacked_fixed32" field.</summary>
    public const int UnpackedFixed32FieldNumber = 96;
    private static readonly pb::FieldCodec<uint> _repeated_unpackedFixed32_codec
        = pb::FieldCodec.ForFixed32(773);
    private readonly pbc::RepeatedField<uint> unpackedFixed32_ = new pbc::RepeatedField<uint>();
    public pbc::RepeatedField<uint> UnpackedFixed32 {
      get { return unpackedFixed32_; }
    }

    /// <summary>Field number for the "unpacked_fixed64" field.</summary>
    public const int UnpackedFixed64FieldNumber = 97;
    private static readonly pb::FieldCodec<ulong> _repeated_unpackedFixed64_codec
        = pb::FieldCodec.ForFixed64(777);
    private readonly pbc::RepeatedField<ulong> unpackedFixed64_ = new pbc::RepeatedField<ulong>();
    public pbc::RepeatedField<ulong> UnpackedFixed64 {
      get { return unpackedFixed64_; }
    }

    /// <summary>Field number for the "unpacked_sfixed32" field.</summary>
    public const int UnpackedSfixed32FieldNumber = 98;
    private static readonly pb::FieldCodec<int> _repeated_unpackedSfixed32_codec
        = pb::FieldCodec.ForSFixed32(789);
    private readonly pbc::RepeatedField<int> unpackedSfixed32_ = new pbc::RepeatedField<int>();
    public pbc::RepeatedField<int> UnpackedSfixed32 {
      get { return unpackedSfixed32_; }
    }

    /// <summary>Field number for the "unpacked_sfixed64" field.</summary>
    public const int UnpackedSfixed64FieldNumber = 99;
    private static readonly pb::FieldCodec<long> _repeated_unpackedSfixed64_codec
        = pb::FieldCodec.ForSFixed64(793);
    private readonly pbc::RepeatedField<long> unpackedSfixed64_ = new pbc::RepeatedField<long>();
    public pbc::RepeatedField<long> UnpackedSfixed64 {
      get { return unpackedSfixed64_; }
    }

    /// <summary>Field number for the "unpacked_float" field.</summary>
    public const int UnpackedFloatFieldNumber = 100;
    private static readonly pb::FieldCodec<float> _repeated_unpackedFloat_codec
        = pb::FieldCodec.ForFloat(805);
    private readonly pbc::RepeatedField<float> unpackedFloat_ = new pbc::RepeatedField<float>();
    public pbc::RepeatedField<float> UnpackedFloat {
      get { return unpackedFloat_; }
    }

    /// <summary>Field number for the "unpacked_double" field.</summary>
    public const int UnpackedDoubleFieldNumber = 101;
    private static readonly pb::FieldCodec<double> _repeated_unpackedDouble_codec
        = pb::FieldCodec.ForDouble(809);
    private readonly pbc::RepeatedField<double> unpackedDouble_ = new pbc::RepeatedField<double>();
    public pbc::RepeatedField<double> UnpackedDouble {
      get { return unpackedDouble_; }
    }

    /// <summary>Field number for the "unpacked_bool" field.</summary>
    public const int UnpackedBoolFieldNumber = 102;
    private static readonly pb::FieldCodec<bool> _repeated_unpackedBool_codec
        = pb::FieldCodec.ForBool(816);
    private readonly pbc::RepeatedField<bool> unpackedBool_ = new pbc::RepeatedField<bool>();
    public pbc::RepeatedField<bool> UnpackedBool {
      get { return unpackedBool_; }
    }

    /// <summary>Field number for the "unpacked_enum" field.</summary>
    public const int UnpackedEnumFieldNumber = 103;
    private static readonly pb::FieldCodec<global::Google.Protobuf.TestProtos.ForeignEnum> _repeated_unpackedEnum_codec
        = pb::FieldCodec.ForEnum(824, x => (int) x, x => (global::Google.Protobuf.TestProtos.ForeignEnum) x);
    private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum> unpackedEnum_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum>();
    public pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum> UnpackedEnum {
      get { return unpackedEnum_; }
    }

    public override bool Equals(object other) {
      return Equals(other as TestUnpackedTypes);
    }

    public bool Equals(TestUnpackedTypes other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if(!unpackedInt32_.Equals(other.unpackedInt32_)) return false;
      if(!unpackedInt64_.Equals(other.unpackedInt64_)) return false;
      if(!unpackedUint32_.Equals(other.unpackedUint32_)) return false;
      if(!unpackedUint64_.Equals(other.unpackedUint64_)) return false;
      if(!unpackedSint32_.Equals(other.unpackedSint32_)) return false;
      if(!unpackedSint64_.Equals(other.unpackedSint64_)) return false;
      if(!unpackedFixed32_.Equals(other.unpackedFixed32_)) return false;
      if(!unpackedFixed64_.Equals(other.unpackedFixed64_)) return false;
      if(!unpackedSfixed32_.Equals(other.unpackedSfixed32_)) return false;
      if(!unpackedSfixed64_.Equals(other.unpackedSfixed64_)) return false;
      if(!unpackedFloat_.Equals(other.unpackedFloat_)) return false;
      if(!unpackedDouble_.Equals(other.unpackedDouble_)) return false;
      if(!unpackedBool_.Equals(other.unpackedBool_)) return false;
      if(!unpackedEnum_.Equals(other.unpackedEnum_)) return false;
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      hash ^= unpackedInt32_.GetHashCode();
      hash ^= unpackedInt64_.GetHashCode();
      hash ^= unpackedUint32_.GetHashCode();
      hash ^= unpackedUint64_.GetHashCode();
      hash ^= unpackedSint32_.GetHashCode();
      hash ^= unpackedSint64_.GetHashCode();
      hash ^= unpackedFixed32_.GetHashCode();
      hash ^= unpackedFixed64_.GetHashCode();
      hash ^= unpackedSfixed32_.GetHashCode();
      hash ^= unpackedSfixed64_.GetHashCode();
      hash ^= unpackedFloat_.GetHashCode();
      hash ^= unpackedDouble_.GetHashCode();
      hash ^= unpackedBool_.GetHashCode();
      hash ^= unpackedEnum_.GetHashCode();
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
      unpackedInt32_.WriteTo(output, _repeated_unpackedInt32_codec);
      unpackedInt64_.WriteTo(output, _repeated_unpackedInt64_codec);
      unpackedUint32_.WriteTo(output, _repeated_unpackedUint32_codec);
      unpackedUint64_.WriteTo(output, _repeated_unpackedUint64_codec);
      unpackedSint32_.WriteTo(output, _repeated_unpackedSint32_codec);
      unpackedSint64_.WriteTo(output, _repeated_unpackedSint64_codec);
      unpackedFixed32_.WriteTo(output, _repeated_unpackedFixed32_codec);
      unpackedFixed64_.WriteTo(output, _repeated_unpackedFixed64_codec);
      unpackedSfixed32_.WriteTo(output, _repeated_unpackedSfixed32_codec);
      unpackedSfixed64_.WriteTo(output, _repeated_unpackedSfixed64_codec);
      unpackedFloat_.WriteTo(output, _repeated_unpackedFloat_codec);
      unpackedDouble_.WriteTo(output, _repeated_unpackedDouble_codec);
      unpackedBool_.WriteTo(output, _repeated_unpackedBool_codec);
      unpackedEnum_.WriteTo(output, _repeated_unpackedEnum_codec);
    }

    public int CalculateSize() {
      int size = 0;
      size += unpackedInt32_.CalculateSize(_repeated_unpackedInt32_codec);
      size += unpackedInt64_.CalculateSize(_repeated_unpackedInt64_codec);
      size += unpackedUint32_.CalculateSize(_repeated_unpackedUint32_codec);
      size += unpackedUint64_.CalculateSize(_repeated_unpackedUint64_codec);
      size += unpackedSint32_.CalculateSize(_repeated_unpackedSint32_codec);
      size += unpackedSint64_.CalculateSize(_repeated_unpackedSint64_codec);
      size += unpackedFixed32_.CalculateSize(_repeated_unpackedFixed32_codec);
      size += unpackedFixed64_.CalculateSize(_repeated_unpackedFixed64_codec);
      size += unpackedSfixed32_.CalculateSize(_repeated_unpackedSfixed32_codec);
      size += unpackedSfixed64_.CalculateSize(_repeated_unpackedSfixed64_codec);
      size += unpackedFloat_.CalculateSize(_repeated_unpackedFloat_codec);
      size += unpackedDouble_.CalculateSize(_repeated_unpackedDouble_codec);
      size += unpackedBool_.CalculateSize(_repeated_unpackedBool_codec);
      size += unpackedEnum_.CalculateSize(_repeated_unpackedEnum_codec);
      return size;
    }

    public void MergeFrom(TestUnpackedTypes other) {
      if (other == null) {
        return;
      }
      unpackedInt32_.Add(other.unpackedInt32_);
      unpackedInt64_.Add(other.unpackedInt64_);
      unpackedUint32_.Add(other.unpackedUint32_);
      unpackedUint64_.Add(other.unpackedUint64_);
      unpackedSint32_.Add(other.unpackedSint32_);
      unpackedSint64_.Add(other.unpackedSint64_);
      unpackedFixed32_.Add(other.unpackedFixed32_);
      unpackedFixed64_.Add(other.unpackedFixed64_);
      unpackedSfixed32_.Add(other.unpackedSfixed32_);
      unpackedSfixed64_.Add(other.unpackedSfixed64_);
      unpackedFloat_.Add(other.unpackedFloat_);
      unpackedDouble_.Add(other.unpackedDouble_);
      unpackedBool_.Add(other.unpackedBool_);
      unpackedEnum_.Add(other.unpackedEnum_);
    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 722:
          case 720: {
            unpackedInt32_.AddEntriesFrom(input, _repeated_unpackedInt32_codec);
            break;
          }
          case 730:
          case 728: {
            unpackedInt64_.AddEntriesFrom(input, _repeated_unpackedInt64_codec);
            break;
          }
          case 738:
          case 736: {
            unpackedUint32_.AddEntriesFrom(input, _repeated_unpackedUint32_codec);
            break;
          }
          case 746:
          case 744: {
            unpackedUint64_.AddEntriesFrom(input, _repeated_unpackedUint64_codec);
            break;
          }
          case 754:
          case 752: {
            unpackedSint32_.AddEntriesFrom(input, _repeated_unpackedSint32_codec);
            break;
          }
          case 762:
          case 760: {
            unpackedSint64_.AddEntriesFrom(input, _repeated_unpackedSint64_codec);
            break;
          }
          case 770:
          case 773: {
            unpackedFixed32_.AddEntriesFrom(input, _repeated_unpackedFixed32_codec);
            break;
          }
          case 778:
          case 777: {
            unpackedFixed64_.AddEntriesFrom(input, _repeated_unpackedFixed64_codec);
            break;
          }
          case 786:
          case 789: {
            unpackedSfixed32_.AddEntriesFrom(input, _repeated_unpackedSfixed32_codec);
            break;
          }
          case 794:
          case 793: {
            unpackedSfixed64_.AddEntriesFrom(input, _repeated_unpackedSfixed64_codec);
            break;
          }
          case 802:
          case 805: {
            unpackedFloat_.AddEntriesFrom(input, _repeated_unpackedFloat_codec);
            break;
          }
          case 810:
          case 809: {
            unpackedDouble_.AddEntriesFrom(input, _repeated_unpackedDouble_codec);
            break;
          }
          case 818:
          case 816: {
            unpackedBool_.AddEntriesFrom(input, _repeated_unpackedBool_codec);
            break;
          }
          case 826:
          case 824: {
            unpackedEnum_.AddEntriesFrom(input, _repeated_unpackedEnum_codec);
            break;
          }
        }
      }
    }

  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestRepeatedScalarDifferentTagSizes : pb::IMessage<TestRepeatedScalarDifferentTagSizes> {
    private static readonly pb::MessageParser<TestRepeatedScalarDifferentTagSizes> _parser = new pb::MessageParser<TestRepeatedScalarDifferentTagSizes>(() => new TestRepeatedScalarDifferentTagSizes());
    public static pb::MessageParser<TestRepeatedScalarDifferentTagSizes> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[25]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public TestRepeatedScalarDifferentTagSizes() {
      OnConstruction();
    }

    partial void OnConstruction();

    public TestRepeatedScalarDifferentTagSizes(TestRepeatedScalarDifferentTagSizes other) : this() {
      repeatedFixed32_ = other.repeatedFixed32_.Clone();
      repeatedInt32_ = other.repeatedInt32_.Clone();
      repeatedFixed64_ = other.repeatedFixed64_.Clone();
      repeatedInt64_ = other.repeatedInt64_.Clone();
      repeatedFloat_ = other.repeatedFloat_.Clone();
      repeatedUint64_ = other.repeatedUint64_.Clone();
    }

    public TestRepeatedScalarDifferentTagSizes Clone() {
      return new TestRepeatedScalarDifferentTagSizes(this);
    }

    /// <summary>Field number for the "repeated_fixed32" field.</summary>
    public const int RepeatedFixed32FieldNumber = 12;
    private static readonly pb::FieldCodec<uint> _repeated_repeatedFixed32_codec
        = pb::FieldCodec.ForFixed32(98);
    private readonly pbc::RepeatedField<uint> repeatedFixed32_ = new pbc::RepeatedField<uint>();
    /// <summary>
    ///  Parsing repeated fixed size values used to fail. This message needs to be
    ///  used in order to get a tag of the right size; all of the repeated fields
    ///  in TestAllTypes didn't trigger the check.
    /// </summary>
    public pbc::RepeatedField<uint> RepeatedFixed32 {
      get { return repeatedFixed32_; }
    }

    /// <summary>Field number for the "repeated_int32" field.</summary>
    public const int RepeatedInt32FieldNumber = 13;
    private static readonly pb::FieldCodec<int> _repeated_repeatedInt32_codec
        = pb::FieldCodec.ForInt32(106);
    private readonly pbc::RepeatedField<int> repeatedInt32_ = new pbc::RepeatedField<int>();
    /// <summary>
    ///  Check for a varint type, just for good measure.
    /// </summary>
    public pbc::RepeatedField<int> RepeatedInt32 {
      get { return repeatedInt32_; }
    }

    /// <summary>Field number for the "repeated_fixed64" field.</summary>
    public const int RepeatedFixed64FieldNumber = 2046;
    private static readonly pb::FieldCodec<ulong> _repeated_repeatedFixed64_codec
        = pb::FieldCodec.ForFixed64(16370);
    private readonly pbc::RepeatedField<ulong> repeatedFixed64_ = new pbc::RepeatedField<ulong>();
    /// <summary>
    ///  These have two-byte tags.
    /// </summary>
    public pbc::RepeatedField<ulong> RepeatedFixed64 {
      get { return repeatedFixed64_; }
    }

    /// <summary>Field number for the "repeated_int64" field.</summary>
    public const int RepeatedInt64FieldNumber = 2047;
    private static readonly pb::FieldCodec<long> _repeated_repeatedInt64_codec
        = pb::FieldCodec.ForInt64(16378);
    private readonly pbc::RepeatedField<long> repeatedInt64_ = new pbc::RepeatedField<long>();
    public pbc::RepeatedField<long> RepeatedInt64 {
      get { return repeatedInt64_; }
    }

    /// <summary>Field number for the "repeated_float" field.</summary>
    public const int RepeatedFloatFieldNumber = 262142;
    private static readonly pb::FieldCodec<float> _repeated_repeatedFloat_codec
        = pb::FieldCodec.ForFloat(2097138);
    private readonly pbc::RepeatedField<float> repeatedFloat_ = new pbc::RepeatedField<float>();
    /// <summary>
    ///  Three byte tags.
    /// </summary>
    public pbc::RepeatedField<float> RepeatedFloat {
      get { return repeatedFloat_; }
    }

    /// <summary>Field number for the "repeated_uint64" field.</summary>
    public const int RepeatedUint64FieldNumber = 262143;
    private static readonly pb::FieldCodec<ulong> _repeated_repeatedUint64_codec
        = pb::FieldCodec.ForUInt64(2097146);
    private readonly pbc::RepeatedField<ulong> repeatedUint64_ = new pbc::RepeatedField<ulong>();
    public pbc::RepeatedField<ulong> RepeatedUint64 {
      get { return repeatedUint64_; }
    }

    public override bool Equals(object other) {
      return Equals(other as TestRepeatedScalarDifferentTagSizes);
    }

    public bool Equals(TestRepeatedScalarDifferentTagSizes other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if(!repeatedFixed32_.Equals(other.repeatedFixed32_)) return false;
      if(!repeatedInt32_.Equals(other.repeatedInt32_)) return false;
      if(!repeatedFixed64_.Equals(other.repeatedFixed64_)) return false;
      if(!repeatedInt64_.Equals(other.repeatedInt64_)) return false;
      if(!repeatedFloat_.Equals(other.repeatedFloat_)) return false;
      if(!repeatedUint64_.Equals(other.repeatedUint64_)) return false;
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      hash ^= repeatedFixed32_.GetHashCode();
      hash ^= repeatedInt32_.GetHashCode();
      hash ^= repeatedFixed64_.GetHashCode();
      hash ^= repeatedInt64_.GetHashCode();
      hash ^= repeatedFloat_.GetHashCode();
      hash ^= repeatedUint64_.GetHashCode();
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
      repeatedFixed32_.WriteTo(output, _repeated_repeatedFixed32_codec);
      repeatedInt32_.WriteTo(output, _repeated_repeatedInt32_codec);
      repeatedFixed64_.WriteTo(output, _repeated_repeatedFixed64_codec);
      repeatedInt64_.WriteTo(output, _repeated_repeatedInt64_codec);
      repeatedFloat_.WriteTo(output, _repeated_repeatedFloat_codec);
      repeatedUint64_.WriteTo(output, _repeated_repeatedUint64_codec);
    }

    public int CalculateSize() {
      int size = 0;
      size += repeatedFixed32_.CalculateSize(_repeated_repeatedFixed32_codec);
      size += repeatedInt32_.CalculateSize(_repeated_repeatedInt32_codec);
      size += repeatedFixed64_.CalculateSize(_repeated_repeatedFixed64_codec);
      size += repeatedInt64_.CalculateSize(_repeated_repeatedInt64_codec);
      size += repeatedFloat_.CalculateSize(_repeated_repeatedFloat_codec);
      size += repeatedUint64_.CalculateSize(_repeated_repeatedUint64_codec);
      return size;
    }

    public void MergeFrom(TestRepeatedScalarDifferentTagSizes other) {
      if (other == null) {
        return;
      }
      repeatedFixed32_.Add(other.repeatedFixed32_);
      repeatedInt32_.Add(other.repeatedInt32_);
      repeatedFixed64_.Add(other.repeatedFixed64_);
      repeatedInt64_.Add(other.repeatedInt64_);
      repeatedFloat_.Add(other.repeatedFloat_);
      repeatedUint64_.Add(other.repeatedUint64_);
    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 98:
          case 101: {
            repeatedFixed32_.AddEntriesFrom(input, _repeated_repeatedFixed32_codec);
            break;
          }
          case 106:
          case 104: {
            repeatedInt32_.AddEntriesFrom(input, _repeated_repeatedInt32_codec);
            break;
          }
          case 16370:
          case 16369: {
            repeatedFixed64_.AddEntriesFrom(input, _repeated_repeatedFixed64_codec);
            break;
          }
          case 16378:
          case 16376: {
            repeatedInt64_.AddEntriesFrom(input, _repeated_repeatedInt64_codec);
            break;
          }
          case 2097138:
          case 2097141: {
            repeatedFloat_.AddEntriesFrom(input, _repeated_repeatedFloat_codec);
            break;
          }
          case 2097146:
          case 2097144: {
            repeatedUint64_.AddEntriesFrom(input, _repeated_repeatedUint64_codec);
            break;
          }
        }
      }
    }

  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestCommentInjectionMessage : pb::IMessage<TestCommentInjectionMessage> {
    private static readonly pb::MessageParser<TestCommentInjectionMessage> _parser = new pb::MessageParser<TestCommentInjectionMessage>(() => new TestCommentInjectionMessage());
    public static pb::MessageParser<TestCommentInjectionMessage> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[26]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public TestCommentInjectionMessage() {
      OnConstruction();
    }

    partial void OnConstruction();

    public TestCommentInjectionMessage(TestCommentInjectionMessage other) : this() {
      a_ = other.a_;
    }

    public TestCommentInjectionMessage Clone() {
      return new TestCommentInjectionMessage(this);
    }

    /// <summary>Field number for the "a" field.</summary>
    public const int AFieldNumber = 1;
    private string a_ = "";
    /// <summary>
    ///  */ &lt;- This should not close the generated doc comment
    /// </summary>
    public string A {
      get { return a_; }
      set {
        a_ = pb::Preconditions.CheckNotNull(value, "value");
      }
    }

    public override bool Equals(object other) {
      return Equals(other as TestCommentInjectionMessage);
    }

    public bool Equals(TestCommentInjectionMessage other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (A != other.A) return false;
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      if (A.Length != 0) hash ^= A.GetHashCode();
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
      if (A.Length != 0) {
        output.WriteRawTag(10);
        output.WriteString(A);
      }
    }

    public int CalculateSize() {
      int size = 0;
      if (A.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(A);
      }
      return size;
    }

    public void MergeFrom(TestCommentInjectionMessage other) {
      if (other == null) {
        return;
      }
      if (other.A.Length != 0) {
        A = other.A;
      }
    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 10: {
            A = input.ReadString();
            break;
          }
        }
      }
    }

  }

  /// <summary>
  ///  Test that RPC services work.
  /// </summary>
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class FooRequest : pb::IMessage<FooRequest> {
    private static readonly pb::MessageParser<FooRequest> _parser = new pb::MessageParser<FooRequest>(() => new FooRequest());
    public static pb::MessageParser<FooRequest> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[27]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public FooRequest() {
      OnConstruction();
    }

    partial void OnConstruction();

    public FooRequest(FooRequest other) : this() {
    }

    public FooRequest Clone() {
      return new FooRequest(this);
    }

    public override bool Equals(object other) {
      return Equals(other as FooRequest);
    }

    public bool Equals(FooRequest other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
    }

    public int CalculateSize() {
      int size = 0;
      return size;
    }

    public void MergeFrom(FooRequest other) {
      if (other == null) {
        return;
      }
    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
        }
      }
    }

  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class FooResponse : pb::IMessage<FooResponse> {
    private static readonly pb::MessageParser<FooResponse> _parser = new pb::MessageParser<FooResponse>(() => new FooResponse());
    public static pb::MessageParser<FooResponse> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[28]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public FooResponse() {
      OnConstruction();
    }

    partial void OnConstruction();

    public FooResponse(FooResponse other) : this() {
    }

    public FooResponse Clone() {
      return new FooResponse(this);
    }

    public override bool Equals(object other) {
      return Equals(other as FooResponse);
    }

    public bool Equals(FooResponse other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
    }

    public int CalculateSize() {
      int size = 0;
      return size;
    }

    public void MergeFrom(FooResponse other) {
      if (other == null) {
        return;
      }
    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
        }
      }
    }

  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class FooClientMessage : pb::IMessage<FooClientMessage> {
    private static readonly pb::MessageParser<FooClientMessage> _parser = new pb::MessageParser<FooClientMessage>(() => new FooClientMessage());
    public static pb::MessageParser<FooClientMessage> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[29]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public FooClientMessage() {
      OnConstruction();
    }

    partial void OnConstruction();

    public FooClientMessage(FooClientMessage other) : this() {
    }

    public FooClientMessage Clone() {
      return new FooClientMessage(this);
    }

    public override bool Equals(object other) {
      return Equals(other as FooClientMessage);
    }

    public bool Equals(FooClientMessage other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
    }

    public int CalculateSize() {
      int size = 0;
      return size;
    }

    public void MergeFrom(FooClientMessage other) {
      if (other == null) {
        return;
      }
    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
        }
      }
    }

  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class FooServerMessage : pb::IMessage<FooServerMessage> {
    private static readonly pb::MessageParser<FooServerMessage> _parser = new pb::MessageParser<FooServerMessage>(() => new FooServerMessage());
    public static pb::MessageParser<FooServerMessage> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[30]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public FooServerMessage() {
      OnConstruction();
    }

    partial void OnConstruction();

    public FooServerMessage(FooServerMessage other) : this() {
    }

    public FooServerMessage Clone() {
      return new FooServerMessage(this);
    }

    public override bool Equals(object other) {
      return Equals(other as FooServerMessage);
    }

    public bool Equals(FooServerMessage other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
    }

    public int CalculateSize() {
      int size = 0;
      return size;
    }

    public void MergeFrom(FooServerMessage other) {
      if (other == null) {
        return;
      }
    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
        }
      }
    }

  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class BarRequest : pb::IMessage<BarRequest> {
    private static readonly pb::MessageParser<BarRequest> _parser = new pb::MessageParser<BarRequest>(() => new BarRequest());
    public static pb::MessageParser<BarRequest> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[31]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public BarRequest() {
      OnConstruction();
    }

    partial void OnConstruction();

    public BarRequest(BarRequest other) : this() {
    }

    public BarRequest Clone() {
      return new BarRequest(this);
    }

    public override bool Equals(object other) {
      return Equals(other as BarRequest);
    }

    public bool Equals(BarRequest other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
    }

    public int CalculateSize() {
      int size = 0;
      return size;
    }

    public void MergeFrom(BarRequest other) {
      if (other == null) {
        return;
      }
    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
        }
      }
    }

  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class BarResponse : pb::IMessage<BarResponse> {
    private static readonly pb::MessageParser<BarResponse> _parser = new pb::MessageParser<BarResponse>(() => new BarResponse());
    public static pb::MessageParser<BarResponse> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[32]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public BarResponse() {
      OnConstruction();
    }

    partial void OnConstruction();

    public BarResponse(BarResponse other) : this() {
    }

    public BarResponse Clone() {
      return new BarResponse(this);
    }

    public override bool Equals(object other) {
      return Equals(other as BarResponse);
    }

    public bool Equals(BarResponse other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
    }

    public int CalculateSize() {
      int size = 0;
      return size;
    }

    public void MergeFrom(BarResponse other) {
      if (other == null) {
        return;
      }
    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
        }
      }
    }

  }

  #endregion

}

#endregion Designer generated code
