// <auto-generated>
//     Generated by the protocol buffer compiler.  DO NOT EDIT!
//     source: google/protobuf/descriptor.proto
// </auto-generated>
#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.Reflection {

  /// <summary>Holder for reflection information generated from google/protobuf/descriptor.proto</summary>
  internal static partial class DescriptorReflection {

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

    static DescriptorReflection() {
      byte[] descriptorData = global::System.Convert.FromBase64String(
          string.Concat(
            "CiBnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90bxIPZ29vZ2xlLnBy",
            "b3RvYnVmIkcKEUZpbGVEZXNjcmlwdG9yU2V0EjIKBGZpbGUYASADKAsyJC5n",
            "b29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90byLbAwoTRmlsZURl",
            "c2NyaXB0b3JQcm90bxIMCgRuYW1lGAEgASgJEg8KB3BhY2thZ2UYAiABKAkS",
            "EgoKZGVwZW5kZW5jeRgDIAMoCRIZChFwdWJsaWNfZGVwZW5kZW5jeRgKIAMo",
            "BRIXCg93ZWFrX2RlcGVuZGVuY3kYCyADKAUSNgoMbWVzc2FnZV90eXBlGAQg",
            "AygLMiAuZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90bxI3CgllbnVt",
            "X3R5cGUYBSADKAsyJC5nb29nbGUucHJvdG9idWYuRW51bURlc2NyaXB0b3JQ",
            "cm90bxI4CgdzZXJ2aWNlGAYgAygLMicuZ29vZ2xlLnByb3RvYnVmLlNlcnZp",
            "Y2VEZXNjcmlwdG9yUHJvdG8SOAoJZXh0ZW5zaW9uGAcgAygLMiUuZ29vZ2xl",
            "LnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvEi0KB29wdGlvbnMYCCAB",
            "KAsyHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMSOQoQc291cmNlX2Nv",
            "ZGVfaW5mbxgJIAEoCzIfLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5m",
            "bxIOCgZzeW50YXgYDCABKAkiqQUKD0Rlc2NyaXB0b3JQcm90bxIMCgRuYW1l",
            "GAEgASgJEjQKBWZpZWxkGAIgAygLMiUuZ29vZ2xlLnByb3RvYnVmLkZpZWxk",
            "RGVzY3JpcHRvclByb3RvEjgKCWV4dGVuc2lvbhgGIAMoCzIlLmdvb2dsZS5w",
            "cm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90bxI1CgtuZXN0ZWRfdHlwZRgD",
            "IAMoCzIgLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8SNwoJZW51",
            "bV90eXBlGAQgAygLMiQuZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9y",
            "UHJvdG8SSAoPZXh0ZW5zaW9uX3JhbmdlGAUgAygLMi8uZ29vZ2xlLnByb3Rv",
            "YnVmLkRlc2NyaXB0b3JQcm90by5FeHRlbnNpb25SYW5nZRI5CgpvbmVvZl9k",
            "ZWNsGAggAygLMiUuZ29vZ2xlLnByb3RvYnVmLk9uZW9mRGVzY3JpcHRvclBy",
            "b3RvEjAKB29wdGlvbnMYByABKAsyHy5nb29nbGUucHJvdG9idWYuTWVzc2Fn",
            "ZU9wdGlvbnMSRgoOcmVzZXJ2ZWRfcmFuZ2UYCSADKAsyLi5nb29nbGUucHJv",
            "dG9idWYuRGVzY3JpcHRvclByb3RvLlJlc2VydmVkUmFuZ2USFQoNcmVzZXJ2",
            "ZWRfbmFtZRgKIAMoCRplCg5FeHRlbnNpb25SYW5nZRINCgVzdGFydBgBIAEo",
            "BRILCgNlbmQYAiABKAUSNwoHb3B0aW9ucxgDIAEoCzImLmdvb2dsZS5wcm90",
            "b2J1Zi5FeHRlbnNpb25SYW5nZU9wdGlvbnMaKwoNUmVzZXJ2ZWRSYW5nZRIN",
            "CgVzdGFydBgBIAEoBRILCgNlbmQYAiABKAUiZwoVRXh0ZW5zaW9uUmFuZ2VP",
            "cHRpb25zEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2ds",
            "ZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIivAUK",
            "FEZpZWxkRGVzY3JpcHRvclByb3RvEgwKBG5hbWUYASABKAkSDgoGbnVtYmVy",
            "GAMgASgFEjoKBWxhYmVsGAQgASgOMisuZ29vZ2xlLnByb3RvYnVmLkZpZWxk",
            "RGVzY3JpcHRvclByb3RvLkxhYmVsEjgKBHR5cGUYBSABKA4yKi5nb29nbGUu",
            "cHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uVHlwZRIRCgl0eXBlX25h",
            "bWUYBiABKAkSEAoIZXh0ZW5kZWUYAiABKAkSFQoNZGVmYXVsdF92YWx1ZRgH",
            "IAEoCRITCgtvbmVvZl9pbmRleBgJIAEoBRIRCglqc29uX25hbWUYCiABKAkS",
            "LgoHb3B0aW9ucxgIIAEoCzIdLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlv",
            "bnMitgIKBFR5cGUSDwoLVFlQRV9ET1VCTEUQARIOCgpUWVBFX0ZMT0FUEAIS",
            "DgoKVFlQRV9JTlQ2NBADEg8KC1RZUEVfVUlOVDY0EAQSDgoKVFlQRV9JTlQz",
            "MhAFEhAKDFRZUEVfRklYRUQ2NBAGEhAKDFRZUEVfRklYRUQzMhAHEg0KCVRZ",
            "UEVfQk9PTBAIEg8KC1RZUEVfU1RSSU5HEAkSDgoKVFlQRV9HUk9VUBAKEhAK",
            "DFRZUEVfTUVTU0FHRRALEg4KClRZUEVfQllURVMQDBIPCgtUWVBFX1VJTlQz",
            "MhANEg0KCVRZUEVfRU5VTRAOEhEKDVRZUEVfU0ZJWEVEMzIQDxIRCg1UWVBF",
            "X1NGSVhFRDY0EBASDwoLVFlQRV9TSU5UMzIQERIPCgtUWVBFX1NJTlQ2NBAS",
            "IkMKBUxhYmVsEhIKDkxBQkVMX09QVElPTkFMEAESEgoOTEFCRUxfUkVRVUlS",
            "RUQQAhISCg5MQUJFTF9SRVBFQVRFRBADIlQKFE9uZW9mRGVzY3JpcHRvclBy",
            "b3RvEgwKBG5hbWUYASABKAkSLgoHb3B0aW9ucxgCIAEoCzIdLmdvb2dsZS5w",
            "cm90b2J1Zi5PbmVvZk9wdGlvbnMipAIKE0VudW1EZXNjcmlwdG9yUHJvdG8S",
            "DAoEbmFtZRgBIAEoCRI4CgV2YWx1ZRgCIAMoCzIpLmdvb2dsZS5wcm90b2J1",
            "Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8SLQoHb3B0aW9ucxgDIAEoCzIc",
            "Lmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucxJOCg5yZXNlcnZlZF9yYW5n",
            "ZRgEIAMoCzI2Lmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3Rv",
            "LkVudW1SZXNlcnZlZFJhbmdlEhUKDXJlc2VydmVkX25hbWUYBSADKAkaLwoR",
            "RW51bVJlc2VydmVkUmFuZ2USDQoFc3RhcnQYASABKAUSCwoDZW5kGAIgASgF",
            "ImwKGEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bxIMCgRuYW1lGAEgASgJEg4K",
            "Bm51bWJlchgCIAEoBRIyCgdvcHRpb25zGAMgASgLMiEuZ29vZ2xlLnByb3Rv",
            "YnVmLkVudW1WYWx1ZU9wdGlvbnMikAEKFlNlcnZpY2VEZXNjcmlwdG9yUHJv",
            "dG8SDAoEbmFtZRgBIAEoCRI2CgZtZXRob2QYAiADKAsyJi5nb29nbGUucHJv",
            "dG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvEjAKB29wdGlvbnMYAyABKAsy",
            "Hy5nb29nbGUucHJvdG9idWYuU2VydmljZU9wdGlvbnMiwQEKFU1ldGhvZERl",
            "c2NyaXB0b3JQcm90bxIMCgRuYW1lGAEgASgJEhIKCmlucHV0X3R5cGUYAiAB",
            "KAkSEwoLb3V0cHV0X3R5cGUYAyABKAkSLwoHb3B0aW9ucxgEIAEoCzIeLmdv",
            "b2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zEh8KEGNsaWVudF9zdHJlYW1p",
            "bmcYBSABKAg6BWZhbHNlEh8KEHNlcnZlcl9zdHJlYW1pbmcYBiABKAg6BWZh",
            "bHNlIqYGCgtGaWxlT3B0aW9ucxIUCgxqYXZhX3BhY2thZ2UYASABKAkSHAoU",
            "amF2YV9vdXRlcl9jbGFzc25hbWUYCCABKAkSIgoTamF2YV9tdWx0aXBsZV9m",
            "aWxlcxgKIAEoCDoFZmFsc2USKQodamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5k",
            "X2hhc2gYFCABKAhCAhgBEiUKFmphdmFfc3RyaW5nX2NoZWNrX3V0ZjgYGyAB",
            "KAg6BWZhbHNlEkYKDG9wdGltaXplX2ZvchgJIAEoDjIpLmdvb2dsZS5wcm90",
            "b2J1Zi5GaWxlT3B0aW9ucy5PcHRpbWl6ZU1vZGU6BVNQRUVEEhIKCmdvX3Bh",
            "Y2thZ2UYCyABKAkSIgoTY2NfZ2VuZXJpY19zZXJ2aWNlcxgQIAEoCDoFZmFs",
            "c2USJAoVamF2YV9nZW5lcmljX3NlcnZpY2VzGBEgASgIOgVmYWxzZRIiChNw",
            "eV9nZW5lcmljX3NlcnZpY2VzGBIgASgIOgVmYWxzZRIjChRwaHBfZ2VuZXJp",
            "Y19zZXJ2aWNlcxgqIAEoCDoFZmFsc2USGQoKZGVwcmVjYXRlZBgXIAEoCDoF",
            "ZmFsc2USHwoQY2NfZW5hYmxlX2FyZW5hcxgfIAEoCDoFZmFsc2USGQoRb2Jq",
            "Y19jbGFzc19wcmVmaXgYJCABKAkSGAoQY3NoYXJwX25hbWVzcGFjZRglIAEo",
            "CRIUCgxzd2lmdF9wcmVmaXgYJyABKAkSGAoQcGhwX2NsYXNzX3ByZWZpeBgo",
            "IAEoCRIVCg1waHBfbmFtZXNwYWNlGCkgASgJEh4KFnBocF9tZXRhZGF0YV9u",
            "YW1lc3BhY2UYLCABKAkSFAoMcnVieV9wYWNrYWdlGC0gASgJEkMKFHVuaW50",
            "ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5Vbmlu",
            "dGVycHJldGVkT3B0aW9uIjoKDE9wdGltaXplTW9kZRIJCgVTUEVFRBABEg0K",
            "CUNPREVfU0laRRACEhAKDExJVEVfUlVOVElNRRADKgkI6AcQgICAgAJKBAgm",
            "ECci8gEKDk1lc3NhZ2VPcHRpb25zEiYKF21lc3NhZ2Vfc2V0X3dpcmVfZm9y",
            "bWF0GAEgASgIOgVmYWxzZRIuCh9ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2Fj",
            "Y2Vzc29yGAIgASgIOgVmYWxzZRIZCgpkZXByZWNhdGVkGAMgASgIOgVmYWxz",
            "ZRIRCgltYXBfZW50cnkYByABKAgSQwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y",
            "5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24q",
            "CQjoBxCAgICAAkoECAgQCUoECAkQCiKeAwoMRmllbGRPcHRpb25zEjoKBWN0",
            "eXBlGAEgASgOMiMuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5DVHlw",
            "ZToGU1RSSU5HEg4KBnBhY2tlZBgCIAEoCBI/CgZqc3R5cGUYBiABKA4yJC5n",
            "b29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLkpTVHlwZToJSlNfTk9STUFM",
            "EhMKBGxhenkYBSABKAg6BWZhbHNlEhkKCmRlcHJlY2F0ZWQYAyABKAg6BWZh",
            "bHNlEhMKBHdlYWsYCiABKAg6BWZhbHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0",
            "aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0",
            "aW9uIi8KBUNUeXBlEgoKBlNUUklORxAAEggKBENPUkQQARIQCgxTVFJJTkdf",
            "UElFQ0UQAiI1CgZKU1R5cGUSDQoJSlNfTk9STUFMEAASDQoJSlNfU1RSSU5H",
            "EAESDQoJSlNfTlVNQkVSEAIqCQjoBxCAgICAAkoECAQQBSJeCgxPbmVvZk9w",
            "dGlvbnMSQwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xl",
            "LnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAiKTAQoL",
            "RW51bU9wdGlvbnMSEwoLYWxsb3dfYWxpYXMYAiABKAgSGQoKZGVwcmVjYXRl",
            "ZBgDIAEoCDoFZmFsc2USQwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygL",
            "MiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCA",
            "gICAAkoECAUQBiJ9ChBFbnVtVmFsdWVPcHRpb25zEhkKCmRlcHJlY2F0ZWQY",
            "ASABKAg6BWZhbHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIk",
            "Lmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICA",
            "gAIiewoOU2VydmljZU9wdGlvbnMSGQoKZGVwcmVjYXRlZBghIAEoCDoFZmFs",
            "c2USQwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnBy",
            "b3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAiKtAgoNTWV0",
            "aG9kT3B0aW9ucxIZCgpkZXByZWNhdGVkGCEgASgIOgVmYWxzZRJfChFpZGVt",
            "cG90ZW5jeV9sZXZlbBgiIAEoDjIvLmdvb2dsZS5wcm90b2J1Zi5NZXRob2RP",
            "cHRpb25zLklkZW1wb3RlbmN5TGV2ZWw6E0lERU1QT1RFTkNZX1VOS05PV04S",
            "QwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3Rv",
            "YnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24iUAoQSWRlbXBvdGVuY3lMZXZlbBIX",
            "ChNJREVNUE9URU5DWV9VTktOT1dOEAASEwoPTk9fU0lERV9FRkZFQ1RTEAES",
            "DgoKSURFTVBPVEVOVBACKgkI6AcQgICAgAIingIKE1VuaW50ZXJwcmV0ZWRP",
            "cHRpb24SOwoEbmFtZRgCIAMoCzItLmdvb2dsZS5wcm90b2J1Zi5VbmludGVy",
            "cHJldGVkT3B0aW9uLk5hbWVQYXJ0EhgKEGlkZW50aWZpZXJfdmFsdWUYAyAB",
            "KAkSGgoScG9zaXRpdmVfaW50X3ZhbHVlGAQgASgEEhoKEm5lZ2F0aXZlX2lu",
            "dF92YWx1ZRgFIAEoAxIUCgxkb3VibGVfdmFsdWUYBiABKAESFAoMc3RyaW5n",
            "X3ZhbHVlGAcgASgMEhcKD2FnZ3JlZ2F0ZV92YWx1ZRgIIAEoCRozCghOYW1l",
            "UGFydBIRCgluYW1lX3BhcnQYASACKAkSFAoMaXNfZXh0ZW5zaW9uGAIgAigI",
            "ItUBCg5Tb3VyY2VDb2RlSW5mbxI6Cghsb2NhdGlvbhgBIAMoCzIoLmdvb2ds",
            "ZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbhqGAQoITG9jYXRp",
            "b24SEAoEcGF0aBgBIAMoBUICEAESEAoEc3BhbhgCIAMoBUICEAESGAoQbGVh",
            "ZGluZ19jb21tZW50cxgDIAEoCRIZChF0cmFpbGluZ19jb21tZW50cxgEIAEo",
            "CRIhChlsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzGAYgAygJIqcBChFHZW5l",
            "cmF0ZWRDb2RlSW5mbxJBCgphbm5vdGF0aW9uGAEgAygLMi0uZ29vZ2xlLnBy",
            "b3RvYnVmLkdlbmVyYXRlZENvZGVJbmZvLkFubm90YXRpb24aTwoKQW5ub3Rh",
            "dGlvbhIQCgRwYXRoGAEgAygFQgIQARITCgtzb3VyY2VfZmlsZRgCIAEoCRIN",
            "CgViZWdpbhgDIAEoBRILCgNlbmQYBCABKAVCjwEKE2NvbS5nb29nbGUucHJv",
            "dG9idWZCEERlc2NyaXB0b3JQcm90b3NIAVo+Z2l0aHViLmNvbS9nb2xhbmcv",
            "cHJvdG9idWYvcHJvdG9jLWdlbi1nby9kZXNjcmlwdG9yO2Rlc2NyaXB0b3L4",
            "AQGiAgNHUEKqAhpHb29nbGUuUHJvdG9idWYuUmVmbGVjdGlvbg=="));
      descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
          new pbr::FileDescriptor[] { },
          new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FileDescriptorSet), global::Google.Protobuf.Reflection.FileDescriptorSet.Parser, new[]{ "File" }, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FileDescriptorProto), global::Google.Protobuf.Reflection.FileDescriptorProto.Parser, new[]{ "Name", "Package", "Dependency", "PublicDependency", "WeakDependency", "MessageType", "EnumType", "Service", "Extension", "Options", "SourceCodeInfo", "Syntax" }, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.DescriptorProto), global::Google.Protobuf.Reflection.DescriptorProto.Parser, new[]{ "Name", "Field", "Extension", "NestedType", "EnumType", "ExtensionRange", "OneofDecl", "Options", "ReservedRange", "ReservedName" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.DescriptorProto.Types.ExtensionRange), global::Google.Protobuf.Reflection.DescriptorProto.Types.ExtensionRange.Parser, new[]{ "Start", "End", "Options" }, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.DescriptorProto.Types.ReservedRange), global::Google.Protobuf.Reflection.DescriptorProto.Types.ReservedRange.Parser, new[]{ "Start", "End" }, null, null, null)}),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.ExtensionRangeOptions), global::Google.Protobuf.Reflection.ExtensionRangeOptions.Parser, new[]{ "UninterpretedOption" }, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FieldDescriptorProto), global::Google.Protobuf.Reflection.FieldDescriptorProto.Parser, new[]{ "Name", "Number", "Label", "Type", "TypeName", "Extendee", "DefaultValue", "OneofIndex", "JsonName", "Options" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type), typeof(global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label) }, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.OneofDescriptorProto), global::Google.Protobuf.Reflection.OneofDescriptorProto.Parser, new[]{ "Name", "Options" }, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumDescriptorProto), global::Google.Protobuf.Reflection.EnumDescriptorProto.Parser, new[]{ "Name", "Value", "Options", "ReservedRange", "ReservedName" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumDescriptorProto.Types.EnumReservedRange), global::Google.Protobuf.Reflection.EnumDescriptorProto.Types.EnumReservedRange.Parser, new[]{ "Start", "End" }, null, null, null)}),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumValueDescriptorProto), global::Google.Protobuf.Reflection.EnumValueDescriptorProto.Parser, new[]{ "Name", "Number", "Options" }, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.ServiceDescriptorProto), global::Google.Protobuf.Reflection.ServiceDescriptorProto.Parser, new[]{ "Name", "Method", "Options" }, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.MethodDescriptorProto), global::Google.Protobuf.Reflection.MethodDescriptorProto.Parser, new[]{ "Name", "InputType", "OutputType", "Options", "ClientStreaming", "ServerStreaming" }, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FileOptions), global::Google.Protobuf.Reflection.FileOptions.Parser, new[]{ "JavaPackage", "JavaOuterClassname", "JavaMultipleFiles", "JavaGenerateEqualsAndHash", "JavaStringCheckUtf8", "OptimizeFor", "GoPackage", "CcGenericServices", "JavaGenericServices", "PyGenericServices", "PhpGenericServices", "Deprecated", "CcEnableArenas", "ObjcClassPrefix", "CsharpNamespace", "SwiftPrefix", "PhpClassPrefix", "PhpNamespace", "PhpMetadataNamespace", "RubyPackage", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode) }, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.MessageOptions), global::Google.Protobuf.Reflection.MessageOptions.Parser, new[]{ "MessageSetWireFormat", "NoStandardDescriptorAccessor", "Deprecated", "MapEntry", "UninterpretedOption" }, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FieldOptions), global::Google.Protobuf.Reflection.FieldOptions.Parser, new[]{ "Ctype", "Packed", "Jstype", "Lazy", "Deprecated", "Weak", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.CType), typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.JSType) }, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.OneofOptions), global::Google.Protobuf.Reflection.OneofOptions.Parser, new[]{ "UninterpretedOption" }, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumOptions), global::Google.Protobuf.Reflection.EnumOptions.Parser, new[]{ "AllowAlias", "Deprecated", "UninterpretedOption" }, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumValueOptions), global::Google.Protobuf.Reflection.EnumValueOptions.Parser, new[]{ "Deprecated", "UninterpretedOption" }, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.ServiceOptions), global::Google.Protobuf.Reflection.ServiceOptions.Parser, new[]{ "Deprecated", "UninterpretedOption" }, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.MethodOptions), global::Google.Protobuf.Reflection.MethodOptions.Parser, new[]{ "Deprecated", "IdempotencyLevel", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.MethodOptions.Types.IdempotencyLevel) }, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.UninterpretedOption), global::Google.Protobuf.Reflection.UninterpretedOption.Parser, new[]{ "Name", "IdentifierValue", "PositiveIntValue", "NegativeIntValue", "DoubleValue", "StringValue", "AggregateValue" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.UninterpretedOption.Types.NamePart), global::Google.Protobuf.Reflection.UninterpretedOption.Types.NamePart.Parser, new[]{ "NamePart_", "IsExtension" }, null, null, null)}),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.SourceCodeInfo), global::Google.Protobuf.Reflection.SourceCodeInfo.Parser, new[]{ "Location" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.SourceCodeInfo.Types.Location), global::Google.Protobuf.Reflection.SourceCodeInfo.Types.Location.Parser, new[]{ "Path", "Span", "LeadingComments", "TrailingComments", "LeadingDetachedComments" }, null, null, null)}),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.GeneratedCodeInfo), global::Google.Protobuf.Reflection.GeneratedCodeInfo.Parser, new[]{ "Annotation" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation), global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation.Parser, new[]{ "Path", "SourceFile", "Begin", "End" }, null, null, null)})
          }));
    }
    #endregion

  }
  #region Messages
  /// <summary>
  /// The protocol compiler can output a FileDescriptorSet containing the .proto
  /// files it parses.
  /// </summary>
  internal sealed partial class FileDescriptorSet : pb::IMessage<FileDescriptorSet> {
    private static readonly pb::MessageParser<FileDescriptorSet> _parser = new pb::MessageParser<FileDescriptorSet>(() => new FileDescriptorSet());
    private pb::UnknownFieldSet _unknownFields;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pb::MessageParser<FileDescriptorSet> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[0]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public FileDescriptorSet() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public FileDescriptorSet(FileDescriptorSet other) : this() {
      file_ = other.file_.Clone();
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public FileDescriptorSet Clone() {
      return new FileDescriptorSet(this);
    }

    /// <summary>Field number for the "file" field.</summary>
    public const int FileFieldNumber = 1;
    private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.FileDescriptorProto> _repeated_file_codec
        = pb::FieldCodec.ForMessage(10, global::Google.Protobuf.Reflection.FileDescriptorProto.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.FileDescriptorProto> file_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.FileDescriptorProto>();
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.FileDescriptorProto> File {
      get { return file_; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override bool Equals(object other) {
      return Equals(other as FileDescriptorSet);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(FileDescriptorSet other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if(!file_.Equals(other.file_)) return false;
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      hash ^= file_.GetHashCode();
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void WriteTo(pb::CodedOutputStream output) {
      file_.WriteTo(output, _repeated_file_codec);
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      size += file_.CalculateSize(_repeated_file_codec);
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(FileDescriptorSet other) {
      if (other == null) {
        return;
      }
      file_.Add(other.file_);
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            break;
          case 10: {
            file_.AddEntriesFrom(input, _repeated_file_codec);
            break;
          }
        }
      }
    }

  }

  /// <summary>
  /// Describes a complete .proto file.
  /// </summary>
  internal sealed partial class FileDescriptorProto : pb::IMessage<FileDescriptorProto> {
    private static readonly pb::MessageParser<FileDescriptorProto> _parser = new pb::MessageParser<FileDescriptorProto>(() => new FileDescriptorProto());
    private pb::UnknownFieldSet _unknownFields;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pb::MessageParser<FileDescriptorProto> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[1]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public FileDescriptorProto() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public FileDescriptorProto(FileDescriptorProto other) : this() {
      name_ = other.name_;
      package_ = other.package_;
      dependency_ = other.dependency_.Clone();
      publicDependency_ = other.publicDependency_.Clone();
      weakDependency_ = other.weakDependency_.Clone();
      messageType_ = other.messageType_.Clone();
      enumType_ = other.enumType_.Clone();
      service_ = other.service_.Clone();
      extension_ = other.extension_.Clone();
      options_ = other.options_ != null ? other.options_.Clone() : null;
      sourceCodeInfo_ = other.sourceCodeInfo_ != null ? other.sourceCodeInfo_.Clone() : null;
      syntax_ = other.syntax_;
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public FileDescriptorProto Clone() {
      return new FileDescriptorProto(this);
    }

    /// <summary>Field number for the "name" field.</summary>
    public const int NameFieldNumber = 1;
    private string name_ = "";
    /// <summary>
    /// file name, relative to root of source tree
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string Name {
      get { return name_; }
      set {
        name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "package" field.</summary>
    public const int PackageFieldNumber = 2;
    private string package_ = "";
    /// <summary>
    /// e.g. "foo", "foo.bar", etc.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string Package {
      get { return package_; }
      set {
        package_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "dependency" field.</summary>
    public const int DependencyFieldNumber = 3;
    private static readonly pb::FieldCodec<string> _repeated_dependency_codec
        = pb::FieldCodec.ForString(26);
    private readonly pbc::RepeatedField<string> dependency_ = new pbc::RepeatedField<string>();
    /// <summary>
    /// Names of files imported by this file.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<string> Dependency {
      get { return dependency_; }
    }

    /// <summary>Field number for the "public_dependency" field.</summary>
    public const int PublicDependencyFieldNumber = 10;
    private static readonly pb::FieldCodec<int> _repeated_publicDependency_codec
        = pb::FieldCodec.ForInt32(80);
    private readonly pbc::RepeatedField<int> publicDependency_ = new pbc::RepeatedField<int>();
    /// <summary>
    /// Indexes of the public imported files in the dependency list above.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<int> PublicDependency {
      get { return publicDependency_; }
    }

    /// <summary>Field number for the "weak_dependency" field.</summary>
    public const int WeakDependencyFieldNumber = 11;
    private static readonly pb::FieldCodec<int> _repeated_weakDependency_codec
        = pb::FieldCodec.ForInt32(88);
    private readonly pbc::RepeatedField<int> weakDependency_ = new pbc::RepeatedField<int>();
    /// <summary>
    /// Indexes of the weak imported files in the dependency list.
    /// For Google-internal migration only. Do not use.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<int> WeakDependency {
      get { return weakDependency_; }
    }

    /// <summary>Field number for the "message_type" field.</summary>
    public const int MessageTypeFieldNumber = 4;
    private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.DescriptorProto> _repeated_messageType_codec
        = pb::FieldCodec.ForMessage(34, global::Google.Protobuf.Reflection.DescriptorProto.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.DescriptorProto> messageType_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.DescriptorProto>();
    /// <summary>
    /// All top-level definitions in this file.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.DescriptorProto> MessageType {
      get { return messageType_; }
    }

    /// <summary>Field number for the "enum_type" field.</summary>
    public const int EnumTypeFieldNumber = 5;
    private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.EnumDescriptorProto> _repeated_enumType_codec
        = pb::FieldCodec.ForMessage(42, global::Google.Protobuf.Reflection.EnumDescriptorProto.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.EnumDescriptorProto> enumType_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.EnumDescriptorProto>();
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.EnumDescriptorProto> EnumType {
      get { return enumType_; }
    }

    /// <summary>Field number for the "service" field.</summary>
    public const int ServiceFieldNumber = 6;
    private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.ServiceDescriptorProto> _repeated_service_codec
        = pb::FieldCodec.ForMessage(50, global::Google.Protobuf.Reflection.ServiceDescriptorProto.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.ServiceDescriptorProto> service_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.ServiceDescriptorProto>();
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.ServiceDescriptorProto> Service {
      get { return service_; }
    }

    /// <summary>Field number for the "extension" field.</summary>
    public const int ExtensionFieldNumber = 7;
    private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.FieldDescriptorProto> _repeated_extension_codec
        = pb::FieldCodec.ForMessage(58, global::Google.Protobuf.Reflection.FieldDescriptorProto.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.FieldDescriptorProto> extension_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.FieldDescriptorProto>();
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.FieldDescriptorProto> Extension {
      get { return extension_; }
    }

    /// <summary>Field number for the "options" field.</summary>
    public const int OptionsFieldNumber = 8;
    private global::Google.Protobuf.Reflection.FileOptions options_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public global::Google.Protobuf.Reflection.FileOptions Options {
      get { return options_; }
      set {
        options_ = value;
      }
    }

    /// <summary>Field number for the "source_code_info" field.</summary>
    public const int SourceCodeInfoFieldNumber = 9;
    private global::Google.Protobuf.Reflection.SourceCodeInfo sourceCodeInfo_;
    /// <summary>
    /// This field contains optional information about the original source code.
    /// You may safely remove this entire field without harming runtime
    /// functionality of the descriptors -- the information is needed only by
    /// development tools.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public global::Google.Protobuf.Reflection.SourceCodeInfo SourceCodeInfo {
      get { return sourceCodeInfo_; }
      set {
        sourceCodeInfo_ = value;
      }
    }

    /// <summary>Field number for the "syntax" field.</summary>
    public const int SyntaxFieldNumber = 12;
    private string syntax_ = "";
    /// <summary>
    /// The syntax of the proto file.
    /// The supported values are "proto2" and "proto3".
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string Syntax {
      get { return syntax_; }
      set {
        syntax_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override bool Equals(object other) {
      return Equals(other as FileDescriptorProto);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(FileDescriptorProto other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (Name != other.Name) return false;
      if (Package != other.Package) return false;
      if(!dependency_.Equals(other.dependency_)) return false;
      if(!publicDependency_.Equals(other.publicDependency_)) return false;
      if(!weakDependency_.Equals(other.weakDependency_)) return false;
      if(!messageType_.Equals(other.messageType_)) return false;
      if(!enumType_.Equals(other.enumType_)) return false;
      if(!service_.Equals(other.service_)) return false;
      if(!extension_.Equals(other.extension_)) return false;
      if (!object.Equals(Options, other.Options)) return false;
      if (!object.Equals(SourceCodeInfo, other.SourceCodeInfo)) return false;
      if (Syntax != other.Syntax) return false;
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (Name.Length != 0) hash ^= Name.GetHashCode();
      if (Package.Length != 0) hash ^= Package.GetHashCode();
      hash ^= dependency_.GetHashCode();
      hash ^= publicDependency_.GetHashCode();
      hash ^= weakDependency_.GetHashCode();
      hash ^= messageType_.GetHashCode();
      hash ^= enumType_.GetHashCode();
      hash ^= service_.GetHashCode();
      hash ^= extension_.GetHashCode();
      if (options_ != null) hash ^= Options.GetHashCode();
      if (sourceCodeInfo_ != null) hash ^= SourceCodeInfo.GetHashCode();
      if (Syntax.Length != 0) hash ^= Syntax.GetHashCode();
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void WriteTo(pb::CodedOutputStream output) {
      if (Name.Length != 0) {
        output.WriteRawTag(10);
        output.WriteString(Name);
      }
      if (Package.Length != 0) {
        output.WriteRawTag(18);
        output.WriteString(Package);
      }
      dependency_.WriteTo(output, _repeated_dependency_codec);
      messageType_.WriteTo(output, _repeated_messageType_codec);
      enumType_.WriteTo(output, _repeated_enumType_codec);
      service_.WriteTo(output, _repeated_service_codec);
      extension_.WriteTo(output, _repeated_extension_codec);
      if (options_ != null) {
        output.WriteRawTag(66);
        output.WriteMessage(Options);
      }
      if (sourceCodeInfo_ != null) {
        output.WriteRawTag(74);
        output.WriteMessage(SourceCodeInfo);
      }
      publicDependency_.WriteTo(output, _repeated_publicDependency_codec);
      weakDependency_.WriteTo(output, _repeated_weakDependency_codec);
      if (Syntax.Length != 0) {
        output.WriteRawTag(98);
        output.WriteString(Syntax);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (Name.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
      }
      if (Package.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(Package);
      }
      size += dependency_.CalculateSize(_repeated_dependency_codec);
      size += publicDependency_.CalculateSize(_repeated_publicDependency_codec);
      size += weakDependency_.CalculateSize(_repeated_weakDependency_codec);
      size += messageType_.CalculateSize(_repeated_messageType_codec);
      size += enumType_.CalculateSize(_repeated_enumType_codec);
      size += service_.CalculateSize(_repeated_service_codec);
      size += extension_.CalculateSize(_repeated_extension_codec);
      if (options_ != null) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Options);
      }
      if (sourceCodeInfo_ != null) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(SourceCodeInfo);
      }
      if (Syntax.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(Syntax);
      }
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(FileDescriptorProto other) {
      if (other == null) {
        return;
      }
      if (other.Name.Length != 0) {
        Name = other.Name;
      }
      if (other.Package.Length != 0) {
        Package = other.Package;
      }
      dependency_.Add(other.dependency_);
      publicDependency_.Add(other.publicDependency_);
      weakDependency_.Add(other.weakDependency_);
      messageType_.Add(other.messageType_);
      enumType_.Add(other.enumType_);
      service_.Add(other.service_);
      extension_.Add(other.extension_);
      if (other.options_ != null) {
        if (options_ == null) {
          options_ = new global::Google.Protobuf.Reflection.FileOptions();
        }
        Options.MergeFrom(other.Options);
      }
      if (other.sourceCodeInfo_ != null) {
        if (sourceCodeInfo_ == null) {
          sourceCodeInfo_ = new global::Google.Protobuf.Reflection.SourceCodeInfo();
        }
        SourceCodeInfo.MergeFrom(other.SourceCodeInfo);
      }
      if (other.Syntax.Length != 0) {
        Syntax = other.Syntax;
      }
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            break;
          case 10: {
            Name = input.ReadString();
            break;
          }
          case 18: {
            Package = input.ReadString();
            break;
          }
          case 26: {
            dependency_.AddEntriesFrom(input, _repeated_dependency_codec);
            break;
          }
          case 34: {
            messageType_.AddEntriesFrom(input, _repeated_messageType_codec);
            break;
          }
          case 42: {
            enumType_.AddEntriesFrom(input, _repeated_enumType_codec);
            break;
          }
          case 50: {
            service_.AddEntriesFrom(input, _repeated_service_codec);
            break;
          }
          case 58: {
            extension_.AddEntriesFrom(input, _repeated_extension_codec);
            break;
          }
          case 66: {
            if (options_ == null) {
              options_ = new global::Google.Protobuf.Reflection.FileOptions();
            }
            input.ReadMessage(options_);
            break;
          }
          case 74: {
            if (sourceCodeInfo_ == null) {
              sourceCodeInfo_ = new global::Google.Protobuf.Reflection.SourceCodeInfo();
            }
            input.ReadMessage(sourceCodeInfo_);
            break;
          }
          case 82:
          case 80: {
            publicDependency_.AddEntriesFrom(input, _repeated_publicDependency_codec);
            break;
          }
          case 90:
          case 88: {
            weakDependency_.AddEntriesFrom(input, _repeated_weakDependency_codec);
            break;
          }
          case 98: {
            Syntax = input.ReadString();
            break;
          }
        }
      }
    }

  }

  /// <summary>
  /// Describes a message type.
  /// </summary>
  internal sealed partial class DescriptorProto : pb::IMessage<DescriptorProto> {
    private static readonly pb::MessageParser<DescriptorProto> _parser = new pb::MessageParser<DescriptorProto>(() => new DescriptorProto());
    private pb::UnknownFieldSet _unknownFields;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pb::MessageParser<DescriptorProto> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[2]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public DescriptorProto() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public DescriptorProto(DescriptorProto other) : this() {
      name_ = other.name_;
      field_ = other.field_.Clone();
      extension_ = other.extension_.Clone();
      nestedType_ = other.nestedType_.Clone();
      enumType_ = other.enumType_.Clone();
      extensionRange_ = other.extensionRange_.Clone();
      oneofDecl_ = other.oneofDecl_.Clone();
      options_ = other.options_ != null ? other.options_.Clone() : null;
      reservedRange_ = other.reservedRange_.Clone();
      reservedName_ = other.reservedName_.Clone();
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public DescriptorProto Clone() {
      return new DescriptorProto(this);
    }

    /// <summary>Field number for the "name" field.</summary>
    public const int NameFieldNumber = 1;
    private string name_ = "";
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string Name {
      get { return name_; }
      set {
        name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "field" field.</summary>
    public const int FieldFieldNumber = 2;
    private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.FieldDescriptorProto> _repeated_field_codec
        = pb::FieldCodec.ForMessage(18, global::Google.Protobuf.Reflection.FieldDescriptorProto.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.FieldDescriptorProto> field_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.FieldDescriptorProto>();
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.FieldDescriptorProto> Field {
      get { return field_; }
    }

    /// <summary>Field number for the "extension" field.</summary>
    public const int ExtensionFieldNumber = 6;
    private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.FieldDescriptorProto> _repeated_extension_codec
        = pb::FieldCodec.ForMessage(50, global::Google.Protobuf.Reflection.FieldDescriptorProto.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.FieldDescriptorProto> extension_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.FieldDescriptorProto>();
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.FieldDescriptorProto> Extension {
      get { return extension_; }
    }

    /// <summary>Field number for the "nested_type" field.</summary>
    public const int NestedTypeFieldNumber = 3;
    private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.DescriptorProto> _repeated_nestedType_codec
        = pb::FieldCodec.ForMessage(26, global::Google.Protobuf.Reflection.DescriptorProto.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.DescriptorProto> nestedType_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.DescriptorProto>();
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.DescriptorProto> NestedType {
      get { return nestedType_; }
    }

    /// <summary>Field number for the "enum_type" field.</summary>
    public const int EnumTypeFieldNumber = 4;
    private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.EnumDescriptorProto> _repeated_enumType_codec
        = pb::FieldCodec.ForMessage(34, global::Google.Protobuf.Reflection.EnumDescriptorProto.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.EnumDescriptorProto> enumType_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.EnumDescriptorProto>();
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.EnumDescriptorProto> EnumType {
      get { return enumType_; }
    }

    /// <summary>Field number for the "extension_range" field.</summary>
    public const int ExtensionRangeFieldNumber = 5;
    private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.DescriptorProto.Types.ExtensionRange> _repeated_extensionRange_codec
        = pb::FieldCodec.ForMessage(42, global::Google.Protobuf.Reflection.DescriptorProto.Types.ExtensionRange.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.DescriptorProto.Types.ExtensionRange> extensionRange_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.DescriptorProto.Types.ExtensionRange>();
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.DescriptorProto.Types.ExtensionRange> ExtensionRange {
      get { return extensionRange_; }
    }

    /// <summary>Field number for the "oneof_decl" field.</summary>
    public const int OneofDeclFieldNumber = 8;
    private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.OneofDescriptorProto> _repeated_oneofDecl_codec
        = pb::FieldCodec.ForMessage(66, global::Google.Protobuf.Reflection.OneofDescriptorProto.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.OneofDescriptorProto> oneofDecl_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.OneofDescriptorProto>();
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.OneofDescriptorProto> OneofDecl {
      get { return oneofDecl_; }
    }

    /// <summary>Field number for the "options" field.</summary>
    public const int OptionsFieldNumber = 7;
    private global::Google.Protobuf.Reflection.MessageOptions options_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public global::Google.Protobuf.Reflection.MessageOptions Options {
      get { return options_; }
      set {
        options_ = value;
      }
    }

    /// <summary>Field number for the "reserved_range" field.</summary>
    public const int ReservedRangeFieldNumber = 9;
    private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.DescriptorProto.Types.ReservedRange> _repeated_reservedRange_codec
        = pb::FieldCodec.ForMessage(74, global::Google.Protobuf.Reflection.DescriptorProto.Types.ReservedRange.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.DescriptorProto.Types.ReservedRange> reservedRange_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.DescriptorProto.Types.ReservedRange>();
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.DescriptorProto.Types.ReservedRange> ReservedRange {
      get { return reservedRange_; }
    }

    /// <summary>Field number for the "reserved_name" field.</summary>
    public const int ReservedNameFieldNumber = 10;
    private static readonly pb::FieldCodec<string> _repeated_reservedName_codec
        = pb::FieldCodec.ForString(82);
    private readonly pbc::RepeatedField<string> reservedName_ = new pbc::RepeatedField<string>();
    /// <summary>
    /// Reserved field names, which may not be used by fields in the same message.
    /// A given name may only be reserved once.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<string> ReservedName {
      get { return reservedName_; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override bool Equals(object other) {
      return Equals(other as DescriptorProto);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(DescriptorProto other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (Name != other.Name) return false;
      if(!field_.Equals(other.field_)) return false;
      if(!extension_.Equals(other.extension_)) return false;
      if(!nestedType_.Equals(other.nestedType_)) return false;
      if(!enumType_.Equals(other.enumType_)) return false;
      if(!extensionRange_.Equals(other.extensionRange_)) return false;
      if(!oneofDecl_.Equals(other.oneofDecl_)) return false;
      if (!object.Equals(Options, other.Options)) return false;
      if(!reservedRange_.Equals(other.reservedRange_)) return false;
      if(!reservedName_.Equals(other.reservedName_)) return false;
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (Name.Length != 0) hash ^= Name.GetHashCode();
      hash ^= field_.GetHashCode();
      hash ^= extension_.GetHashCode();
      hash ^= nestedType_.GetHashCode();
      hash ^= enumType_.GetHashCode();
      hash ^= extensionRange_.GetHashCode();
      hash ^= oneofDecl_.GetHashCode();
      if (options_ != null) hash ^= Options.GetHashCode();
      hash ^= reservedRange_.GetHashCode();
      hash ^= reservedName_.GetHashCode();
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void WriteTo(pb::CodedOutputStream output) {
      if (Name.Length != 0) {
        output.WriteRawTag(10);
        output.WriteString(Name);
      }
      field_.WriteTo(output, _repeated_field_codec);
      nestedType_.WriteTo(output, _repeated_nestedType_codec);
      enumType_.WriteTo(output, _repeated_enumType_codec);
      extensionRange_.WriteTo(output, _repeated_extensionRange_codec);
      extension_.WriteTo(output, _repeated_extension_codec);
      if (options_ != null) {
        output.WriteRawTag(58);
        output.WriteMessage(Options);
      }
      oneofDecl_.WriteTo(output, _repeated_oneofDecl_codec);
      reservedRange_.WriteTo(output, _repeated_reservedRange_codec);
      reservedName_.WriteTo(output, _repeated_reservedName_codec);
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (Name.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
      }
      size += field_.CalculateSize(_repeated_field_codec);
      size += extension_.CalculateSize(_repeated_extension_codec);
      size += nestedType_.CalculateSize(_repeated_nestedType_codec);
      size += enumType_.CalculateSize(_repeated_enumType_codec);
      size += extensionRange_.CalculateSize(_repeated_extensionRange_codec);
      size += oneofDecl_.CalculateSize(_repeated_oneofDecl_codec);
      if (options_ != null) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Options);
      }
      size += reservedRange_.CalculateSize(_repeated_reservedRange_codec);
      size += reservedName_.CalculateSize(_repeated_reservedName_codec);
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(DescriptorProto other) {
      if (other == null) {
        return;
      }
      if (other.Name.Length != 0) {
        Name = other.Name;
      }
      field_.Add(other.field_);
      extension_.Add(other.extension_);
      nestedType_.Add(other.nestedType_);
      enumType_.Add(other.enumType_);
      extensionRange_.Add(other.extensionRange_);
      oneofDecl_.Add(other.oneofDecl_);
      if (other.options_ != null) {
        if (options_ == null) {
          options_ = new global::Google.Protobuf.Reflection.MessageOptions();
        }
        Options.MergeFrom(other.Options);
      }
      reservedRange_.Add(other.reservedRange_);
      reservedName_.Add(other.reservedName_);
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            break;
          case 10: {
            Name = input.ReadString();
            break;
          }
          case 18: {
            field_.AddEntriesFrom(input, _repeated_field_codec);
            break;
          }
          case 26: {
            nestedType_.AddEntriesFrom(input, _repeated_nestedType_codec);
            break;
          }
          case 34: {
            enumType_.AddEntriesFrom(input, _repeated_enumType_codec);
            break;
          }
          case 42: {
            extensionRange_.AddEntriesFrom(input, _repeated_extensionRange_codec);
            break;
          }
          case 50: {
            extension_.AddEntriesFrom(input, _repeated_extension_codec);
            break;
          }
          case 58: {
            if (options_ == null) {
              options_ = new global::Google.Protobuf.Reflection.MessageOptions();
            }
            input.ReadMessage(options_);
            break;
          }
          case 66: {
            oneofDecl_.AddEntriesFrom(input, _repeated_oneofDecl_codec);
            break;
          }
          case 74: {
            reservedRange_.AddEntriesFrom(input, _repeated_reservedRange_codec);
            break;
          }
          case 82: {
            reservedName_.AddEntriesFrom(input, _repeated_reservedName_codec);
            break;
          }
        }
      }
    }

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

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public static pbr::MessageDescriptor Descriptor {
          get { return global::Google.Protobuf.Reflection.DescriptorProto.Descriptor.NestedTypes[0]; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        pbr::MessageDescriptor pb::IMessage.Descriptor {
          get { return Descriptor; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public ExtensionRange() {
          OnConstruction();
        }

        partial void OnConstruction();

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public ExtensionRange(ExtensionRange other) : this() {
          start_ = other.start_;
          end_ = other.end_;
          options_ = other.options_ != null ? other.options_.Clone() : null;
          _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public ExtensionRange Clone() {
          return new ExtensionRange(this);
        }

        /// <summary>Field number for the "start" field.</summary>
        public const int StartFieldNumber = 1;
        private int start_;
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public int Start {
          get { return start_; }
          set {
            start_ = value;
          }
        }

        /// <summary>Field number for the "end" field.</summary>
        public const int EndFieldNumber = 2;
        private int end_;
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public int End {
          get { return end_; }
          set {
            end_ = value;
          }
        }

        /// <summary>Field number for the "options" field.</summary>
        public const int OptionsFieldNumber = 3;
        private global::Google.Protobuf.Reflection.ExtensionRangeOptions options_;
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public global::Google.Protobuf.Reflection.ExtensionRangeOptions Options {
          get { return options_; }
          set {
            options_ = value;
          }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public override bool Equals(object other) {
          return Equals(other as ExtensionRange);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public bool Equals(ExtensionRange other) {
          if (ReferenceEquals(other, null)) {
            return false;
          }
          if (ReferenceEquals(other, this)) {
            return true;
          }
          if (Start != other.Start) return false;
          if (End != other.End) return false;
          if (!object.Equals(Options, other.Options)) return false;
          return Equals(_unknownFields, other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public override int GetHashCode() {
          int hash = 1;
          if (Start != 0) hash ^= Start.GetHashCode();
          if (End != 0) hash ^= End.GetHashCode();
          if (options_ != null) hash ^= Options.GetHashCode();
          if (_unknownFields != null) {
            hash ^= _unknownFields.GetHashCode();
          }
          return hash;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public override string ToString() {
          return pb::JsonFormatter.ToDiagnosticString(this);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void WriteTo(pb::CodedOutputStream output) {
          if (Start != 0) {
            output.WriteRawTag(8);
            output.WriteInt32(Start);
          }
          if (End != 0) {
            output.WriteRawTag(16);
            output.WriteInt32(End);
          }
          if (options_ != null) {
            output.WriteRawTag(26);
            output.WriteMessage(Options);
          }
          if (_unknownFields != null) {
            _unknownFields.WriteTo(output);
          }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public int CalculateSize() {
          int size = 0;
          if (Start != 0) {
            size += 1 + pb::CodedOutputStream.ComputeInt32Size(Start);
          }
          if (End != 0) {
            size += 1 + pb::CodedOutputStream.ComputeInt32Size(End);
          }
          if (options_ != null) {
            size += 1 + pb::CodedOutputStream.ComputeMessageSize(Options);
          }
          if (_unknownFields != null) {
            size += _unknownFields.CalculateSize();
          }
          return size;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void MergeFrom(ExtensionRange other) {
          if (other == null) {
            return;
          }
          if (other.Start != 0) {
            Start = other.Start;
          }
          if (other.End != 0) {
            End = other.End;
          }
          if (other.options_ != null) {
            if (options_ == null) {
              options_ = new global::Google.Protobuf.Reflection.ExtensionRangeOptions();
            }
            Options.MergeFrom(other.Options);
          }
          _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void MergeFrom(pb::CodedInputStream input) {
          uint tag;
          while ((tag = input.ReadTag()) != 0) {
            switch(tag) {
              default:
                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                break;
              case 8: {
                Start = input.ReadInt32();
                break;
              }
              case 16: {
                End = input.ReadInt32();
                break;
              }
              case 26: {
                if (options_ == null) {
                  options_ = new global::Google.Protobuf.Reflection.ExtensionRangeOptions();
                }
                input.ReadMessage(options_);
                break;
              }
            }
          }
        }

      }

      /// <summary>
      /// Range of reserved tag numbers. Reserved tag numbers may not be used by
      /// fields or extension ranges in the same message. Reserved ranges may
      /// not overlap.
      /// </summary>
      internal sealed partial class ReservedRange : pb::IMessage<ReservedRange> {
        private static readonly pb::MessageParser<ReservedRange> _parser = new pb::MessageParser<ReservedRange>(() => new ReservedRange());
        private pb::UnknownFieldSet _unknownFields;
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public static pb::MessageParser<ReservedRange> Parser { get { return _parser; } }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public static pbr::MessageDescriptor Descriptor {
          get { return global::Google.Protobuf.Reflection.DescriptorProto.Descriptor.NestedTypes[1]; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        pbr::MessageDescriptor pb::IMessage.Descriptor {
          get { return Descriptor; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public ReservedRange() {
          OnConstruction();
        }

        partial void OnConstruction();

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public ReservedRange(ReservedRange other) : this() {
          start_ = other.start_;
          end_ = other.end_;
          _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public ReservedRange Clone() {
          return new ReservedRange(this);
        }

        /// <summary>Field number for the "start" field.</summary>
        public const int StartFieldNumber = 1;
        private int start_;
        /// <summary>
        /// Inclusive.
        /// </summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public int Start {
          get { return start_; }
          set {
            start_ = value;
          }
        }

        /// <summary>Field number for the "end" field.</summary>
        public const int EndFieldNumber = 2;
        private int end_;
        /// <summary>
        /// Exclusive.
        /// </summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public int End {
          get { return end_; }
          set {
            end_ = value;
          }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public override bool Equals(object other) {
          return Equals(other as ReservedRange);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public bool Equals(ReservedRange other) {
          if (ReferenceEquals(other, null)) {
            return false;
          }
          if (ReferenceEquals(other, this)) {
            return true;
          }
          if (Start != other.Start) return false;
          if (End != other.End) return false;
          return Equals(_unknownFields, other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public override int GetHashCode() {
          int hash = 1;
          if (Start != 0) hash ^= Start.GetHashCode();
          if (End != 0) hash ^= End.GetHashCode();
          if (_unknownFields != null) {
            hash ^= _unknownFields.GetHashCode();
          }
          return hash;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public override string ToString() {
          return pb::JsonFormatter.ToDiagnosticString(this);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void WriteTo(pb::CodedOutputStream output) {
          if (Start != 0) {
            output.WriteRawTag(8);
            output.WriteInt32(Start);
          }
          if (End != 0) {
            output.WriteRawTag(16);
            output.WriteInt32(End);
          }
          if (_unknownFields != null) {
            _unknownFields.WriteTo(output);
          }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public int CalculateSize() {
          int size = 0;
          if (Start != 0) {
            size += 1 + pb::CodedOutputStream.ComputeInt32Size(Start);
          }
          if (End != 0) {
            size += 1 + pb::CodedOutputStream.ComputeInt32Size(End);
          }
          if (_unknownFields != null) {
            size += _unknownFields.CalculateSize();
          }
          return size;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void MergeFrom(ReservedRange other) {
          if (other == null) {
            return;
          }
          if (other.Start != 0) {
            Start = other.Start;
          }
          if (other.End != 0) {
            End = other.End;
          }
          _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void MergeFrom(pb::CodedInputStream input) {
          uint tag;
          while ((tag = input.ReadTag()) != 0) {
            switch(tag) {
              default:
                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                break;
              case 8: {
                Start = input.ReadInt32();
                break;
              }
              case 16: {
                End = input.ReadInt32();
                break;
              }
            }
          }
        }

      }

    }
    #endregion

  }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[3]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public ExtensionRangeOptions() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public ExtensionRangeOptions(ExtensionRangeOptions other) : this() {
      uninterpretedOption_ = other.uninterpretedOption_.Clone();
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public ExtensionRangeOptions Clone() {
      return new ExtensionRangeOptions(this);
    }

    /// <summary>Field number for the "uninterpreted_option" field.</summary>
    public const int UninterpretedOptionFieldNumber = 999;
    private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.UninterpretedOption> _repeated_uninterpretedOption_codec
        = pb::FieldCodec.ForMessage(7994, global::Google.Protobuf.Reflection.UninterpretedOption.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption> uninterpretedOption_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption>();
    /// <summary>
    /// The parser stores options it doesn't recognize here. See above.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption> UninterpretedOption {
      get { return uninterpretedOption_; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override bool Equals(object other) {
      return Equals(other as ExtensionRangeOptions);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(ExtensionRangeOptions other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if(!uninterpretedOption_.Equals(other.uninterpretedOption_)) return false;
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      hash ^= uninterpretedOption_.GetHashCode();
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void WriteTo(pb::CodedOutputStream output) {
      uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec);
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(ExtensionRangeOptions other) {
      if (other == null) {
        return;
      }
      uninterpretedOption_.Add(other.uninterpretedOption_);
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            break;
          case 7994: {
            uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec);
            break;
          }
        }
      }
    }

  }

  /// <summary>
  /// Describes a field within a message.
  /// </summary>
  internal sealed partial class FieldDescriptorProto : pb::IMessage<FieldDescriptorProto> {
    private static readonly pb::MessageParser<FieldDescriptorProto> _parser = new pb::MessageParser<FieldDescriptorProto>(() => new FieldDescriptorProto());
    private pb::UnknownFieldSet _unknownFields;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pb::MessageParser<FieldDescriptorProto> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[4]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public FieldDescriptorProto() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public FieldDescriptorProto(FieldDescriptorProto other) : this() {
      name_ = other.name_;
      number_ = other.number_;
      label_ = other.label_;
      type_ = other.type_;
      typeName_ = other.typeName_;
      extendee_ = other.extendee_;
      defaultValue_ = other.defaultValue_;
      oneofIndex_ = other.oneofIndex_;
      jsonName_ = other.jsonName_;
      options_ = other.options_ != null ? other.options_.Clone() : null;
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public FieldDescriptorProto Clone() {
      return new FieldDescriptorProto(this);
    }

    /// <summary>Field number for the "name" field.</summary>
    public const int NameFieldNumber = 1;
    private string name_ = "";
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string Name {
      get { return name_; }
      set {
        name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "number" field.</summary>
    public const int NumberFieldNumber = 3;
    private int number_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int Number {
      get { return number_; }
      set {
        number_ = value;
      }
    }

    /// <summary>Field number for the "label" field.</summary>
    public const int LabelFieldNumber = 4;
    private global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label label_ = 0;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label Label {
      get { return label_; }
      set {
        label_ = value;
      }
    }

    /// <summary>Field number for the "type" field.</summary>
    public const int TypeFieldNumber = 5;
    private global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type type_ = 0;
    /// <summary>
    /// If type_name is set, this need not be set.  If both this and type_name
    /// are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type Type {
      get { return type_; }
      set {
        type_ = value;
      }
    }

    /// <summary>Field number for the "type_name" field.</summary>
    public const int TypeNameFieldNumber = 6;
    private string typeName_ = "";
    /// <summary>
    /// For message and enum types, this is the name of the type.  If the name
    /// starts with a '.', it is fully-qualified.  Otherwise, C++-like scoping
    /// rules are used to find the type (i.e. first the nested types within this
    /// message are searched, then within the parent, on up to the root
    /// namespace).
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string TypeName {
      get { return typeName_; }
      set {
        typeName_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "extendee" field.</summary>
    public const int ExtendeeFieldNumber = 2;
    private string extendee_ = "";
    /// <summary>
    /// For extensions, this is the name of the type being extended.  It is
    /// resolved in the same manner as type_name.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string Extendee {
      get { return extendee_; }
      set {
        extendee_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "default_value" field.</summary>
    public const int DefaultValueFieldNumber = 7;
    private string defaultValue_ = "";
    /// <summary>
    /// For numeric types, contains the original text representation of the value.
    /// For booleans, "true" or "false".
    /// For strings, contains the default text contents (not escaped in any way).
    /// For bytes, contains the C escaped value.  All bytes >= 128 are escaped.
    /// TODO(kenton):  Base-64 encode?
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string DefaultValue {
      get { return defaultValue_; }
      set {
        defaultValue_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "oneof_index" field.</summary>
    public const int OneofIndexFieldNumber = 9;
    private int oneofIndex_;
    /// <summary>
    /// If set, gives the index of a oneof in the containing type's oneof_decl
    /// list.  This field is a member of that oneof.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int OneofIndex {
      get { return oneofIndex_; }
      set {
        oneofIndex_ = value;
      }
    }

    /// <summary>Field number for the "json_name" field.</summary>
    public const int JsonNameFieldNumber = 10;
    private string jsonName_ = "";
    /// <summary>
    /// JSON name of this field. The value is set by protocol compiler. If the
    /// user has set a "json_name" option on this field, that option's value
    /// will be used. Otherwise, it's deduced from the field's name by converting
    /// it to camelCase.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string JsonName {
      get { return jsonName_; }
      set {
        jsonName_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "options" field.</summary>
    public const int OptionsFieldNumber = 8;
    private global::Google.Protobuf.Reflection.FieldOptions options_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public global::Google.Protobuf.Reflection.FieldOptions Options {
      get { return options_; }
      set {
        options_ = value;
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override bool Equals(object other) {
      return Equals(other as FieldDescriptorProto);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(FieldDescriptorProto other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (Name != other.Name) return false;
      if (Number != other.Number) return false;
      if (Label != other.Label) return false;
      if (Type != other.Type) return false;
      if (TypeName != other.TypeName) return false;
      if (Extendee != other.Extendee) return false;
      if (DefaultValue != other.DefaultValue) return false;
      if (OneofIndex != other.OneofIndex) return false;
      if (JsonName != other.JsonName) return false;
      if (!object.Equals(Options, other.Options)) return false;
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (Name.Length != 0) hash ^= Name.GetHashCode();
      if (Number != 0) hash ^= Number.GetHashCode();
      if (Label != 0) hash ^= Label.GetHashCode();
      if (Type != 0) hash ^= Type.GetHashCode();
      if (TypeName.Length != 0) hash ^= TypeName.GetHashCode();
      if (Extendee.Length != 0) hash ^= Extendee.GetHashCode();
      if (DefaultValue.Length != 0) hash ^= DefaultValue.GetHashCode();
      if (OneofIndex != 0) hash ^= OneofIndex.GetHashCode();
      if (JsonName.Length != 0) hash ^= JsonName.GetHashCode();
      if (options_ != null) hash ^= Options.GetHashCode();
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void WriteTo(pb::CodedOutputStream output) {
      if (Name.Length != 0) {
        output.WriteRawTag(10);
        output.WriteString(Name);
      }
      if (Extendee.Length != 0) {
        output.WriteRawTag(18);
        output.WriteString(Extendee);
      }
      if (Number != 0) {
        output.WriteRawTag(24);
        output.WriteInt32(Number);
      }
      if (Label != 0) {
        output.WriteRawTag(32);
        output.WriteEnum((int) Label);
      }
      if (Type != 0) {
        output.WriteRawTag(40);
        output.WriteEnum((int) Type);
      }
      if (TypeName.Length != 0) {
        output.WriteRawTag(50);
        output.WriteString(TypeName);
      }
      if (DefaultValue.Length != 0) {
        output.WriteRawTag(58);
        output.WriteString(DefaultValue);
      }
      if (options_ != null) {
        output.WriteRawTag(66);
        output.WriteMessage(Options);
      }
      if (OneofIndex != 0) {
        output.WriteRawTag(72);
        output.WriteInt32(OneofIndex);
      }
      if (JsonName.Length != 0) {
        output.WriteRawTag(82);
        output.WriteString(JsonName);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (Name.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
      }
      if (Number != 0) {
        size += 1 + pb::CodedOutputStream.ComputeInt32Size(Number);
      }
      if (Label != 0) {
        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Label);
      }
      if (Type != 0) {
        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Type);
      }
      if (TypeName.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(TypeName);
      }
      if (Extendee.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(Extendee);
      }
      if (DefaultValue.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(DefaultValue);
      }
      if (OneofIndex != 0) {
        size += 1 + pb::CodedOutputStream.ComputeInt32Size(OneofIndex);
      }
      if (JsonName.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(JsonName);
      }
      if (options_ != null) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Options);
      }
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(FieldDescriptorProto other) {
      if (other == null) {
        return;
      }
      if (other.Name.Length != 0) {
        Name = other.Name;
      }
      if (other.Number != 0) {
        Number = other.Number;
      }
      if (other.Label != 0) {
        Label = other.Label;
      }
      if (other.Type != 0) {
        Type = other.Type;
      }
      if (other.TypeName.Length != 0) {
        TypeName = other.TypeName;
      }
      if (other.Extendee.Length != 0) {
        Extendee = other.Extendee;
      }
      if (other.DefaultValue.Length != 0) {
        DefaultValue = other.DefaultValue;
      }
      if (other.OneofIndex != 0) {
        OneofIndex = other.OneofIndex;
      }
      if (other.JsonName.Length != 0) {
        JsonName = other.JsonName;
      }
      if (other.options_ != null) {
        if (options_ == null) {
          options_ = new global::Google.Protobuf.Reflection.FieldOptions();
        }
        Options.MergeFrom(other.Options);
      }
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            break;
          case 10: {
            Name = input.ReadString();
            break;
          }
          case 18: {
            Extendee = input.ReadString();
            break;
          }
          case 24: {
            Number = input.ReadInt32();
            break;
          }
          case 32: {
            label_ = (global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label) input.ReadEnum();
            break;
          }
          case 40: {
            type_ = (global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type) input.ReadEnum();
            break;
          }
          case 50: {
            TypeName = input.ReadString();
            break;
          }
          case 58: {
            DefaultValue = input.ReadString();
            break;
          }
          case 66: {
            if (options_ == null) {
              options_ = new global::Google.Protobuf.Reflection.FieldOptions();
            }
            input.ReadMessage(options_);
            break;
          }
          case 72: {
            OneofIndex = input.ReadInt32();
            break;
          }
          case 82: {
            JsonName = input.ReadString();
            break;
          }
        }
      }
    }

    #region Nested types
    /// <summary>Container for nested types declared in the FieldDescriptorProto message type.</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static partial class Types {
      internal enum Type {
        /// <summary>
        /// 0 is reserved for errors.
        /// Order is weird for historical reasons.
        /// </summary>
        [pbr::OriginalName("TYPE_DOUBLE")] Double = 1,
        [pbr::OriginalName("TYPE_FLOAT")] Float = 2,
        /// <summary>
        /// Not ZigZag encoded.  Negative numbers take 10 bytes.  Use TYPE_SINT64 if
        /// negative values are likely.
        /// </summary>
        [pbr::OriginalName("TYPE_INT64")] Int64 = 3,
        [pbr::OriginalName("TYPE_UINT64")] Uint64 = 4,
        /// <summary>
        /// Not ZigZag encoded.  Negative numbers take 10 bytes.  Use TYPE_SINT32 if
        /// negative values are likely.
        /// </summary>
        [pbr::OriginalName("TYPE_INT32")] Int32 = 5,
        [pbr::OriginalName("TYPE_FIXED64")] Fixed64 = 6,
        [pbr::OriginalName("TYPE_FIXED32")] Fixed32 = 7,
        [pbr::OriginalName("TYPE_BOOL")] Bool = 8,
        [pbr::OriginalName("TYPE_STRING")] String = 9,
        /// <summary>
        /// Tag-delimited aggregate.
        /// Group type is deprecated and not supported in proto3. However, Proto3
        /// implementations should still be able to parse the group wire format and
        /// treat group fields as unknown fields.
        /// </summary>
        [pbr::OriginalName("TYPE_GROUP")] Group = 10,
        /// <summary>
        /// Length-delimited aggregate.
        /// </summary>
        [pbr::OriginalName("TYPE_MESSAGE")] Message = 11,
        /// <summary>
        /// New in version 2.
        /// </summary>
        [pbr::OriginalName("TYPE_BYTES")] Bytes = 12,
        [pbr::OriginalName("TYPE_UINT32")] Uint32 = 13,
        [pbr::OriginalName("TYPE_ENUM")] Enum = 14,
        [pbr::OriginalName("TYPE_SFIXED32")] Sfixed32 = 15,
        [pbr::OriginalName("TYPE_SFIXED64")] Sfixed64 = 16,
        /// <summary>
        /// Uses ZigZag encoding.
        /// </summary>
        [pbr::OriginalName("TYPE_SINT32")] Sint32 = 17,
        /// <summary>
        /// Uses ZigZag encoding.
        /// </summary>
        [pbr::OriginalName("TYPE_SINT64")] Sint64 = 18,
      }

      internal enum Label {
        /// <summary>
        /// 0 is reserved for errors
        /// </summary>
        [pbr::OriginalName("LABEL_OPTIONAL")] Optional = 1,
        [pbr::OriginalName("LABEL_REQUIRED")] Required = 2,
        [pbr::OriginalName("LABEL_REPEATED")] Repeated = 3,
      }

    }
    #endregion

  }

  /// <summary>
  /// Describes a oneof.
  /// </summary>
  internal sealed partial class OneofDescriptorProto : pb::IMessage<OneofDescriptorProto> {
    private static readonly pb::MessageParser<OneofDescriptorProto> _parser = new pb::MessageParser<OneofDescriptorProto>(() => new OneofDescriptorProto());
    private pb::UnknownFieldSet _unknownFields;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pb::MessageParser<OneofDescriptorProto> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[5]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public OneofDescriptorProto() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public OneofDescriptorProto(OneofDescriptorProto other) : this() {
      name_ = other.name_;
      options_ = other.options_ != null ? other.options_.Clone() : null;
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public OneofDescriptorProto Clone() {
      return new OneofDescriptorProto(this);
    }

    /// <summary>Field number for the "name" field.</summary>
    public const int NameFieldNumber = 1;
    private string name_ = "";
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string Name {
      get { return name_; }
      set {
        name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "options" field.</summary>
    public const int OptionsFieldNumber = 2;
    private global::Google.Protobuf.Reflection.OneofOptions options_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public global::Google.Protobuf.Reflection.OneofOptions Options {
      get { return options_; }
      set {
        options_ = value;
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override bool Equals(object other) {
      return Equals(other as OneofDescriptorProto);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(OneofDescriptorProto other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (Name != other.Name) return false;
      if (!object.Equals(Options, other.Options)) return false;
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (Name.Length != 0) hash ^= Name.GetHashCode();
      if (options_ != null) hash ^= Options.GetHashCode();
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void WriteTo(pb::CodedOutputStream output) {
      if (Name.Length != 0) {
        output.WriteRawTag(10);
        output.WriteString(Name);
      }
      if (options_ != null) {
        output.WriteRawTag(18);
        output.WriteMessage(Options);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (Name.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
      }
      if (options_ != null) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Options);
      }
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(OneofDescriptorProto other) {
      if (other == null) {
        return;
      }
      if (other.Name.Length != 0) {
        Name = other.Name;
      }
      if (other.options_ != null) {
        if (options_ == null) {
          options_ = new global::Google.Protobuf.Reflection.OneofOptions();
        }
        Options.MergeFrom(other.Options);
      }
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            break;
          case 10: {
            Name = input.ReadString();
            break;
          }
          case 18: {
            if (options_ == null) {
              options_ = new global::Google.Protobuf.Reflection.OneofOptions();
            }
            input.ReadMessage(options_);
            break;
          }
        }
      }
    }

  }

  /// <summary>
  /// Describes an enum type.
  /// </summary>
  internal sealed partial class EnumDescriptorProto : pb::IMessage<EnumDescriptorProto> {
    private static readonly pb::MessageParser<EnumDescriptorProto> _parser = new pb::MessageParser<EnumDescriptorProto>(() => new EnumDescriptorProto());
    private pb::UnknownFieldSet _unknownFields;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pb::MessageParser<EnumDescriptorProto> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[6]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public EnumDescriptorProto() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public EnumDescriptorProto(EnumDescriptorProto other) : this() {
      name_ = other.name_;
      value_ = other.value_.Clone();
      options_ = other.options_ != null ? other.options_.Clone() : null;
      reservedRange_ = other.reservedRange_.Clone();
      reservedName_ = other.reservedName_.Clone();
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public EnumDescriptorProto Clone() {
      return new EnumDescriptorProto(this);
    }

    /// <summary>Field number for the "name" field.</summary>
    public const int NameFieldNumber = 1;
    private string name_ = "";
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string Name {
      get { return name_; }
      set {
        name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "value" field.</summary>
    public const int ValueFieldNumber = 2;
    private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.EnumValueDescriptorProto> _repeated_value_codec
        = pb::FieldCodec.ForMessage(18, global::Google.Protobuf.Reflection.EnumValueDescriptorProto.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.EnumValueDescriptorProto> value_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.EnumValueDescriptorProto>();
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.EnumValueDescriptorProto> Value {
      get { return value_; }
    }

    /// <summary>Field number for the "options" field.</summary>
    public const int OptionsFieldNumber = 3;
    private global::Google.Protobuf.Reflection.EnumOptions options_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public global::Google.Protobuf.Reflection.EnumOptions Options {
      get { return options_; }
      set {
        options_ = value;
      }
    }

    /// <summary>Field number for the "reserved_range" field.</summary>
    public const int ReservedRangeFieldNumber = 4;
    private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.EnumDescriptorProto.Types.EnumReservedRange> _repeated_reservedRange_codec
        = pb::FieldCodec.ForMessage(34, global::Google.Protobuf.Reflection.EnumDescriptorProto.Types.EnumReservedRange.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.EnumDescriptorProto.Types.EnumReservedRange> reservedRange_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.EnumDescriptorProto.Types.EnumReservedRange>();
    /// <summary>
    /// Range of reserved numeric values. Reserved numeric values may not be used
    /// by enum values in the same enum declaration. Reserved ranges may not
    /// overlap.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.EnumDescriptorProto.Types.EnumReservedRange> ReservedRange {
      get { return reservedRange_; }
    }

    /// <summary>Field number for the "reserved_name" field.</summary>
    public const int ReservedNameFieldNumber = 5;
    private static readonly pb::FieldCodec<string> _repeated_reservedName_codec
        = pb::FieldCodec.ForString(42);
    private readonly pbc::RepeatedField<string> reservedName_ = new pbc::RepeatedField<string>();
    /// <summary>
    /// Reserved enum value names, which may not be reused. A given name may only
    /// be reserved once.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<string> ReservedName {
      get { return reservedName_; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override bool Equals(object other) {
      return Equals(other as EnumDescriptorProto);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(EnumDescriptorProto other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (Name != other.Name) return false;
      if(!value_.Equals(other.value_)) return false;
      if (!object.Equals(Options, other.Options)) return false;
      if(!reservedRange_.Equals(other.reservedRange_)) return false;
      if(!reservedName_.Equals(other.reservedName_)) return false;
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (Name.Length != 0) hash ^= Name.GetHashCode();
      hash ^= value_.GetHashCode();
      if (options_ != null) hash ^= Options.GetHashCode();
      hash ^= reservedRange_.GetHashCode();
      hash ^= reservedName_.GetHashCode();
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void WriteTo(pb::CodedOutputStream output) {
      if (Name.Length != 0) {
        output.WriteRawTag(10);
        output.WriteString(Name);
      }
      value_.WriteTo(output, _repeated_value_codec);
      if (options_ != null) {
        output.WriteRawTag(26);
        output.WriteMessage(Options);
      }
      reservedRange_.WriteTo(output, _repeated_reservedRange_codec);
      reservedName_.WriteTo(output, _repeated_reservedName_codec);
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (Name.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
      }
      size += value_.CalculateSize(_repeated_value_codec);
      if (options_ != null) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Options);
      }
      size += reservedRange_.CalculateSize(_repeated_reservedRange_codec);
      size += reservedName_.CalculateSize(_repeated_reservedName_codec);
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(EnumDescriptorProto other) {
      if (other == null) {
        return;
      }
      if (other.Name.Length != 0) {
        Name = other.Name;
      }
      value_.Add(other.value_);
      if (other.options_ != null) {
        if (options_ == null) {
          options_ = new global::Google.Protobuf.Reflection.EnumOptions();
        }
        Options.MergeFrom(other.Options);
      }
      reservedRange_.Add(other.reservedRange_);
      reservedName_.Add(other.reservedName_);
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            break;
          case 10: {
            Name = input.ReadString();
            break;
          }
          case 18: {
            value_.AddEntriesFrom(input, _repeated_value_codec);
            break;
          }
          case 26: {
            if (options_ == null) {
              options_ = new global::Google.Protobuf.Reflection.EnumOptions();
            }
            input.ReadMessage(options_);
            break;
          }
          case 34: {
            reservedRange_.AddEntriesFrom(input, _repeated_reservedRange_codec);
            break;
          }
          case 42: {
            reservedName_.AddEntriesFrom(input, _repeated_reservedName_codec);
            break;
          }
        }
      }
    }

    #region Nested types
    /// <summary>Container for nested types declared in the EnumDescriptorProto message type.</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static partial class Types {
      /// <summary>
      /// Range of reserved numeric values. Reserved values may not be used by
      /// entries in the same enum. Reserved ranges may not overlap.
      ///
      /// Note that this is distinct from DescriptorProto.ReservedRange in that it
      /// is inclusive such that it can appropriately represent the entire int32
      /// domain.
      /// </summary>
      internal sealed partial class EnumReservedRange : pb::IMessage<EnumReservedRange> {
        private static readonly pb::MessageParser<EnumReservedRange> _parser = new pb::MessageParser<EnumReservedRange>(() => new EnumReservedRange());
        private pb::UnknownFieldSet _unknownFields;
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public static pb::MessageParser<EnumReservedRange> Parser { get { return _parser; } }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public static pbr::MessageDescriptor Descriptor {
          get { return global::Google.Protobuf.Reflection.EnumDescriptorProto.Descriptor.NestedTypes[0]; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        pbr::MessageDescriptor pb::IMessage.Descriptor {
          get { return Descriptor; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public EnumReservedRange() {
          OnConstruction();
        }

        partial void OnConstruction();

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public EnumReservedRange(EnumReservedRange other) : this() {
          start_ = other.start_;
          end_ = other.end_;
          _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public EnumReservedRange Clone() {
          return new EnumReservedRange(this);
        }

        /// <summary>Field number for the "start" field.</summary>
        public const int StartFieldNumber = 1;
        private int start_;
        /// <summary>
        /// Inclusive.
        /// </summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public int Start {
          get { return start_; }
          set {
            start_ = value;
          }
        }

        /// <summary>Field number for the "end" field.</summary>
        public const int EndFieldNumber = 2;
        private int end_;
        /// <summary>
        /// Inclusive.
        /// </summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public int End {
          get { return end_; }
          set {
            end_ = value;
          }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public override bool Equals(object other) {
          return Equals(other as EnumReservedRange);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public bool Equals(EnumReservedRange other) {
          if (ReferenceEquals(other, null)) {
            return false;
          }
          if (ReferenceEquals(other, this)) {
            return true;
          }
          if (Start != other.Start) return false;
          if (End != other.End) return false;
          return Equals(_unknownFields, other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public override int GetHashCode() {
          int hash = 1;
          if (Start != 0) hash ^= Start.GetHashCode();
          if (End != 0) hash ^= End.GetHashCode();
          if (_unknownFields != null) {
            hash ^= _unknownFields.GetHashCode();
          }
          return hash;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public override string ToString() {
          return pb::JsonFormatter.ToDiagnosticString(this);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void WriteTo(pb::CodedOutputStream output) {
          if (Start != 0) {
            output.WriteRawTag(8);
            output.WriteInt32(Start);
          }
          if (End != 0) {
            output.WriteRawTag(16);
            output.WriteInt32(End);
          }
          if (_unknownFields != null) {
            _unknownFields.WriteTo(output);
          }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public int CalculateSize() {
          int size = 0;
          if (Start != 0) {
            size += 1 + pb::CodedOutputStream.ComputeInt32Size(Start);
          }
          if (End != 0) {
            size += 1 + pb::CodedOutputStream.ComputeInt32Size(End);
          }
          if (_unknownFields != null) {
            size += _unknownFields.CalculateSize();
          }
          return size;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void MergeFrom(EnumReservedRange other) {
          if (other == null) {
            return;
          }
          if (other.Start != 0) {
            Start = other.Start;
          }
          if (other.End != 0) {
            End = other.End;
          }
          _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void MergeFrom(pb::CodedInputStream input) {
          uint tag;
          while ((tag = input.ReadTag()) != 0) {
            switch(tag) {
              default:
                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                break;
              case 8: {
                Start = input.ReadInt32();
                break;
              }
              case 16: {
                End = input.ReadInt32();
                break;
              }
            }
          }
        }

      }

    }
    #endregion

  }

  /// <summary>
  /// Describes a value within an enum.
  /// </summary>
  internal sealed partial class EnumValueDescriptorProto : pb::IMessage<EnumValueDescriptorProto> {
    private static readonly pb::MessageParser<EnumValueDescriptorProto> _parser = new pb::MessageParser<EnumValueDescriptorProto>(() => new EnumValueDescriptorProto());
    private pb::UnknownFieldSet _unknownFields;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pb::MessageParser<EnumValueDescriptorProto> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[7]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public EnumValueDescriptorProto() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public EnumValueDescriptorProto(EnumValueDescriptorProto other) : this() {
      name_ = other.name_;
      number_ = other.number_;
      options_ = other.options_ != null ? other.options_.Clone() : null;
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public EnumValueDescriptorProto Clone() {
      return new EnumValueDescriptorProto(this);
    }

    /// <summary>Field number for the "name" field.</summary>
    public const int NameFieldNumber = 1;
    private string name_ = "";
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string Name {
      get { return name_; }
      set {
        name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "number" field.</summary>
    public const int NumberFieldNumber = 2;
    private int number_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int Number {
      get { return number_; }
      set {
        number_ = value;
      }
    }

    /// <summary>Field number for the "options" field.</summary>
    public const int OptionsFieldNumber = 3;
    private global::Google.Protobuf.Reflection.EnumValueOptions options_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public global::Google.Protobuf.Reflection.EnumValueOptions Options {
      get { return options_; }
      set {
        options_ = value;
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override bool Equals(object other) {
      return Equals(other as EnumValueDescriptorProto);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(EnumValueDescriptorProto other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (Name != other.Name) return false;
      if (Number != other.Number) return false;
      if (!object.Equals(Options, other.Options)) return false;
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (Name.Length != 0) hash ^= Name.GetHashCode();
      if (Number != 0) hash ^= Number.GetHashCode();
      if (options_ != null) hash ^= Options.GetHashCode();
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void WriteTo(pb::CodedOutputStream output) {
      if (Name.Length != 0) {
        output.WriteRawTag(10);
        output.WriteString(Name);
      }
      if (Number != 0) {
        output.WriteRawTag(16);
        output.WriteInt32(Number);
      }
      if (options_ != null) {
        output.WriteRawTag(26);
        output.WriteMessage(Options);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (Name.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
      }
      if (Number != 0) {
        size += 1 + pb::CodedOutputStream.ComputeInt32Size(Number);
      }
      if (options_ != null) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Options);
      }
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(EnumValueDescriptorProto other) {
      if (other == null) {
        return;
      }
      if (other.Name.Length != 0) {
        Name = other.Name;
      }
      if (other.Number != 0) {
        Number = other.Number;
      }
      if (other.options_ != null) {
        if (options_ == null) {
          options_ = new global::Google.Protobuf.Reflection.EnumValueOptions();
        }
        Options.MergeFrom(other.Options);
      }
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            break;
          case 10: {
            Name = input.ReadString();
            break;
          }
          case 16: {
            Number = input.ReadInt32();
            break;
          }
          case 26: {
            if (options_ == null) {
              options_ = new global::Google.Protobuf.Reflection.EnumValueOptions();
            }
            input.ReadMessage(options_);
            break;
          }
        }
      }
    }

  }

  /// <summary>
  /// Describes a service.
  /// </summary>
  internal sealed partial class ServiceDescriptorProto : pb::IMessage<ServiceDescriptorProto> {
    private static readonly pb::MessageParser<ServiceDescriptorProto> _parser = new pb::MessageParser<ServiceDescriptorProto>(() => new ServiceDescriptorProto());
    private pb::UnknownFieldSet _unknownFields;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pb::MessageParser<ServiceDescriptorProto> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[8]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public ServiceDescriptorProto() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public ServiceDescriptorProto(ServiceDescriptorProto other) : this() {
      name_ = other.name_;
      method_ = other.method_.Clone();
      options_ = other.options_ != null ? other.options_.Clone() : null;
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public ServiceDescriptorProto Clone() {
      return new ServiceDescriptorProto(this);
    }

    /// <summary>Field number for the "name" field.</summary>
    public const int NameFieldNumber = 1;
    private string name_ = "";
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string Name {
      get { return name_; }
      set {
        name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "method" field.</summary>
    public const int MethodFieldNumber = 2;
    private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.MethodDescriptorProto> _repeated_method_codec
        = pb::FieldCodec.ForMessage(18, global::Google.Protobuf.Reflection.MethodDescriptorProto.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.MethodDescriptorProto> method_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.MethodDescriptorProto>();
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.MethodDescriptorProto> Method {
      get { return method_; }
    }

    /// <summary>Field number for the "options" field.</summary>
    public const int OptionsFieldNumber = 3;
    private global::Google.Protobuf.Reflection.ServiceOptions options_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public global::Google.Protobuf.Reflection.ServiceOptions Options {
      get { return options_; }
      set {
        options_ = value;
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override bool Equals(object other) {
      return Equals(other as ServiceDescriptorProto);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(ServiceDescriptorProto other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (Name != other.Name) return false;
      if(!method_.Equals(other.method_)) return false;
      if (!object.Equals(Options, other.Options)) return false;
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (Name.Length != 0) hash ^= Name.GetHashCode();
      hash ^= method_.GetHashCode();
      if (options_ != null) hash ^= Options.GetHashCode();
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void WriteTo(pb::CodedOutputStream output) {
      if (Name.Length != 0) {
        output.WriteRawTag(10);
        output.WriteString(Name);
      }
      method_.WriteTo(output, _repeated_method_codec);
      if (options_ != null) {
        output.WriteRawTag(26);
        output.WriteMessage(Options);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (Name.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
      }
      size += method_.CalculateSize(_repeated_method_codec);
      if (options_ != null) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Options);
      }
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(ServiceDescriptorProto other) {
      if (other == null) {
        return;
      }
      if (other.Name.Length != 0) {
        Name = other.Name;
      }
      method_.Add(other.method_);
      if (other.options_ != null) {
        if (options_ == null) {
          options_ = new global::Google.Protobuf.Reflection.ServiceOptions();
        }
        Options.MergeFrom(other.Options);
      }
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            break;
          case 10: {
            Name = input.ReadString();
            break;
          }
          case 18: {
            method_.AddEntriesFrom(input, _repeated_method_codec);
            break;
          }
          case 26: {
            if (options_ == null) {
              options_ = new global::Google.Protobuf.Reflection.ServiceOptions();
            }
            input.ReadMessage(options_);
            break;
          }
        }
      }
    }

  }

  /// <summary>
  /// Describes a method of a service.
  /// </summary>
  internal sealed partial class MethodDescriptorProto : pb::IMessage<MethodDescriptorProto> {
    private static readonly pb::MessageParser<MethodDescriptorProto> _parser = new pb::MessageParser<MethodDescriptorProto>(() => new MethodDescriptorProto());
    private pb::UnknownFieldSet _unknownFields;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pb::MessageParser<MethodDescriptorProto> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[9]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public MethodDescriptorProto() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public MethodDescriptorProto(MethodDescriptorProto other) : this() {
      name_ = other.name_;
      inputType_ = other.inputType_;
      outputType_ = other.outputType_;
      options_ = other.options_ != null ? other.options_.Clone() : null;
      clientStreaming_ = other.clientStreaming_;
      serverStreaming_ = other.serverStreaming_;
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public MethodDescriptorProto Clone() {
      return new MethodDescriptorProto(this);
    }

    /// <summary>Field number for the "name" field.</summary>
    public const int NameFieldNumber = 1;
    private string name_ = "";
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string Name {
      get { return name_; }
      set {
        name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "input_type" field.</summary>
    public const int InputTypeFieldNumber = 2;
    private string inputType_ = "";
    /// <summary>
    /// Input and output type names.  These are resolved in the same way as
    /// FieldDescriptorProto.type_name, but must refer to a message type.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string InputType {
      get { return inputType_; }
      set {
        inputType_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "output_type" field.</summary>
    public const int OutputTypeFieldNumber = 3;
    private string outputType_ = "";
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string OutputType {
      get { return outputType_; }
      set {
        outputType_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "options" field.</summary>
    public const int OptionsFieldNumber = 4;
    private global::Google.Protobuf.Reflection.MethodOptions options_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public global::Google.Protobuf.Reflection.MethodOptions Options {
      get { return options_; }
      set {
        options_ = value;
      }
    }

    /// <summary>Field number for the "client_streaming" field.</summary>
    public const int ClientStreamingFieldNumber = 5;
    private bool clientStreaming_;
    /// <summary>
    /// Identifies if client streams multiple client messages
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool ClientStreaming {
      get { return clientStreaming_; }
      set {
        clientStreaming_ = value;
      }
    }

    /// <summary>Field number for the "server_streaming" field.</summary>
    public const int ServerStreamingFieldNumber = 6;
    private bool serverStreaming_;
    /// <summary>
    /// Identifies if server streams multiple server messages
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool ServerStreaming {
      get { return serverStreaming_; }
      set {
        serverStreaming_ = value;
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override bool Equals(object other) {
      return Equals(other as MethodDescriptorProto);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(MethodDescriptorProto other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (Name != other.Name) return false;
      if (InputType != other.InputType) return false;
      if (OutputType != other.OutputType) return false;
      if (!object.Equals(Options, other.Options)) return false;
      if (ClientStreaming != other.ClientStreaming) return false;
      if (ServerStreaming != other.ServerStreaming) return false;
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (Name.Length != 0) hash ^= Name.GetHashCode();
      if (InputType.Length != 0) hash ^= InputType.GetHashCode();
      if (OutputType.Length != 0) hash ^= OutputType.GetHashCode();
      if (options_ != null) hash ^= Options.GetHashCode();
      if (ClientStreaming != false) hash ^= ClientStreaming.GetHashCode();
      if (ServerStreaming != false) hash ^= ServerStreaming.GetHashCode();
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void WriteTo(pb::CodedOutputStream output) {
      if (Name.Length != 0) {
        output.WriteRawTag(10);
        output.WriteString(Name);
      }
      if (InputType.Length != 0) {
        output.WriteRawTag(18);
        output.WriteString(InputType);
      }
      if (OutputType.Length != 0) {
        output.WriteRawTag(26);
        output.WriteString(OutputType);
      }
      if (options_ != null) {
        output.WriteRawTag(34);
        output.WriteMessage(Options);
      }
      if (ClientStreaming != false) {
        output.WriteRawTag(40);
        output.WriteBool(ClientStreaming);
      }
      if (ServerStreaming != false) {
        output.WriteRawTag(48);
        output.WriteBool(ServerStreaming);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (Name.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
      }
      if (InputType.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(InputType);
      }
      if (OutputType.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(OutputType);
      }
      if (options_ != null) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Options);
      }
      if (ClientStreaming != false) {
        size += 1 + 1;
      }
      if (ServerStreaming != false) {
        size += 1 + 1;
      }
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(MethodDescriptorProto other) {
      if (other == null) {
        return;
      }
      if (other.Name.Length != 0) {
        Name = other.Name;
      }
      if (other.InputType.Length != 0) {
        InputType = other.InputType;
      }
      if (other.OutputType.Length != 0) {
        OutputType = other.OutputType;
      }
      if (other.options_ != null) {
        if (options_ == null) {
          options_ = new global::Google.Protobuf.Reflection.MethodOptions();
        }
        Options.MergeFrom(other.Options);
      }
      if (other.ClientStreaming != false) {
        ClientStreaming = other.ClientStreaming;
      }
      if (other.ServerStreaming != false) {
        ServerStreaming = other.ServerStreaming;
      }
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            break;
          case 10: {
            Name = input.ReadString();
            break;
          }
          case 18: {
            InputType = input.ReadString();
            break;
          }
          case 26: {
            OutputType = input.ReadString();
            break;
          }
          case 34: {
            if (options_ == null) {
              options_ = new global::Google.Protobuf.Reflection.MethodOptions();
            }
            input.ReadMessage(options_);
            break;
          }
          case 40: {
            ClientStreaming = input.ReadBool();
            break;
          }
          case 48: {
            ServerStreaming = input.ReadBool();
            break;
          }
        }
      }
    }

  }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[10]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    internal CustomOptions CustomOptions{ get; private set; } = CustomOptions.Empty;

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public FileOptions() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public FileOptions(FileOptions other) : this() {
      javaPackage_ = other.javaPackage_;
      javaOuterClassname_ = other.javaOuterClassname_;
      javaMultipleFiles_ = other.javaMultipleFiles_;
      javaGenerateEqualsAndHash_ = other.javaGenerateEqualsAndHash_;
      javaStringCheckUtf8_ = other.javaStringCheckUtf8_;
      optimizeFor_ = other.optimizeFor_;
      goPackage_ = other.goPackage_;
      ccGenericServices_ = other.ccGenericServices_;
      javaGenericServices_ = other.javaGenericServices_;
      pyGenericServices_ = other.pyGenericServices_;
      phpGenericServices_ = other.phpGenericServices_;
      deprecated_ = other.deprecated_;
      ccEnableArenas_ = other.ccEnableArenas_;
      objcClassPrefix_ = other.objcClassPrefix_;
      csharpNamespace_ = other.csharpNamespace_;
      swiftPrefix_ = other.swiftPrefix_;
      phpClassPrefix_ = other.phpClassPrefix_;
      phpNamespace_ = other.phpNamespace_;
      phpMetadataNamespace_ = other.phpMetadataNamespace_;
      rubyPackage_ = other.rubyPackage_;
      uninterpretedOption_ = other.uninterpretedOption_.Clone();
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public FileOptions Clone() {
      return new FileOptions(this);
    }

    /// <summary>Field number for the "java_package" field.</summary>
    public const int JavaPackageFieldNumber = 1;
    private string javaPackage_ = "";
    /// <summary>
    /// Sets the Java package where classes generated from this .proto will be
    /// placed.  By default, the proto package is used, but this is often
    /// inappropriate because proto packages do not normally start with backwards
    /// domain names.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string JavaPackage {
      get { return javaPackage_; }
      set {
        javaPackage_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "java_outer_classname" field.</summary>
    public const int JavaOuterClassnameFieldNumber = 8;
    private string javaOuterClassname_ = "";
    /// <summary>
    /// If set, all the classes from the .proto file are wrapped in a single
    /// outer class with the given name.  This applies to both Proto1
    /// (equivalent to the old "--one_java_file" option) and Proto2 (where
    /// a .proto always translates to a single class, but you may want to
    /// explicitly choose the class name).
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string JavaOuterClassname {
      get { return javaOuterClassname_; }
      set {
        javaOuterClassname_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "java_multiple_files" field.</summary>
    public const int JavaMultipleFilesFieldNumber = 10;
    private bool javaMultipleFiles_;
    /// <summary>
    /// If set true, then the Java code generator will generate a separate .java
    /// file for each top-level message, enum, and service defined in the .proto
    /// file.  Thus, these types will *not* be nested inside the outer class
    /// named by java_outer_classname.  However, the outer class will still be
    /// generated to contain the file's getDescriptor() method as well as any
    /// top-level extensions defined in the file.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool JavaMultipleFiles {
      get { return javaMultipleFiles_; }
      set {
        javaMultipleFiles_ = value;
      }
    }

    /// <summary>Field number for the "java_generate_equals_and_hash" field.</summary>
    public const int JavaGenerateEqualsAndHashFieldNumber = 20;
    private bool javaGenerateEqualsAndHash_;
    /// <summary>
    /// This option does nothing.
    /// </summary>
    [global::System.ObsoleteAttribute]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool JavaGenerateEqualsAndHash {
      get { return javaGenerateEqualsAndHash_; }
      set {
        javaGenerateEqualsAndHash_ = value;
      }
    }

    /// <summary>Field number for the "java_string_check_utf8" field.</summary>
    public const int JavaStringCheckUtf8FieldNumber = 27;
    private bool javaStringCheckUtf8_;
    /// <summary>
    /// If set true, then the Java2 code generator will generate code that
    /// throws an exception whenever an attempt is made to assign a non-UTF-8
    /// byte sequence to a string field.
    /// Message reflection will do the same.
    /// However, an extension field still accepts non-UTF-8 byte sequences.
    /// This option has no effect on when used with the lite runtime.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool JavaStringCheckUtf8 {
      get { return javaStringCheckUtf8_; }
      set {
        javaStringCheckUtf8_ = value;
      }
    }

    /// <summary>Field number for the "optimize_for" field.</summary>
    public const int OptimizeForFieldNumber = 9;
    private global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode optimizeFor_ = 0;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode OptimizeFor {
      get { return optimizeFor_; }
      set {
        optimizeFor_ = value;
      }
    }

    /// <summary>Field number for the "go_package" field.</summary>
    public const int GoPackageFieldNumber = 11;
    private string goPackage_ = "";
    /// <summary>
    /// Sets the Go package where structs generated from this .proto will be
    /// placed. If omitted, the Go package will be derived from the following:
    ///   - The basename of the package import path, if provided.
    ///   - Otherwise, the package statement in the .proto file, if present.
    ///   - Otherwise, the basename of the .proto file, without extension.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string GoPackage {
      get { return goPackage_; }
      set {
        goPackage_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "cc_generic_services" field.</summary>
    public const int CcGenericServicesFieldNumber = 16;
    private bool ccGenericServices_;
    /// <summary>
    /// Should generic services be generated in each language?  "Generic" services
    /// are not specific to any particular RPC system.  They are generated by the
    /// main code generators in each language (without additional plugins).
    /// Generic services were the only kind of service generation supported by
    /// early versions of google.protobuf.
    ///
    /// Generic services are now considered deprecated in favor of using plugins
    /// that generate code specific to your particular RPC system.  Therefore,
    /// these default to false.  Old code which depends on generic services should
    /// explicitly set them to true.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool CcGenericServices {
      get { return ccGenericServices_; }
      set {
        ccGenericServices_ = value;
      }
    }

    /// <summary>Field number for the "java_generic_services" field.</summary>
    public const int JavaGenericServicesFieldNumber = 17;
    private bool javaGenericServices_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool JavaGenericServices {
      get { return javaGenericServices_; }
      set {
        javaGenericServices_ = value;
      }
    }

    /// <summary>Field number for the "py_generic_services" field.</summary>
    public const int PyGenericServicesFieldNumber = 18;
    private bool pyGenericServices_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool PyGenericServices {
      get { return pyGenericServices_; }
      set {
        pyGenericServices_ = value;
      }
    }

    /// <summary>Field number for the "php_generic_services" field.</summary>
    public const int PhpGenericServicesFieldNumber = 42;
    private bool phpGenericServices_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool PhpGenericServices {
      get { return phpGenericServices_; }
      set {
        phpGenericServices_ = value;
      }
    }

    /// <summary>Field number for the "deprecated" field.</summary>
    public const int DeprecatedFieldNumber = 23;
    private bool deprecated_;
    /// <summary>
    /// Is this file deprecated?
    /// Depending on the target platform, this can emit Deprecated annotations
    /// for everything in the file, or it will be completely ignored; in the very
    /// least, this is a formalization for deprecating files.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Deprecated {
      get { return deprecated_; }
      set {
        deprecated_ = value;
      }
    }

    /// <summary>Field number for the "cc_enable_arenas" field.</summary>
    public const int CcEnableArenasFieldNumber = 31;
    private bool ccEnableArenas_;
    /// <summary>
    /// Enables the use of arenas for the proto messages in this file. This applies
    /// only to generated classes for C++.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool CcEnableArenas {
      get { return ccEnableArenas_; }
      set {
        ccEnableArenas_ = value;
      }
    }

    /// <summary>Field number for the "objc_class_prefix" field.</summary>
    public const int ObjcClassPrefixFieldNumber = 36;
    private string objcClassPrefix_ = "";
    /// <summary>
    /// Sets the objective c class prefix which is prepended to all objective c
    /// generated classes from this .proto. There is no default.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string ObjcClassPrefix {
      get { return objcClassPrefix_; }
      set {
        objcClassPrefix_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "csharp_namespace" field.</summary>
    public const int CsharpNamespaceFieldNumber = 37;
    private string csharpNamespace_ = "";
    /// <summary>
    /// Namespace for generated classes; defaults to the package.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string CsharpNamespace {
      get { return csharpNamespace_; }
      set {
        csharpNamespace_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "swift_prefix" field.</summary>
    public const int SwiftPrefixFieldNumber = 39;
    private string swiftPrefix_ = "";
    /// <summary>
    /// By default Swift generators will take the proto package and CamelCase it
    /// replacing '.' with underscore and use that to prefix the types/symbols
    /// defined. When this options is provided, they will use this value instead
    /// to prefix the types/symbols defined.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string SwiftPrefix {
      get { return swiftPrefix_; }
      set {
        swiftPrefix_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "php_class_prefix" field.</summary>
    public const int PhpClassPrefixFieldNumber = 40;
    private string phpClassPrefix_ = "";
    /// <summary>
    /// Sets the php class prefix which is prepended to all php generated classes
    /// from this .proto. Default is empty.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string PhpClassPrefix {
      get { return phpClassPrefix_; }
      set {
        phpClassPrefix_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "php_namespace" field.</summary>
    public const int PhpNamespaceFieldNumber = 41;
    private string phpNamespace_ = "";
    /// <summary>
    /// Use this option to change the namespace of php generated classes. Default
    /// is empty. When this option is empty, the package name will be used for
    /// determining the namespace.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string PhpNamespace {
      get { return phpNamespace_; }
      set {
        phpNamespace_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "php_metadata_namespace" field.</summary>
    public const int PhpMetadataNamespaceFieldNumber = 44;
    private string phpMetadataNamespace_ = "";
    /// <summary>
    /// Use this option to change the namespace of php generated metadata classes.
    /// Default is empty. When this option is empty, the proto file name will be used
    /// for determining the namespace.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string PhpMetadataNamespace {
      get { return phpMetadataNamespace_; }
      set {
        phpMetadataNamespace_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "ruby_package" field.</summary>
    public const int RubyPackageFieldNumber = 45;
    private string rubyPackage_ = "";
    /// <summary>
    /// Use this option to change the package of ruby generated classes. Default
    /// is empty. When this option is not set, the package name will be used for
    /// determining the ruby package.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string RubyPackage {
      get { return rubyPackage_; }
      set {
        rubyPackage_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "uninterpreted_option" field.</summary>
    public const int UninterpretedOptionFieldNumber = 999;
    private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.UninterpretedOption> _repeated_uninterpretedOption_codec
        = pb::FieldCodec.ForMessage(7994, global::Google.Protobuf.Reflection.UninterpretedOption.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption> uninterpretedOption_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption>();
    /// <summary>
    /// The parser stores options it doesn't recognize here.
    /// See the documentation for the "Options" section above.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption> UninterpretedOption {
      get { return uninterpretedOption_; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override bool Equals(object other) {
      return Equals(other as FileOptions);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(FileOptions other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (JavaPackage != other.JavaPackage) return false;
      if (JavaOuterClassname != other.JavaOuterClassname) return false;
      if (JavaMultipleFiles != other.JavaMultipleFiles) return false;
      if (JavaGenerateEqualsAndHash != other.JavaGenerateEqualsAndHash) return false;
      if (JavaStringCheckUtf8 != other.JavaStringCheckUtf8) return false;
      if (OptimizeFor != other.OptimizeFor) return false;
      if (GoPackage != other.GoPackage) return false;
      if (CcGenericServices != other.CcGenericServices) return false;
      if (JavaGenericServices != other.JavaGenericServices) return false;
      if (PyGenericServices != other.PyGenericServices) return false;
      if (PhpGenericServices != other.PhpGenericServices) return false;
      if (Deprecated != other.Deprecated) return false;
      if (CcEnableArenas != other.CcEnableArenas) return false;
      if (ObjcClassPrefix != other.ObjcClassPrefix) return false;
      if (CsharpNamespace != other.CsharpNamespace) return false;
      if (SwiftPrefix != other.SwiftPrefix) return false;
      if (PhpClassPrefix != other.PhpClassPrefix) return false;
      if (PhpNamespace != other.PhpNamespace) return false;
      if (PhpMetadataNamespace != other.PhpMetadataNamespace) return false;
      if (RubyPackage != other.RubyPackage) return false;
      if(!uninterpretedOption_.Equals(other.uninterpretedOption_)) return false;
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (JavaPackage.Length != 0) hash ^= JavaPackage.GetHashCode();
      if (JavaOuterClassname.Length != 0) hash ^= JavaOuterClassname.GetHashCode();
      if (JavaMultipleFiles != false) hash ^= JavaMultipleFiles.GetHashCode();
      if (JavaGenerateEqualsAndHash != false) hash ^= JavaGenerateEqualsAndHash.GetHashCode();
      if (JavaStringCheckUtf8 != false) hash ^= JavaStringCheckUtf8.GetHashCode();
      if (OptimizeFor != 0) hash ^= OptimizeFor.GetHashCode();
      if (GoPackage.Length != 0) hash ^= GoPackage.GetHashCode();
      if (CcGenericServices != false) hash ^= CcGenericServices.GetHashCode();
      if (JavaGenericServices != false) hash ^= JavaGenericServices.GetHashCode();
      if (PyGenericServices != false) hash ^= PyGenericServices.GetHashCode();
      if (PhpGenericServices != false) hash ^= PhpGenericServices.GetHashCode();
      if (Deprecated != false) hash ^= Deprecated.GetHashCode();
      if (CcEnableArenas != false) hash ^= CcEnableArenas.GetHashCode();
      if (ObjcClassPrefix.Length != 0) hash ^= ObjcClassPrefix.GetHashCode();
      if (CsharpNamespace.Length != 0) hash ^= CsharpNamespace.GetHashCode();
      if (SwiftPrefix.Length != 0) hash ^= SwiftPrefix.GetHashCode();
      if (PhpClassPrefix.Length != 0) hash ^= PhpClassPrefix.GetHashCode();
      if (PhpNamespace.Length != 0) hash ^= PhpNamespace.GetHashCode();
      if (PhpMetadataNamespace.Length != 0) hash ^= PhpMetadataNamespace.GetHashCode();
      if (RubyPackage.Length != 0) hash ^= RubyPackage.GetHashCode();
      hash ^= uninterpretedOption_.GetHashCode();
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void WriteTo(pb::CodedOutputStream output) {
      if (JavaPackage.Length != 0) {
        output.WriteRawTag(10);
        output.WriteString(JavaPackage);
      }
      if (JavaOuterClassname.Length != 0) {
        output.WriteRawTag(66);
        output.WriteString(JavaOuterClassname);
      }
      if (OptimizeFor != 0) {
        output.WriteRawTag(72);
        output.WriteEnum((int) OptimizeFor);
      }
      if (JavaMultipleFiles != false) {
        output.WriteRawTag(80);
        output.WriteBool(JavaMultipleFiles);
      }
      if (GoPackage.Length != 0) {
        output.WriteRawTag(90);
        output.WriteString(GoPackage);
      }
      if (CcGenericServices != false) {
        output.WriteRawTag(128, 1);
        output.WriteBool(CcGenericServices);
      }
      if (JavaGenericServices != false) {
        output.WriteRawTag(136, 1);
        output.WriteBool(JavaGenericServices);
      }
      if (PyGenericServices != false) {
        output.WriteRawTag(144, 1);
        output.WriteBool(PyGenericServices);
      }
      if (JavaGenerateEqualsAndHash != false) {
        output.WriteRawTag(160, 1);
        output.WriteBool(JavaGenerateEqualsAndHash);
      }
      if (Deprecated != false) {
        output.WriteRawTag(184, 1);
        output.WriteBool(Deprecated);
      }
      if (JavaStringCheckUtf8 != false) {
        output.WriteRawTag(216, 1);
        output.WriteBool(JavaStringCheckUtf8);
      }
      if (CcEnableArenas != false) {
        output.WriteRawTag(248, 1);
        output.WriteBool(CcEnableArenas);
      }
      if (ObjcClassPrefix.Length != 0) {
        output.WriteRawTag(162, 2);
        output.WriteString(ObjcClassPrefix);
      }
      if (CsharpNamespace.Length != 0) {
        output.WriteRawTag(170, 2);
        output.WriteString(CsharpNamespace);
      }
      if (SwiftPrefix.Length != 0) {
        output.WriteRawTag(186, 2);
        output.WriteString(SwiftPrefix);
      }
      if (PhpClassPrefix.Length != 0) {
        output.WriteRawTag(194, 2);
        output.WriteString(PhpClassPrefix);
      }
      if (PhpNamespace.Length != 0) {
        output.WriteRawTag(202, 2);
        output.WriteString(PhpNamespace);
      }
      if (PhpGenericServices != false) {
        output.WriteRawTag(208, 2);
        output.WriteBool(PhpGenericServices);
      }
      if (PhpMetadataNamespace.Length != 0) {
        output.WriteRawTag(226, 2);
        output.WriteString(PhpMetadataNamespace);
      }
      if (RubyPackage.Length != 0) {
        output.WriteRawTag(234, 2);
        output.WriteString(RubyPackage);
      }
      uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (JavaPackage.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(JavaPackage);
      }
      if (JavaOuterClassname.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(JavaOuterClassname);
      }
      if (JavaMultipleFiles != false) {
        size += 1 + 1;
      }
      if (JavaGenerateEqualsAndHash != false) {
        size += 2 + 1;
      }
      if (JavaStringCheckUtf8 != false) {
        size += 2 + 1;
      }
      if (OptimizeFor != 0) {
        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) OptimizeFor);
      }
      if (GoPackage.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(GoPackage);
      }
      if (CcGenericServices != false) {
        size += 2 + 1;
      }
      if (JavaGenericServices != false) {
        size += 2 + 1;
      }
      if (PyGenericServices != false) {
        size += 2 + 1;
      }
      if (PhpGenericServices != false) {
        size += 2 + 1;
      }
      if (Deprecated != false) {
        size += 2 + 1;
      }
      if (CcEnableArenas != false) {
        size += 2 + 1;
      }
      if (ObjcClassPrefix.Length != 0) {
        size += 2 + pb::CodedOutputStream.ComputeStringSize(ObjcClassPrefix);
      }
      if (CsharpNamespace.Length != 0) {
        size += 2 + pb::CodedOutputStream.ComputeStringSize(CsharpNamespace);
      }
      if (SwiftPrefix.Length != 0) {
        size += 2 + pb::CodedOutputStream.ComputeStringSize(SwiftPrefix);
      }
      if (PhpClassPrefix.Length != 0) {
        size += 2 + pb::CodedOutputStream.ComputeStringSize(PhpClassPrefix);
      }
      if (PhpNamespace.Length != 0) {
        size += 2 + pb::CodedOutputStream.ComputeStringSize(PhpNamespace);
      }
      if (PhpMetadataNamespace.Length != 0) {
        size += 2 + pb::CodedOutputStream.ComputeStringSize(PhpMetadataNamespace);
      }
      if (RubyPackage.Length != 0) {
        size += 2 + pb::CodedOutputStream.ComputeStringSize(RubyPackage);
      }
      size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec);
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(FileOptions other) {
      if (other == null) {
        return;
      }
      if (other.JavaPackage.Length != 0) {
        JavaPackage = other.JavaPackage;
      }
      if (other.JavaOuterClassname.Length != 0) {
        JavaOuterClassname = other.JavaOuterClassname;
      }
      if (other.JavaMultipleFiles != false) {
        JavaMultipleFiles = other.JavaMultipleFiles;
      }
      if (other.JavaGenerateEqualsAndHash != false) {
        JavaGenerateEqualsAndHash = other.JavaGenerateEqualsAndHash;
      }
      if (other.JavaStringCheckUtf8 != false) {
        JavaStringCheckUtf8 = other.JavaStringCheckUtf8;
      }
      if (other.OptimizeFor != 0) {
        OptimizeFor = other.OptimizeFor;
      }
      if (other.GoPackage.Length != 0) {
        GoPackage = other.GoPackage;
      }
      if (other.CcGenericServices != false) {
        CcGenericServices = other.CcGenericServices;
      }
      if (other.JavaGenericServices != false) {
        JavaGenericServices = other.JavaGenericServices;
      }
      if (other.PyGenericServices != false) {
        PyGenericServices = other.PyGenericServices;
      }
      if (other.PhpGenericServices != false) {
        PhpGenericServices = other.PhpGenericServices;
      }
      if (other.Deprecated != false) {
        Deprecated = other.Deprecated;
      }
      if (other.CcEnableArenas != false) {
        CcEnableArenas = other.CcEnableArenas;
      }
      if (other.ObjcClassPrefix.Length != 0) {
        ObjcClassPrefix = other.ObjcClassPrefix;
      }
      if (other.CsharpNamespace.Length != 0) {
        CsharpNamespace = other.CsharpNamespace;
      }
      if (other.SwiftPrefix.Length != 0) {
        SwiftPrefix = other.SwiftPrefix;
      }
      if (other.PhpClassPrefix.Length != 0) {
        PhpClassPrefix = other.PhpClassPrefix;
      }
      if (other.PhpNamespace.Length != 0) {
        PhpNamespace = other.PhpNamespace;
      }
      if (other.PhpMetadataNamespace.Length != 0) {
        PhpMetadataNamespace = other.PhpMetadataNamespace;
      }
      if (other.RubyPackage.Length != 0) {
        RubyPackage = other.RubyPackage;
      }
      uninterpretedOption_.Add(other.uninterpretedOption_);
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            CustomOptions = CustomOptions.ReadOrSkipUnknownField(input);
            break;
          case 10: {
            JavaPackage = input.ReadString();
            break;
          }
          case 66: {
            JavaOuterClassname = input.ReadString();
            break;
          }
          case 72: {
            optimizeFor_ = (global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode) input.ReadEnum();
            break;
          }
          case 80: {
            JavaMultipleFiles = input.ReadBool();
            break;
          }
          case 90: {
            GoPackage = input.ReadString();
            break;
          }
          case 128: {
            CcGenericServices = input.ReadBool();
            break;
          }
          case 136: {
            JavaGenericServices = input.ReadBool();
            break;
          }
          case 144: {
            PyGenericServices = input.ReadBool();
            break;
          }
          case 160: {
            JavaGenerateEqualsAndHash = input.ReadBool();
            break;
          }
          case 184: {
            Deprecated = input.ReadBool();
            break;
          }
          case 216: {
            JavaStringCheckUtf8 = input.ReadBool();
            break;
          }
          case 248: {
            CcEnableArenas = input.ReadBool();
            break;
          }
          case 290: {
            ObjcClassPrefix = input.ReadString();
            break;
          }
          case 298: {
            CsharpNamespace = input.ReadString();
            break;
          }
          case 314: {
            SwiftPrefix = input.ReadString();
            break;
          }
          case 322: {
            PhpClassPrefix = input.ReadString();
            break;
          }
          case 330: {
            PhpNamespace = input.ReadString();
            break;
          }
          case 336: {
            PhpGenericServices = input.ReadBool();
            break;
          }
          case 354: {
            PhpMetadataNamespace = input.ReadString();
            break;
          }
          case 362: {
            RubyPackage = input.ReadString();
            break;
          }
          case 7994: {
            uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec);
            break;
          }
        }
      }
    }

    #region Nested types
    /// <summary>Container for nested types declared in the FileOptions message type.</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static partial class Types {
      /// <summary>
      /// Generated classes can be optimized for speed or code size.
      /// </summary>
      internal enum OptimizeMode {
        /// <summary>
        /// Generate complete code for parsing, serialization,
        /// </summary>
        [pbr::OriginalName("SPEED")] Speed = 1,
        /// <summary>
        /// etc.
        /// </summary>
        [pbr::OriginalName("CODE_SIZE")] CodeSize = 2,
        /// <summary>
        /// Generate code using MessageLite and the lite runtime.
        /// </summary>
        [pbr::OriginalName("LITE_RUNTIME")] LiteRuntime = 3,
      }

    }
    #endregion

  }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[11]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    internal CustomOptions CustomOptions{ get; private set; } = CustomOptions.Empty;

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public MessageOptions() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public MessageOptions(MessageOptions other) : this() {
      messageSetWireFormat_ = other.messageSetWireFormat_;
      noStandardDescriptorAccessor_ = other.noStandardDescriptorAccessor_;
      deprecated_ = other.deprecated_;
      mapEntry_ = other.mapEntry_;
      uninterpretedOption_ = other.uninterpretedOption_.Clone();
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public MessageOptions Clone() {
      return new MessageOptions(this);
    }

    /// <summary>Field number for the "message_set_wire_format" field.</summary>
    public const int MessageSetWireFormatFieldNumber = 1;
    private bool messageSetWireFormat_;
    /// <summary>
    /// Set true to use the old proto1 MessageSet wire format for extensions.
    /// This is provided for backwards-compatibility with the MessageSet wire
    /// format.  You should not use this for any other reason:  It's less
    /// efficient, has fewer features, and is more complicated.
    ///
    /// The message must be defined exactly as follows:
    ///   message Foo {
    ///     option message_set_wire_format = true;
    ///     extensions 4 to max;
    ///   }
    /// Note that the message cannot have any defined fields; MessageSets only
    /// have extensions.
    ///
    /// All extensions of your type must be singular messages; e.g. they cannot
    /// be int32s, enums, or repeated messages.
    ///
    /// Because this is an option, the above two restrictions are not enforced by
    /// the protocol compiler.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool MessageSetWireFormat {
      get { return messageSetWireFormat_; }
      set {
        messageSetWireFormat_ = value;
      }
    }

    /// <summary>Field number for the "no_standard_descriptor_accessor" field.</summary>
    public const int NoStandardDescriptorAccessorFieldNumber = 2;
    private bool noStandardDescriptorAccessor_;
    /// <summary>
    /// Disables the generation of the standard "descriptor()" accessor, which can
    /// conflict with a field of the same name.  This is meant to make migration
    /// from proto1 easier; new code should avoid fields named "descriptor".
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool NoStandardDescriptorAccessor {
      get { return noStandardDescriptorAccessor_; }
      set {
        noStandardDescriptorAccessor_ = value;
      }
    }

    /// <summary>Field number for the "deprecated" field.</summary>
    public const int DeprecatedFieldNumber = 3;
    private bool deprecated_;
    /// <summary>
    /// Is this message deprecated?
    /// Depending on the target platform, this can emit Deprecated annotations
    /// for the message, or it will be completely ignored; in the very least,
    /// this is a formalization for deprecating messages.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Deprecated {
      get { return deprecated_; }
      set {
        deprecated_ = value;
      }
    }

    /// <summary>Field number for the "map_entry" field.</summary>
    public const int MapEntryFieldNumber = 7;
    private bool mapEntry_;
    /// <summary>
    /// Whether the message is an automatically generated map entry type for the
    /// maps field.
    ///
    /// For maps fields:
    ///     map&lt;KeyType, ValueType> map_field = 1;
    /// The parsed descriptor looks like:
    ///     message MapFieldEntry {
    ///         option map_entry = true;
    ///         optional KeyType key = 1;
    ///         optional ValueType value = 2;
    ///     }
    ///     repeated MapFieldEntry map_field = 1;
    ///
    /// Implementations may choose not to generate the map_entry=true message, but
    /// use a native map in the target language to hold the keys and values.
    /// The reflection APIs in such implementions still need to work as
    /// if the field is a repeated message field.
    ///
    /// NOTE: Do not set the option in .proto files. Always use the maps syntax
    /// instead. The option should only be implicitly set by the proto compiler
    /// parser.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool MapEntry {
      get { return mapEntry_; }
      set {
        mapEntry_ = value;
      }
    }

    /// <summary>Field number for the "uninterpreted_option" field.</summary>
    public const int UninterpretedOptionFieldNumber = 999;
    private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.UninterpretedOption> _repeated_uninterpretedOption_codec
        = pb::FieldCodec.ForMessage(7994, global::Google.Protobuf.Reflection.UninterpretedOption.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption> uninterpretedOption_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption>();
    /// <summary>
    /// The parser stores options it doesn't recognize here. See above.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption> UninterpretedOption {
      get { return uninterpretedOption_; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override bool Equals(object other) {
      return Equals(other as MessageOptions);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(MessageOptions other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (MessageSetWireFormat != other.MessageSetWireFormat) return false;
      if (NoStandardDescriptorAccessor != other.NoStandardDescriptorAccessor) return false;
      if (Deprecated != other.Deprecated) return false;
      if (MapEntry != other.MapEntry) return false;
      if(!uninterpretedOption_.Equals(other.uninterpretedOption_)) return false;
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (MessageSetWireFormat != false) hash ^= MessageSetWireFormat.GetHashCode();
      if (NoStandardDescriptorAccessor != false) hash ^= NoStandardDescriptorAccessor.GetHashCode();
      if (Deprecated != false) hash ^= Deprecated.GetHashCode();
      if (MapEntry != false) hash ^= MapEntry.GetHashCode();
      hash ^= uninterpretedOption_.GetHashCode();
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void WriteTo(pb::CodedOutputStream output) {
      if (MessageSetWireFormat != false) {
        output.WriteRawTag(8);
        output.WriteBool(MessageSetWireFormat);
      }
      if (NoStandardDescriptorAccessor != false) {
        output.WriteRawTag(16);
        output.WriteBool(NoStandardDescriptorAccessor);
      }
      if (Deprecated != false) {
        output.WriteRawTag(24);
        output.WriteBool(Deprecated);
      }
      if (MapEntry != false) {
        output.WriteRawTag(56);
        output.WriteBool(MapEntry);
      }
      uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (MessageSetWireFormat != false) {
        size += 1 + 1;
      }
      if (NoStandardDescriptorAccessor != false) {
        size += 1 + 1;
      }
      if (Deprecated != false) {
        size += 1 + 1;
      }
      if (MapEntry != false) {
        size += 1 + 1;
      }
      size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec);
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(MessageOptions other) {
      if (other == null) {
        return;
      }
      if (other.MessageSetWireFormat != false) {
        MessageSetWireFormat = other.MessageSetWireFormat;
      }
      if (other.NoStandardDescriptorAccessor != false) {
        NoStandardDescriptorAccessor = other.NoStandardDescriptorAccessor;
      }
      if (other.Deprecated != false) {
        Deprecated = other.Deprecated;
      }
      if (other.MapEntry != false) {
        MapEntry = other.MapEntry;
      }
      uninterpretedOption_.Add(other.uninterpretedOption_);
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            CustomOptions = CustomOptions.ReadOrSkipUnknownField(input);
            break;
          case 8: {
            MessageSetWireFormat = input.ReadBool();
            break;
          }
          case 16: {
            NoStandardDescriptorAccessor = input.ReadBool();
            break;
          }
          case 24: {
            Deprecated = input.ReadBool();
            break;
          }
          case 56: {
            MapEntry = input.ReadBool();
            break;
          }
          case 7994: {
            uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec);
            break;
          }
        }
      }
    }

  }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[12]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    internal CustomOptions CustomOptions{ get; private set; } = CustomOptions.Empty;

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public FieldOptions() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public FieldOptions(FieldOptions other) : this() {
      ctype_ = other.ctype_;
      packed_ = other.packed_;
      jstype_ = other.jstype_;
      lazy_ = other.lazy_;
      deprecated_ = other.deprecated_;
      weak_ = other.weak_;
      uninterpretedOption_ = other.uninterpretedOption_.Clone();
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public FieldOptions Clone() {
      return new FieldOptions(this);
    }

    /// <summary>Field number for the "ctype" field.</summary>
    public const int CtypeFieldNumber = 1;
    private global::Google.Protobuf.Reflection.FieldOptions.Types.CType ctype_ = 0;
    /// <summary>
    /// The ctype option instructs the C++ code generator to use a different
    /// representation of the field than it normally would.  See the specific
    /// options below.  This option is not yet implemented in the open source
    /// release -- sorry, we'll try to include it in a future version!
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public global::Google.Protobuf.Reflection.FieldOptions.Types.CType Ctype {
      get { return ctype_; }
      set {
        ctype_ = value;
      }
    }

    /// <summary>Field number for the "packed" field.</summary>
    public const int PackedFieldNumber = 2;
    private bool packed_;
    /// <summary>
    /// The packed option can be enabled for repeated primitive fields to enable
    /// a more efficient representation on the wire. Rather than repeatedly
    /// writing the tag and type for each element, the entire array is encoded as
    /// a single length-delimited blob. In proto3, only explicit setting it to
    /// false will avoid using packed encoding.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Packed {
      get { return packed_; }
      set {
        packed_ = value;
      }
    }

    /// <summary>Field number for the "jstype" field.</summary>
    public const int JstypeFieldNumber = 6;
    private global::Google.Protobuf.Reflection.FieldOptions.Types.JSType jstype_ = 0;
    /// <summary>
    /// The jstype option determines the JavaScript type used for values of the
    /// field.  The option is permitted only for 64 bit integral and fixed types
    /// (int64, uint64, sint64, fixed64, sfixed64).  A field with jstype JS_STRING
    /// is represented as JavaScript string, which avoids loss of precision that
    /// can happen when a large value is converted to a floating point JavaScript.
    /// Specifying JS_NUMBER for the jstype causes the generated JavaScript code to
    /// use the JavaScript "number" type.  The behavior of the default option
    /// JS_NORMAL is implementation dependent.
    ///
    /// This option is an enum to permit additional types to be added, e.g.
    /// goog.math.Integer.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public global::Google.Protobuf.Reflection.FieldOptions.Types.JSType Jstype {
      get { return jstype_; }
      set {
        jstype_ = value;
      }
    }

    /// <summary>Field number for the "lazy" field.</summary>
    public const int LazyFieldNumber = 5;
    private bool lazy_;
    /// <summary>
    /// Should this field be parsed lazily?  Lazy applies only to message-type
    /// fields.  It means that when the outer message is initially parsed, the
    /// inner message's contents will not be parsed but instead stored in encoded
    /// form.  The inner message will actually be parsed when it is first accessed.
    ///
    /// This is only a hint.  Implementations are free to choose whether to use
    /// eager or lazy parsing regardless of the value of this option.  However,
    /// setting this option true suggests that the protocol author believes that
    /// using lazy parsing on this field is worth the additional bookkeeping
    /// overhead typically needed to implement it.
    ///
    /// This option does not affect the public interface of any generated code;
    /// all method signatures remain the same.  Furthermore, thread-safety of the
    /// interface is not affected by this option; const methods remain safe to
    /// call from multiple threads concurrently, while non-const methods continue
    /// to require exclusive access.
    ///
    /// Note that implementations may choose not to check required fields within
    /// a lazy sub-message.  That is, calling IsInitialized() on the outer message
    /// may return true even if the inner message has missing required fields.
    /// This is necessary because otherwise the inner message would have to be
    /// parsed in order to perform the check, defeating the purpose of lazy
    /// parsing.  An implementation which chooses not to check required fields
    /// must be consistent about it.  That is, for any particular sub-message, the
    /// implementation must either *always* check its required fields, or *never*
    /// check its required fields, regardless of whether or not the message has
    /// been parsed.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Lazy {
      get { return lazy_; }
      set {
        lazy_ = value;
      }
    }

    /// <summary>Field number for the "deprecated" field.</summary>
    public const int DeprecatedFieldNumber = 3;
    private bool deprecated_;
    /// <summary>
    /// Is this field deprecated?
    /// Depending on the target platform, this can emit Deprecated annotations
    /// for accessors, or it will be completely ignored; in the very least, this
    /// is a formalization for deprecating fields.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Deprecated {
      get { return deprecated_; }
      set {
        deprecated_ = value;
      }
    }

    /// <summary>Field number for the "weak" field.</summary>
    public const int WeakFieldNumber = 10;
    private bool weak_;
    /// <summary>
    /// For Google-internal migration only. Do not use.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Weak {
      get { return weak_; }
      set {
        weak_ = value;
      }
    }

    /// <summary>Field number for the "uninterpreted_option" field.</summary>
    public const int UninterpretedOptionFieldNumber = 999;
    private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.UninterpretedOption> _repeated_uninterpretedOption_codec
        = pb::FieldCodec.ForMessage(7994, global::Google.Protobuf.Reflection.UninterpretedOption.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption> uninterpretedOption_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption>();
    /// <summary>
    /// The parser stores options it doesn't recognize here. See above.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption> UninterpretedOption {
      get { return uninterpretedOption_; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override bool Equals(object other) {
      return Equals(other as FieldOptions);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(FieldOptions other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (Ctype != other.Ctype) return false;
      if (Packed != other.Packed) return false;
      if (Jstype != other.Jstype) return false;
      if (Lazy != other.Lazy) return false;
      if (Deprecated != other.Deprecated) return false;
      if (Weak != other.Weak) return false;
      if(!uninterpretedOption_.Equals(other.uninterpretedOption_)) return false;
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (Ctype != 0) hash ^= Ctype.GetHashCode();
      if (Packed != false) hash ^= Packed.GetHashCode();
      if (Jstype != 0) hash ^= Jstype.GetHashCode();
      if (Lazy != false) hash ^= Lazy.GetHashCode();
      if (Deprecated != false) hash ^= Deprecated.GetHashCode();
      if (Weak != false) hash ^= Weak.GetHashCode();
      hash ^= uninterpretedOption_.GetHashCode();
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void WriteTo(pb::CodedOutputStream output) {
      if (Ctype != 0) {
        output.WriteRawTag(8);
        output.WriteEnum((int) Ctype);
      }
      if (Packed != false) {
        output.WriteRawTag(16);
        output.WriteBool(Packed);
      }
      if (Deprecated != false) {
        output.WriteRawTag(24);
        output.WriteBool(Deprecated);
      }
      if (Lazy != false) {
        output.WriteRawTag(40);
        output.WriteBool(Lazy);
      }
      if (Jstype != 0) {
        output.WriteRawTag(48);
        output.WriteEnum((int) Jstype);
      }
      if (Weak != false) {
        output.WriteRawTag(80);
        output.WriteBool(Weak);
      }
      uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (Ctype != 0) {
        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Ctype);
      }
      if (Packed != false) {
        size += 1 + 1;
      }
      if (Jstype != 0) {
        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Jstype);
      }
      if (Lazy != false) {
        size += 1 + 1;
      }
      if (Deprecated != false) {
        size += 1 + 1;
      }
      if (Weak != false) {
        size += 1 + 1;
      }
      size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec);
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(FieldOptions other) {
      if (other == null) {
        return;
      }
      if (other.Ctype != 0) {
        Ctype = other.Ctype;
      }
      if (other.Packed != false) {
        Packed = other.Packed;
      }
      if (other.Jstype != 0) {
        Jstype = other.Jstype;
      }
      if (other.Lazy != false) {
        Lazy = other.Lazy;
      }
      if (other.Deprecated != false) {
        Deprecated = other.Deprecated;
      }
      if (other.Weak != false) {
        Weak = other.Weak;
      }
      uninterpretedOption_.Add(other.uninterpretedOption_);
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            CustomOptions = CustomOptions.ReadOrSkipUnknownField(input);
            break;
          case 8: {
            ctype_ = (global::Google.Protobuf.Reflection.FieldOptions.Types.CType) input.ReadEnum();
            break;
          }
          case 16: {
            Packed = input.ReadBool();
            break;
          }
          case 24: {
            Deprecated = input.ReadBool();
            break;
          }
          case 40: {
            Lazy = input.ReadBool();
            break;
          }
          case 48: {
            jstype_ = (global::Google.Protobuf.Reflection.FieldOptions.Types.JSType) input.ReadEnum();
            break;
          }
          case 80: {
            Weak = input.ReadBool();
            break;
          }
          case 7994: {
            uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec);
            break;
          }
        }
      }
    }

    #region Nested types
    /// <summary>Container for nested types declared in the FieldOptions message type.</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static partial class Types {
      internal enum CType {
        /// <summary>
        /// Default mode.
        /// </summary>
        [pbr::OriginalName("STRING")] String = 0,
        [pbr::OriginalName("CORD")] Cord = 1,
        [pbr::OriginalName("STRING_PIECE")] StringPiece = 2,
      }

      internal enum JSType {
        /// <summary>
        /// Use the default type.
        /// </summary>
        [pbr::OriginalName("JS_NORMAL")] JsNormal = 0,
        /// <summary>
        /// Use JavaScript strings.
        /// </summary>
        [pbr::OriginalName("JS_STRING")] JsString = 1,
        /// <summary>
        /// Use JavaScript numbers.
        /// </summary>
        [pbr::OriginalName("JS_NUMBER")] JsNumber = 2,
      }

    }
    #endregion

  }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[13]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    internal CustomOptions CustomOptions{ get; private set; } = CustomOptions.Empty;

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public OneofOptions() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public OneofOptions(OneofOptions other) : this() {
      uninterpretedOption_ = other.uninterpretedOption_.Clone();
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public OneofOptions Clone() {
      return new OneofOptions(this);
    }

    /// <summary>Field number for the "uninterpreted_option" field.</summary>
    public const int UninterpretedOptionFieldNumber = 999;
    private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.UninterpretedOption> _repeated_uninterpretedOption_codec
        = pb::FieldCodec.ForMessage(7994, global::Google.Protobuf.Reflection.UninterpretedOption.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption> uninterpretedOption_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption>();
    /// <summary>
    /// The parser stores options it doesn't recognize here. See above.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption> UninterpretedOption {
      get { return uninterpretedOption_; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override bool Equals(object other) {
      return Equals(other as OneofOptions);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(OneofOptions other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if(!uninterpretedOption_.Equals(other.uninterpretedOption_)) return false;
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      hash ^= uninterpretedOption_.GetHashCode();
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void WriteTo(pb::CodedOutputStream output) {
      uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec);
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(OneofOptions other) {
      if (other == null) {
        return;
      }
      uninterpretedOption_.Add(other.uninterpretedOption_);
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            CustomOptions = CustomOptions.ReadOrSkipUnknownField(input);
            break;
          case 7994: {
            uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec);
            break;
          }
        }
      }
    }

  }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[14]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    internal CustomOptions CustomOptions{ get; private set; } = CustomOptions.Empty;

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public EnumOptions() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public EnumOptions(EnumOptions other) : this() {
      allowAlias_ = other.allowAlias_;
      deprecated_ = other.deprecated_;
      uninterpretedOption_ = other.uninterpretedOption_.Clone();
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public EnumOptions Clone() {
      return new EnumOptions(this);
    }

    /// <summary>Field number for the "allow_alias" field.</summary>
    public const int AllowAliasFieldNumber = 2;
    private bool allowAlias_;
    /// <summary>
    /// Set this option to true to allow mapping different tag names to the same
    /// value.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool AllowAlias {
      get { return allowAlias_; }
      set {
        allowAlias_ = value;
      }
    }

    /// <summary>Field number for the "deprecated" field.</summary>
    public const int DeprecatedFieldNumber = 3;
    private bool deprecated_;
    /// <summary>
    /// Is this enum deprecated?
    /// Depending on the target platform, this can emit Deprecated annotations
    /// for the enum, or it will be completely ignored; in the very least, this
    /// is a formalization for deprecating enums.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Deprecated {
      get { return deprecated_; }
      set {
        deprecated_ = value;
      }
    }

    /// <summary>Field number for the "uninterpreted_option" field.</summary>
    public const int UninterpretedOptionFieldNumber = 999;
    private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.UninterpretedOption> _repeated_uninterpretedOption_codec
        = pb::FieldCodec.ForMessage(7994, global::Google.Protobuf.Reflection.UninterpretedOption.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption> uninterpretedOption_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption>();
    /// <summary>
    /// The parser stores options it doesn't recognize here. See above.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption> UninterpretedOption {
      get { return uninterpretedOption_; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override bool Equals(object other) {
      return Equals(other as EnumOptions);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(EnumOptions other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (AllowAlias != other.AllowAlias) return false;
      if (Deprecated != other.Deprecated) return false;
      if(!uninterpretedOption_.Equals(other.uninterpretedOption_)) return false;
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (AllowAlias != false) hash ^= AllowAlias.GetHashCode();
      if (Deprecated != false) hash ^= Deprecated.GetHashCode();
      hash ^= uninterpretedOption_.GetHashCode();
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void WriteTo(pb::CodedOutputStream output) {
      if (AllowAlias != false) {
        output.WriteRawTag(16);
        output.WriteBool(AllowAlias);
      }
      if (Deprecated != false) {
        output.WriteRawTag(24);
        output.WriteBool(Deprecated);
      }
      uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (AllowAlias != false) {
        size += 1 + 1;
      }
      if (Deprecated != false) {
        size += 1 + 1;
      }
      size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec);
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(EnumOptions other) {
      if (other == null) {
        return;
      }
      if (other.AllowAlias != false) {
        AllowAlias = other.AllowAlias;
      }
      if (other.Deprecated != false) {
        Deprecated = other.Deprecated;
      }
      uninterpretedOption_.Add(other.uninterpretedOption_);
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            CustomOptions = CustomOptions.ReadOrSkipUnknownField(input);
            break;
          case 16: {
            AllowAlias = input.ReadBool();
            break;
          }
          case 24: {
            Deprecated = input.ReadBool();
            break;
          }
          case 7994: {
            uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec);
            break;
          }
        }
      }
    }

  }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[15]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    internal CustomOptions CustomOptions{ get; private set; } = CustomOptions.Empty;

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public EnumValueOptions() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public EnumValueOptions(EnumValueOptions other) : this() {
      deprecated_ = other.deprecated_;
      uninterpretedOption_ = other.uninterpretedOption_.Clone();
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public EnumValueOptions Clone() {
      return new EnumValueOptions(this);
    }

    /// <summary>Field number for the "deprecated" field.</summary>
    public const int DeprecatedFieldNumber = 1;
    private bool deprecated_;
    /// <summary>
    /// Is this enum value deprecated?
    /// Depending on the target platform, this can emit Deprecated annotations
    /// for the enum value, or it will be completely ignored; in the very least,
    /// this is a formalization for deprecating enum values.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Deprecated {
      get { return deprecated_; }
      set {
        deprecated_ = value;
      }
    }

    /// <summary>Field number for the "uninterpreted_option" field.</summary>
    public const int UninterpretedOptionFieldNumber = 999;
    private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.UninterpretedOption> _repeated_uninterpretedOption_codec
        = pb::FieldCodec.ForMessage(7994, global::Google.Protobuf.Reflection.UninterpretedOption.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption> uninterpretedOption_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption>();
    /// <summary>
    /// The parser stores options it doesn't recognize here. See above.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption> UninterpretedOption {
      get { return uninterpretedOption_; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override bool Equals(object other) {
      return Equals(other as EnumValueOptions);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(EnumValueOptions other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (Deprecated != other.Deprecated) return false;
      if(!uninterpretedOption_.Equals(other.uninterpretedOption_)) return false;
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (Deprecated != false) hash ^= Deprecated.GetHashCode();
      hash ^= uninterpretedOption_.GetHashCode();
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void WriteTo(pb::CodedOutputStream output) {
      if (Deprecated != false) {
        output.WriteRawTag(8);
        output.WriteBool(Deprecated);
      }
      uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (Deprecated != false) {
        size += 1 + 1;
      }
      size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec);
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(EnumValueOptions other) {
      if (other == null) {
        return;
      }
      if (other.Deprecated != false) {
        Deprecated = other.Deprecated;
      }
      uninterpretedOption_.Add(other.uninterpretedOption_);
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            CustomOptions = CustomOptions.ReadOrSkipUnknownField(input);
            break;
          case 8: {
            Deprecated = input.ReadBool();
            break;
          }
          case 7994: {
            uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec);
            break;
          }
        }
      }
    }

  }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[16]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    internal CustomOptions CustomOptions{ get; private set; } = CustomOptions.Empty;

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public ServiceOptions() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public ServiceOptions(ServiceOptions other) : this() {
      deprecated_ = other.deprecated_;
      uninterpretedOption_ = other.uninterpretedOption_.Clone();
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public ServiceOptions Clone() {
      return new ServiceOptions(this);
    }

    /// <summary>Field number for the "deprecated" field.</summary>
    public const int DeprecatedFieldNumber = 33;
    private bool deprecated_;
    /// <summary>
    /// Is this service deprecated?
    /// Depending on the target platform, this can emit Deprecated annotations
    /// for the service, or it will be completely ignored; in the very least,
    /// this is a formalization for deprecating services.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Deprecated {
      get { return deprecated_; }
      set {
        deprecated_ = value;
      }
    }

    /// <summary>Field number for the "uninterpreted_option" field.</summary>
    public const int UninterpretedOptionFieldNumber = 999;
    private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.UninterpretedOption> _repeated_uninterpretedOption_codec
        = pb::FieldCodec.ForMessage(7994, global::Google.Protobuf.Reflection.UninterpretedOption.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption> uninterpretedOption_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption>();
    /// <summary>
    /// The parser stores options it doesn't recognize here. See above.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption> UninterpretedOption {
      get { return uninterpretedOption_; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override bool Equals(object other) {
      return Equals(other as ServiceOptions);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(ServiceOptions other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (Deprecated != other.Deprecated) return false;
      if(!uninterpretedOption_.Equals(other.uninterpretedOption_)) return false;
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (Deprecated != false) hash ^= Deprecated.GetHashCode();
      hash ^= uninterpretedOption_.GetHashCode();
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void WriteTo(pb::CodedOutputStream output) {
      if (Deprecated != false) {
        output.WriteRawTag(136, 2);
        output.WriteBool(Deprecated);
      }
      uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (Deprecated != false) {
        size += 2 + 1;
      }
      size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec);
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(ServiceOptions other) {
      if (other == null) {
        return;
      }
      if (other.Deprecated != false) {
        Deprecated = other.Deprecated;
      }
      uninterpretedOption_.Add(other.uninterpretedOption_);
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            CustomOptions = CustomOptions.ReadOrSkipUnknownField(input);
            break;
          case 264: {
            Deprecated = input.ReadBool();
            break;
          }
          case 7994: {
            uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec);
            break;
          }
        }
      }
    }

  }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[17]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    internal CustomOptions CustomOptions{ get; private set; } = CustomOptions.Empty;

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public MethodOptions() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public MethodOptions(MethodOptions other) : this() {
      deprecated_ = other.deprecated_;
      idempotencyLevel_ = other.idempotencyLevel_;
      uninterpretedOption_ = other.uninterpretedOption_.Clone();
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public MethodOptions Clone() {
      return new MethodOptions(this);
    }

    /// <summary>Field number for the "deprecated" field.</summary>
    public const int DeprecatedFieldNumber = 33;
    private bool deprecated_;
    /// <summary>
    /// Is this method deprecated?
    /// Depending on the target platform, this can emit Deprecated annotations
    /// for the method, or it will be completely ignored; in the very least,
    /// this is a formalization for deprecating methods.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Deprecated {
      get { return deprecated_; }
      set {
        deprecated_ = value;
      }
    }

    /// <summary>Field number for the "idempotency_level" field.</summary>
    public const int IdempotencyLevelFieldNumber = 34;
    private global::Google.Protobuf.Reflection.MethodOptions.Types.IdempotencyLevel idempotencyLevel_ = 0;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public global::Google.Protobuf.Reflection.MethodOptions.Types.IdempotencyLevel IdempotencyLevel {
      get { return idempotencyLevel_; }
      set {
        idempotencyLevel_ = value;
      }
    }

    /// <summary>Field number for the "uninterpreted_option" field.</summary>
    public const int UninterpretedOptionFieldNumber = 999;
    private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.UninterpretedOption> _repeated_uninterpretedOption_codec
        = pb::FieldCodec.ForMessage(7994, global::Google.Protobuf.Reflection.UninterpretedOption.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption> uninterpretedOption_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption>();
    /// <summary>
    /// The parser stores options it doesn't recognize here. See above.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption> UninterpretedOption {
      get { return uninterpretedOption_; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override bool Equals(object other) {
      return Equals(other as MethodOptions);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(MethodOptions other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (Deprecated != other.Deprecated) return false;
      if (IdempotencyLevel != other.IdempotencyLevel) return false;
      if(!uninterpretedOption_.Equals(other.uninterpretedOption_)) return false;
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (Deprecated != false) hash ^= Deprecated.GetHashCode();
      if (IdempotencyLevel != 0) hash ^= IdempotencyLevel.GetHashCode();
      hash ^= uninterpretedOption_.GetHashCode();
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void WriteTo(pb::CodedOutputStream output) {
      if (Deprecated != false) {
        output.WriteRawTag(136, 2);
        output.WriteBool(Deprecated);
      }
      if (IdempotencyLevel != 0) {
        output.WriteRawTag(144, 2);
        output.WriteEnum((int) IdempotencyLevel);
      }
      uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (Deprecated != false) {
        size += 2 + 1;
      }
      if (IdempotencyLevel != 0) {
        size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) IdempotencyLevel);
      }
      size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec);
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(MethodOptions other) {
      if (other == null) {
        return;
      }
      if (other.Deprecated != false) {
        Deprecated = other.Deprecated;
      }
      if (other.IdempotencyLevel != 0) {
        IdempotencyLevel = other.IdempotencyLevel;
      }
      uninterpretedOption_.Add(other.uninterpretedOption_);
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            CustomOptions = CustomOptions.ReadOrSkipUnknownField(input);
            break;
          case 264: {
            Deprecated = input.ReadBool();
            break;
          }
          case 272: {
            idempotencyLevel_ = (global::Google.Protobuf.Reflection.MethodOptions.Types.IdempotencyLevel) input.ReadEnum();
            break;
          }
          case 7994: {
            uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec);
            break;
          }
        }
      }
    }

    #region Nested types
    /// <summary>Container for nested types declared in the MethodOptions message type.</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static partial class Types {
      /// <summary>
      /// Is this method side-effect-free (or safe in HTTP parlance), or idempotent,
      /// or neither? HTTP based RPC implementation may choose GET verb for safe
      /// methods, and PUT verb for idempotent methods instead of the default POST.
      /// </summary>
      internal enum IdempotencyLevel {
        [pbr::OriginalName("IDEMPOTENCY_UNKNOWN")] IdempotencyUnknown = 0,
        /// <summary>
        /// implies idempotent
        /// </summary>
        [pbr::OriginalName("NO_SIDE_EFFECTS")] NoSideEffects = 1,
        /// <summary>
        /// idempotent, but may have side effects
        /// </summary>
        [pbr::OriginalName("IDEMPOTENT")] Idempotent = 2,
      }

    }
    #endregion

  }

  /// <summary>
  /// A message representing a option the parser does not recognize. This only
  /// appears in options protos created by the compiler::Parser class.
  /// DescriptorPool resolves these when building Descriptor objects. Therefore,
  /// options protos in descriptor objects (e.g. returned by Descriptor::options(),
  /// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions
  /// in them.
  /// </summary>
  internal sealed partial class UninterpretedOption : pb::IMessage<UninterpretedOption> {
    private static readonly pb::MessageParser<UninterpretedOption> _parser = new pb::MessageParser<UninterpretedOption>(() => new UninterpretedOption());
    private pb::UnknownFieldSet _unknownFields;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pb::MessageParser<UninterpretedOption> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[18]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public UninterpretedOption() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public UninterpretedOption(UninterpretedOption other) : this() {
      name_ = other.name_.Clone();
      identifierValue_ = other.identifierValue_;
      positiveIntValue_ = other.positiveIntValue_;
      negativeIntValue_ = other.negativeIntValue_;
      doubleValue_ = other.doubleValue_;
      stringValue_ = other.stringValue_;
      aggregateValue_ = other.aggregateValue_;
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public UninterpretedOption Clone() {
      return new UninterpretedOption(this);
    }

    /// <summary>Field number for the "name" field.</summary>
    public const int NameFieldNumber = 2;
    private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.UninterpretedOption.Types.NamePart> _repeated_name_codec
        = pb::FieldCodec.ForMessage(18, global::Google.Protobuf.Reflection.UninterpretedOption.Types.NamePart.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption.Types.NamePart> name_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption.Types.NamePart>();
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption.Types.NamePart> Name {
      get { return name_; }
    }

    /// <summary>Field number for the "identifier_value" field.</summary>
    public const int IdentifierValueFieldNumber = 3;
    private string identifierValue_ = "";
    /// <summary>
    /// The value of the uninterpreted option, in whatever type the tokenizer
    /// identified it as during parsing. Exactly one of these should be set.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string IdentifierValue {
      get { return identifierValue_; }
      set {
        identifierValue_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "positive_int_value" field.</summary>
    public const int PositiveIntValueFieldNumber = 4;
    private ulong positiveIntValue_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public ulong PositiveIntValue {
      get { return positiveIntValue_; }
      set {
        positiveIntValue_ = value;
      }
    }

    /// <summary>Field number for the "negative_int_value" field.</summary>
    public const int NegativeIntValueFieldNumber = 5;
    private long negativeIntValue_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public long NegativeIntValue {
      get { return negativeIntValue_; }
      set {
        negativeIntValue_ = value;
      }
    }

    /// <summary>Field number for the "double_value" field.</summary>
    public const int DoubleValueFieldNumber = 6;
    private double doubleValue_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public double DoubleValue {
      get { return doubleValue_; }
      set {
        doubleValue_ = value;
      }
    }

    /// <summary>Field number for the "string_value" field.</summary>
    public const int StringValueFieldNumber = 7;
    private pb::ByteString stringValue_ = pb::ByteString.Empty;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pb::ByteString StringValue {
      get { return stringValue_; }
      set {
        stringValue_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "aggregate_value" field.</summary>
    public const int AggregateValueFieldNumber = 8;
    private string aggregateValue_ = "";
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string AggregateValue {
      get { return aggregateValue_; }
      set {
        aggregateValue_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override bool Equals(object other) {
      return Equals(other as UninterpretedOption);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(UninterpretedOption other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if(!name_.Equals(other.name_)) return false;
      if (IdentifierValue != other.IdentifierValue) return false;
      if (PositiveIntValue != other.PositiveIntValue) return false;
      if (NegativeIntValue != other.NegativeIntValue) return false;
      if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleValue, other.DoubleValue)) return false;
      if (StringValue != other.StringValue) return false;
      if (AggregateValue != other.AggregateValue) return false;
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      hash ^= name_.GetHashCode();
      if (IdentifierValue.Length != 0) hash ^= IdentifierValue.GetHashCode();
      if (PositiveIntValue != 0UL) hash ^= PositiveIntValue.GetHashCode();
      if (NegativeIntValue != 0L) hash ^= NegativeIntValue.GetHashCode();
      if (DoubleValue != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleValue);
      if (StringValue.Length != 0) hash ^= StringValue.GetHashCode();
      if (AggregateValue.Length != 0) hash ^= AggregateValue.GetHashCode();
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void WriteTo(pb::CodedOutputStream output) {
      name_.WriteTo(output, _repeated_name_codec);
      if (IdentifierValue.Length != 0) {
        output.WriteRawTag(26);
        output.WriteString(IdentifierValue);
      }
      if (PositiveIntValue != 0UL) {
        output.WriteRawTag(32);
        output.WriteUInt64(PositiveIntValue);
      }
      if (NegativeIntValue != 0L) {
        output.WriteRawTag(40);
        output.WriteInt64(NegativeIntValue);
      }
      if (DoubleValue != 0D) {
        output.WriteRawTag(49);
        output.WriteDouble(DoubleValue);
      }
      if (StringValue.Length != 0) {
        output.WriteRawTag(58);
        output.WriteBytes(StringValue);
      }
      if (AggregateValue.Length != 0) {
        output.WriteRawTag(66);
        output.WriteString(AggregateValue);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      size += name_.CalculateSize(_repeated_name_codec);
      if (IdentifierValue.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(IdentifierValue);
      }
      if (PositiveIntValue != 0UL) {
        size += 1 + pb::CodedOutputStream.ComputeUInt64Size(PositiveIntValue);
      }
      if (NegativeIntValue != 0L) {
        size += 1 + pb::CodedOutputStream.ComputeInt64Size(NegativeIntValue);
      }
      if (DoubleValue != 0D) {
        size += 1 + 8;
      }
      if (StringValue.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeBytesSize(StringValue);
      }
      if (AggregateValue.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(AggregateValue);
      }
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(UninterpretedOption other) {
      if (other == null) {
        return;
      }
      name_.Add(other.name_);
      if (other.IdentifierValue.Length != 0) {
        IdentifierValue = other.IdentifierValue;
      }
      if (other.PositiveIntValue != 0UL) {
        PositiveIntValue = other.PositiveIntValue;
      }
      if (other.NegativeIntValue != 0L) {
        NegativeIntValue = other.NegativeIntValue;
      }
      if (other.DoubleValue != 0D) {
        DoubleValue = other.DoubleValue;
      }
      if (other.StringValue.Length != 0) {
        StringValue = other.StringValue;
      }
      if (other.AggregateValue.Length != 0) {
        AggregateValue = other.AggregateValue;
      }
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            break;
          case 18: {
            name_.AddEntriesFrom(input, _repeated_name_codec);
            break;
          }
          case 26: {
            IdentifierValue = input.ReadString();
            break;
          }
          case 32: {
            PositiveIntValue = input.ReadUInt64();
            break;
          }
          case 40: {
            NegativeIntValue = input.ReadInt64();
            break;
          }
          case 49: {
            DoubleValue = input.ReadDouble();
            break;
          }
          case 58: {
            StringValue = input.ReadBytes();
            break;
          }
          case 66: {
            AggregateValue = input.ReadString();
            break;
          }
        }
      }
    }

    #region Nested types
    /// <summary>Container for nested types declared in the UninterpretedOption message type.</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static partial class Types {
      /// <summary>
      /// The name of the uninterpreted option.  Each string represents a segment in
      /// a dot-separated name.  is_extension is true iff a segment represents an
      /// extension (denoted with parentheses in options specs in .proto files).
      /// E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents
      /// "foo.(bar.baz).qux".
      /// </summary>
      internal sealed partial class NamePart : pb::IMessage<NamePart> {
        private static readonly pb::MessageParser<NamePart> _parser = new pb::MessageParser<NamePart>(() => new NamePart());
        private pb::UnknownFieldSet _unknownFields;
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public static pb::MessageParser<NamePart> Parser { get { return _parser; } }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public static pbr::MessageDescriptor Descriptor {
          get { return global::Google.Protobuf.Reflection.UninterpretedOption.Descriptor.NestedTypes[0]; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        pbr::MessageDescriptor pb::IMessage.Descriptor {
          get { return Descriptor; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public NamePart() {
          OnConstruction();
        }

        partial void OnConstruction();

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public NamePart(NamePart other) : this() {
          namePart_ = other.namePart_;
          isExtension_ = other.isExtension_;
          _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public NamePart Clone() {
          return new NamePart(this);
        }

        /// <summary>Field number for the "name_part" field.</summary>
        public const int NamePart_FieldNumber = 1;
        private string namePart_ = "";
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public string NamePart_ {
          get { return namePart_; }
          set {
            namePart_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
          }
        }

        /// <summary>Field number for the "is_extension" field.</summary>
        public const int IsExtensionFieldNumber = 2;
        private bool isExtension_;
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public bool IsExtension {
          get { return isExtension_; }
          set {
            isExtension_ = value;
          }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public override bool Equals(object other) {
          return Equals(other as NamePart);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public bool Equals(NamePart other) {
          if (ReferenceEquals(other, null)) {
            return false;
          }
          if (ReferenceEquals(other, this)) {
            return true;
          }
          if (NamePart_ != other.NamePart_) return false;
          if (IsExtension != other.IsExtension) return false;
          return Equals(_unknownFields, other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public override int GetHashCode() {
          int hash = 1;
          if (NamePart_.Length != 0) hash ^= NamePart_.GetHashCode();
          if (IsExtension != false) hash ^= IsExtension.GetHashCode();
          if (_unknownFields != null) {
            hash ^= _unknownFields.GetHashCode();
          }
          return hash;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public override string ToString() {
          return pb::JsonFormatter.ToDiagnosticString(this);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void WriteTo(pb::CodedOutputStream output) {
          if (NamePart_.Length != 0) {
            output.WriteRawTag(10);
            output.WriteString(NamePart_);
          }
          if (IsExtension != false) {
            output.WriteRawTag(16);
            output.WriteBool(IsExtension);
          }
          if (_unknownFields != null) {
            _unknownFields.WriteTo(output);
          }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public int CalculateSize() {
          int size = 0;
          if (NamePart_.Length != 0) {
            size += 1 + pb::CodedOutputStream.ComputeStringSize(NamePart_);
          }
          if (IsExtension != false) {
            size += 1 + 1;
          }
          if (_unknownFields != null) {
            size += _unknownFields.CalculateSize();
          }
          return size;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void MergeFrom(NamePart other) {
          if (other == null) {
            return;
          }
          if (other.NamePart_.Length != 0) {
            NamePart_ = other.NamePart_;
          }
          if (other.IsExtension != false) {
            IsExtension = other.IsExtension;
          }
          _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void MergeFrom(pb::CodedInputStream input) {
          uint tag;
          while ((tag = input.ReadTag()) != 0) {
            switch(tag) {
              default:
                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                break;
              case 10: {
                NamePart_ = input.ReadString();
                break;
              }
              case 16: {
                IsExtension = input.ReadBool();
                break;
              }
            }
          }
        }

      }

    }
    #endregion

  }

  /// <summary>
  /// Encapsulates information about the original source file from which a
  /// FileDescriptorProto was generated.
  /// </summary>
  internal sealed partial class SourceCodeInfo : pb::IMessage<SourceCodeInfo> {
    private static readonly pb::MessageParser<SourceCodeInfo> _parser = new pb::MessageParser<SourceCodeInfo>(() => new SourceCodeInfo());
    private pb::UnknownFieldSet _unknownFields;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pb::MessageParser<SourceCodeInfo> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[19]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public SourceCodeInfo() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public SourceCodeInfo(SourceCodeInfo other) : this() {
      location_ = other.location_.Clone();
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public SourceCodeInfo Clone() {
      return new SourceCodeInfo(this);
    }

    /// <summary>Field number for the "location" field.</summary>
    public const int LocationFieldNumber = 1;
    private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.SourceCodeInfo.Types.Location> _repeated_location_codec
        = pb::FieldCodec.ForMessage(10, global::Google.Protobuf.Reflection.SourceCodeInfo.Types.Location.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.SourceCodeInfo.Types.Location> location_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.SourceCodeInfo.Types.Location>();
    /// <summary>
    /// A Location identifies a piece of source code in a .proto file which
    /// corresponds to a particular definition.  This information is intended
    /// to be useful to IDEs, code indexers, documentation generators, and similar
    /// tools.
    ///
    /// For example, say we have a file like:
    ///   message Foo {
    ///     optional string foo = 1;
    ///   }
    /// Let's look at just the field definition:
    ///   optional string foo = 1;
    ///   ^       ^^     ^^  ^  ^^^
    ///   a       bc     de  f  ghi
    /// We have the following locations:
    ///   span   path               represents
    ///   [a,i)  [ 4, 0, 2, 0 ]     The whole field definition.
    ///   [a,b)  [ 4, 0, 2, 0, 4 ]  The label (optional).
    ///   [c,d)  [ 4, 0, 2, 0, 5 ]  The type (string).
    ///   [e,f)  [ 4, 0, 2, 0, 1 ]  The name (foo).
    ///   [g,h)  [ 4, 0, 2, 0, 3 ]  The number (1).
    ///
    /// Notes:
    /// - A location may refer to a repeated field itself (i.e. not to any
    ///   particular index within it).  This is used whenever a set of elements are
    ///   logically enclosed in a single code segment.  For example, an entire
    ///   extend block (possibly containing multiple extension definitions) will
    ///   have an outer location whose path refers to the "extensions" repeated
    ///   field without an index.
    /// - Multiple locations may have the same path.  This happens when a single
    ///   logical declaration is spread out across multiple places.  The most
    ///   obvious example is the "extend" block again -- there may be multiple
    ///   extend blocks in the same scope, each of which will have the same path.
    /// - A location's span is not always a subset of its parent's span.  For
    ///   example, the "extendee" of an extension declaration appears at the
    ///   beginning of the "extend" block and is shared by all extensions within
    ///   the block.
    /// - Just because a location's span is a subset of some other location's span
    ///   does not mean that it is a descendent.  For example, a "group" defines
    ///   both a type and a field in a single declaration.  Thus, the locations
    ///   corresponding to the type and field and their components will overlap.
    /// - Code which tries to interpret locations should probably be designed to
    ///   ignore those that it doesn't understand, as more types of locations could
    ///   be recorded in the future.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.SourceCodeInfo.Types.Location> Location {
      get { return location_; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override bool Equals(object other) {
      return Equals(other as SourceCodeInfo);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(SourceCodeInfo other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if(!location_.Equals(other.location_)) return false;
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      hash ^= location_.GetHashCode();
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void WriteTo(pb::CodedOutputStream output) {
      location_.WriteTo(output, _repeated_location_codec);
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      size += location_.CalculateSize(_repeated_location_codec);
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(SourceCodeInfo other) {
      if (other == null) {
        return;
      }
      location_.Add(other.location_);
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            break;
          case 10: {
            location_.AddEntriesFrom(input, _repeated_location_codec);
            break;
          }
        }
      }
    }

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

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public static pbr::MessageDescriptor Descriptor {
          get { return global::Google.Protobuf.Reflection.SourceCodeInfo.Descriptor.NestedTypes[0]; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        pbr::MessageDescriptor pb::IMessage.Descriptor {
          get { return Descriptor; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public Location() {
          OnConstruction();
        }

        partial void OnConstruction();

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public Location(Location other) : this() {
          path_ = other.path_.Clone();
          span_ = other.span_.Clone();
          leadingComments_ = other.leadingComments_;
          trailingComments_ = other.trailingComments_;
          leadingDetachedComments_ = other.leadingDetachedComments_.Clone();
          _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public Location Clone() {
          return new Location(this);
        }

        /// <summary>Field number for the "path" field.</summary>
        public const int PathFieldNumber = 1;
        private static readonly pb::FieldCodec<int> _repeated_path_codec
            = pb::FieldCodec.ForInt32(10);
        private readonly pbc::RepeatedField<int> path_ = new pbc::RepeatedField<int>();
        /// <summary>
        /// Identifies which part of the FileDescriptorProto was defined at this
        /// location.
        ///
        /// Each element is a field number or an index.  They form a path from
        /// the root FileDescriptorProto to the place where the definition.  For
        /// example, this path:
        ///   [ 4, 3, 2, 7, 1 ]
        /// refers to:
        ///   file.message_type(3)  // 4, 3
        ///       .field(7)         // 2, 7
        ///       .name()           // 1
        /// This is because FileDescriptorProto.message_type has field number 4:
        ///   repeated DescriptorProto message_type = 4;
        /// and DescriptorProto.field has field number 2:
        ///   repeated FieldDescriptorProto field = 2;
        /// and FieldDescriptorProto.name has field number 1:
        ///   optional string name = 1;
        ///
        /// Thus, the above path gives the location of a field name.  If we removed
        /// the last element:
        ///   [ 4, 3, 2, 7 ]
        /// this path refers to the whole field declaration (from the beginning
        /// of the label to the terminating semicolon).
        /// </summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public pbc::RepeatedField<int> Path {
          get { return path_; }
        }

        /// <summary>Field number for the "span" field.</summary>
        public const int SpanFieldNumber = 2;
        private static readonly pb::FieldCodec<int> _repeated_span_codec
            = pb::FieldCodec.ForInt32(18);
        private readonly pbc::RepeatedField<int> span_ = new pbc::RepeatedField<int>();
        /// <summary>
        /// Always has exactly three or four elements: start line, start column,
        /// end line (optional, otherwise assumed same as start line), end column.
        /// These are packed into a single field for efficiency.  Note that line
        /// and column numbers are zero-based -- typically you will want to add
        /// 1 to each before displaying to a user.
        /// </summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public pbc::RepeatedField<int> Span {
          get { return span_; }
        }

        /// <summary>Field number for the "leading_comments" field.</summary>
        public const int LeadingCommentsFieldNumber = 3;
        private string leadingComments_ = "";
        /// <summary>
        /// If this SourceCodeInfo represents a complete declaration, these are any
        /// comments appearing before and after the declaration which appear to be
        /// attached to the declaration.
        ///
        /// A series of line comments appearing on consecutive lines, with no other
        /// tokens appearing on those lines, will be treated as a single comment.
        ///
        /// leading_detached_comments will keep paragraphs of comments that appear
        /// before (but not connected to) the current element. Each paragraph,
        /// separated by empty lines, will be one comment element in the repeated
        /// field.
        ///
        /// Only the comment content is provided; comment markers (e.g. //) are
        /// stripped out.  For block comments, leading whitespace and an asterisk
        /// will be stripped from the beginning of each line other than the first.
        /// Newlines are included in the output.
        ///
        /// Examples:
        ///
        ///   optional int32 foo = 1;  // Comment attached to foo.
        ///   // Comment attached to bar.
        ///   optional int32 bar = 2;
        ///
        ///   optional string baz = 3;
        ///   // Comment attached to baz.
        ///   // Another line attached to baz.
        ///
        ///   // Comment attached to qux.
        ///   //
        ///   // Another line attached to qux.
        ///   optional double qux = 4;
        ///
        ///   // Detached comment for corge. This is not leading or trailing comments
        ///   // to qux or corge because there are blank lines separating it from
        ///   // both.
        ///
        ///   // Detached comment for corge paragraph 2.
        ///
        ///   optional string corge = 5;
        ///   /* Block comment attached
        ///    * to corge.  Leading asterisks
        ///    * will be removed. */
        ///   /* Block comment attached to
        ///    * grault. */
        ///   optional int32 grault = 6;
        ///
        ///   // ignored detached comments.
        /// </summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public string LeadingComments {
          get { return leadingComments_; }
          set {
            leadingComments_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
          }
        }

        /// <summary>Field number for the "trailing_comments" field.</summary>
        public const int TrailingCommentsFieldNumber = 4;
        private string trailingComments_ = "";
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public string TrailingComments {
          get { return trailingComments_; }
          set {
            trailingComments_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
          }
        }

        /// <summary>Field number for the "leading_detached_comments" field.</summary>
        public const int LeadingDetachedCommentsFieldNumber = 6;
        private static readonly pb::FieldCodec<string> _repeated_leadingDetachedComments_codec
            = pb::FieldCodec.ForString(50);
        private readonly pbc::RepeatedField<string> leadingDetachedComments_ = new pbc::RepeatedField<string>();
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public pbc::RepeatedField<string> LeadingDetachedComments {
          get { return leadingDetachedComments_; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public override bool Equals(object other) {
          return Equals(other as Location);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public bool Equals(Location other) {
          if (ReferenceEquals(other, null)) {
            return false;
          }
          if (ReferenceEquals(other, this)) {
            return true;
          }
          if(!path_.Equals(other.path_)) return false;
          if(!span_.Equals(other.span_)) return false;
          if (LeadingComments != other.LeadingComments) return false;
          if (TrailingComments != other.TrailingComments) return false;
          if(!leadingDetachedComments_.Equals(other.leadingDetachedComments_)) return false;
          return Equals(_unknownFields, other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public override int GetHashCode() {
          int hash = 1;
          hash ^= path_.GetHashCode();
          hash ^= span_.GetHashCode();
          if (LeadingComments.Length != 0) hash ^= LeadingComments.GetHashCode();
          if (TrailingComments.Length != 0) hash ^= TrailingComments.GetHashCode();
          hash ^= leadingDetachedComments_.GetHashCode();
          if (_unknownFields != null) {
            hash ^= _unknownFields.GetHashCode();
          }
          return hash;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public override string ToString() {
          return pb::JsonFormatter.ToDiagnosticString(this);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void WriteTo(pb::CodedOutputStream output) {
          path_.WriteTo(output, _repeated_path_codec);
          span_.WriteTo(output, _repeated_span_codec);
          if (LeadingComments.Length != 0) {
            output.WriteRawTag(26);
            output.WriteString(LeadingComments);
          }
          if (TrailingComments.Length != 0) {
            output.WriteRawTag(34);
            output.WriteString(TrailingComments);
          }
          leadingDetachedComments_.WriteTo(output, _repeated_leadingDetachedComments_codec);
          if (_unknownFields != null) {
            _unknownFields.WriteTo(output);
          }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public int CalculateSize() {
          int size = 0;
          size += path_.CalculateSize(_repeated_path_codec);
          size += span_.CalculateSize(_repeated_span_codec);
          if (LeadingComments.Length != 0) {
            size += 1 + pb::CodedOutputStream.ComputeStringSize(LeadingComments);
          }
          if (TrailingComments.Length != 0) {
            size += 1 + pb::CodedOutputStream.ComputeStringSize(TrailingComments);
          }
          size += leadingDetachedComments_.CalculateSize(_repeated_leadingDetachedComments_codec);
          if (_unknownFields != null) {
            size += _unknownFields.CalculateSize();
          }
          return size;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void MergeFrom(Location other) {
          if (other == null) {
            return;
          }
          path_.Add(other.path_);
          span_.Add(other.span_);
          if (other.LeadingComments.Length != 0) {
            LeadingComments = other.LeadingComments;
          }
          if (other.TrailingComments.Length != 0) {
            TrailingComments = other.TrailingComments;
          }
          leadingDetachedComments_.Add(other.leadingDetachedComments_);
          _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void MergeFrom(pb::CodedInputStream input) {
          uint tag;
          while ((tag = input.ReadTag()) != 0) {
            switch(tag) {
              default:
                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                break;
              case 10:
              case 8: {
                path_.AddEntriesFrom(input, _repeated_path_codec);
                break;
              }
              case 18:
              case 16: {
                span_.AddEntriesFrom(input, _repeated_span_codec);
                break;
              }
              case 26: {
                LeadingComments = input.ReadString();
                break;
              }
              case 34: {
                TrailingComments = input.ReadString();
                break;
              }
              case 50: {
                leadingDetachedComments_.AddEntriesFrom(input, _repeated_leadingDetachedComments_codec);
                break;
              }
            }
          }
        }

      }

    }
    #endregion

  }

  /// <summary>
  /// Describes the relationship between generated code and its original source
  /// file. A GeneratedCodeInfo message is associated with only one generated
  /// source file, but may contain references to different source .proto files.
  /// </summary>
  internal sealed partial class GeneratedCodeInfo : pb::IMessage<GeneratedCodeInfo> {
    private static readonly pb::MessageParser<GeneratedCodeInfo> _parser = new pb::MessageParser<GeneratedCodeInfo>(() => new GeneratedCodeInfo());
    private pb::UnknownFieldSet _unknownFields;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pb::MessageParser<GeneratedCodeInfo> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[20]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public GeneratedCodeInfo() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public GeneratedCodeInfo(GeneratedCodeInfo other) : this() {
      annotation_ = other.annotation_.Clone();
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public GeneratedCodeInfo Clone() {
      return new GeneratedCodeInfo(this);
    }

    /// <summary>Field number for the "annotation" field.</summary>
    public const int AnnotationFieldNumber = 1;
    private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation> _repeated_annotation_codec
        = pb::FieldCodec.ForMessage(10, global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation> annotation_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation>();
    /// <summary>
    /// An Annotation connects some span of text in generated code to an element
    /// of its generating .proto file.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation> Annotation {
      get { return annotation_; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override bool Equals(object other) {
      return Equals(other as GeneratedCodeInfo);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(GeneratedCodeInfo other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if(!annotation_.Equals(other.annotation_)) return false;
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      hash ^= annotation_.GetHashCode();
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void WriteTo(pb::CodedOutputStream output) {
      annotation_.WriteTo(output, _repeated_annotation_codec);
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      size += annotation_.CalculateSize(_repeated_annotation_codec);
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(GeneratedCodeInfo other) {
      if (other == null) {
        return;
      }
      annotation_.Add(other.annotation_);
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            break;
          case 10: {
            annotation_.AddEntriesFrom(input, _repeated_annotation_codec);
            break;
          }
        }
      }
    }

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

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public static pbr::MessageDescriptor Descriptor {
          get { return global::Google.Protobuf.Reflection.GeneratedCodeInfo.Descriptor.NestedTypes[0]; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        pbr::MessageDescriptor pb::IMessage.Descriptor {
          get { return Descriptor; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public Annotation() {
          OnConstruction();
        }

        partial void OnConstruction();

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public Annotation(Annotation other) : this() {
          path_ = other.path_.Clone();
          sourceFile_ = other.sourceFile_;
          begin_ = other.begin_;
          end_ = other.end_;
          _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public Annotation Clone() {
          return new Annotation(this);
        }

        /// <summary>Field number for the "path" field.</summary>
        public const int PathFieldNumber = 1;
        private static readonly pb::FieldCodec<int> _repeated_path_codec
            = pb::FieldCodec.ForInt32(10);
        private readonly pbc::RepeatedField<int> path_ = new pbc::RepeatedField<int>();
        /// <summary>
        /// Identifies the element in the original source .proto file. This field
        /// is formatted the same as SourceCodeInfo.Location.path.
        /// </summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public pbc::RepeatedField<int> Path {
          get { return path_; }
        }

        /// <summary>Field number for the "source_file" field.</summary>
        public const int SourceFileFieldNumber = 2;
        private string sourceFile_ = "";
        /// <summary>
        /// Identifies the filesystem path to the original source .proto.
        /// </summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public string SourceFile {
          get { return sourceFile_; }
          set {
            sourceFile_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
          }
        }

        /// <summary>Field number for the "begin" field.</summary>
        public const int BeginFieldNumber = 3;
        private int begin_;
        /// <summary>
        /// Identifies the starting offset in bytes in the generated code
        /// that relates to the identified object.
        /// </summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public int Begin {
          get { return begin_; }
          set {
            begin_ = value;
          }
        }

        /// <summary>Field number for the "end" field.</summary>
        public const int EndFieldNumber = 4;
        private int end_;
        /// <summary>
        /// Identifies the ending offset in bytes in the generated code that
        /// relates to the identified offset. The end offset should be one past
        /// the last relevant byte (so the length of the text = end - begin).
        /// </summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public int End {
          get { return end_; }
          set {
            end_ = value;
          }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public override bool Equals(object other) {
          return Equals(other as Annotation);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public bool Equals(Annotation other) {
          if (ReferenceEquals(other, null)) {
            return false;
          }
          if (ReferenceEquals(other, this)) {
            return true;
          }
          if(!path_.Equals(other.path_)) return false;
          if (SourceFile != other.SourceFile) return false;
          if (Begin != other.Begin) return false;
          if (End != other.End) return false;
          return Equals(_unknownFields, other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public override int GetHashCode() {
          int hash = 1;
          hash ^= path_.GetHashCode();
          if (SourceFile.Length != 0) hash ^= SourceFile.GetHashCode();
          if (Begin != 0) hash ^= Begin.GetHashCode();
          if (End != 0) hash ^= End.GetHashCode();
          if (_unknownFields != null) {
            hash ^= _unknownFields.GetHashCode();
          }
          return hash;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public override string ToString() {
          return pb::JsonFormatter.ToDiagnosticString(this);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void WriteTo(pb::CodedOutputStream output) {
          path_.WriteTo(output, _repeated_path_codec);
          if (SourceFile.Length != 0) {
            output.WriteRawTag(18);
            output.WriteString(SourceFile);
          }
          if (Begin != 0) {
            output.WriteRawTag(24);
            output.WriteInt32(Begin);
          }
          if (End != 0) {
            output.WriteRawTag(32);
            output.WriteInt32(End);
          }
          if (_unknownFields != null) {
            _unknownFields.WriteTo(output);
          }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public int CalculateSize() {
          int size = 0;
          size += path_.CalculateSize(_repeated_path_codec);
          if (SourceFile.Length != 0) {
            size += 1 + pb::CodedOutputStream.ComputeStringSize(SourceFile);
          }
          if (Begin != 0) {
            size += 1 + pb::CodedOutputStream.ComputeInt32Size(Begin);
          }
          if (End != 0) {
            size += 1 + pb::CodedOutputStream.ComputeInt32Size(End);
          }
          if (_unknownFields != null) {
            size += _unknownFields.CalculateSize();
          }
          return size;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void MergeFrom(Annotation other) {
          if (other == null) {
            return;
          }
          path_.Add(other.path_);
          if (other.SourceFile.Length != 0) {
            SourceFile = other.SourceFile;
          }
          if (other.Begin != 0) {
            Begin = other.Begin;
          }
          if (other.End != 0) {
            End = other.End;
          }
          _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void MergeFrom(pb::CodedInputStream input) {
          uint tag;
          while ((tag = input.ReadTag()) != 0) {
            switch(tag) {
              default:
                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                break;
              case 10:
              case 8: {
                path_.AddEntriesFrom(input, _repeated_path_codec);
                break;
              }
              case 18: {
                SourceFile = input.ReadString();
                break;
              }
              case 24: {
                Begin = input.ReadInt32();
                break;
              }
              case 32: {
                End = input.ReadInt32();
                break;
              }
            }
          }
        }

      }

    }
    #endregion

  }

  #endregion

}

#endregion Designer generated code
