// <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>
  public 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, null, new pbr::GeneratedClrTypeInfo[] {
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FileDescriptorSet), global::Google.Protobuf.Reflection.FileDescriptorSet.Parser, new[]{ "File" }, null, 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, 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, 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, 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, null)}),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.ExtensionRangeOptions), global::Google.Protobuf.Reflection.ExtensionRangeOptions.Parser, new[]{ "UninterpretedOption" }, null, 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, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.OneofDescriptorProto), global::Google.Protobuf.Reflection.OneofDescriptorProto.Parser, new[]{ "Name", "Options" }, null, 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, 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, null)}),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumValueDescriptorProto), global::Google.Protobuf.Reflection.EnumValueDescriptorProto.Parser, new[]{ "Name", "Number", "Options" }, null, 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, 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, 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, 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, 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, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.OneofOptions), global::Google.Protobuf.Reflection.OneofOptions.Parser, new[]{ "UninterpretedOption" }, null, 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, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumValueOptions), global::Google.Protobuf.Reflection.EnumValueOptions.Parser, new[]{ "Deprecated", "UninterpretedOption" }, null, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.ServiceOptions), global::Google.Protobuf.Reflection.ServiceOptions.Parser, new[]{ "Deprecated", "UninterpretedOption" }, null, 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, 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, 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, null)}),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.SourceCodeInfo), global::Google.Protobuf.Reflection.SourceCodeInfo.Parser, new[]{ "Location" }, null, 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, null)}),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.GeneratedCodeInfo), global::Google.Protobuf.Reflection.GeneratedCodeInfo.Parser, new[]{ "Annotation" }, null, 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, null)})
          }));
    }
    #endregion

  }
  #region Messages
  /// <summary>
  /// The protocol compiler can output a FileDescriptorSet containing the .proto
  /// files it parses.
  /// </summary>
  public 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>
  public 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.HasOptions ? other.options_.Clone() : null;
      sourceCodeInfo_ = other.HasSourceCodeInfo ? 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 readonly static string NameDefaultValue = "";

    private string name_;
    /// <summary>
    /// file name, relative to root of source tree
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string Name {
      get { return name_ ?? NameDefaultValue; }
      set {
        name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }
    /// <summary>Gets whether the "name" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasName {
      get { return name_ != null; }
    }
    /// <summary>Clears the value of the "name" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearName() {
      name_ = null;
    }

    /// <summary>Field number for the "package" field.</summary>
    public const int PackageFieldNumber = 2;
    private readonly static string PackageDefaultValue = "";

    private string package_;
    /// <summary>
    /// e.g. "foo", "foo.bar", etc.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string Package {
      get { return package_ ?? PackageDefaultValue; }
      set {
        package_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }
    /// <summary>Gets whether the "package" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasPackage {
      get { return package_ != null; }
    }
    /// <summary>Clears the value of the "package" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearPackage() {
      package_ = null;
    }

    /// <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>Gets whether the options field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasOptions {
      get { return options_ != null; }
    }
    /// <summary>Clears the value of the options field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearOptions() {
      options_ = null;
    }

    /// <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>Gets whether the source_code_info field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasSourceCodeInfo {
      get { return sourceCodeInfo_ != null; }
    }
    /// <summary>Clears the value of the source_code_info field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearSourceCodeInfo() {
      sourceCodeInfo_ = null;
    }

    /// <summary>Field number for the "syntax" field.</summary>
    public const int SyntaxFieldNumber = 12;
    private readonly static string SyntaxDefaultValue = "";

    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_ ?? SyntaxDefaultValue; }
      set {
        syntax_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }
    /// <summary>Gets whether the "syntax" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasSyntax {
      get { return syntax_ != null; }
    }
    /// <summary>Clears the value of the "syntax" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearSyntax() {
      syntax_ = null;
    }

    [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 (HasName) hash ^= Name.GetHashCode();
      if (HasPackage) 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 (HasOptions) hash ^= Options.GetHashCode();
      if (HasSourceCodeInfo) hash ^= SourceCodeInfo.GetHashCode();
      if (HasSyntax) 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 (HasName) {
        output.WriteRawTag(10);
        output.WriteString(Name);
      }
      if (HasPackage) {
        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 (HasOptions) {
        output.WriteRawTag(66);
        output.WriteMessage(Options);
      }
      if (HasSourceCodeInfo) {
        output.WriteRawTag(74);
        output.WriteMessage(SourceCodeInfo);
      }
      publicDependency_.WriteTo(output, _repeated_publicDependency_codec);
      weakDependency_.WriteTo(output, _repeated_weakDependency_codec);
      if (HasSyntax) {
        output.WriteRawTag(98);
        output.WriteString(Syntax);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (HasName) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
      }
      if (HasPackage) {
        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 (HasOptions) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Options);
      }
      if (HasSourceCodeInfo) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(SourceCodeInfo);
      }
      if (HasSyntax) {
        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.HasName) {
        Name = other.Name;
      }
      if (other.HasPackage) {
        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.HasOptions) {
        if (!HasOptions) {
          Options = new global::Google.Protobuf.Reflection.FileOptions();
        }
        Options.MergeFrom(other.Options);
      }
      if (other.HasSourceCodeInfo) {
        if (!HasSourceCodeInfo) {
          SourceCodeInfo = new global::Google.Protobuf.Reflection.SourceCodeInfo();
        }
        SourceCodeInfo.MergeFrom(other.SourceCodeInfo);
      }
      if (other.HasSyntax) {
        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 (!HasOptions) {
              Options = new global::Google.Protobuf.Reflection.FileOptions();
            }
            input.ReadMessage(Options);
            break;
          }
          case 74: {
            if (!HasSourceCodeInfo) {
              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>
  public 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.HasOptions ? 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 readonly static string NameDefaultValue = "";

    private string name_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string Name {
      get { return name_ ?? NameDefaultValue; }
      set {
        name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }
    /// <summary>Gets whether the "name" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasName {
      get { return name_ != null; }
    }
    /// <summary>Clears the value of the "name" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearName() {
      name_ = null;
    }

    /// <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>Gets whether the options field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasOptions {
      get { return options_ != null; }
    }
    /// <summary>Clears the value of the options field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearOptions() {
      options_ = null;
    }

    /// <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 (HasName) hash ^= Name.GetHashCode();
      hash ^= field_.GetHashCode();
      hash ^= extension_.GetHashCode();
      hash ^= nestedType_.GetHashCode();
      hash ^= enumType_.GetHashCode();
      hash ^= extensionRange_.GetHashCode();
      hash ^= oneofDecl_.GetHashCode();
      if (HasOptions) 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 (HasName) {
        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 (HasOptions) {
        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 (HasName) {
        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 (HasOptions) {
        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.HasName) {
        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.HasOptions) {
        if (!HasOptions) {
          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 (!HasOptions) {
              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 {
      public sealed partial class ExtensionRange : pb::IMessage<ExtensionRange> {
        private static readonly pb::MessageParser<ExtensionRange> _parser = new pb::MessageParser<ExtensionRange>(() => new ExtensionRange());
        private pb::UnknownFieldSet _unknownFields;
        private int _hasBits0;
        [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() {
          _hasBits0 = other._hasBits0;
          start_ = other.start_;
          end_ = other.end_;
          options_ = other.HasOptions ? 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 readonly static int StartDefaultValue = 0;

        private int start_;
        /// <summary>
        /// Inclusive.
        /// </summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public int Start {
          get { if ((_hasBits0 & 1) != 0) { return start_; } else { return StartDefaultValue; } }
          set {
            _hasBits0 |= 1;
            start_ = value;
          }
        }
        /// <summary>Gets whether the "start" field is set</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public bool HasStart {
          get { return (_hasBits0 & 1) != 0; }
        }
        /// <summary>Clears the value of the "start" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void ClearStart() {
          _hasBits0 &= ~1;
        }

        /// <summary>Field number for the "end" field.</summary>
        public const int EndFieldNumber = 2;
        private readonly static int EndDefaultValue = 0;

        private int end_;
        /// <summary>
        /// Exclusive.
        /// </summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public int End {
          get { if ((_hasBits0 & 2) != 0) { return end_; } else { return EndDefaultValue; } }
          set {
            _hasBits0 |= 2;
            end_ = value;
          }
        }
        /// <summary>Gets whether the "end" field is set</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public bool HasEnd {
          get { return (_hasBits0 & 2) != 0; }
        }
        /// <summary>Clears the value of the "end" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void ClearEnd() {
          _hasBits0 &= ~2;
        }

        /// <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;
          }
        }
        /// <summary>Gets whether the options field is set</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public bool HasOptions {
          get { return options_ != null; }
        }
        /// <summary>Clears the value of the options field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void ClearOptions() {
          options_ = null;
        }

        [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 (HasStart) hash ^= Start.GetHashCode();
          if (HasEnd) hash ^= End.GetHashCode();
          if (HasOptions) 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 (HasStart) {
            output.WriteRawTag(8);
            output.WriteInt32(Start);
          }
          if (HasEnd) {
            output.WriteRawTag(16);
            output.WriteInt32(End);
          }
          if (HasOptions) {
            output.WriteRawTag(26);
            output.WriteMessage(Options);
          }
          if (_unknownFields != null) {
            _unknownFields.WriteTo(output);
          }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public int CalculateSize() {
          int size = 0;
          if (HasStart) {
            size += 1 + pb::CodedOutputStream.ComputeInt32Size(Start);
          }
          if (HasEnd) {
            size += 1 + pb::CodedOutputStream.ComputeInt32Size(End);
          }
          if (HasOptions) {
            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.HasStart) {
            Start = other.Start;
          }
          if (other.HasEnd) {
            End = other.End;
          }
          if (other.HasOptions) {
            if (!HasOptions) {
              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 (!HasOptions) {
                  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>
      public sealed partial class ReservedRange : pb::IMessage<ReservedRange> {
        private static readonly pb::MessageParser<ReservedRange> _parser = new pb::MessageParser<ReservedRange>(() => new ReservedRange());
        private pb::UnknownFieldSet _unknownFields;
        private int _hasBits0;
        [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() {
          _hasBits0 = other._hasBits0;
          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 readonly static int StartDefaultValue = 0;

        private int start_;
        /// <summary>
        /// Inclusive.
        /// </summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public int Start {
          get { if ((_hasBits0 & 1) != 0) { return start_; } else { return StartDefaultValue; } }
          set {
            _hasBits0 |= 1;
            start_ = value;
          }
        }
        /// <summary>Gets whether the "start" field is set</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public bool HasStart {
          get { return (_hasBits0 & 1) != 0; }
        }
        /// <summary>Clears the value of the "start" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void ClearStart() {
          _hasBits0 &= ~1;
        }

        /// <summary>Field number for the "end" field.</summary>
        public const int EndFieldNumber = 2;
        private readonly static int EndDefaultValue = 0;

        private int end_;
        /// <summary>
        /// Exclusive.
        /// </summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public int End {
          get { if ((_hasBits0 & 2) != 0) { return end_; } else { return EndDefaultValue; } }
          set {
            _hasBits0 |= 2;
            end_ = value;
          }
        }
        /// <summary>Gets whether the "end" field is set</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public bool HasEnd {
          get { return (_hasBits0 & 2) != 0; }
        }
        /// <summary>Clears the value of the "end" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void ClearEnd() {
          _hasBits0 &= ~2;
        }

        [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 (HasStart) hash ^= Start.GetHashCode();
          if (HasEnd) 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 (HasStart) {
            output.WriteRawTag(8);
            output.WriteInt32(Start);
          }
          if (HasEnd) {
            output.WriteRawTag(16);
            output.WriteInt32(End);
          }
          if (_unknownFields != null) {
            _unknownFields.WriteTo(output);
          }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public int CalculateSize() {
          int size = 0;
          if (HasStart) {
            size += 1 + pb::CodedOutputStream.ComputeInt32Size(Start);
          }
          if (HasEnd) {
            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.HasStart) {
            Start = other.Start;
          }
          if (other.HasEnd) {
            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

  }

  public sealed partial class ExtensionRangeOptions : pb::IExtendableMessage<ExtensionRangeOptions> {
    private static readonly pb::MessageParser<ExtensionRangeOptions> _parser = new pb::MessageParser<ExtensionRangeOptions>(() => new ExtensionRangeOptions());
    private pb::UnknownFieldSet _unknownFields;
    internal pb::ExtensionSet<ExtensionRangeOptions> _extensions;
    private pb::ExtensionSet<ExtensionRangeOptions> _Extensions => _extensions;
    [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);
      _extensions = pb::ExtensionSet.Clone(other._extensions);
    }

    [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;
      if (!Equals(_extensions, other._extensions)) {
        return false;
      }
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      hash ^= uninterpretedOption_.GetHashCode();
      if (_extensions != null) {
        hash ^= _extensions.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 (_extensions != null) {
        _extensions.WriteTo(output);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec);
      if (_extensions != null) {
        size += _extensions.CalculateSize();
      }
      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_);
      pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions);
      _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:
            if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, input)) {
              _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            }
            break;
          case 7994: {
            uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec);
            break;
          }
        }
      }
    }

    public TValue GetExtension<TValue>(pb::Extension<ExtensionRangeOptions, TValue> extension) {
      return pb::ExtensionSet.Get(ref _extensions, extension);
    }
    public pbc::RepeatedField<TValue> GetExtension<TValue>(pb::RepeatedExtension<ExtensionRangeOptions, TValue> extension) {
      return pb::ExtensionSet.Get(ref _extensions, extension);
    }
    public pbc::RepeatedField<TValue> GetOrInitializeExtension<TValue>(pb::RepeatedExtension<ExtensionRangeOptions, TValue> extension) {
      return pb::ExtensionSet.GetOrInitialize(ref _extensions, extension);
    }
    public void SetExtension<TValue>(pb::Extension<ExtensionRangeOptions, TValue> extension, TValue value) {
      pb::ExtensionSet.Set(ref _extensions, extension, value);
    }
    public bool HasExtension<TValue>(pb::Extension<ExtensionRangeOptions, TValue> extension) {
      return pb::ExtensionSet.Has(ref _extensions, extension);
    }
    public void ClearExtension<TValue>(pb::Extension<ExtensionRangeOptions, TValue> extension) {
      pb::ExtensionSet.Clear(ref _extensions, extension);
    }
    public void ClearExtension<TValue>(pb::RepeatedExtension<ExtensionRangeOptions, TValue> extension) {
      pb::ExtensionSet.Clear(ref _extensions, extension);
    }

  }

  /// <summary>
  /// Describes a field within a message.
  /// </summary>
  public sealed partial class FieldDescriptorProto : pb::IMessage<FieldDescriptorProto> {
    private static readonly pb::MessageParser<FieldDescriptorProto> _parser = new pb::MessageParser<FieldDescriptorProto>(() => new FieldDescriptorProto());
    private pb::UnknownFieldSet _unknownFields;
    private int _hasBits0;
    [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() {
      _hasBits0 = other._hasBits0;
      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.HasOptions ? 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 readonly static string NameDefaultValue = "";

    private string name_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string Name {
      get { return name_ ?? NameDefaultValue; }
      set {
        name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }
    /// <summary>Gets whether the "name" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasName {
      get { return name_ != null; }
    }
    /// <summary>Clears the value of the "name" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearName() {
      name_ = null;
    }

    /// <summary>Field number for the "number" field.</summary>
    public const int NumberFieldNumber = 3;
    private readonly static int NumberDefaultValue = 0;

    private int number_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int Number {
      get { if ((_hasBits0 & 1) != 0) { return number_; } else { return NumberDefaultValue; } }
      set {
        _hasBits0 |= 1;
        number_ = value;
      }
    }
    /// <summary>Gets whether the "number" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasNumber {
      get { return (_hasBits0 & 1) != 0; }
    }
    /// <summary>Clears the value of the "number" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearNumber() {
      _hasBits0 &= ~1;
    }

    /// <summary>Field number for the "label" field.</summary>
    public const int LabelFieldNumber = 4;
    private readonly static global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label LabelDefaultValue = global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label.Optional;

    private global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label label_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label Label {
      get { if ((_hasBits0 & 2) != 0) { return label_; } else { return LabelDefaultValue; } }
      set {
        _hasBits0 |= 2;
        label_ = value;
      }
    }
    /// <summary>Gets whether the "label" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasLabel {
      get { return (_hasBits0 & 2) != 0; }
    }
    /// <summary>Clears the value of the "label" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearLabel() {
      _hasBits0 &= ~2;
    }

    /// <summary>Field number for the "type" field.</summary>
    public const int TypeFieldNumber = 5;
    private readonly static global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type TypeDefaultValue = global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type.Double;

    private global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type type_;
    /// <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 { if ((_hasBits0 & 4) != 0) { return type_; } else { return TypeDefaultValue; } }
      set {
        _hasBits0 |= 4;
        type_ = value;
      }
    }
    /// <summary>Gets whether the "type" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasType {
      get { return (_hasBits0 & 4) != 0; }
    }
    /// <summary>Clears the value of the "type" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearType() {
      _hasBits0 &= ~4;
    }

    /// <summary>Field number for the "type_name" field.</summary>
    public const int TypeNameFieldNumber = 6;
    private readonly static string TypeNameDefaultValue = "";

    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_ ?? TypeNameDefaultValue; }
      set {
        typeName_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }
    /// <summary>Gets whether the "type_name" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasTypeName {
      get { return typeName_ != null; }
    }
    /// <summary>Clears the value of the "type_name" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearTypeName() {
      typeName_ = null;
    }

    /// <summary>Field number for the "extendee" field.</summary>
    public const int ExtendeeFieldNumber = 2;
    private readonly static string ExtendeeDefaultValue = "";

    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_ ?? ExtendeeDefaultValue; }
      set {
        extendee_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }
    /// <summary>Gets whether the "extendee" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasExtendee {
      get { return extendee_ != null; }
    }
    /// <summary>Clears the value of the "extendee" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearExtendee() {
      extendee_ = null;
    }

    /// <summary>Field number for the "default_value" field.</summary>
    public const int DefaultValueFieldNumber = 7;
    private readonly static string DefaultValueDefaultValue = "";

    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_ ?? DefaultValueDefaultValue; }
      set {
        defaultValue_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }
    /// <summary>Gets whether the "default_value" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasDefaultValue {
      get { return defaultValue_ != null; }
    }
    /// <summary>Clears the value of the "default_value" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearDefaultValue() {
      defaultValue_ = null;
    }

    /// <summary>Field number for the "oneof_index" field.</summary>
    public const int OneofIndexFieldNumber = 9;
    private readonly static int OneofIndexDefaultValue = 0;

    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 { if ((_hasBits0 & 8) != 0) { return oneofIndex_; } else { return OneofIndexDefaultValue; } }
      set {
        _hasBits0 |= 8;
        oneofIndex_ = value;
      }
    }
    /// <summary>Gets whether the "oneof_index" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasOneofIndex {
      get { return (_hasBits0 & 8) != 0; }
    }
    /// <summary>Clears the value of the "oneof_index" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearOneofIndex() {
      _hasBits0 &= ~8;
    }

    /// <summary>Field number for the "json_name" field.</summary>
    public const int JsonNameFieldNumber = 10;
    private readonly static string JsonNameDefaultValue = "";

    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_ ?? JsonNameDefaultValue; }
      set {
        jsonName_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }
    /// <summary>Gets whether the "json_name" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasJsonName {
      get { return jsonName_ != null; }
    }
    /// <summary>Clears the value of the "json_name" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearJsonName() {
      jsonName_ = null;
    }

    /// <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;
      }
    }
    /// <summary>Gets whether the options field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasOptions {
      get { return options_ != null; }
    }
    /// <summary>Clears the value of the options field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearOptions() {
      options_ = null;
    }

    [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 (HasName) hash ^= Name.GetHashCode();
      if (HasNumber) hash ^= Number.GetHashCode();
      if (HasLabel) hash ^= Label.GetHashCode();
      if (HasType) hash ^= Type.GetHashCode();
      if (HasTypeName) hash ^= TypeName.GetHashCode();
      if (HasExtendee) hash ^= Extendee.GetHashCode();
      if (HasDefaultValue) hash ^= DefaultValue.GetHashCode();
      if (HasOneofIndex) hash ^= OneofIndex.GetHashCode();
      if (HasJsonName) hash ^= JsonName.GetHashCode();
      if (HasOptions) 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 (HasName) {
        output.WriteRawTag(10);
        output.WriteString(Name);
      }
      if (HasExtendee) {
        output.WriteRawTag(18);
        output.WriteString(Extendee);
      }
      if (HasNumber) {
        output.WriteRawTag(24);
        output.WriteInt32(Number);
      }
      if (HasLabel) {
        output.WriteRawTag(32);
        output.WriteEnum((int) Label);
      }
      if (HasType) {
        output.WriteRawTag(40);
        output.WriteEnum((int) Type);
      }
      if (HasTypeName) {
        output.WriteRawTag(50);
        output.WriteString(TypeName);
      }
      if (HasDefaultValue) {
        output.WriteRawTag(58);
        output.WriteString(DefaultValue);
      }
      if (HasOptions) {
        output.WriteRawTag(66);
        output.WriteMessage(Options);
      }
      if (HasOneofIndex) {
        output.WriteRawTag(72);
        output.WriteInt32(OneofIndex);
      }
      if (HasJsonName) {
        output.WriteRawTag(82);
        output.WriteString(JsonName);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (HasName) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
      }
      if (HasNumber) {
        size += 1 + pb::CodedOutputStream.ComputeInt32Size(Number);
      }
      if (HasLabel) {
        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Label);
      }
      if (HasType) {
        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Type);
      }
      if (HasTypeName) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(TypeName);
      }
      if (HasExtendee) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(Extendee);
      }
      if (HasDefaultValue) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(DefaultValue);
      }
      if (HasOneofIndex) {
        size += 1 + pb::CodedOutputStream.ComputeInt32Size(OneofIndex);
      }
      if (HasJsonName) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(JsonName);
      }
      if (HasOptions) {
        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.HasName) {
        Name = other.Name;
      }
      if (other.HasNumber) {
        Number = other.Number;
      }
      if (other.HasLabel) {
        Label = other.Label;
      }
      if (other.HasType) {
        Type = other.Type;
      }
      if (other.HasTypeName) {
        TypeName = other.TypeName;
      }
      if (other.HasExtendee) {
        Extendee = other.Extendee;
      }
      if (other.HasDefaultValue) {
        DefaultValue = other.DefaultValue;
      }
      if (other.HasOneofIndex) {
        OneofIndex = other.OneofIndex;
      }
      if (other.HasJsonName) {
        JsonName = other.JsonName;
      }
      if (other.HasOptions) {
        if (!HasOptions) {
          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 (!HasOptions) {
              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 {
      public 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,
      }

      public 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>
  public 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.HasOptions ? 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 readonly static string NameDefaultValue = "";

    private string name_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string Name {
      get { return name_ ?? NameDefaultValue; }
      set {
        name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }
    /// <summary>Gets whether the "name" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasName {
      get { return name_ != null; }
    }
    /// <summary>Clears the value of the "name" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearName() {
      name_ = null;
    }

    /// <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;
      }
    }
    /// <summary>Gets whether the options field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasOptions {
      get { return options_ != null; }
    }
    /// <summary>Clears the value of the options field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearOptions() {
      options_ = null;
    }

    [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 (HasName) hash ^= Name.GetHashCode();
      if (HasOptions) 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 (HasName) {
        output.WriteRawTag(10);
        output.WriteString(Name);
      }
      if (HasOptions) {
        output.WriteRawTag(18);
        output.WriteMessage(Options);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (HasName) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
      }
      if (HasOptions) {
        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.HasName) {
        Name = other.Name;
      }
      if (other.HasOptions) {
        if (!HasOptions) {
          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 (!HasOptions) {
              Options = new global::Google.Protobuf.Reflection.OneofOptions();
            }
            input.ReadMessage(Options);
            break;
          }
        }
      }
    }

  }

  /// <summary>
  /// Describes an enum type.
  /// </summary>
  public 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.HasOptions ? 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 readonly static string NameDefaultValue = "";

    private string name_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string Name {
      get { return name_ ?? NameDefaultValue; }
      set {
        name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }
    /// <summary>Gets whether the "name" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasName {
      get { return name_ != null; }
    }
    /// <summary>Clears the value of the "name" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearName() {
      name_ = null;
    }

    /// <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>Gets whether the options field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasOptions {
      get { return options_ != null; }
    }
    /// <summary>Clears the value of the options field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearOptions() {
      options_ = null;
    }

    /// <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 (HasName) hash ^= Name.GetHashCode();
      hash ^= value_.GetHashCode();
      if (HasOptions) 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 (HasName) {
        output.WriteRawTag(10);
        output.WriteString(Name);
      }
      value_.WriteTo(output, _repeated_value_codec);
      if (HasOptions) {
        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 (HasName) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
      }
      size += value_.CalculateSize(_repeated_value_codec);
      if (HasOptions) {
        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.HasName) {
        Name = other.Name;
      }
      value_.Add(other.value_);
      if (other.HasOptions) {
        if (!HasOptions) {
          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 (!HasOptions) {
              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>
      public sealed partial class EnumReservedRange : pb::IMessage<EnumReservedRange> {
        private static readonly pb::MessageParser<EnumReservedRange> _parser = new pb::MessageParser<EnumReservedRange>(() => new EnumReservedRange());
        private pb::UnknownFieldSet _unknownFields;
        private int _hasBits0;
        [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() {
          _hasBits0 = other._hasBits0;
          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 readonly static int StartDefaultValue = 0;

        private int start_;
        /// <summary>
        /// Inclusive.
        /// </summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public int Start {
          get { if ((_hasBits0 & 1) != 0) { return start_; } else { return StartDefaultValue; } }
          set {
            _hasBits0 |= 1;
            start_ = value;
          }
        }
        /// <summary>Gets whether the "start" field is set</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public bool HasStart {
          get { return (_hasBits0 & 1) != 0; }
        }
        /// <summary>Clears the value of the "start" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void ClearStart() {
          _hasBits0 &= ~1;
        }

        /// <summary>Field number for the "end" field.</summary>
        public const int EndFieldNumber = 2;
        private readonly static int EndDefaultValue = 0;

        private int end_;
        /// <summary>
        /// Inclusive.
        /// </summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public int End {
          get { if ((_hasBits0 & 2) != 0) { return end_; } else { return EndDefaultValue; } }
          set {
            _hasBits0 |= 2;
            end_ = value;
          }
        }
        /// <summary>Gets whether the "end" field is set</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public bool HasEnd {
          get { return (_hasBits0 & 2) != 0; }
        }
        /// <summary>Clears the value of the "end" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void ClearEnd() {
          _hasBits0 &= ~2;
        }

        [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 (HasStart) hash ^= Start.GetHashCode();
          if (HasEnd) 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 (HasStart) {
            output.WriteRawTag(8);
            output.WriteInt32(Start);
          }
          if (HasEnd) {
            output.WriteRawTag(16);
            output.WriteInt32(End);
          }
          if (_unknownFields != null) {
            _unknownFields.WriteTo(output);
          }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public int CalculateSize() {
          int size = 0;
          if (HasStart) {
            size += 1 + pb::CodedOutputStream.ComputeInt32Size(Start);
          }
          if (HasEnd) {
            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.HasStart) {
            Start = other.Start;
          }
          if (other.HasEnd) {
            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>
  public sealed partial class EnumValueDescriptorProto : pb::IMessage<EnumValueDescriptorProto> {
    private static readonly pb::MessageParser<EnumValueDescriptorProto> _parser = new pb::MessageParser<EnumValueDescriptorProto>(() => new EnumValueDescriptorProto());
    private pb::UnknownFieldSet _unknownFields;
    private int _hasBits0;
    [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() {
      _hasBits0 = other._hasBits0;
      name_ = other.name_;
      number_ = other.number_;
      options_ = other.HasOptions ? 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 readonly static string NameDefaultValue = "";

    private string name_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string Name {
      get { return name_ ?? NameDefaultValue; }
      set {
        name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }
    /// <summary>Gets whether the "name" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasName {
      get { return name_ != null; }
    }
    /// <summary>Clears the value of the "name" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearName() {
      name_ = null;
    }

    /// <summary>Field number for the "number" field.</summary>
    public const int NumberFieldNumber = 2;
    private readonly static int NumberDefaultValue = 0;

    private int number_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int Number {
      get { if ((_hasBits0 & 1) != 0) { return number_; } else { return NumberDefaultValue; } }
      set {
        _hasBits0 |= 1;
        number_ = value;
      }
    }
    /// <summary>Gets whether the "number" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasNumber {
      get { return (_hasBits0 & 1) != 0; }
    }
    /// <summary>Clears the value of the "number" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearNumber() {
      _hasBits0 &= ~1;
    }

    /// <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;
      }
    }
    /// <summary>Gets whether the options field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasOptions {
      get { return options_ != null; }
    }
    /// <summary>Clears the value of the options field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearOptions() {
      options_ = null;
    }

    [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 (HasName) hash ^= Name.GetHashCode();
      if (HasNumber) hash ^= Number.GetHashCode();
      if (HasOptions) 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 (HasName) {
        output.WriteRawTag(10);
        output.WriteString(Name);
      }
      if (HasNumber) {
        output.WriteRawTag(16);
        output.WriteInt32(Number);
      }
      if (HasOptions) {
        output.WriteRawTag(26);
        output.WriteMessage(Options);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (HasName) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
      }
      if (HasNumber) {
        size += 1 + pb::CodedOutputStream.ComputeInt32Size(Number);
      }
      if (HasOptions) {
        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.HasName) {
        Name = other.Name;
      }
      if (other.HasNumber) {
        Number = other.Number;
      }
      if (other.HasOptions) {
        if (!HasOptions) {
          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 (!HasOptions) {
              Options = new global::Google.Protobuf.Reflection.EnumValueOptions();
            }
            input.ReadMessage(Options);
            break;
          }
        }
      }
    }

  }

  /// <summary>
  /// Describes a service.
  /// </summary>
  public 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.HasOptions ? 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 readonly static string NameDefaultValue = "";

    private string name_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string Name {
      get { return name_ ?? NameDefaultValue; }
      set {
        name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }
    /// <summary>Gets whether the "name" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasName {
      get { return name_ != null; }
    }
    /// <summary>Clears the value of the "name" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearName() {
      name_ = null;
    }

    /// <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;
      }
    }
    /// <summary>Gets whether the options field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasOptions {
      get { return options_ != null; }
    }
    /// <summary>Clears the value of the options field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearOptions() {
      options_ = null;
    }

    [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 (HasName) hash ^= Name.GetHashCode();
      hash ^= method_.GetHashCode();
      if (HasOptions) 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 (HasName) {
        output.WriteRawTag(10);
        output.WriteString(Name);
      }
      method_.WriteTo(output, _repeated_method_codec);
      if (HasOptions) {
        output.WriteRawTag(26);
        output.WriteMessage(Options);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (HasName) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
      }
      size += method_.CalculateSize(_repeated_method_codec);
      if (HasOptions) {
        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.HasName) {
        Name = other.Name;
      }
      method_.Add(other.method_);
      if (other.HasOptions) {
        if (!HasOptions) {
          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 (!HasOptions) {
              Options = new global::Google.Protobuf.Reflection.ServiceOptions();
            }
            input.ReadMessage(Options);
            break;
          }
        }
      }
    }

  }

  /// <summary>
  /// Describes a method of a service.
  /// </summary>
  public sealed partial class MethodDescriptorProto : pb::IMessage<MethodDescriptorProto> {
    private static readonly pb::MessageParser<MethodDescriptorProto> _parser = new pb::MessageParser<MethodDescriptorProto>(() => new MethodDescriptorProto());
    private pb::UnknownFieldSet _unknownFields;
    private int _hasBits0;
    [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() {
      _hasBits0 = other._hasBits0;
      name_ = other.name_;
      inputType_ = other.inputType_;
      outputType_ = other.outputType_;
      options_ = other.HasOptions ? 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 readonly static string NameDefaultValue = "";

    private string name_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string Name {
      get { return name_ ?? NameDefaultValue; }
      set {
        name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }
    /// <summary>Gets whether the "name" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasName {
      get { return name_ != null; }
    }
    /// <summary>Clears the value of the "name" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearName() {
      name_ = null;
    }

    /// <summary>Field number for the "input_type" field.</summary>
    public const int InputTypeFieldNumber = 2;
    private readonly static string InputTypeDefaultValue = "";

    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_ ?? InputTypeDefaultValue; }
      set {
        inputType_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }
    /// <summary>Gets whether the "input_type" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasInputType {
      get { return inputType_ != null; }
    }
    /// <summary>Clears the value of the "input_type" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearInputType() {
      inputType_ = null;
    }

    /// <summary>Field number for the "output_type" field.</summary>
    public const int OutputTypeFieldNumber = 3;
    private readonly static string OutputTypeDefaultValue = "";

    private string outputType_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string OutputType {
      get { return outputType_ ?? OutputTypeDefaultValue; }
      set {
        outputType_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }
    /// <summary>Gets whether the "output_type" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasOutputType {
      get { return outputType_ != null; }
    }
    /// <summary>Clears the value of the "output_type" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearOutputType() {
      outputType_ = null;
    }

    /// <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>Gets whether the options field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasOptions {
      get { return options_ != null; }
    }
    /// <summary>Clears the value of the options field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearOptions() {
      options_ = null;
    }

    /// <summary>Field number for the "client_streaming" field.</summary>
    public const int ClientStreamingFieldNumber = 5;
    private readonly static bool ClientStreamingDefaultValue = false;

    private bool clientStreaming_;
    /// <summary>
    /// Identifies if client streams multiple client messages
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool ClientStreaming {
      get { if ((_hasBits0 & 1) != 0) { return clientStreaming_; } else { return ClientStreamingDefaultValue; } }
      set {
        _hasBits0 |= 1;
        clientStreaming_ = value;
      }
    }
    /// <summary>Gets whether the "client_streaming" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasClientStreaming {
      get { return (_hasBits0 & 1) != 0; }
    }
    /// <summary>Clears the value of the "client_streaming" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearClientStreaming() {
      _hasBits0 &= ~1;
    }

    /// <summary>Field number for the "server_streaming" field.</summary>
    public const int ServerStreamingFieldNumber = 6;
    private readonly static bool ServerStreamingDefaultValue = false;

    private bool serverStreaming_;
    /// <summary>
    /// Identifies if server streams multiple server messages
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool ServerStreaming {
      get { if ((_hasBits0 & 2) != 0) { return serverStreaming_; } else { return ServerStreamingDefaultValue; } }
      set {
        _hasBits0 |= 2;
        serverStreaming_ = value;
      }
    }
    /// <summary>Gets whether the "server_streaming" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasServerStreaming {
      get { return (_hasBits0 & 2) != 0; }
    }
    /// <summary>Clears the value of the "server_streaming" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearServerStreaming() {
      _hasBits0 &= ~2;
    }

    [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 (HasName) hash ^= Name.GetHashCode();
      if (HasInputType) hash ^= InputType.GetHashCode();
      if (HasOutputType) hash ^= OutputType.GetHashCode();
      if (HasOptions) hash ^= Options.GetHashCode();
      if (HasClientStreaming) hash ^= ClientStreaming.GetHashCode();
      if (HasServerStreaming) 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 (HasName) {
        output.WriteRawTag(10);
        output.WriteString(Name);
      }
      if (HasInputType) {
        output.WriteRawTag(18);
        output.WriteString(InputType);
      }
      if (HasOutputType) {
        output.WriteRawTag(26);
        output.WriteString(OutputType);
      }
      if (HasOptions) {
        output.WriteRawTag(34);
        output.WriteMessage(Options);
      }
      if (HasClientStreaming) {
        output.WriteRawTag(40);
        output.WriteBool(ClientStreaming);
      }
      if (HasServerStreaming) {
        output.WriteRawTag(48);
        output.WriteBool(ServerStreaming);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (HasName) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
      }
      if (HasInputType) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(InputType);
      }
      if (HasOutputType) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(OutputType);
      }
      if (HasOptions) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Options);
      }
      if (HasClientStreaming) {
        size += 1 + 1;
      }
      if (HasServerStreaming) {
        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.HasName) {
        Name = other.Name;
      }
      if (other.HasInputType) {
        InputType = other.InputType;
      }
      if (other.HasOutputType) {
        OutputType = other.OutputType;
      }
      if (other.HasOptions) {
        if (!HasOptions) {
          Options = new global::Google.Protobuf.Reflection.MethodOptions();
        }
        Options.MergeFrom(other.Options);
      }
      if (other.HasClientStreaming) {
        ClientStreaming = other.ClientStreaming;
      }
      if (other.HasServerStreaming) {
        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 (!HasOptions) {
              Options = new global::Google.Protobuf.Reflection.MethodOptions();
            }
            input.ReadMessage(Options);
            break;
          }
          case 40: {
            ClientStreaming = input.ReadBool();
            break;
          }
          case 48: {
            ServerStreaming = input.ReadBool();
            break;
          }
        }
      }
    }

  }

  public sealed partial class FileOptions : pb::IExtendableMessage<FileOptions> {
    private static readonly pb::MessageParser<FileOptions> _parser = new pb::MessageParser<FileOptions>(() => new FileOptions());
    private pb::UnknownFieldSet _unknownFields;
    internal pb::ExtensionSet<FileOptions> _extensions;
    private pb::ExtensionSet<FileOptions> _Extensions => _extensions;
    private int _hasBits0;
    [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; }
    }

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

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public FileOptions(FileOptions other) : this() {
      _hasBits0 = other._hasBits0;
      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);
      _extensions = pb::ExtensionSet.Clone(other._extensions);
    }

    [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 readonly static string JavaPackageDefaultValue = "";

    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_ ?? JavaPackageDefaultValue; }
      set {
        javaPackage_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }
    /// <summary>Gets whether the "java_package" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasJavaPackage {
      get { return javaPackage_ != null; }
    }
    /// <summary>Clears the value of the "java_package" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearJavaPackage() {
      javaPackage_ = null;
    }

    /// <summary>Field number for the "java_outer_classname" field.</summary>
    public const int JavaOuterClassnameFieldNumber = 8;
    private readonly static string JavaOuterClassnameDefaultValue = "";

    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_ ?? JavaOuterClassnameDefaultValue; }
      set {
        javaOuterClassname_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }
    /// <summary>Gets whether the "java_outer_classname" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasJavaOuterClassname {
      get { return javaOuterClassname_ != null; }
    }
    /// <summary>Clears the value of the "java_outer_classname" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearJavaOuterClassname() {
      javaOuterClassname_ = null;
    }

    /// <summary>Field number for the "java_multiple_files" field.</summary>
    public const int JavaMultipleFilesFieldNumber = 10;
    private readonly static bool JavaMultipleFilesDefaultValue = false;

    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 { if ((_hasBits0 & 2) != 0) { return javaMultipleFiles_; } else { return JavaMultipleFilesDefaultValue; } }
      set {
        _hasBits0 |= 2;
        javaMultipleFiles_ = value;
      }
    }
    /// <summary>Gets whether the "java_multiple_files" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasJavaMultipleFiles {
      get { return (_hasBits0 & 2) != 0; }
    }
    /// <summary>Clears the value of the "java_multiple_files" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearJavaMultipleFiles() {
      _hasBits0 &= ~2;
    }

    /// <summary>Field number for the "java_generate_equals_and_hash" field.</summary>
    public const int JavaGenerateEqualsAndHashFieldNumber = 20;
    private readonly static bool JavaGenerateEqualsAndHashDefaultValue = false;

    private bool javaGenerateEqualsAndHash_;
    /// <summary>
    /// This option does nothing.
    /// </summary>
    [global::System.ObsoleteAttribute]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool JavaGenerateEqualsAndHash {
      get { if ((_hasBits0 & 32) != 0) { return javaGenerateEqualsAndHash_; } else { return JavaGenerateEqualsAndHashDefaultValue; } }
      set {
        _hasBits0 |= 32;
        javaGenerateEqualsAndHash_ = value;
      }
    }
    /// <summary>Gets whether the "java_generate_equals_and_hash" field is set</summary>
    [global::System.ObsoleteAttribute]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasJavaGenerateEqualsAndHash {
      get { return (_hasBits0 & 32) != 0; }
    }
    /// <summary>Clears the value of the "java_generate_equals_and_hash" field</summary>
    [global::System.ObsoleteAttribute]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearJavaGenerateEqualsAndHash() {
      _hasBits0 &= ~32;
    }

    /// <summary>Field number for the "java_string_check_utf8" field.</summary>
    public const int JavaStringCheckUtf8FieldNumber = 27;
    private readonly static bool JavaStringCheckUtf8DefaultValue = false;

    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 { if ((_hasBits0 & 128) != 0) { return javaStringCheckUtf8_; } else { return JavaStringCheckUtf8DefaultValue; } }
      set {
        _hasBits0 |= 128;
        javaStringCheckUtf8_ = value;
      }
    }
    /// <summary>Gets whether the "java_string_check_utf8" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasJavaStringCheckUtf8 {
      get { return (_hasBits0 & 128) != 0; }
    }
    /// <summary>Clears the value of the "java_string_check_utf8" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearJavaStringCheckUtf8() {
      _hasBits0 &= ~128;
    }

    /// <summary>Field number for the "optimize_for" field.</summary>
    public const int OptimizeForFieldNumber = 9;
    private readonly static global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode OptimizeForDefaultValue = global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode.Speed;

    private global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode optimizeFor_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode OptimizeFor {
      get { if ((_hasBits0 & 1) != 0) { return optimizeFor_; } else { return OptimizeForDefaultValue; } }
      set {
        _hasBits0 |= 1;
        optimizeFor_ = value;
      }
    }
    /// <summary>Gets whether the "optimize_for" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasOptimizeFor {
      get { return (_hasBits0 & 1) != 0; }
    }
    /// <summary>Clears the value of the "optimize_for" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearOptimizeFor() {
      _hasBits0 &= ~1;
    }

    /// <summary>Field number for the "go_package" field.</summary>
    public const int GoPackageFieldNumber = 11;
    private readonly static string GoPackageDefaultValue = "";

    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_ ?? GoPackageDefaultValue; }
      set {
        goPackage_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }
    /// <summary>Gets whether the "go_package" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasGoPackage {
      get { return goPackage_ != null; }
    }
    /// <summary>Clears the value of the "go_package" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearGoPackage() {
      goPackage_ = null;
    }

    /// <summary>Field number for the "cc_generic_services" field.</summary>
    public const int CcGenericServicesFieldNumber = 16;
    private readonly static bool CcGenericServicesDefaultValue = false;

    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 { if ((_hasBits0 & 4) != 0) { return ccGenericServices_; } else { return CcGenericServicesDefaultValue; } }
      set {
        _hasBits0 |= 4;
        ccGenericServices_ = value;
      }
    }
    /// <summary>Gets whether the "cc_generic_services" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasCcGenericServices {
      get { return (_hasBits0 & 4) != 0; }
    }
    /// <summary>Clears the value of the "cc_generic_services" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearCcGenericServices() {
      _hasBits0 &= ~4;
    }

    /// <summary>Field number for the "java_generic_services" field.</summary>
    public const int JavaGenericServicesFieldNumber = 17;
    private readonly static bool JavaGenericServicesDefaultValue = false;

    private bool javaGenericServices_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool JavaGenericServices {
      get { if ((_hasBits0 & 8) != 0) { return javaGenericServices_; } else { return JavaGenericServicesDefaultValue; } }
      set {
        _hasBits0 |= 8;
        javaGenericServices_ = value;
      }
    }
    /// <summary>Gets whether the "java_generic_services" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasJavaGenericServices {
      get { return (_hasBits0 & 8) != 0; }
    }
    /// <summary>Clears the value of the "java_generic_services" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearJavaGenericServices() {
      _hasBits0 &= ~8;
    }

    /// <summary>Field number for the "py_generic_services" field.</summary>
    public const int PyGenericServicesFieldNumber = 18;
    private readonly static bool PyGenericServicesDefaultValue = false;

    private bool pyGenericServices_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool PyGenericServices {
      get { if ((_hasBits0 & 16) != 0) { return pyGenericServices_; } else { return PyGenericServicesDefaultValue; } }
      set {
        _hasBits0 |= 16;
        pyGenericServices_ = value;
      }
    }
    /// <summary>Gets whether the "py_generic_services" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasPyGenericServices {
      get { return (_hasBits0 & 16) != 0; }
    }
    /// <summary>Clears the value of the "py_generic_services" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearPyGenericServices() {
      _hasBits0 &= ~16;
    }

    /// <summary>Field number for the "php_generic_services" field.</summary>
    public const int PhpGenericServicesFieldNumber = 42;
    private readonly static bool PhpGenericServicesDefaultValue = false;

    private bool phpGenericServices_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool PhpGenericServices {
      get { if ((_hasBits0 & 512) != 0) { return phpGenericServices_; } else { return PhpGenericServicesDefaultValue; } }
      set {
        _hasBits0 |= 512;
        phpGenericServices_ = value;
      }
    }
    /// <summary>Gets whether the "php_generic_services" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasPhpGenericServices {
      get { return (_hasBits0 & 512) != 0; }
    }
    /// <summary>Clears the value of the "php_generic_services" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearPhpGenericServices() {
      _hasBits0 &= ~512;
    }

    /// <summary>Field number for the "deprecated" field.</summary>
    public const int DeprecatedFieldNumber = 23;
    private readonly static bool DeprecatedDefaultValue = false;

    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 { if ((_hasBits0 & 64) != 0) { return deprecated_; } else { return DeprecatedDefaultValue; } }
      set {
        _hasBits0 |= 64;
        deprecated_ = value;
      }
    }
    /// <summary>Gets whether the "deprecated" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasDeprecated {
      get { return (_hasBits0 & 64) != 0; }
    }
    /// <summary>Clears the value of the "deprecated" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearDeprecated() {
      _hasBits0 &= ~64;
    }

    /// <summary>Field number for the "cc_enable_arenas" field.</summary>
    public const int CcEnableArenasFieldNumber = 31;
    private readonly static bool CcEnableArenasDefaultValue = false;

    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 { if ((_hasBits0 & 256) != 0) { return ccEnableArenas_; } else { return CcEnableArenasDefaultValue; } }
      set {
        _hasBits0 |= 256;
        ccEnableArenas_ = value;
      }
    }
    /// <summary>Gets whether the "cc_enable_arenas" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasCcEnableArenas {
      get { return (_hasBits0 & 256) != 0; }
    }
    /// <summary>Clears the value of the "cc_enable_arenas" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearCcEnableArenas() {
      _hasBits0 &= ~256;
    }

    /// <summary>Field number for the "objc_class_prefix" field.</summary>
    public const int ObjcClassPrefixFieldNumber = 36;
    private readonly static string ObjcClassPrefixDefaultValue = "";

    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_ ?? ObjcClassPrefixDefaultValue; }
      set {
        objcClassPrefix_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }
    /// <summary>Gets whether the "objc_class_prefix" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasObjcClassPrefix {
      get { return objcClassPrefix_ != null; }
    }
    /// <summary>Clears the value of the "objc_class_prefix" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearObjcClassPrefix() {
      objcClassPrefix_ = null;
    }

    /// <summary>Field number for the "csharp_namespace" field.</summary>
    public const int CsharpNamespaceFieldNumber = 37;
    private readonly static string CsharpNamespaceDefaultValue = "";

    private string csharpNamespace_;
    /// <summary>
    /// Namespace for generated classes; defaults to the package.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string CsharpNamespace {
      get { return csharpNamespace_ ?? CsharpNamespaceDefaultValue; }
      set {
        csharpNamespace_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }
    /// <summary>Gets whether the "csharp_namespace" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasCsharpNamespace {
      get { return csharpNamespace_ != null; }
    }
    /// <summary>Clears the value of the "csharp_namespace" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearCsharpNamespace() {
      csharpNamespace_ = null;
    }

    /// <summary>Field number for the "swift_prefix" field.</summary>
    public const int SwiftPrefixFieldNumber = 39;
    private readonly static string SwiftPrefixDefaultValue = "";

    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_ ?? SwiftPrefixDefaultValue; }
      set {
        swiftPrefix_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }
    /// <summary>Gets whether the "swift_prefix" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasSwiftPrefix {
      get { return swiftPrefix_ != null; }
    }
    /// <summary>Clears the value of the "swift_prefix" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearSwiftPrefix() {
      swiftPrefix_ = null;
    }

    /// <summary>Field number for the "php_class_prefix" field.</summary>
    public const int PhpClassPrefixFieldNumber = 40;
    private readonly static string PhpClassPrefixDefaultValue = "";

    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_ ?? PhpClassPrefixDefaultValue; }
      set {
        phpClassPrefix_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }
    /// <summary>Gets whether the "php_class_prefix" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasPhpClassPrefix {
      get { return phpClassPrefix_ != null; }
    }
    /// <summary>Clears the value of the "php_class_prefix" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearPhpClassPrefix() {
      phpClassPrefix_ = null;
    }

    /// <summary>Field number for the "php_namespace" field.</summary>
    public const int PhpNamespaceFieldNumber = 41;
    private readonly static string PhpNamespaceDefaultValue = "";

    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_ ?? PhpNamespaceDefaultValue; }
      set {
        phpNamespace_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }
    /// <summary>Gets whether the "php_namespace" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasPhpNamespace {
      get { return phpNamespace_ != null; }
    }
    /// <summary>Clears the value of the "php_namespace" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearPhpNamespace() {
      phpNamespace_ = null;
    }

    /// <summary>Field number for the "php_metadata_namespace" field.</summary>
    public const int PhpMetadataNamespaceFieldNumber = 44;
    private readonly static string PhpMetadataNamespaceDefaultValue = "";

    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_ ?? PhpMetadataNamespaceDefaultValue; }
      set {
        phpMetadataNamespace_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }
    /// <summary>Gets whether the "php_metadata_namespace" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasPhpMetadataNamespace {
      get { return phpMetadataNamespace_ != null; }
    }
    /// <summary>Clears the value of the "php_metadata_namespace" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearPhpMetadataNamespace() {
      phpMetadataNamespace_ = null;
    }

    /// <summary>Field number for the "ruby_package" field.</summary>
    public const int RubyPackageFieldNumber = 45;
    private readonly static string RubyPackageDefaultValue = "";

    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_ ?? RubyPackageDefaultValue; }
      set {
        rubyPackage_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }
    /// <summary>Gets whether the "ruby_package" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasRubyPackage {
      get { return rubyPackage_ != null; }
    }
    /// <summary>Clears the value of the "ruby_package" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearRubyPackage() {
      rubyPackage_ = null;
    }

    /// <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;
      if (!Equals(_extensions, other._extensions)) {
        return false;
      }
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (HasJavaPackage) hash ^= JavaPackage.GetHashCode();
      if (HasJavaOuterClassname) hash ^= JavaOuterClassname.GetHashCode();
      if (HasJavaMultipleFiles) hash ^= JavaMultipleFiles.GetHashCode();
      if (HasJavaGenerateEqualsAndHash) hash ^= JavaGenerateEqualsAndHash.GetHashCode();
      if (HasJavaStringCheckUtf8) hash ^= JavaStringCheckUtf8.GetHashCode();
      if (HasOptimizeFor) hash ^= OptimizeFor.GetHashCode();
      if (HasGoPackage) hash ^= GoPackage.GetHashCode();
      if (HasCcGenericServices) hash ^= CcGenericServices.GetHashCode();
      if (HasJavaGenericServices) hash ^= JavaGenericServices.GetHashCode();
      if (HasPyGenericServices) hash ^= PyGenericServices.GetHashCode();
      if (HasPhpGenericServices) hash ^= PhpGenericServices.GetHashCode();
      if (HasDeprecated) hash ^= Deprecated.GetHashCode();
      if (HasCcEnableArenas) hash ^= CcEnableArenas.GetHashCode();
      if (HasObjcClassPrefix) hash ^= ObjcClassPrefix.GetHashCode();
      if (HasCsharpNamespace) hash ^= CsharpNamespace.GetHashCode();
      if (HasSwiftPrefix) hash ^= SwiftPrefix.GetHashCode();
      if (HasPhpClassPrefix) hash ^= PhpClassPrefix.GetHashCode();
      if (HasPhpNamespace) hash ^= PhpNamespace.GetHashCode();
      if (HasPhpMetadataNamespace) hash ^= PhpMetadataNamespace.GetHashCode();
      if (HasRubyPackage) hash ^= RubyPackage.GetHashCode();
      hash ^= uninterpretedOption_.GetHashCode();
      if (_extensions != null) {
        hash ^= _extensions.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 (HasJavaPackage) {
        output.WriteRawTag(10);
        output.WriteString(JavaPackage);
      }
      if (HasJavaOuterClassname) {
        output.WriteRawTag(66);
        output.WriteString(JavaOuterClassname);
      }
      if (HasOptimizeFor) {
        output.WriteRawTag(72);
        output.WriteEnum((int) OptimizeFor);
      }
      if (HasJavaMultipleFiles) {
        output.WriteRawTag(80);
        output.WriteBool(JavaMultipleFiles);
      }
      if (HasGoPackage) {
        output.WriteRawTag(90);
        output.WriteString(GoPackage);
      }
      if (HasCcGenericServices) {
        output.WriteRawTag(128, 1);
        output.WriteBool(CcGenericServices);
      }
      if (HasJavaGenericServices) {
        output.WriteRawTag(136, 1);
        output.WriteBool(JavaGenericServices);
      }
      if (HasPyGenericServices) {
        output.WriteRawTag(144, 1);
        output.WriteBool(PyGenericServices);
      }
      if (HasJavaGenerateEqualsAndHash) {
        output.WriteRawTag(160, 1);
        output.WriteBool(JavaGenerateEqualsAndHash);
      }
      if (HasDeprecated) {
        output.WriteRawTag(184, 1);
        output.WriteBool(Deprecated);
      }
      if (HasJavaStringCheckUtf8) {
        output.WriteRawTag(216, 1);
        output.WriteBool(JavaStringCheckUtf8);
      }
      if (HasCcEnableArenas) {
        output.WriteRawTag(248, 1);
        output.WriteBool(CcEnableArenas);
      }
      if (HasObjcClassPrefix) {
        output.WriteRawTag(162, 2);
        output.WriteString(ObjcClassPrefix);
      }
      if (HasCsharpNamespace) {
        output.WriteRawTag(170, 2);
        output.WriteString(CsharpNamespace);
      }
      if (HasSwiftPrefix) {
        output.WriteRawTag(186, 2);
        output.WriteString(SwiftPrefix);
      }
      if (HasPhpClassPrefix) {
        output.WriteRawTag(194, 2);
        output.WriteString(PhpClassPrefix);
      }
      if (HasPhpNamespace) {
        output.WriteRawTag(202, 2);
        output.WriteString(PhpNamespace);
      }
      if (HasPhpGenericServices) {
        output.WriteRawTag(208, 2);
        output.WriteBool(PhpGenericServices);
      }
      if (HasPhpMetadataNamespace) {
        output.WriteRawTag(226, 2);
        output.WriteString(PhpMetadataNamespace);
      }
      if (HasRubyPackage) {
        output.WriteRawTag(234, 2);
        output.WriteString(RubyPackage);
      }
      uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
      if (_extensions != null) {
        _extensions.WriteTo(output);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (HasJavaPackage) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(JavaPackage);
      }
      if (HasJavaOuterClassname) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(JavaOuterClassname);
      }
      if (HasJavaMultipleFiles) {
        size += 1 + 1;
      }
      if (HasJavaGenerateEqualsAndHash) {
        size += 2 + 1;
      }
      if (HasJavaStringCheckUtf8) {
        size += 2 + 1;
      }
      if (HasOptimizeFor) {
        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) OptimizeFor);
      }
      if (HasGoPackage) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(GoPackage);
      }
      if (HasCcGenericServices) {
        size += 2 + 1;
      }
      if (HasJavaGenericServices) {
        size += 2 + 1;
      }
      if (HasPyGenericServices) {
        size += 2 + 1;
      }
      if (HasPhpGenericServices) {
        size += 2 + 1;
      }
      if (HasDeprecated) {
        size += 2 + 1;
      }
      if (HasCcEnableArenas) {
        size += 2 + 1;
      }
      if (HasObjcClassPrefix) {
        size += 2 + pb::CodedOutputStream.ComputeStringSize(ObjcClassPrefix);
      }
      if (HasCsharpNamespace) {
        size += 2 + pb::CodedOutputStream.ComputeStringSize(CsharpNamespace);
      }
      if (HasSwiftPrefix) {
        size += 2 + pb::CodedOutputStream.ComputeStringSize(SwiftPrefix);
      }
      if (HasPhpClassPrefix) {
        size += 2 + pb::CodedOutputStream.ComputeStringSize(PhpClassPrefix);
      }
      if (HasPhpNamespace) {
        size += 2 + pb::CodedOutputStream.ComputeStringSize(PhpNamespace);
      }
      if (HasPhpMetadataNamespace) {
        size += 2 + pb::CodedOutputStream.ComputeStringSize(PhpMetadataNamespace);
      }
      if (HasRubyPackage) {
        size += 2 + pb::CodedOutputStream.ComputeStringSize(RubyPackage);
      }
      size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec);
      if (_extensions != null) {
        size += _extensions.CalculateSize();
      }
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(FileOptions other) {
      if (other == null) {
        return;
      }
      if (other.HasJavaPackage) {
        JavaPackage = other.JavaPackage;
      }
      if (other.HasJavaOuterClassname) {
        JavaOuterClassname = other.JavaOuterClassname;
      }
      if (other.HasJavaMultipleFiles) {
        JavaMultipleFiles = other.JavaMultipleFiles;
      }
      if (other.HasJavaGenerateEqualsAndHash) {
        JavaGenerateEqualsAndHash = other.JavaGenerateEqualsAndHash;
      }
      if (other.HasJavaStringCheckUtf8) {
        JavaStringCheckUtf8 = other.JavaStringCheckUtf8;
      }
      if (other.HasOptimizeFor) {
        OptimizeFor = other.OptimizeFor;
      }
      if (other.HasGoPackage) {
        GoPackage = other.GoPackage;
      }
      if (other.HasCcGenericServices) {
        CcGenericServices = other.CcGenericServices;
      }
      if (other.HasJavaGenericServices) {
        JavaGenericServices = other.JavaGenericServices;
      }
      if (other.HasPyGenericServices) {
        PyGenericServices = other.PyGenericServices;
      }
      if (other.HasPhpGenericServices) {
        PhpGenericServices = other.PhpGenericServices;
      }
      if (other.HasDeprecated) {
        Deprecated = other.Deprecated;
      }
      if (other.HasCcEnableArenas) {
        CcEnableArenas = other.CcEnableArenas;
      }
      if (other.HasObjcClassPrefix) {
        ObjcClassPrefix = other.ObjcClassPrefix;
      }
      if (other.HasCsharpNamespace) {
        CsharpNamespace = other.CsharpNamespace;
      }
      if (other.HasSwiftPrefix) {
        SwiftPrefix = other.SwiftPrefix;
      }
      if (other.HasPhpClassPrefix) {
        PhpClassPrefix = other.PhpClassPrefix;
      }
      if (other.HasPhpNamespace) {
        PhpNamespace = other.PhpNamespace;
      }
      if (other.HasPhpMetadataNamespace) {
        PhpMetadataNamespace = other.PhpMetadataNamespace;
      }
      if (other.HasRubyPackage) {
        RubyPackage = other.RubyPackage;
      }
      uninterpretedOption_.Add(other.uninterpretedOption_);
      pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions);
      _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:
            if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, input)) {
              _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, 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;
          }
        }
      }
    }

    public TValue GetExtension<TValue>(pb::Extension<FileOptions, TValue> extension) {
      return pb::ExtensionSet.Get(ref _extensions, extension);
    }
    public pbc::RepeatedField<TValue> GetExtension<TValue>(pb::RepeatedExtension<FileOptions, TValue> extension) {
      return pb::ExtensionSet.Get(ref _extensions, extension);
    }
    public pbc::RepeatedField<TValue> GetOrInitializeExtension<TValue>(pb::RepeatedExtension<FileOptions, TValue> extension) {
      return pb::ExtensionSet.GetOrInitialize(ref _extensions, extension);
    }
    public void SetExtension<TValue>(pb::Extension<FileOptions, TValue> extension, TValue value) {
      pb::ExtensionSet.Set(ref _extensions, extension, value);
    }
    public bool HasExtension<TValue>(pb::Extension<FileOptions, TValue> extension) {
      return pb::ExtensionSet.Has(ref _extensions, extension);
    }
    public void ClearExtension<TValue>(pb::Extension<FileOptions, TValue> extension) {
      pb::ExtensionSet.Clear(ref _extensions, extension);
    }
    public void ClearExtension<TValue>(pb::RepeatedExtension<FileOptions, TValue> extension) {
      pb::ExtensionSet.Clear(ref _extensions, extension);
    }

    #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>
      public 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

  }

  public sealed partial class MessageOptions : pb::IExtendableMessage<MessageOptions> {
    private static readonly pb::MessageParser<MessageOptions> _parser = new pb::MessageParser<MessageOptions>(() => new MessageOptions());
    private pb::UnknownFieldSet _unknownFields;
    internal pb::ExtensionSet<MessageOptions> _extensions;
    private pb::ExtensionSet<MessageOptions> _Extensions => _extensions;
    private int _hasBits0;
    [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; }
    }

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

    partial void OnConstruction();

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

    [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 readonly static bool MessageSetWireFormatDefaultValue = false;

    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 { if ((_hasBits0 & 1) != 0) { return messageSetWireFormat_; } else { return MessageSetWireFormatDefaultValue; } }
      set {
        _hasBits0 |= 1;
        messageSetWireFormat_ = value;
      }
    }
    /// <summary>Gets whether the "message_set_wire_format" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasMessageSetWireFormat {
      get { return (_hasBits0 & 1) != 0; }
    }
    /// <summary>Clears the value of the "message_set_wire_format" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearMessageSetWireFormat() {
      _hasBits0 &= ~1;
    }

    /// <summary>Field number for the "no_standard_descriptor_accessor" field.</summary>
    public const int NoStandardDescriptorAccessorFieldNumber = 2;
    private readonly static bool NoStandardDescriptorAccessorDefaultValue = false;

    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 { if ((_hasBits0 & 2) != 0) { return noStandardDescriptorAccessor_; } else { return NoStandardDescriptorAccessorDefaultValue; } }
      set {
        _hasBits0 |= 2;
        noStandardDescriptorAccessor_ = value;
      }
    }
    /// <summary>Gets whether the "no_standard_descriptor_accessor" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasNoStandardDescriptorAccessor {
      get { return (_hasBits0 & 2) != 0; }
    }
    /// <summary>Clears the value of the "no_standard_descriptor_accessor" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearNoStandardDescriptorAccessor() {
      _hasBits0 &= ~2;
    }

    /// <summary>Field number for the "deprecated" field.</summary>
    public const int DeprecatedFieldNumber = 3;
    private readonly static bool DeprecatedDefaultValue = false;

    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 { if ((_hasBits0 & 4) != 0) { return deprecated_; } else { return DeprecatedDefaultValue; } }
      set {
        _hasBits0 |= 4;
        deprecated_ = value;
      }
    }
    /// <summary>Gets whether the "deprecated" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasDeprecated {
      get { return (_hasBits0 & 4) != 0; }
    }
    /// <summary>Clears the value of the "deprecated" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearDeprecated() {
      _hasBits0 &= ~4;
    }

    /// <summary>Field number for the "map_entry" field.</summary>
    public const int MapEntryFieldNumber = 7;
    private readonly static bool MapEntryDefaultValue = false;

    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 implementations 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 { if ((_hasBits0 & 8) != 0) { return mapEntry_; } else { return MapEntryDefaultValue; } }
      set {
        _hasBits0 |= 8;
        mapEntry_ = value;
      }
    }
    /// <summary>Gets whether the "map_entry" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasMapEntry {
      get { return (_hasBits0 & 8) != 0; }
    }
    /// <summary>Clears the value of the "map_entry" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearMapEntry() {
      _hasBits0 &= ~8;
    }

    /// <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;
      if (!Equals(_extensions, other._extensions)) {
        return false;
      }
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (HasMessageSetWireFormat) hash ^= MessageSetWireFormat.GetHashCode();
      if (HasNoStandardDescriptorAccessor) hash ^= NoStandardDescriptorAccessor.GetHashCode();
      if (HasDeprecated) hash ^= Deprecated.GetHashCode();
      if (HasMapEntry) hash ^= MapEntry.GetHashCode();
      hash ^= uninterpretedOption_.GetHashCode();
      if (_extensions != null) {
        hash ^= _extensions.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 (HasMessageSetWireFormat) {
        output.WriteRawTag(8);
        output.WriteBool(MessageSetWireFormat);
      }
      if (HasNoStandardDescriptorAccessor) {
        output.WriteRawTag(16);
        output.WriteBool(NoStandardDescriptorAccessor);
      }
      if (HasDeprecated) {
        output.WriteRawTag(24);
        output.WriteBool(Deprecated);
      }
      if (HasMapEntry) {
        output.WriteRawTag(56);
        output.WriteBool(MapEntry);
      }
      uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
      if (_extensions != null) {
        _extensions.WriteTo(output);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(MessageOptions other) {
      if (other == null) {
        return;
      }
      if (other.HasMessageSetWireFormat) {
        MessageSetWireFormat = other.MessageSetWireFormat;
      }
      if (other.HasNoStandardDescriptorAccessor) {
        NoStandardDescriptorAccessor = other.NoStandardDescriptorAccessor;
      }
      if (other.HasDeprecated) {
        Deprecated = other.Deprecated;
      }
      if (other.HasMapEntry) {
        MapEntry = other.MapEntry;
      }
      uninterpretedOption_.Add(other.uninterpretedOption_);
      pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions);
      _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:
            if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, input)) {
              _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, 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;
          }
        }
      }
    }

    public TValue GetExtension<TValue>(pb::Extension<MessageOptions, TValue> extension) {
      return pb::ExtensionSet.Get(ref _extensions, extension);
    }
    public pbc::RepeatedField<TValue> GetExtension<TValue>(pb::RepeatedExtension<MessageOptions, TValue> extension) {
      return pb::ExtensionSet.Get(ref _extensions, extension);
    }
    public pbc::RepeatedField<TValue> GetOrInitializeExtension<TValue>(pb::RepeatedExtension<MessageOptions, TValue> extension) {
      return pb::ExtensionSet.GetOrInitialize(ref _extensions, extension);
    }
    public void SetExtension<TValue>(pb::Extension<MessageOptions, TValue> extension, TValue value) {
      pb::ExtensionSet.Set(ref _extensions, extension, value);
    }
    public bool HasExtension<TValue>(pb::Extension<MessageOptions, TValue> extension) {
      return pb::ExtensionSet.Has(ref _extensions, extension);
    }
    public void ClearExtension<TValue>(pb::Extension<MessageOptions, TValue> extension) {
      pb::ExtensionSet.Clear(ref _extensions, extension);
    }
    public void ClearExtension<TValue>(pb::RepeatedExtension<MessageOptions, TValue> extension) {
      pb::ExtensionSet.Clear(ref _extensions, extension);
    }

  }

  public sealed partial class FieldOptions : pb::IExtendableMessage<FieldOptions> {
    private static readonly pb::MessageParser<FieldOptions> _parser = new pb::MessageParser<FieldOptions>(() => new FieldOptions());
    private pb::UnknownFieldSet _unknownFields;
    internal pb::ExtensionSet<FieldOptions> _extensions;
    private pb::ExtensionSet<FieldOptions> _Extensions => _extensions;
    private int _hasBits0;
    [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; }
    }

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

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public FieldOptions(FieldOptions other) : this() {
      _hasBits0 = other._hasBits0;
      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);
      _extensions = pb::ExtensionSet.Clone(other._extensions);
    }

    [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 readonly static global::Google.Protobuf.Reflection.FieldOptions.Types.CType CtypeDefaultValue = global::Google.Protobuf.Reflection.FieldOptions.Types.CType.String;

    private global::Google.Protobuf.Reflection.FieldOptions.Types.CType ctype_;
    /// <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 { if ((_hasBits0 & 1) != 0) { return ctype_; } else { return CtypeDefaultValue; } }
      set {
        _hasBits0 |= 1;
        ctype_ = value;
      }
    }
    /// <summary>Gets whether the "ctype" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasCtype {
      get { return (_hasBits0 & 1) != 0; }
    }
    /// <summary>Clears the value of the "ctype" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearCtype() {
      _hasBits0 &= ~1;
    }

    /// <summary>Field number for the "packed" field.</summary>
    public const int PackedFieldNumber = 2;
    private readonly static bool PackedDefaultValue = false;

    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 { if ((_hasBits0 & 2) != 0) { return packed_; } else { return PackedDefaultValue; } }
      set {
        _hasBits0 |= 2;
        packed_ = value;
      }
    }
    /// <summary>Gets whether the "packed" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasPacked {
      get { return (_hasBits0 & 2) != 0; }
    }
    /// <summary>Clears the value of the "packed" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearPacked() {
      _hasBits0 &= ~2;
    }

    /// <summary>Field number for the "jstype" field.</summary>
    public const int JstypeFieldNumber = 6;
    private readonly static global::Google.Protobuf.Reflection.FieldOptions.Types.JSType JstypeDefaultValue = global::Google.Protobuf.Reflection.FieldOptions.Types.JSType.JsNormal;

    private global::Google.Protobuf.Reflection.FieldOptions.Types.JSType jstype_;
    /// <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 { if ((_hasBits0 & 16) != 0) { return jstype_; } else { return JstypeDefaultValue; } }
      set {
        _hasBits0 |= 16;
        jstype_ = value;
      }
    }
    /// <summary>Gets whether the "jstype" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasJstype {
      get { return (_hasBits0 & 16) != 0; }
    }
    /// <summary>Clears the value of the "jstype" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearJstype() {
      _hasBits0 &= ~16;
    }

    /// <summary>Field number for the "lazy" field.</summary>
    public const int LazyFieldNumber = 5;
    private readonly static bool LazyDefaultValue = false;

    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 { if ((_hasBits0 & 8) != 0) { return lazy_; } else { return LazyDefaultValue; } }
      set {
        _hasBits0 |= 8;
        lazy_ = value;
      }
    }
    /// <summary>Gets whether the "lazy" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasLazy {
      get { return (_hasBits0 & 8) != 0; }
    }
    /// <summary>Clears the value of the "lazy" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearLazy() {
      _hasBits0 &= ~8;
    }

    /// <summary>Field number for the "deprecated" field.</summary>
    public const int DeprecatedFieldNumber = 3;
    private readonly static bool DeprecatedDefaultValue = false;

    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 { if ((_hasBits0 & 4) != 0) { return deprecated_; } else { return DeprecatedDefaultValue; } }
      set {
        _hasBits0 |= 4;
        deprecated_ = value;
      }
    }
    /// <summary>Gets whether the "deprecated" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasDeprecated {
      get { return (_hasBits0 & 4) != 0; }
    }
    /// <summary>Clears the value of the "deprecated" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearDeprecated() {
      _hasBits0 &= ~4;
    }

    /// <summary>Field number for the "weak" field.</summary>
    public const int WeakFieldNumber = 10;
    private readonly static bool WeakDefaultValue = false;

    private bool weak_;
    /// <summary>
    /// For Google-internal migration only. Do not use.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Weak {
      get { if ((_hasBits0 & 32) != 0) { return weak_; } else { return WeakDefaultValue; } }
      set {
        _hasBits0 |= 32;
        weak_ = value;
      }
    }
    /// <summary>Gets whether the "weak" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasWeak {
      get { return (_hasBits0 & 32) != 0; }
    }
    /// <summary>Clears the value of the "weak" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearWeak() {
      _hasBits0 &= ~32;
    }

    /// <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;
      if (!Equals(_extensions, other._extensions)) {
        return false;
      }
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (HasCtype) hash ^= Ctype.GetHashCode();
      if (HasPacked) hash ^= Packed.GetHashCode();
      if (HasJstype) hash ^= Jstype.GetHashCode();
      if (HasLazy) hash ^= Lazy.GetHashCode();
      if (HasDeprecated) hash ^= Deprecated.GetHashCode();
      if (HasWeak) hash ^= Weak.GetHashCode();
      hash ^= uninterpretedOption_.GetHashCode();
      if (_extensions != null) {
        hash ^= _extensions.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 (HasCtype) {
        output.WriteRawTag(8);
        output.WriteEnum((int) Ctype);
      }
      if (HasPacked) {
        output.WriteRawTag(16);
        output.WriteBool(Packed);
      }
      if (HasDeprecated) {
        output.WriteRawTag(24);
        output.WriteBool(Deprecated);
      }
      if (HasLazy) {
        output.WriteRawTag(40);
        output.WriteBool(Lazy);
      }
      if (HasJstype) {
        output.WriteRawTag(48);
        output.WriteEnum((int) Jstype);
      }
      if (HasWeak) {
        output.WriteRawTag(80);
        output.WriteBool(Weak);
      }
      uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
      if (_extensions != null) {
        _extensions.WriteTo(output);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (HasCtype) {
        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Ctype);
      }
      if (HasPacked) {
        size += 1 + 1;
      }
      if (HasJstype) {
        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Jstype);
      }
      if (HasLazy) {
        size += 1 + 1;
      }
      if (HasDeprecated) {
        size += 1 + 1;
      }
      if (HasWeak) {
        size += 1 + 1;
      }
      size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec);
      if (_extensions != null) {
        size += _extensions.CalculateSize();
      }
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(FieldOptions other) {
      if (other == null) {
        return;
      }
      if (other.HasCtype) {
        Ctype = other.Ctype;
      }
      if (other.HasPacked) {
        Packed = other.Packed;
      }
      if (other.HasJstype) {
        Jstype = other.Jstype;
      }
      if (other.HasLazy) {
        Lazy = other.Lazy;
      }
      if (other.HasDeprecated) {
        Deprecated = other.Deprecated;
      }
      if (other.HasWeak) {
        Weak = other.Weak;
      }
      uninterpretedOption_.Add(other.uninterpretedOption_);
      pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions);
      _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:
            if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, input)) {
              _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, 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;
          }
        }
      }
    }

    public TValue GetExtension<TValue>(pb::Extension<FieldOptions, TValue> extension) {
      return pb::ExtensionSet.Get(ref _extensions, extension);
    }
    public pbc::RepeatedField<TValue> GetExtension<TValue>(pb::RepeatedExtension<FieldOptions, TValue> extension) {
      return pb::ExtensionSet.Get(ref _extensions, extension);
    }
    public pbc::RepeatedField<TValue> GetOrInitializeExtension<TValue>(pb::RepeatedExtension<FieldOptions, TValue> extension) {
      return pb::ExtensionSet.GetOrInitialize(ref _extensions, extension);
    }
    public void SetExtension<TValue>(pb::Extension<FieldOptions, TValue> extension, TValue value) {
      pb::ExtensionSet.Set(ref _extensions, extension, value);
    }
    public bool HasExtension<TValue>(pb::Extension<FieldOptions, TValue> extension) {
      return pb::ExtensionSet.Has(ref _extensions, extension);
    }
    public void ClearExtension<TValue>(pb::Extension<FieldOptions, TValue> extension) {
      pb::ExtensionSet.Clear(ref _extensions, extension);
    }
    public void ClearExtension<TValue>(pb::RepeatedExtension<FieldOptions, TValue> extension) {
      pb::ExtensionSet.Clear(ref _extensions, extension);
    }

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

      public 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

  }

  public sealed partial class OneofOptions : pb::IExtendableMessage<OneofOptions> {
    private static readonly pb::MessageParser<OneofOptions> _parser = new pb::MessageParser<OneofOptions>(() => new OneofOptions());
    private pb::UnknownFieldSet _unknownFields;
    internal pb::ExtensionSet<OneofOptions> _extensions;
    private pb::ExtensionSet<OneofOptions> _Extensions => _extensions;
    [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; }
    }

    [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);
      _extensions = pb::ExtensionSet.Clone(other._extensions);
    }

    [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;
      if (!Equals(_extensions, other._extensions)) {
        return false;
      }
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      hash ^= uninterpretedOption_.GetHashCode();
      if (_extensions != null) {
        hash ^= _extensions.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 (_extensions != null) {
        _extensions.WriteTo(output);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec);
      if (_extensions != null) {
        size += _extensions.CalculateSize();
      }
      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_);
      pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions);
      _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:
            if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, input)) {
              _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            }
            break;
          case 7994: {
            uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec);
            break;
          }
        }
      }
    }

    public TValue GetExtension<TValue>(pb::Extension<OneofOptions, TValue> extension) {
      return pb::ExtensionSet.Get(ref _extensions, extension);
    }
    public pbc::RepeatedField<TValue> GetExtension<TValue>(pb::RepeatedExtension<OneofOptions, TValue> extension) {
      return pb::ExtensionSet.Get(ref _extensions, extension);
    }
    public pbc::RepeatedField<TValue> GetOrInitializeExtension<TValue>(pb::RepeatedExtension<OneofOptions, TValue> extension) {
      return pb::ExtensionSet.GetOrInitialize(ref _extensions, extension);
    }
    public void SetExtension<TValue>(pb::Extension<OneofOptions, TValue> extension, TValue value) {
      pb::ExtensionSet.Set(ref _extensions, extension, value);
    }
    public bool HasExtension<TValue>(pb::Extension<OneofOptions, TValue> extension) {
      return pb::ExtensionSet.Has(ref _extensions, extension);
    }
    public void ClearExtension<TValue>(pb::Extension<OneofOptions, TValue> extension) {
      pb::ExtensionSet.Clear(ref _extensions, extension);
    }
    public void ClearExtension<TValue>(pb::RepeatedExtension<OneofOptions, TValue> extension) {
      pb::ExtensionSet.Clear(ref _extensions, extension);
    }

  }

  public sealed partial class EnumOptions : pb::IExtendableMessage<EnumOptions> {
    private static readonly pb::MessageParser<EnumOptions> _parser = new pb::MessageParser<EnumOptions>(() => new EnumOptions());
    private pb::UnknownFieldSet _unknownFields;
    internal pb::ExtensionSet<EnumOptions> _extensions;
    private pb::ExtensionSet<EnumOptions> _Extensions => _extensions;
    private int _hasBits0;
    [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; }
    }

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

    partial void OnConstruction();

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

    [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 readonly static bool AllowAliasDefaultValue = false;

    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 { if ((_hasBits0 & 1) != 0) { return allowAlias_; } else { return AllowAliasDefaultValue; } }
      set {
        _hasBits0 |= 1;
        allowAlias_ = value;
      }
    }
    /// <summary>Gets whether the "allow_alias" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasAllowAlias {
      get { return (_hasBits0 & 1) != 0; }
    }
    /// <summary>Clears the value of the "allow_alias" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearAllowAlias() {
      _hasBits0 &= ~1;
    }

    /// <summary>Field number for the "deprecated" field.</summary>
    public const int DeprecatedFieldNumber = 3;
    private readonly static bool DeprecatedDefaultValue = false;

    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 { if ((_hasBits0 & 2) != 0) { return deprecated_; } else { return DeprecatedDefaultValue; } }
      set {
        _hasBits0 |= 2;
        deprecated_ = value;
      }
    }
    /// <summary>Gets whether the "deprecated" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasDeprecated {
      get { return (_hasBits0 & 2) != 0; }
    }
    /// <summary>Clears the value of the "deprecated" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearDeprecated() {
      _hasBits0 &= ~2;
    }

    /// <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;
      if (!Equals(_extensions, other._extensions)) {
        return false;
      }
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (HasAllowAlias) hash ^= AllowAlias.GetHashCode();
      if (HasDeprecated) hash ^= Deprecated.GetHashCode();
      hash ^= uninterpretedOption_.GetHashCode();
      if (_extensions != null) {
        hash ^= _extensions.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 (HasAllowAlias) {
        output.WriteRawTag(16);
        output.WriteBool(AllowAlias);
      }
      if (HasDeprecated) {
        output.WriteRawTag(24);
        output.WriteBool(Deprecated);
      }
      uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
      if (_extensions != null) {
        _extensions.WriteTo(output);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(EnumOptions other) {
      if (other == null) {
        return;
      }
      if (other.HasAllowAlias) {
        AllowAlias = other.AllowAlias;
      }
      if (other.HasDeprecated) {
        Deprecated = other.Deprecated;
      }
      uninterpretedOption_.Add(other.uninterpretedOption_);
      pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions);
      _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:
            if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, input)) {
              _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            }
            break;
          case 16: {
            AllowAlias = input.ReadBool();
            break;
          }
          case 24: {
            Deprecated = input.ReadBool();
            break;
          }
          case 7994: {
            uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec);
            break;
          }
        }
      }
    }

    public TValue GetExtension<TValue>(pb::Extension<EnumOptions, TValue> extension) {
      return pb::ExtensionSet.Get(ref _extensions, extension);
    }
    public pbc::RepeatedField<TValue> GetExtension<TValue>(pb::RepeatedExtension<EnumOptions, TValue> extension) {
      return pb::ExtensionSet.Get(ref _extensions, extension);
    }
    public pbc::RepeatedField<TValue> GetOrInitializeExtension<TValue>(pb::RepeatedExtension<EnumOptions, TValue> extension) {
      return pb::ExtensionSet.GetOrInitialize(ref _extensions, extension);
    }
    public void SetExtension<TValue>(pb::Extension<EnumOptions, TValue> extension, TValue value) {
      pb::ExtensionSet.Set(ref _extensions, extension, value);
    }
    public bool HasExtension<TValue>(pb::Extension<EnumOptions, TValue> extension) {
      return pb::ExtensionSet.Has(ref _extensions, extension);
    }
    public void ClearExtension<TValue>(pb::Extension<EnumOptions, TValue> extension) {
      pb::ExtensionSet.Clear(ref _extensions, extension);
    }
    public void ClearExtension<TValue>(pb::RepeatedExtension<EnumOptions, TValue> extension) {
      pb::ExtensionSet.Clear(ref _extensions, extension);
    }

  }

  public sealed partial class EnumValueOptions : pb::IExtendableMessage<EnumValueOptions> {
    private static readonly pb::MessageParser<EnumValueOptions> _parser = new pb::MessageParser<EnumValueOptions>(() => new EnumValueOptions());
    private pb::UnknownFieldSet _unknownFields;
    internal pb::ExtensionSet<EnumValueOptions> _extensions;
    private pb::ExtensionSet<EnumValueOptions> _Extensions => _extensions;
    private int _hasBits0;
    [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; }
    }

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

    partial void OnConstruction();

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

    [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 readonly static bool DeprecatedDefaultValue = false;

    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 { if ((_hasBits0 & 1) != 0) { return deprecated_; } else { return DeprecatedDefaultValue; } }
      set {
        _hasBits0 |= 1;
        deprecated_ = value;
      }
    }
    /// <summary>Gets whether the "deprecated" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasDeprecated {
      get { return (_hasBits0 & 1) != 0; }
    }
    /// <summary>Clears the value of the "deprecated" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearDeprecated() {
      _hasBits0 &= ~1;
    }

    /// <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;
      if (!Equals(_extensions, other._extensions)) {
        return false;
      }
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (HasDeprecated) hash ^= Deprecated.GetHashCode();
      hash ^= uninterpretedOption_.GetHashCode();
      if (_extensions != null) {
        hash ^= _extensions.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 (HasDeprecated) {
        output.WriteRawTag(8);
        output.WriteBool(Deprecated);
      }
      uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
      if (_extensions != null) {
        _extensions.WriteTo(output);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(EnumValueOptions other) {
      if (other == null) {
        return;
      }
      if (other.HasDeprecated) {
        Deprecated = other.Deprecated;
      }
      uninterpretedOption_.Add(other.uninterpretedOption_);
      pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions);
      _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:
            if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, input)) {
              _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            }
            break;
          case 8: {
            Deprecated = input.ReadBool();
            break;
          }
          case 7994: {
            uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec);
            break;
          }
        }
      }
    }

    public TValue GetExtension<TValue>(pb::Extension<EnumValueOptions, TValue> extension) {
      return pb::ExtensionSet.Get(ref _extensions, extension);
    }
    public pbc::RepeatedField<TValue> GetExtension<TValue>(pb::RepeatedExtension<EnumValueOptions, TValue> extension) {
      return pb::ExtensionSet.Get(ref _extensions, extension);
    }
    public pbc::RepeatedField<TValue> GetOrInitializeExtension<TValue>(pb::RepeatedExtension<EnumValueOptions, TValue> extension) {
      return pb::ExtensionSet.GetOrInitialize(ref _extensions, extension);
    }
    public void SetExtension<TValue>(pb::Extension<EnumValueOptions, TValue> extension, TValue value) {
      pb::ExtensionSet.Set(ref _extensions, extension, value);
    }
    public bool HasExtension<TValue>(pb::Extension<EnumValueOptions, TValue> extension) {
      return pb::ExtensionSet.Has(ref _extensions, extension);
    }
    public void ClearExtension<TValue>(pb::Extension<EnumValueOptions, TValue> extension) {
      pb::ExtensionSet.Clear(ref _extensions, extension);
    }
    public void ClearExtension<TValue>(pb::RepeatedExtension<EnumValueOptions, TValue> extension) {
      pb::ExtensionSet.Clear(ref _extensions, extension);
    }

  }

  public sealed partial class ServiceOptions : pb::IExtendableMessage<ServiceOptions> {
    private static readonly pb::MessageParser<ServiceOptions> _parser = new pb::MessageParser<ServiceOptions>(() => new ServiceOptions());
    private pb::UnknownFieldSet _unknownFields;
    internal pb::ExtensionSet<ServiceOptions> _extensions;
    private pb::ExtensionSet<ServiceOptions> _Extensions => _extensions;
    private int _hasBits0;
    [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; }
    }

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

    partial void OnConstruction();

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

    [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 readonly static bool DeprecatedDefaultValue = false;

    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 { if ((_hasBits0 & 1) != 0) { return deprecated_; } else { return DeprecatedDefaultValue; } }
      set {
        _hasBits0 |= 1;
        deprecated_ = value;
      }
    }
    /// <summary>Gets whether the "deprecated" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasDeprecated {
      get { return (_hasBits0 & 1) != 0; }
    }
    /// <summary>Clears the value of the "deprecated" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearDeprecated() {
      _hasBits0 &= ~1;
    }

    /// <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;
      if (!Equals(_extensions, other._extensions)) {
        return false;
      }
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (HasDeprecated) hash ^= Deprecated.GetHashCode();
      hash ^= uninterpretedOption_.GetHashCode();
      if (_extensions != null) {
        hash ^= _extensions.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 (HasDeprecated) {
        output.WriteRawTag(136, 2);
        output.WriteBool(Deprecated);
      }
      uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
      if (_extensions != null) {
        _extensions.WriteTo(output);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(ServiceOptions other) {
      if (other == null) {
        return;
      }
      if (other.HasDeprecated) {
        Deprecated = other.Deprecated;
      }
      uninterpretedOption_.Add(other.uninterpretedOption_);
      pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions);
      _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:
            if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, input)) {
              _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            }
            break;
          case 264: {
            Deprecated = input.ReadBool();
            break;
          }
          case 7994: {
            uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec);
            break;
          }
        }
      }
    }

    public TValue GetExtension<TValue>(pb::Extension<ServiceOptions, TValue> extension) {
      return pb::ExtensionSet.Get(ref _extensions, extension);
    }
    public pbc::RepeatedField<TValue> GetExtension<TValue>(pb::RepeatedExtension<ServiceOptions, TValue> extension) {
      return pb::ExtensionSet.Get(ref _extensions, extension);
    }
    public pbc::RepeatedField<TValue> GetOrInitializeExtension<TValue>(pb::RepeatedExtension<ServiceOptions, TValue> extension) {
      return pb::ExtensionSet.GetOrInitialize(ref _extensions, extension);
    }
    public void SetExtension<TValue>(pb::Extension<ServiceOptions, TValue> extension, TValue value) {
      pb::ExtensionSet.Set(ref _extensions, extension, value);
    }
    public bool HasExtension<TValue>(pb::Extension<ServiceOptions, TValue> extension) {
      return pb::ExtensionSet.Has(ref _extensions, extension);
    }
    public void ClearExtension<TValue>(pb::Extension<ServiceOptions, TValue> extension) {
      pb::ExtensionSet.Clear(ref _extensions, extension);
    }
    public void ClearExtension<TValue>(pb::RepeatedExtension<ServiceOptions, TValue> extension) {
      pb::ExtensionSet.Clear(ref _extensions, extension);
    }

  }

  public sealed partial class MethodOptions : pb::IExtendableMessage<MethodOptions> {
    private static readonly pb::MessageParser<MethodOptions> _parser = new pb::MessageParser<MethodOptions>(() => new MethodOptions());
    private pb::UnknownFieldSet _unknownFields;
    internal pb::ExtensionSet<MethodOptions> _extensions;
    private pb::ExtensionSet<MethodOptions> _Extensions => _extensions;
    private int _hasBits0;
    [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; }
    }

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

    partial void OnConstruction();

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

    [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 readonly static bool DeprecatedDefaultValue = false;

    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 { if ((_hasBits0 & 1) != 0) { return deprecated_; } else { return DeprecatedDefaultValue; } }
      set {
        _hasBits0 |= 1;
        deprecated_ = value;
      }
    }
    /// <summary>Gets whether the "deprecated" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasDeprecated {
      get { return (_hasBits0 & 1) != 0; }
    }
    /// <summary>Clears the value of the "deprecated" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearDeprecated() {
      _hasBits0 &= ~1;
    }

    /// <summary>Field number for the "idempotency_level" field.</summary>
    public const int IdempotencyLevelFieldNumber = 34;
    private readonly static global::Google.Protobuf.Reflection.MethodOptions.Types.IdempotencyLevel IdempotencyLevelDefaultValue = global::Google.Protobuf.Reflection.MethodOptions.Types.IdempotencyLevel.IdempotencyUnknown;

    private global::Google.Protobuf.Reflection.MethodOptions.Types.IdempotencyLevel idempotencyLevel_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public global::Google.Protobuf.Reflection.MethodOptions.Types.IdempotencyLevel IdempotencyLevel {
      get { if ((_hasBits0 & 2) != 0) { return idempotencyLevel_; } else { return IdempotencyLevelDefaultValue; } }
      set {
        _hasBits0 |= 2;
        idempotencyLevel_ = value;
      }
    }
    /// <summary>Gets whether the "idempotency_level" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasIdempotencyLevel {
      get { return (_hasBits0 & 2) != 0; }
    }
    /// <summary>Clears the value of the "idempotency_level" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearIdempotencyLevel() {
      _hasBits0 &= ~2;
    }

    /// <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;
      if (!Equals(_extensions, other._extensions)) {
        return false;
      }
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (HasDeprecated) hash ^= Deprecated.GetHashCode();
      if (HasIdempotencyLevel) hash ^= IdempotencyLevel.GetHashCode();
      hash ^= uninterpretedOption_.GetHashCode();
      if (_extensions != null) {
        hash ^= _extensions.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 (HasDeprecated) {
        output.WriteRawTag(136, 2);
        output.WriteBool(Deprecated);
      }
      if (HasIdempotencyLevel) {
        output.WriteRawTag(144, 2);
        output.WriteEnum((int) IdempotencyLevel);
      }
      uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
      if (_extensions != null) {
        _extensions.WriteTo(output);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(MethodOptions other) {
      if (other == null) {
        return;
      }
      if (other.HasDeprecated) {
        Deprecated = other.Deprecated;
      }
      if (other.HasIdempotencyLevel) {
        IdempotencyLevel = other.IdempotencyLevel;
      }
      uninterpretedOption_.Add(other.uninterpretedOption_);
      pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions);
      _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:
            if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, input)) {
              _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, 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;
          }
        }
      }
    }

    public TValue GetExtension<TValue>(pb::Extension<MethodOptions, TValue> extension) {
      return pb::ExtensionSet.Get(ref _extensions, extension);
    }
    public pbc::RepeatedField<TValue> GetExtension<TValue>(pb::RepeatedExtension<MethodOptions, TValue> extension) {
      return pb::ExtensionSet.Get(ref _extensions, extension);
    }
    public pbc::RepeatedField<TValue> GetOrInitializeExtension<TValue>(pb::RepeatedExtension<MethodOptions, TValue> extension) {
      return pb::ExtensionSet.GetOrInitialize(ref _extensions, extension);
    }
    public void SetExtension<TValue>(pb::Extension<MethodOptions, TValue> extension, TValue value) {
      pb::ExtensionSet.Set(ref _extensions, extension, value);
    }
    public bool HasExtension<TValue>(pb::Extension<MethodOptions, TValue> extension) {
      return pb::ExtensionSet.Has(ref _extensions, extension);
    }
    public void ClearExtension<TValue>(pb::Extension<MethodOptions, TValue> extension) {
      pb::ExtensionSet.Clear(ref _extensions, extension);
    }
    public void ClearExtension<TValue>(pb::RepeatedExtension<MethodOptions, TValue> extension) {
      pb::ExtensionSet.Clear(ref _extensions, extension);
    }

    #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>
      public 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>
  public sealed partial class UninterpretedOption : pb::IMessage<UninterpretedOption> {
    private static readonly pb::MessageParser<UninterpretedOption> _parser = new pb::MessageParser<UninterpretedOption>(() => new UninterpretedOption());
    private pb::UnknownFieldSet _unknownFields;
    private int _hasBits0;
    [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() {
      _hasBits0 = other._hasBits0;
      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 readonly static string IdentifierValueDefaultValue = "";

    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_ ?? IdentifierValueDefaultValue; }
      set {
        identifierValue_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }
    /// <summary>Gets whether the "identifier_value" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasIdentifierValue {
      get { return identifierValue_ != null; }
    }
    /// <summary>Clears the value of the "identifier_value" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearIdentifierValue() {
      identifierValue_ = null;
    }

    /// <summary>Field number for the "positive_int_value" field.</summary>
    public const int PositiveIntValueFieldNumber = 4;
    private readonly static ulong PositiveIntValueDefaultValue = 0UL;

    private ulong positiveIntValue_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public ulong PositiveIntValue {
      get { if ((_hasBits0 & 1) != 0) { return positiveIntValue_; } else { return PositiveIntValueDefaultValue; } }
      set {
        _hasBits0 |= 1;
        positiveIntValue_ = value;
      }
    }
    /// <summary>Gets whether the "positive_int_value" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasPositiveIntValue {
      get { return (_hasBits0 & 1) != 0; }
    }
    /// <summary>Clears the value of the "positive_int_value" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearPositiveIntValue() {
      _hasBits0 &= ~1;
    }

    /// <summary>Field number for the "negative_int_value" field.</summary>
    public const int NegativeIntValueFieldNumber = 5;
    private readonly static long NegativeIntValueDefaultValue = 0L;

    private long negativeIntValue_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public long NegativeIntValue {
      get { if ((_hasBits0 & 2) != 0) { return negativeIntValue_; } else { return NegativeIntValueDefaultValue; } }
      set {
        _hasBits0 |= 2;
        negativeIntValue_ = value;
      }
    }
    /// <summary>Gets whether the "negative_int_value" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasNegativeIntValue {
      get { return (_hasBits0 & 2) != 0; }
    }
    /// <summary>Clears the value of the "negative_int_value" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearNegativeIntValue() {
      _hasBits0 &= ~2;
    }

    /// <summary>Field number for the "double_value" field.</summary>
    public const int DoubleValueFieldNumber = 6;
    private readonly static double DoubleValueDefaultValue = 0D;

    private double doubleValue_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public double DoubleValue {
      get { if ((_hasBits0 & 4) != 0) { return doubleValue_; } else { return DoubleValueDefaultValue; } }
      set {
        _hasBits0 |= 4;
        doubleValue_ = value;
      }
    }
    /// <summary>Gets whether the "double_value" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasDoubleValue {
      get { return (_hasBits0 & 4) != 0; }
    }
    /// <summary>Clears the value of the "double_value" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearDoubleValue() {
      _hasBits0 &= ~4;
    }

    /// <summary>Field number for the "string_value" field.</summary>
    public const int StringValueFieldNumber = 7;
    private readonly static pb::ByteString StringValueDefaultValue = pb::ByteString.Empty;

    private pb::ByteString stringValue_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pb::ByteString StringValue {
      get { return stringValue_ ?? StringValueDefaultValue; }
      set {
        stringValue_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }
    /// <summary>Gets whether the "string_value" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasStringValue {
      get { return stringValue_ != null; }
    }
    /// <summary>Clears the value of the "string_value" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearStringValue() {
      stringValue_ = null;
    }

    /// <summary>Field number for the "aggregate_value" field.</summary>
    public const int AggregateValueFieldNumber = 8;
    private readonly static string AggregateValueDefaultValue = "";

    private string aggregateValue_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string AggregateValue {
      get { return aggregateValue_ ?? AggregateValueDefaultValue; }
      set {
        aggregateValue_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }
    /// <summary>Gets whether the "aggregate_value" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasAggregateValue {
      get { return aggregateValue_ != null; }
    }
    /// <summary>Clears the value of the "aggregate_value" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearAggregateValue() {
      aggregateValue_ = null;
    }

    [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 (HasIdentifierValue) hash ^= IdentifierValue.GetHashCode();
      if (HasPositiveIntValue) hash ^= PositiveIntValue.GetHashCode();
      if (HasNegativeIntValue) hash ^= NegativeIntValue.GetHashCode();
      if (HasDoubleValue) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleValue);
      if (HasStringValue) hash ^= StringValue.GetHashCode();
      if (HasAggregateValue) 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 (HasIdentifierValue) {
        output.WriteRawTag(26);
        output.WriteString(IdentifierValue);
      }
      if (HasPositiveIntValue) {
        output.WriteRawTag(32);
        output.WriteUInt64(PositiveIntValue);
      }
      if (HasNegativeIntValue) {
        output.WriteRawTag(40);
        output.WriteInt64(NegativeIntValue);
      }
      if (HasDoubleValue) {
        output.WriteRawTag(49);
        output.WriteDouble(DoubleValue);
      }
      if (HasStringValue) {
        output.WriteRawTag(58);
        output.WriteBytes(StringValue);
      }
      if (HasAggregateValue) {
        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 (HasIdentifierValue) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(IdentifierValue);
      }
      if (HasPositiveIntValue) {
        size += 1 + pb::CodedOutputStream.ComputeUInt64Size(PositiveIntValue);
      }
      if (HasNegativeIntValue) {
        size += 1 + pb::CodedOutputStream.ComputeInt64Size(NegativeIntValue);
      }
      if (HasDoubleValue) {
        size += 1 + 8;
      }
      if (HasStringValue) {
        size += 1 + pb::CodedOutputStream.ComputeBytesSize(StringValue);
      }
      if (HasAggregateValue) {
        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.HasIdentifierValue) {
        IdentifierValue = other.IdentifierValue;
      }
      if (other.HasPositiveIntValue) {
        PositiveIntValue = other.PositiveIntValue;
      }
      if (other.HasNegativeIntValue) {
        NegativeIntValue = other.NegativeIntValue;
      }
      if (other.HasDoubleValue) {
        DoubleValue = other.DoubleValue;
      }
      if (other.HasStringValue) {
        StringValue = other.StringValue;
      }
      if (other.HasAggregateValue) {
        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>
      public sealed partial class NamePart : pb::IMessage<NamePart> {
        private static readonly pb::MessageParser<NamePart> _parser = new pb::MessageParser<NamePart>(() => new NamePart());
        private pb::UnknownFieldSet _unknownFields;
        private int _hasBits0;
        [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() {
          _hasBits0 = other._hasBits0;
          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 readonly static string NamePart_DefaultValue = "";

        private string namePart_;
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public string NamePart_ {
          get { return namePart_ ?? NamePart_DefaultValue; }
          set {
            namePart_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
          }
        }
        /// <summary>Gets whether the "name_part" field is set</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public bool HasNamePart_ {
          get { return namePart_ != null; }
        }
        /// <summary>Clears the value of the "name_part" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void ClearNamePart_() {
          namePart_ = null;
        }

        /// <summary>Field number for the "is_extension" field.</summary>
        public const int IsExtensionFieldNumber = 2;
        private readonly static bool IsExtensionDefaultValue = false;

        private bool isExtension_;
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public bool IsExtension {
          get { if ((_hasBits0 & 1) != 0) { return isExtension_; } else { return IsExtensionDefaultValue; } }
          set {
            _hasBits0 |= 1;
            isExtension_ = value;
          }
        }
        /// <summary>Gets whether the "is_extension" field is set</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public bool HasIsExtension {
          get { return (_hasBits0 & 1) != 0; }
        }
        /// <summary>Clears the value of the "is_extension" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void ClearIsExtension() {
          _hasBits0 &= ~1;
        }

        [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 (HasNamePart_) hash ^= NamePart_.GetHashCode();
          if (HasIsExtension) 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 (HasNamePart_) {
            output.WriteRawTag(10);
            output.WriteString(NamePart_);
          }
          if (HasIsExtension) {
            output.WriteRawTag(16);
            output.WriteBool(IsExtension);
          }
          if (_unknownFields != null) {
            _unknownFields.WriteTo(output);
          }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public int CalculateSize() {
          int size = 0;
          if (HasNamePart_) {
            size += 1 + pb::CodedOutputStream.ComputeStringSize(NamePart_);
          }
          if (HasIsExtension) {
            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.HasNamePart_) {
            NamePart_ = other.NamePart_;
          }
          if (other.HasIsExtension) {
            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>
  public 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 descendant.  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 {
      public 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 readonly static string LeadingCommentsDefaultValue = "";

        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_ ?? LeadingCommentsDefaultValue; }
          set {
            leadingComments_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
          }
        }
        /// <summary>Gets whether the "leading_comments" field is set</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public bool HasLeadingComments {
          get { return leadingComments_ != null; }
        }
        /// <summary>Clears the value of the "leading_comments" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void ClearLeadingComments() {
          leadingComments_ = null;
        }

        /// <summary>Field number for the "trailing_comments" field.</summary>
        public const int TrailingCommentsFieldNumber = 4;
        private readonly static string TrailingCommentsDefaultValue = "";

        private string trailingComments_;
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public string TrailingComments {
          get { return trailingComments_ ?? TrailingCommentsDefaultValue; }
          set {
            trailingComments_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
          }
        }
        /// <summary>Gets whether the "trailing_comments" field is set</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public bool HasTrailingComments {
          get { return trailingComments_ != null; }
        }
        /// <summary>Clears the value of the "trailing_comments" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void ClearTrailingComments() {
          trailingComments_ = null;
        }

        /// <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 (HasLeadingComments) hash ^= LeadingComments.GetHashCode();
          if (HasTrailingComments) 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 (HasLeadingComments) {
            output.WriteRawTag(26);
            output.WriteString(LeadingComments);
          }
          if (HasTrailingComments) {
            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 (HasLeadingComments) {
            size += 1 + pb::CodedOutputStream.ComputeStringSize(LeadingComments);
          }
          if (HasTrailingComments) {
            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.HasLeadingComments) {
            LeadingComments = other.LeadingComments;
          }
          if (other.HasTrailingComments) {
            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>
  public 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 {
      public sealed partial class Annotation : pb::IMessage<Annotation> {
        private static readonly pb::MessageParser<Annotation> _parser = new pb::MessageParser<Annotation>(() => new Annotation());
        private pb::UnknownFieldSet _unknownFields;
        private int _hasBits0;
        [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() {
          _hasBits0 = other._hasBits0;
          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 readonly static string SourceFileDefaultValue = "";

        private string sourceFile_;
        /// <summary>
        /// Identifies the filesystem path to the original source .proto.
        /// </summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public string SourceFile {
          get { return sourceFile_ ?? SourceFileDefaultValue; }
          set {
            sourceFile_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
          }
        }
        /// <summary>Gets whether the "source_file" field is set</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public bool HasSourceFile {
          get { return sourceFile_ != null; }
        }
        /// <summary>Clears the value of the "source_file" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void ClearSourceFile() {
          sourceFile_ = null;
        }

        /// <summary>Field number for the "begin" field.</summary>
        public const int BeginFieldNumber = 3;
        private readonly static int BeginDefaultValue = 0;

        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 { if ((_hasBits0 & 1) != 0) { return begin_; } else { return BeginDefaultValue; } }
          set {
            _hasBits0 |= 1;
            begin_ = value;
          }
        }
        /// <summary>Gets whether the "begin" field is set</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public bool HasBegin {
          get { return (_hasBits0 & 1) != 0; }
        }
        /// <summary>Clears the value of the "begin" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void ClearBegin() {
          _hasBits0 &= ~1;
        }

        /// <summary>Field number for the "end" field.</summary>
        public const int EndFieldNumber = 4;
        private readonly static int EndDefaultValue = 0;

        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 { if ((_hasBits0 & 2) != 0) { return end_; } else { return EndDefaultValue; } }
          set {
            _hasBits0 |= 2;
            end_ = value;
          }
        }
        /// <summary>Gets whether the "end" field is set</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public bool HasEnd {
          get { return (_hasBits0 & 2) != 0; }
        }
        /// <summary>Clears the value of the "end" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void ClearEnd() {
          _hasBits0 &= ~2;
        }

        [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 (HasSourceFile) hash ^= SourceFile.GetHashCode();
          if (HasBegin) hash ^= Begin.GetHashCode();
          if (HasEnd) 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 (HasSourceFile) {
            output.WriteRawTag(18);
            output.WriteString(SourceFile);
          }
          if (HasBegin) {
            output.WriteRawTag(24);
            output.WriteInt32(Begin);
          }
          if (HasEnd) {
            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 (HasSourceFile) {
            size += 1 + pb::CodedOutputStream.ComputeStringSize(SourceFile);
          }
          if (HasBegin) {
            size += 1 + pb::CodedOutputStream.ComputeInt32Size(Begin);
          }
          if (HasEnd) {
            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.HasSourceFile) {
            SourceFile = other.SourceFile;
          }
          if (other.HasBegin) {
            Begin = other.Begin;
          }
          if (other.HasEnd) {
            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
